Send switch timing info in extended switch state netobject

This commit is contained in:
trml 2022-05-24 23:53:40 +02:00
parent 548de3804e
commit 882ddae201
5 changed files with 41 additions and 58 deletions

View file

@ -312,15 +312,13 @@ Objects = [
# Switch state for a player team. # Switch state for a player team.
NetObjectEx("SwitchState", "switch-state@netobj.ddnet.tw", [ NetObjectEx("SwitchState", "switch-state@netobj.ddnet.tw", [
NetIntRange("m_HighestSwitchNumber", 0, 256), NetIntAny("m_HighestSwitchNumber"),
# 256 switches / 32 bits = 8 int32 # 256 switches / 32 bits = 8 int32
NetArray(NetIntAny("m_Status"), 8), NetArray(NetIntAny("m_aStatus"), 8),
]), # send the endtick of up to 4 timed switchers
NetArray(NetIntAny("m_aSwitchNumbers"), 4),
NetObjectEx("SwitchTimeState", "switch-time-state@netobj.ddnet.tw", [ NetArray(NetIntAny("m_aEndTicks"), 4),
NetArray(NetIntAny("m_SwitchNumber"), 4), ], validate_size=False),
NetArray(NetIntAny("m_EndTick"), 4),
]),
# Switch info for map items # Switch info for map items
NetObjectEx("EntityEx", "entity-ex@netobj.ddnet.tw", [ NetObjectEx("EntityEx", "entity-ex@netobj.ddnet.tw", [

View file

@ -1447,14 +1447,31 @@ void CGameClient::OnNewSnapshot()
for(int j = 0; j < (int)Switchers().size(); j++) for(int j = 0; j < (int)Switchers().size(); j++)
{ {
Switchers()[j].m_Status[Team] = (pSwitchStateData->m_Status[j / 32] >> (j % 32)) & 1; Switchers()[j].m_Status[Team] = (pSwitchStateData->m_aStatus[j / 32] >> (j % 32)) & 1;
}
// update const int SnapItemSize = Client()->SnapItemSize(IClient::SNAP_CURRENT, i);
if(Switchers()[j].m_Status[Team]) if(SnapItemSize >= 68)
Switchers()[j].m_Type[Team] = TILE_SWITCHOPEN; {
// update the endtick of up to four timed switchers
for(int j = 0; j < (int)std::size(pSwitchStateData->m_aEndTicks); j++)
{
int SwitchNumber = pSwitchStateData->m_aSwitchNumbers[j];
int EndTick = pSwitchStateData->m_aEndTicks[j];
if(EndTick > 0 && in_range(SwitchNumber, 0, (int)Switchers().size()))
{
Switchers()[SwitchNumber].m_EndTick[Team] = EndTick;
}
}
}
// update switch types
for(auto &Switcher : Switchers())
{
if(Switcher.m_Status[Team])
Switcher.m_Type[Team] = Switcher.m_EndTick[Team] ? TILE_SWITCHTIMEDOPEN : TILE_SWITCHOPEN;
else else
Switchers()[j].m_Type[Team] = TILE_SWITCHCLOSE; Switcher.m_Type[Team] = Switcher.m_EndTick[Team] ? TILE_SWITCHTIMEDCLOSE : TILE_SWITCHCLOSE;
Switchers()[j].m_EndTick[Team] = 0;
} }
if(!GotSwitchStateTeam) if(!GotSwitchStateTeam)
@ -2230,32 +2247,6 @@ void CGameClient::UpdatePrediction()
m_GameWorld.m_WorldConfig.m_PredictWeapons = AntiPingWeapons(); m_GameWorld.m_WorldConfig.m_PredictWeapons = AntiPingWeapons();
m_GameWorld.m_WorldConfig.m_BugDDRaceInput = m_GameInfo.m_BugDDRaceInput; 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 j = 0; j < (int)(sizeof(pSwitchTimeStateData->m_EndTick) / sizeof(pSwitchTimeStateData->m_EndTick[0])); j++)
{
int Team = clamp(Item.m_ID, (int)TEAM_FLOCK, (int)TEAM_SUPER - 1);
int SwitchNum = pSwitchTimeStateData->m_SwitchNumber[j];
int EndTick = pSwitchTimeStateData->m_EndTick[j];
if(in_range(SwitchNum, 0, (int)Switchers().size()) && EndTick > 0)
{
// update EndTick
if(Switchers()[SwitchNum].m_Status[Team])
Switchers()[SwitchNum].m_Type[Team] = TILE_SWITCHTIMEDOPEN;
else
Switchers()[SwitchNum].m_Type[Team] = TILE_SWITCHTIMEDCLOSE;
Switchers()[SwitchNum].m_EndTick[Team] = EndTick;
}
}
}
}
// always update default tune zone, even without character // always update default tune zone, even without character
if(!m_GameWorld.m_WorldConfig.m_UseTuneZones) if(!m_GameWorld.m_WorldConfig.m_UseTuneZones)
m_GameWorld.TuningList()[0] = m_Tuning[g_Config.m_ClDummy]; m_GameWorld.TuningList()[0] = m_Tuning[g_Config.m_ClDummy];

View file

@ -10,6 +10,7 @@
#include <algorithm> #include <algorithm>
#include <engine/shared/config.h> #include <engine/shared/config.h>
#include <game/client/projectile_data.h> #include <game/client/projectile_data.h>
#include <game/mapitems.h>
#include <utility> #include <utility>
////////////////////////////////////////////////// //////////////////////////////////////////////////

View file

@ -46,7 +46,7 @@ void CDraggerBeam::Tick()
if(Server()->Tick() % int(Server()->TickSpeed() * 0.15f) == 0) if(Server()->Tick() % int(Server()->TickSpeed() * 0.15f) == 0)
{ {
if(m_Layer == LAYER_SWITCH && m_Number > 0 && if(m_Layer == LAYER_SWITCH && m_Number > 0 &&
!GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[pTarget->Team()]) !Switchers()[m_Number].m_Status[pTarget->Team()])
{ {
Reset(); Reset();
return; return;

View file

@ -647,14 +647,14 @@ void IGameController::Snap(int SnappingClient)
return; return;
pSwitchState->m_HighestSwitchNumber = clamp((int)GameServer()->Switchers().size() - 1, 0, 255); pSwitchState->m_HighestSwitchNumber = clamp((int)GameServer()->Switchers().size() - 1, 0, 255);
mem_zero(pSwitchState->m_Status, sizeof(pSwitchState->m_Status)); mem_zero(pSwitchState->m_aStatus, sizeof(pSwitchState->m_aStatus));
std::vector<std::pair<int, int>> aEndTicks; // <EndTick, SwitchNumber> std::vector<std::pair<int, int>> aEndTicks; // <EndTick, SwitchNumber>
for(int i = 0; i <= pSwitchState->m_HighestSwitchNumber; i++) for(int i = 0; i <= pSwitchState->m_HighestSwitchNumber; i++)
{ {
int Status = (int)GameServer()->Switchers()[i].m_Status[Team]; int Status = (int)GameServer()->Switchers()[i].m_Status[Team];
pSwitchState->m_Status[i / 32] |= (Status << (i % 32)); pSwitchState->m_aStatus[i / 32] |= (Status << (i % 32));
int EndTick = GameServer()->Switchers()[i].m_EndTick[Team]; 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()) if(EndTick > 0 && EndTick < Server()->Tick() + 3 * Server()->TickSpeed() && GameServer()->Switchers()[i].m_LastUpdateTick[Team] < Server()->Tick())
@ -664,24 +664,17 @@ void IGameController::Snap(int SnappingClient)
} }
} }
// send the endtick of switchers that are about to toggle back (up to some number, prioritizing those with the earliest endticks) // send the endtick of switchers that are about to toggle back (up to four, prioritizing those with the earliest endticks)
CNetObj_SwitchTimeState *pSwitchTimeState = static_cast<CNetObj_SwitchTimeState *>(Server()->SnapNewItem(NETOBJTYPE_SWITCHTIMESTATE, Team, sizeof(CNetObj_SwitchTimeState))); mem_zero(pSwitchState->m_aSwitchNumbers, sizeof(pSwitchState->m_aSwitchNumbers));
if(!pSwitchTimeState) mem_zero(pSwitchState->m_aEndTicks, sizeof(pSwitchState->m_aEndTicks));
return;
std::sort(aEndTicks.begin(), aEndTicks.end()); std::sort(aEndTicks.begin(), aEndTicks.end());
for(int i = 0; i < (int)(sizeof(pSwitchTimeState->m_EndTick) / sizeof(pSwitchTimeState->m_EndTick[0])); i++) const int NumTimedSwitchers = minimum((int)aEndTicks.size(), (int)std::size(pSwitchState->m_aEndTicks));
for(int i = 0; i < NumTimedSwitchers; i++)
{ {
if(i < (int)aEndTicks.size()) pSwitchState->m_aSwitchNumbers[i] = aEndTicks[i].second;
{ pSwitchState->m_aEndTicks[i] = aEndTicks[i].first;
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;
}
} }
} }
} }