mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Add rescuemodes
May `/rescuemode` be case-insensitive clang-tidy conflicts clang-tidy `CMDFLAG_PRACTICE`
This commit is contained in:
parent
3887eea18d
commit
4532a64b2b
|
@ -1652,9 +1652,77 @@ void CGameContext::ConRescue(IConsole::IResult *pResult, void *pUserData)
|
|||
return;
|
||||
}
|
||||
|
||||
bool GoRescue = true;
|
||||
|
||||
if(pPlayer->m_RescueMode == RESCUEMODE_MANUAL)
|
||||
{
|
||||
// if character can't set his rescue state then we should rescue him instead
|
||||
GoRescue = !pChr->TrySetRescue(RESCUEMODE_MANUAL);
|
||||
}
|
||||
|
||||
if(GoRescue)
|
||||
{
|
||||
pChr->Rescue();
|
||||
pChr->UnFreeze();
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConRescueMode(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!CheckClientId(pResult->m_ClientId))
|
||||
return;
|
||||
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientId];
|
||||
if(!pPlayer)
|
||||
return;
|
||||
|
||||
CGameTeams &Teams = pSelf->m_pController->Teams();
|
||||
int Team = pSelf->GetDDRaceTeam(pResult->m_ClientId);
|
||||
if(!g_Config.m_SvRescue && !Teams.IsPractice(Team))
|
||||
{
|
||||
pSelf->SendChatTarget(pPlayer->GetCid(), "Rescue is not enabled on this server and you're not in a team with /practice turned on. Note that you can't earn a rank with practice enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(str_comp_nocase(pResult->GetString(0), "auto") == 0)
|
||||
{
|
||||
if(pPlayer->m_RescueMode != RESCUEMODE_AUTO)
|
||||
{
|
||||
pPlayer->m_RescueMode = RESCUEMODE_AUTO;
|
||||
|
||||
pSelf->SendChatTarget(pPlayer->GetCid(), "Rescue mode changed to auto.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(str_comp_nocase(pResult->GetString(0), "manual") == 0)
|
||||
{
|
||||
if(pPlayer->m_RescueMode != RESCUEMODE_MANUAL)
|
||||
{
|
||||
pPlayer->m_RescueMode = RESCUEMODE_MANUAL;
|
||||
|
||||
pSelf->SendChatTarget(pPlayer->GetCid(), "Rescue mode changed to manual.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(str_comp_nocase(pResult->GetString(0), "list") == 0)
|
||||
{
|
||||
pSelf->SendChatTarget(pPlayer->GetCid(), "Available rescue modes: auto, manual");
|
||||
}
|
||||
else if(str_comp_nocase(pResult->GetString(0), "") == 0)
|
||||
{
|
||||
char aBuf[64];
|
||||
str_format(aBuf, sizeof(aBuf), "Current rescue mode: %s.", pPlayer->m_RescueMode == RESCUEMODE_MANUAL ? "manual" : "auto");
|
||||
pSelf->SendChatTarget(pPlayer->GetCid(), aBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSelf->SendChatTarget(pPlayer->GetCid(), "Unknown argument. Check '/rescuemode list'");
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConTeleTo(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
|
|
|
@ -99,6 +99,7 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
|
|||
SendZoneMsgs(); // we want a entermessage also on spawn
|
||||
GameServer()->SendTuningParams(m_pPlayer->GetCid(), m_TuneZone);
|
||||
|
||||
TrySetRescue(RESCUEMODE_MANUAL);
|
||||
Server()->StartRecord(m_pPlayer->GetCid());
|
||||
|
||||
return true;
|
||||
|
@ -2010,10 +2011,46 @@ void CCharacter::SetTeams(CGameTeams *pTeams)
|
|||
m_Core.SetTeamsCore(&m_pTeams->m_Core);
|
||||
}
|
||||
|
||||
void CCharacter::SetRescue()
|
||||
bool CCharacter::TrySetRescue(int RescueMode)
|
||||
{
|
||||
m_RescueTee.Save(this);
|
||||
m_SetSavePos = true;
|
||||
bool Set = false;
|
||||
if(g_Config.m_SvRescue || ((g_Config.m_SvTeam == SV_TEAM_FORCED_SOLO || Team() > TEAM_FLOCK) && Team() >= TEAM_FLOCK && Team() < TEAM_SUPER))
|
||||
{
|
||||
// check for nearby health pickups (also freeze)
|
||||
bool InHealthPickup = false;
|
||||
if(!m_Core.m_IsInFreeze)
|
||||
{
|
||||
CEntity *apEnts[9];
|
||||
int Num = GameWorld()->FindEntities(m_Pos, GetProximityRadius() + CPickup::ms_CollisionExtraSize, apEnts, std::size(apEnts), CGameWorld::ENTTYPE_PICKUP);
|
||||
for(int i = 0; i < Num; ++i)
|
||||
{
|
||||
CPickup *pPickup = static_cast<CPickup *>(apEnts[i]);
|
||||
if(pPickup->Type() == POWERUP_HEALTH)
|
||||
{
|
||||
// This uses a separate variable InHealthPickup instead of setting m_Core.m_IsInFreeze
|
||||
// as the latter causes freezebars to flicker when standing in the freeze range of a
|
||||
// health pickup. When the same code for client prediction is added, the freezebars
|
||||
// still flicker, but only when standing at the edge of the health pickup's freeze range.
|
||||
InHealthPickup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_Core.m_IsInFreeze && IsGrounded() && !m_Core.m_DeepFrozen && !InHealthPickup)
|
||||
{
|
||||
ForceSetRescue(RescueMode);
|
||||
Set = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Set;
|
||||
}
|
||||
|
||||
void CCharacter::ForceSetRescue(int RescueMode)
|
||||
{
|
||||
m_RescueTee[RescueMode].Save(this);
|
||||
m_SetSavePos[RescueMode] = true;
|
||||
}
|
||||
|
||||
void CCharacter::DDRaceTick()
|
||||
|
@ -2061,35 +2098,9 @@ void CCharacter::DDRaceTick()
|
|||
}
|
||||
}
|
||||
|
||||
// check for nearby health pickups (also freeze)
|
||||
bool InHealthPickup = false;
|
||||
if(!m_Core.m_IsInFreeze)
|
||||
{
|
||||
CEntity *apEnts[9];
|
||||
int Num = GameWorld()->FindEntities(m_Pos, GetProximityRadius() + CPickup::ms_CollisionExtraSize, apEnts, std::size(apEnts), CGameWorld::ENTTYPE_PICKUP);
|
||||
for(int i = 0; i < Num; ++i)
|
||||
{
|
||||
CPickup *pPickup = static_cast<CPickup *>(apEnts[i]);
|
||||
if(pPickup->Type() == POWERUP_HEALTH)
|
||||
{
|
||||
// This uses a separate variable InHealthPickup instead of setting m_Core.m_IsInFreeze
|
||||
// as the latter causes freezebars to flicker when standing in the freeze range of a
|
||||
// health pickup. When the same code for client prediction is added, the freezebars
|
||||
// still flicker, but only when standing at the edge of the health pickup's freeze range.
|
||||
InHealthPickup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look for save position for rescue feature
|
||||
if(g_Config.m_SvRescue || ((g_Config.m_SvTeam == SV_TEAM_FORCED_SOLO || Team() > TEAM_FLOCK) && Team() >= TEAM_FLOCK && Team() < TEAM_SUPER))
|
||||
{
|
||||
if(!m_Core.m_IsInFreeze && IsGrounded() && !m_Core.m_DeepFrozen && !InHealthPickup)
|
||||
{
|
||||
SetRescue();
|
||||
}
|
||||
}
|
||||
// always update auto rescue
|
||||
TrySetRescue(RESCUEMODE_AUTO);
|
||||
|
||||
m_Core.m_Id = GetPlayer()->GetCid();
|
||||
}
|
||||
|
@ -2298,7 +2309,8 @@ void CCharacter::DDRaceInit()
|
|||
m_Paused = false;
|
||||
m_DDRaceState = DDRACE_NONE;
|
||||
m_PrevPos = m_Pos;
|
||||
m_SetSavePos = false;
|
||||
for(bool &Set : m_SetSavePos)
|
||||
Set = false;
|
||||
m_LastBroadcast = 0;
|
||||
m_TeamBeforeSuper = 0;
|
||||
m_Core.m_Id = GetPlayer()->GetCid();
|
||||
|
@ -2348,7 +2360,7 @@ void CCharacter::DDRaceInit()
|
|||
|
||||
void CCharacter::Rescue()
|
||||
{
|
||||
if(m_SetSavePos && !m_Core.m_Super)
|
||||
if(m_SetSavePos[GetPlayer()->m_RescueMode] && !m_Core.m_Super)
|
||||
{
|
||||
if(m_LastRescue + (int64_t)g_Config.m_SvRescueDelay * Server()->TickSpeed() > Server()->Tick())
|
||||
{
|
||||
|
@ -2359,7 +2371,7 @@ void CCharacter::Rescue()
|
|||
}
|
||||
|
||||
float StartTime = m_StartTime;
|
||||
m_RescueTee.Load(this, Team());
|
||||
m_RescueTee[GetPlayer()->m_RescueMode].Load(this, Team());
|
||||
// Don't load these from saved tee:
|
||||
m_Core.m_Vel = vec2(0, 0);
|
||||
m_Core.m_HookState = HOOK_IDLE;
|
||||
|
|
|
@ -166,7 +166,7 @@ private:
|
|||
int m_LastBroadcast;
|
||||
void DDRaceInit();
|
||||
void HandleSkippableTiles(int Index);
|
||||
void SetRescue();
|
||||
void ForceSetRescue(int RescueMode);
|
||||
void DDRaceTick();
|
||||
void DDRacePostCoreTick();
|
||||
void HandleBroadcast();
|
||||
|
@ -174,12 +174,13 @@ private:
|
|||
void SendZoneMsgs();
|
||||
IAntibot *Antibot();
|
||||
|
||||
bool m_SetSavePos;
|
||||
CSaveTee m_RescueTee;
|
||||
bool m_SetSavePos[NUM_RESCUEMODES];
|
||||
CSaveTee m_RescueTee[NUM_RESCUEMODES];
|
||||
|
||||
public:
|
||||
CGameTeams *Teams() { return m_pTeams; }
|
||||
void SetTeams(CGameTeams *pTeams);
|
||||
bool TrySetRescue(int RescueMode);
|
||||
|
||||
void FillAntibot(CAntibotCharacterData *pData);
|
||||
void Pause(bool Pause);
|
||||
|
@ -259,7 +260,7 @@ public:
|
|||
|
||||
bool IsSuper() { return m_Core.m_Super; }
|
||||
|
||||
CSaveTee &GetRescueTeeRef() { return m_RescueTee; }
|
||||
CSaveTee &GetLastRescueTeeRef(int Mode = RESCUEMODE_AUTO) { return m_RescueTee[Mode]; }
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -3689,9 +3689,9 @@ void CGameContext::RegisterChatCommands()
|
|||
Console()->Register("saytimeall", "", CFGFLAG_CHAT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race");
|
||||
Console()->Register("time", "", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message");
|
||||
Console()->Register("timer", "?s['gametimer'|'broadcast'|'both'|'none'|'cycle']", CFGFLAG_CHAT | CFGFLAG_SERVER, ConSetTimerType, this, "Personal Setting of showing time in either broadcast or game/round timer, timer s, where s = broadcast for broadcast, gametimer for game/round timer, cycle for cycle, both for both, none for no timer and nothing to show current status");
|
||||
|
||||
Console()->Register("r", "", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConRescue, this, "Teleport yourself out of freeze (use sv_rescue 1 to enable this feature)");
|
||||
Console()->Register("rescue", "", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConRescue, this, "Teleport yourself out of freeze (use sv_rescue 1 to enable this feature)");
|
||||
Console()->Register("r", "", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConRescue, this, "Teleport yourself out of freeze if auto rescue mode is enabled, otherwise it will set position for rescuing if grounded and teleport you out of freeze if not (use sv_rescue 1 to enable this feature)");
|
||||
Console()->Register("rescue", "", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConRescue, this, "Teleport yourself out of freeze if auto rescue mode is enabled, otherwise it will set position for rescuing if grounded and teleport you out of freeze if not (use sv_rescue 1 to enable this feature)");
|
||||
Console()->Register("rescuemode", "?r['auto'|'manual']", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConRescueMode, this, "Sets one of the two rescue modes (auto or manual). Prints current mode if no arguments provided");
|
||||
Console()->Register("tp", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleTo, this, "Depending on the number of supplied arguments, teleport yourself to; (0.) where you are spectating or aiming; (1.) the specified player name");
|
||||
Console()->Register("teleport", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleTo, this, "Depending on the number of supplied arguments, teleport yourself to; (0.) where you are spectating or aiming; (1.) the specified player name");
|
||||
Console()->Register("tpxy", "f[x] f[y]", CFGFLAG_CHAT | CFGFLAG_SERVER | CMDFLAG_PRACTICE, ConTeleXY, this, "Teleport yourself to the specified coordinates. A tilde (~) can be used to denote your current position, e.g. '/tpxy ~1 ~' to teleport one tile to the right");
|
||||
|
@ -3718,7 +3718,6 @@ void CGameContext::RegisterChatCommands()
|
|||
Console()->Register("unweapons", "", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeUnWeapons, this, "Removes all weapons from you");
|
||||
Console()->Register("ninja", "", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeNinja, this, "Makes you a ninja");
|
||||
Console()->Register("unninja", "", CFGFLAG_CHAT | CMDFLAG_PRACTICE, ConPracticeUnNinja, this, "Removes ninja from you");
|
||||
|
||||
Console()->Register("kill", "", CFGFLAG_CHAT | CFGFLAG_SERVER, ConProtectedKill, this, "Kill yourself when kill-protected during a long game (use f1, kill for regular kill)");
|
||||
}
|
||||
|
||||
|
|
|
@ -457,6 +457,7 @@ private:
|
|||
static void ConTime(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConSetTimerType(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConRescue(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConRescueMode(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConTeleTo(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConTeleXY(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConTeleCursor(IConsole::IResult *pResult, void *pUserData);
|
||||
|
|
|
@ -143,6 +143,7 @@ void CPlayer::Reset()
|
|||
m_VotedForPractice = false;
|
||||
m_SwapTargetsClientId = -1;
|
||||
m_BirthdayAnnounced = false;
|
||||
m_RescueMode = RESCUEMODE_AUTO;
|
||||
}
|
||||
|
||||
static int PlayerFlags_SixToSeven(int Flags)
|
||||
|
|
|
@ -225,6 +225,8 @@ public:
|
|||
int m_SwapTargetsClientId; //Client ID of the swap target for the given player
|
||||
bool m_BirthdayAnnounced;
|
||||
|
||||
int m_RescueMode;
|
||||
|
||||
CSaveTee m_LastTeleTee;
|
||||
};
|
||||
|
||||
|
|
|
@ -236,7 +236,8 @@ void CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
|
|||
{
|
||||
// Always create a rescue tee at the exact location we loaded from so that
|
||||
// the old one gets overwritten.
|
||||
pChr->SetRescue();
|
||||
pChr->ForceSetRescue(RESCUEMODE_AUTO);
|
||||
pChr->ForceSetRescue(RESCUEMODE_MANUAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,13 @@ class CGameWorld;
|
|||
class CCharacter;
|
||||
class CSaveTeam;
|
||||
|
||||
enum
|
||||
{
|
||||
RESCUEMODE_AUTO = 0,
|
||||
RESCUEMODE_MANUAL,
|
||||
NUM_RESCUEMODES
|
||||
};
|
||||
|
||||
class CSaveTee
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -951,7 +951,8 @@ void CGameTeams::SwapTeamCharacters(CPlayer *pPrimaryPlayer, CPlayer *pTargetPla
|
|||
}
|
||||
std::swap(m_aTeeStarted[pPrimaryPlayer->GetCid()], m_aTeeStarted[pTargetPlayer->GetCid()]);
|
||||
std::swap(m_aTeeFinished[pPrimaryPlayer->GetCid()], m_aTeeFinished[pTargetPlayer->GetCid()]);
|
||||
std::swap(pPrimaryPlayer->GetCharacter()->GetRescueTeeRef(), pTargetPlayer->GetCharacter()->GetRescueTeeRef());
|
||||
std::swap(pPrimaryPlayer->GetCharacter()->GetLastRescueTeeRef(RESCUEMODE_AUTO), pTargetPlayer->GetCharacter()->GetLastRescueTeeRef(RESCUEMODE_AUTO));
|
||||
std::swap(pPrimaryPlayer->GetCharacter()->GetLastRescueTeeRef(RESCUEMODE_MANUAL), pTargetPlayer->GetCharacter()->GetLastRescueTeeRef(RESCUEMODE_MANUAL));
|
||||
|
||||
GameServer()->m_World.SwapClients(pPrimaryPlayer->GetCid(), pTargetPlayer->GetCid());
|
||||
|
||||
|
|
Loading…
Reference in a new issue