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
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_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
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;

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;
CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
for(; pC; pC = (CCharacter *)pC->TypeNext())
{
// team mates are not as dangerous as enemies
float Scoremod = 1.0f;
if(pEval->m_FriendlyTeam != -1 && pC->GetPlayer()->GetTeam() == pEval->m_FriendlyTeam)
Scoremod = 0.5f;
// ignore players in other teams
if(GameServer()->GetDDRaceTeam(pC->GetPlayer()->GetCID()) != DDTeam)
continue;
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;
}
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
for(int j = 0; j < 2 && !pEval->m_Got; j++)
@ -153,7 +152,7 @@ void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type)
P += Positions[Result];
}
float S = EvaluateSpawnPos(pEval, P);
float S = EvaluateSpawnPos(pEval, P, DDTeam);
if(!pEval->m_Got || (j == 0 && pEval->m_Score > S))
{
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;
@ -172,9 +171,9 @@ bool IGameController::CanSpawn(int Team, vec2 *pOutPos)
if(Team == TEAM_SPECTATORS)
return false;
EvaluateSpawnType(&Eval, 0);
EvaluateSpawnType(&Eval, 1);
EvaluateSpawnType(&Eval, 2);
EvaluateSpawnType(&Eval, 0, DDTeam);
EvaluateSpawnType(&Eval, 1, DDTeam);
EvaluateSpawnType(&Eval, 2, DDTeam);
*pOutPos = Eval.m_Pos;
return Eval.m_Got;

View file

@ -44,8 +44,8 @@ protected:
float m_Score;
};
float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos);
void EvaluateSpawnType(CSpawnEval *pEval, int Type);
float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos, int DDTeam);
void EvaluateSpawnType(CSpawnEval *pEval, int Type, int DDTeam);
void ResetGame();
@ -131,7 +131,7 @@ public:
virtual void Snap(int SnappingClient);
//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);
/*

View file

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