4661: Make spawn position independent of players in other teams r=heinrich5991 a=def-

As suggested by Rockus, should help speedrunners who get followed by
other players

<!-- What is the motivation for the changes of this pull request -->

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: def <dennis@felsin9.de>
This commit is contained in:
bors[bot] 2022-02-06 12:50:04 +00:00 committed by GitHub
commit 00f93da936
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 18 deletions

View file

@ -1935,7 +1935,7 @@ void CCharacter::HandleTiles(int Index)
} }
// if no checkpointout have been found (or if there no recorded checkpoint), teleport to start // if no checkpointout have been found (or if there no recorded checkpoint), teleport to start
vec2 SpawnPos; vec2 SpawnPos;
if(GameServer()->m_pController->CanSpawn(m_pPlayer->GetTeam(), &SpawnPos)) if(GameServer()->m_pController->CanSpawn(m_pPlayer->GetTeam(), &SpawnPos, GameServer()->GetDDRaceTeam(GetPlayer()->GetCID())))
{ {
m_Core.m_Pos = SpawnPos; m_Core.m_Pos = SpawnPos;
m_Core.m_Vel = vec2(0, 0); m_Core.m_Vel = vec2(0, 0);
@ -1970,7 +1970,7 @@ void CCharacter::HandleTiles(int Index)
} }
// if no checkpointout have been found (or if there no recorded checkpoint), teleport to start // if no checkpointout have been found (or if there no recorded checkpoint), teleport to start
vec2 SpawnPos; vec2 SpawnPos;
if(GameServer()->m_pController->CanSpawn(m_pPlayer->GetTeam(), &SpawnPos)) if(GameServer()->m_pController->CanSpawn(m_pPlayer->GetTeam(), &SpawnPos, GameServer()->GetDDRaceTeam(GetPlayer()->GetCID())))
{ {
m_Core.m_Pos = SpawnPos; m_Core.m_Pos = SpawnPos;

View file

@ -99,25 +99,24 @@ void IGameController::DoActivityCheck()
} }
} }
float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos) float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos, int DDTeam)
{ {
float Score = 0.0f; float Score = 0.0f;
CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER)); CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
for(; pC; pC = (CCharacter *)pC->TypeNext()) for(; pC; pC = (CCharacter *)pC->TypeNext())
{ {
// team mates are not as dangerous as enemies // ignore players in other teams
float Scoremod = 1.0f; if(GameServer()->GetDDRaceTeam(pC->GetPlayer()->GetCID()) != DDTeam)
if(pEval->m_FriendlyTeam != -1 && pC->GetPlayer()->GetTeam() == pEval->m_FriendlyTeam) continue;
Scoremod = 0.5f;
float d = distance(Pos, pC->m_Pos); float d = distance(Pos, pC->m_Pos);
Score += Scoremod * (d == 0 ? 1000000000.0f : 1.0f / d); Score += d == 0 ? 1000000000.0f : 1.0f / d;
} }
return Score; return Score;
} }
void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type) void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type, int DDTeam)
{ {
// j == 0: Find an empty slot, j == 1: Take any slot if no empty one found // j == 0: Find an empty slot, j == 1: Take any slot if no empty one found
for(int j = 0; j < 2 && !pEval->m_Got; j++) for(int j = 0; j < 2 && !pEval->m_Got; j++)
@ -153,7 +152,7 @@ void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type)
P += Positions[Result]; P += Positions[Result];
} }
float S = EvaluateSpawnPos(pEval, P); float S = EvaluateSpawnPos(pEval, P, DDTeam);
if(!pEval->m_Got || (j == 0 && pEval->m_Score > S)) if(!pEval->m_Got || (j == 0 && pEval->m_Score > S))
{ {
pEval->m_Got = true; pEval->m_Got = true;
@ -164,7 +163,7 @@ void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type)
} }
} }
bool IGameController::CanSpawn(int Team, vec2 *pOutPos) bool IGameController::CanSpawn(int Team, vec2 *pOutPos, int DDTeam)
{ {
CSpawnEval Eval; CSpawnEval Eval;
@ -172,9 +171,9 @@ bool IGameController::CanSpawn(int Team, vec2 *pOutPos)
if(Team == TEAM_SPECTATORS) if(Team == TEAM_SPECTATORS)
return false; return false;
EvaluateSpawnType(&Eval, 0); EvaluateSpawnType(&Eval, 0, DDTeam);
EvaluateSpawnType(&Eval, 1); EvaluateSpawnType(&Eval, 1, DDTeam);
EvaluateSpawnType(&Eval, 2); EvaluateSpawnType(&Eval, 2, DDTeam);
*pOutPos = Eval.m_Pos; *pOutPos = Eval.m_Pos;
return Eval.m_Got; return Eval.m_Got;

View file

@ -44,8 +44,8 @@ protected:
float m_Score; float m_Score;
}; };
float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos); float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos, int DDTeam);
void EvaluateSpawnType(CSpawnEval *pEval, int Type); void EvaluateSpawnType(CSpawnEval *pEval, int Type, int DDTeam);
void ResetGame(); void ResetGame();
@ -131,7 +131,7 @@ public:
virtual void Snap(int SnappingClient); virtual void Snap(int SnappingClient);
//spawn //spawn
virtual bool CanSpawn(int Team, vec2 *pOutPos); virtual bool CanSpawn(int Team, vec2 *pOutPos, int DDTeam);
virtual void DoTeamChange(class CPlayer *pPlayer, int Team, bool DoChatMsg = true); virtual void DoTeamChange(class CPlayer *pPlayer, int Team, bool DoChatMsg = true);
/* /*

View file

@ -692,7 +692,7 @@ void CPlayer::TryRespawn()
{ {
vec2 SpawnPos; vec2 SpawnPos;
if(!GameServer()->m_pController->CanSpawn(m_Team, &SpawnPos)) if(!GameServer()->m_pController->CanSpawn(m_Team, &SpawnPos, GameServer()->GetDDRaceTeam(m_ClientID)))
return; return;
m_WeakHookSpawn = false; m_WeakHookSpawn = false;