Send timer info for switchers and predict switch state changes

This commit is contained in:
trml 2022-02-13 21:29:36 +01:00
parent 95c4c2db1c
commit 66c0c1e692
8 changed files with 135 additions and 62 deletions

View file

@ -317,6 +317,11 @@ Objects = [
NetArray(NetIntAny("m_Status"), 8),
]),
NetObjectEx("SwitchTimeState", "switch-time-state@netobj.ddnet.tw", [
NetArray(NetIntAny("m_SwitchNumber"), 4),
NetArray(NetIntAny("m_EndTick"), 4),
]),
# Switch info for map items
NetObjectEx("EntityEx", "entity-ex@netobj.ddnet.tw", [
NetIntAny("m_SwitchNumber"),

View file

@ -2230,6 +2230,32 @@ void CGameClient::UpdatePrediction()
m_GameWorld.m_WorldConfig.m_PredictWeapons = AntiPingWeapons();
m_GameWorld.m_WorldConfig.m_BugDDRaceInput = m_GameInfo.m_BugDDRaceInput;
int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT);
for(int i = 0; i < Num; i++)
{
IClient::CSnapItem Item;
const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item);
if(Item.m_Type == NETOBJTYPE_SWITCHTIMESTATE)
{
const CNetObj_SwitchTimeState *pSwitchTimeStateData = (const CNetObj_SwitchTimeState *)pData;
for(int i = 0; i < (int)(sizeof(pSwitchTimeStateData->m_EndTick) / sizeof(pSwitchTimeStateData->m_EndTick[0])); i++)
{
int Team = clamp(Item.m_ID, (int)TEAM_FLOCK, (int)TEAM_SUPER - 1);
int Num = pSwitchTimeStateData->m_SwitchNumber[i];
int EndTick = pSwitchTimeStateData->m_EndTick[i];
if(in_range(Num, 0, (int)Switchers().size()) && EndTick > 0)
{
// update EndTick
if(Switchers()[Num].m_Status[Team])
Switchers()[Num].m_Type[Team] = TILE_SWITCHTIMEDOPEN;
else
Switchers()[Num].m_Type[Team] = TILE_SWITCHTIMEDCLOSE;
Switchers()[Num].m_EndTick[Team] = EndTick;
}
}
}
}
// always update default tune zone, even without character
if(!m_GameWorld.m_WorldConfig.m_UseTuneZones)
m_GameWorld.TuningList()[0] = m_Tuning[g_Config.m_ClDummy];

View file

@ -699,7 +699,35 @@ void CCharacter::HandleTiles(int Index)
}
// handle switch tiles
if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = GameWorld()->GameTick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = GameWorld()->GameTick() + 1 + Collision()->GetSwitchDelay(MapIndex) * GameWorld()->GameTickSpeed();
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = GameWorld()->GameTick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDCLOSE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = GameWorld()->GameTick() + 1 + Collision()->GetSwitchDelay(MapIndex) * GameWorld()->GameTickSpeed();
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = GameWorld()->GameTick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHCLOSE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = GameWorld()->GameTick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
{
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{

View file

@ -199,6 +199,29 @@ void CGameWorld::Tick()
RemoveEntities();
// update switch state
if(Collision()->m_NumSwitchers > 0)
{
for(int i = 0; i < (int)Switchers().size(); ++i)
{
for(int j = 0; j < MAX_CLIENTS; ++j)
{
if(Switchers()[i].m_EndTick[j] <= GameTick() && Switchers()[i].m_Type[j] == TILE_SWITCHTIMEDOPEN)
{
Switchers()[i].m_Status[j] = false;
Switchers()[i].m_EndTick[j] = 0;
Switchers()[i].m_Type[j] = TILE_SWITCHCLOSE;
}
else if(Switchers()[i].m_EndTick[j] <= GameTick() && Switchers()[i].m_Type[j] == TILE_SWITCHTIMEDCLOSE)
{
Switchers()[i].m_Status[j] = true;
Switchers()[i].m_EndTick[j] = 0;
Switchers()[i].m_Type[j] = TILE_SWITCHOPEN;
}
}
}
}
OnModified();
}

View file

@ -670,6 +670,7 @@ void CWorldCore::InitSwitchers(int NumSwitchers)
m_aSwitchers[i].m_Status[j] = true;
m_aSwitchers[i].m_EndTick[j] = 0;
m_aSwitchers[i].m_Type[j] = 0;
m_aSwitchers[i].m_LastUpdateTick[j] = 0;
}
}
}

View file

@ -180,6 +180,7 @@ struct SSwitchers
bool m_Initial;
int m_EndTick[MAX_CLIENTS];
int m_Type[MAX_CLIENTS];
int m_LastUpdateTick[MAX_CLIENTS];
};
class CWorldCore

View file

@ -1599,88 +1599,52 @@ void CCharacter::HandleTiles(int Index)
// handle switch tiles
if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
<<<<<<< HEAD
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN;
=======
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN;
>>>>>>> b7ea8837e (Move switch state to gamecore)
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHOPEN;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = Server()->Tick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDOPEN && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
<<<<<<< HEAD
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN;
=======
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + GameServer()->Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN;
>>>>>>> b7ea8837e (Move switch state to gamecore)
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = true;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDOPEN;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = Server()->Tick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHTIMEDCLOSE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
<<<<<<< HEAD
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE;
=======
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + GameServer()->Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE;
>>>>>>> b7ea8837e (Move switch state to gamecore)
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = Server()->Tick() + 1 + Collision()->GetSwitchDelay(MapIndex) * Server()->TickSpeed();
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHTIMEDCLOSE;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = Server()->Tick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_SWITCHCLOSE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) > 0)
{
<<<<<<< HEAD
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE;
=======
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE;
>>>>>>> b7ea8837e (Move switch state to gamecore)
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()] = false;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_EndTick[Team()] = 0;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Type[Team()] = TILE_SWITCHCLOSE;
Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_LastUpdateTick[Team()] = Server()->Tick();
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER)
{
<<<<<<< HEAD
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
=======
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
>>>>>>> b7ea8837e (Move switch state to gamecore)
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{
Freeze(Collision()->GetSwitchDelay(MapIndex));
}
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER)
{
<<<<<<< HEAD
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
=======
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
>>>>>>> b7ea8837e (Move switch state to gamecore)
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
m_DeepFreeze = true;
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER)
{
<<<<<<< HEAD
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
=======
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
>>>>>>> b7ea8837e (Move switch state to gamecore)
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
m_DeepFreeze = false;
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_LFREEZE && Team() != TEAM_SUPER)
{
<<<<<<< HEAD
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
=======
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
>>>>>>> b7ea8837e (Move switch state to gamecore)
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{
m_LiveFreeze = true;
m_Core.m_LiveFrozen = true;
@ -1688,11 +1652,7 @@ void CCharacter::HandleTiles(int Index)
}
else if(Collision()->GetSwitchType(MapIndex) == TILE_LUNFREEZE && Team() != TEAM_SUPER)
{
<<<<<<< HEAD
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
=======
if(GameServer()->Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[GameServer()->Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
>>>>>>> b7ea8837e (Move switch state to gamecore)
if(Collision()->GetSwitchNumber(MapIndex) == 0 || Switchers()[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()])
{
m_LiveFreeze = false;
m_Core.m_LiveFrozen = false;

View file

@ -649,10 +649,39 @@ void IGameController::Snap(int SnappingClient)
pSwitchState->m_NumSwitchers = clamp(GameServer()->Collision()->m_NumSwitchers, 0, 255);
mem_zero(pSwitchState->m_Status, sizeof(pSwitchState->m_Status));
std::vector<std::pair<int, int>> aEndTicks; // <EndTick, SwitchNumber>
for(int i = 0; i < pSwitchState->m_NumSwitchers + 1; i++)
{
int Status = (int)GameServer()->Switchers()[i].m_Status[Team];
pSwitchState->m_Status[i / 32] |= (Status << (i % 32));
int EndTick = GameServer()->Switchers()[i].m_EndTick[Team];
if(EndTick > 0 && EndTick < Server()->Tick() + 3 * Server()->TickSpeed() && GameServer()->Switchers()[i].m_LastUpdateTick[Team] < Server()->Tick())
{
// only keep track of EndTicks that have less than three second left and are not currently being updated by a player being present on a switch tile, to limit how often these are sent
aEndTicks.push_back({GameServer()->Switchers()[i].m_EndTick[Team], i});
}
}
// send the endtick of switchers that are about to toggle back (up to some number, prioritizing those with the earliest endticks)
CNetObj_SwitchTimeState *pSwitchTimeState = static_cast<CNetObj_SwitchTimeState *>(Server()->SnapNewItem(NETOBJTYPE_SWITCHTIMESTATE, Team, sizeof(CNetObj_SwitchTimeState)));
if(!pSwitchTimeState)
return;
std::sort(aEndTicks.begin(), aEndTicks.end());
for(int i = 0; i < (int)(sizeof(pSwitchTimeState->m_EndTick) / sizeof(pSwitchTimeState->m_EndTick[0])); i++)
{
if(i < (int)aEndTicks.size())
{
pSwitchTimeState->m_EndTick[i] = aEndTicks[i].first;
pSwitchTimeState->m_SwitchNumber[i] = aEndTicks[i].second;
}
else
{
pSwitchTimeState->m_SwitchNumber[i] = -1;
pSwitchTimeState->m_EndTick[i] = 0;
}
}
}
}