Merge pull request #7602 from ChillerDragon/pr_create_switcherscontroller

Move switcher snapping code to own method
This commit is contained in:
heinrich5991 2023-12-13 22:10:49 +00:00 committed by GitHub
commit efe593c7b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 49 deletions

View file

@ -380,6 +380,60 @@ void CGameContext::CreateSoundGlobal(int Sound, int Target)
}
}
void CGameContext::SnapSwitchers(int SnappingClient)
{
if(Switchers().empty())
return;
CPlayer *pPlayer = SnappingClient != SERVER_DEMO_CLIENT ? m_apPlayers[SnappingClient] : 0;
int Team = pPlayer && pPlayer->GetCharacter() ? pPlayer->GetCharacter()->Team() : 0;
if(pPlayer && (pPlayer->GetTeam() == TEAM_SPECTATORS || pPlayer->IsPaused()) && pPlayer->m_SpectatorID != SPEC_FREEVIEW && m_apPlayers[pPlayer->m_SpectatorID] && m_apPlayers[pPlayer->m_SpectatorID]->GetCharacter())
Team = m_apPlayers[pPlayer->m_SpectatorID]->GetCharacter()->Team();
if(Team == TEAM_SUPER)
return;
int SentTeam = Team;
if(g_Config.m_SvTeam == SV_TEAM_FORCED_SOLO)
SentTeam = 0;
CNetObj_SwitchState *pSwitchState = Server()->SnapNewItem<CNetObj_SwitchState>(SentTeam);
if(!pSwitchState)
return;
pSwitchState->m_HighestSwitchNumber = clamp((int)Switchers().size() - 1, 0, 255);
mem_zero(pSwitchState->m_aStatus, sizeof(pSwitchState->m_aStatus));
std::vector<std::pair<int, int>> vEndTicks; // <EndTick, SwitchNumber>
for(int i = 0; i <= pSwitchState->m_HighestSwitchNumber; i++)
{
int Status = (int)Switchers()[i].m_aStatus[Team];
pSwitchState->m_aStatus[i / 32] |= (Status << (i % 32));
int EndTick = Switchers()[i].m_aEndTick[Team];
if(EndTick > 0 && EndTick < Server()->Tick() + 3 * Server()->TickSpeed() && Switchers()[i].m_aLastUpdateTick[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
vEndTicks.emplace_back(Switchers()[i].m_aEndTick[Team], i);
}
}
// send the endtick of switchers that are about to toggle back (up to four, prioritizing those with the earliest endticks)
mem_zero(pSwitchState->m_aSwitchNumbers, sizeof(pSwitchState->m_aSwitchNumbers));
mem_zero(pSwitchState->m_aEndTicks, sizeof(pSwitchState->m_aEndTicks));
std::sort(vEndTicks.begin(), vEndTicks.end());
const int NumTimedSwitchers = minimum((int)vEndTicks.size(), (int)std::size(pSwitchState->m_aEndTicks));
for(int i = 0; i < NumTimedSwitchers; i++)
{
pSwitchState->m_aSwitchNumbers[i] = vEndTicks[i].second;
pSwitchState->m_aEndTicks[i] = vEndTicks[i].first;
}
}
bool CGameContext::SnapLaserObject(const CSnapContext &Context, int SnapID, const vec2 &To, const vec2 &From, int StartTick, int Owner, int LaserType, int Subtype, int SwitchNumber)
{
if(Context.GetClientVersion() >= VERSION_DDNET_MULTI_LASER)

View file

@ -239,6 +239,7 @@ public:
void CreateSound(vec2 Pos, int Sound, CClientMask Mask = CClientMask().set());
void CreateSoundGlobal(int Sound, int Target = -1);
void SnapSwitchers(int SnappingClient);
bool SnapLaserObject(const CSnapContext &Context, int SnapID, const vec2 &To, const vec2 &From, int StartTick, int Owner = -1, int LaserType = -1, int Subtype = -1, int SwitchNumber = -1);
bool SnapPickup(const CSnapContext &Context, int SnapID, const vec2 &Pos, int Type, int SubType, int SwitchNumber);

View file

@ -645,55 +645,7 @@ void IGameController::Snap(int SnappingClient)
pRaceData->m_RaceFlags = protocol7::RACEFLAG_HIDE_KILLMSG | protocol7::RACEFLAG_KEEP_WANTED_WEAPON;
}
if(!GameServer()->Switchers().empty())
{
int Team = pPlayer && pPlayer->GetCharacter() ? pPlayer->GetCharacter()->Team() : 0;
if(pPlayer && (pPlayer->GetTeam() == TEAM_SPECTATORS || pPlayer->IsPaused()) && pPlayer->m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[pPlayer->m_SpectatorID] && GameServer()->m_apPlayers[pPlayer->m_SpectatorID]->GetCharacter())
Team = GameServer()->m_apPlayers[pPlayer->m_SpectatorID]->GetCharacter()->Team();
if(Team == TEAM_SUPER)
return;
int SentTeam = Team;
if(g_Config.m_SvTeam == SV_TEAM_FORCED_SOLO)
SentTeam = 0;
CNetObj_SwitchState *pSwitchState = Server()->SnapNewItem<CNetObj_SwitchState>(SentTeam);
if(!pSwitchState)
return;
pSwitchState->m_HighestSwitchNumber = clamp((int)GameServer()->Switchers().size() - 1, 0, 255);
mem_zero(pSwitchState->m_aStatus, sizeof(pSwitchState->m_aStatus));
std::vector<std::pair<int, int>> vEndTicks; // <EndTick, SwitchNumber>
for(int i = 0; i <= pSwitchState->m_HighestSwitchNumber; i++)
{
int Status = (int)GameServer()->Switchers()[i].m_aStatus[Team];
pSwitchState->m_aStatus[i / 32] |= (Status << (i % 32));
int EndTick = GameServer()->Switchers()[i].m_aEndTick[Team];
if(EndTick > 0 && EndTick < Server()->Tick() + 3 * Server()->TickSpeed() && GameServer()->Switchers()[i].m_aLastUpdateTick[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
vEndTicks.emplace_back(GameServer()->Switchers()[i].m_aEndTick[Team], i);
}
}
// send the endtick of switchers that are about to toggle back (up to four, prioritizing those with the earliest endticks)
mem_zero(pSwitchState->m_aSwitchNumbers, sizeof(pSwitchState->m_aSwitchNumbers));
mem_zero(pSwitchState->m_aEndTicks, sizeof(pSwitchState->m_aEndTicks));
std::sort(vEndTicks.begin(), vEndTicks.end());
const int NumTimedSwitchers = minimum((int)vEndTicks.size(), (int)std::size(pSwitchState->m_aEndTicks));
for(int i = 0; i < NumTimedSwitchers; i++)
{
pSwitchState->m_aSwitchNumbers[i] = vEndTicks[i].second;
pSwitchState->m_aEndTicks[i] = vEndTicks[i].first;
}
}
GameServer()->SnapSwitchers(SnappingClient);
}
int IGameController::GetAutoTeam(int NotThisID)