mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #2424
2424: Keep hook when loading r=heinrich5991 a=Zwelf Solves issue discussed in #2374. Also keeps direction and jump, which is evaluated when player is in /pause. Fire could be deleted, as it does not affect game play in any way. Co-authored-by: Zwelf <zwelf@strct.cc>
This commit is contained in:
commit
98779776e5
|
@ -93,6 +93,15 @@ void CSaveTee::save(CCharacter *pChr)
|
|||
m_HookTick = pChr->m_Core.m_HookTick;
|
||||
|
||||
m_HookState = pChr->m_Core.m_HookState;
|
||||
m_HookedPlayer = pChr->m_Core.m_HookedPlayer;
|
||||
m_NewHook = pChr->m_Core.m_NewHook != 0;
|
||||
|
||||
m_InputDirection = pChr->m_SavedInput.m_Direction;
|
||||
m_InputJump = pChr->m_SavedInput.m_Jump;
|
||||
m_InputFire = pChr->m_SavedInput.m_Fire;
|
||||
m_InputHook = pChr->m_SavedInput.m_Hook;
|
||||
|
||||
m_ReloadTimer = pChr->m_ReloadTimer;
|
||||
|
||||
FormatUuid(pChr->GameServer()->GameUuid(), m_aGameUuid, sizeof(m_aGameUuid));
|
||||
}
|
||||
|
@ -171,15 +180,23 @@ void CSaveTee::load(CCharacter *pChr, int Team)
|
|||
|
||||
pChr->m_Core.m_HookTick = m_HookTick;
|
||||
|
||||
if(m_HookState == HOOK_GRABBED)
|
||||
pChr->m_Core.m_HookState = m_HookState;
|
||||
if(m_HookedPlayer != -1 && pChr->Teams()->m_Core.Team(m_HookedPlayer) != Team)
|
||||
{
|
||||
pChr->m_Core.m_HookState = HOOK_FLYING;
|
||||
pChr->m_Core.m_HookedPlayer = -1;
|
||||
pChr->m_Core.m_HookState = HOOK_FLYING;
|
||||
}
|
||||
else
|
||||
{
|
||||
pChr->m_Core.m_HookState = m_HookState;
|
||||
pChr->m_Core.m_HookedPlayer = m_HookedPlayer;
|
||||
}
|
||||
pChr->m_Core.m_NewHook = m_NewHook;
|
||||
pChr->m_SavedInput.m_Direction = m_InputDirection;
|
||||
pChr->m_SavedInput.m_Jump = m_InputJump;
|
||||
pChr->m_SavedInput.m_Fire = m_InputFire;
|
||||
pChr->m_SavedInput.m_Hook = m_InputHook;
|
||||
|
||||
pChr->m_ReloadTimer = m_ReloadTimer;
|
||||
|
||||
pChr->SetSolo(m_IsSolo);
|
||||
|
||||
|
@ -188,11 +205,24 @@ void CSaveTee::load(CCharacter *pChr, int Team)
|
|||
pChr->SetRescue();
|
||||
}
|
||||
|
||||
char* CSaveTee::GetString()
|
||||
char* CSaveTee::GetString(const CSaveTeam *pTeam)
|
||||
{
|
||||
// Add time penalty of 60 seconds (only to the database)
|
||||
int Time = m_Time + 60 * SERVER_TICK_SPEED;
|
||||
|
||||
int HookedPlayer = -1;
|
||||
if(m_HookedPlayer != -1)
|
||||
{
|
||||
for(int n = 0; n < pTeam->GetMembersCount(); n++)
|
||||
{
|
||||
if(m_HookedPlayer == pTeam->m_pSavedTees[n].GetClientID())
|
||||
{
|
||||
HookedPlayer = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
str_format(m_aString, sizeof(m_aString),
|
||||
"%s\t%d\t%d\t%d\t%d\t%d\t"
|
||||
// weapons
|
||||
|
@ -221,7 +251,10 @@ char* CSaveTee::GetString()
|
|||
"%f\t%f\t%f\t%f\t%f\t"
|
||||
"%d\t"
|
||||
"%d\t%d\t%d\t"
|
||||
"%s",
|
||||
"%s\t"
|
||||
"%d\t%d\t"
|
||||
"%d\t%d\t%d\t%d\t"
|
||||
"%d",
|
||||
m_aName, m_Alive, m_Paused, m_NeededFaketuning, m_TeeFinished, m_IsSolo,
|
||||
// weapons
|
||||
m_aWeapons[0].m_AmmoRegenStart, m_aWeapons[0].m_Ammo, m_aWeapons[0].m_Ammocost, m_aWeapons[0].m_Got,
|
||||
|
@ -249,7 +282,10 @@ char* CSaveTee::GetString()
|
|||
m_aCpCurrent[20], m_aCpCurrent[21], m_aCpCurrent[22], m_aCpCurrent[23], m_aCpCurrent[24],
|
||||
m_NotEligibleForFinish,
|
||||
m_HasTelegunGun, m_HasTelegunLaser, m_HasTelegunGrenade,
|
||||
m_aGameUuid
|
||||
m_aGameUuid,
|
||||
HookedPlayer, m_NewHook,
|
||||
m_InputDirection, m_InputJump, m_InputFire, m_InputHook,
|
||||
m_ReloadTimer
|
||||
);
|
||||
return m_aString;
|
||||
}
|
||||
|
@ -285,7 +321,10 @@ int CSaveTee::LoadString(const char* String)
|
|||
"%f\t%f\t%f\t%f\t%f\t"
|
||||
"%d\t"
|
||||
"%d\t%d\t%d\t"
|
||||
"%*s", // discard the game uuid
|
||||
"%*s\t" // discard the game uuid
|
||||
"%d\t%d"
|
||||
"%d\t%d\t%d\t%d\t"
|
||||
"%d",
|
||||
m_aName, &m_Alive, &m_Paused, &m_NeededFaketuning, &m_TeeFinished, &m_IsSolo,
|
||||
// weapons
|
||||
&m_aWeapons[0].m_AmmoRegenStart, &m_aWeapons[0].m_Ammo, &m_aWeapons[0].m_Ammocost, &m_aWeapons[0].m_Got,
|
||||
|
@ -312,7 +351,10 @@ int CSaveTee::LoadString(const char* String)
|
|||
&m_aCpCurrent[15], &m_aCpCurrent[16], &m_aCpCurrent[17], &m_aCpCurrent[18], &m_aCpCurrent[19],
|
||||
&m_aCpCurrent[20], &m_aCpCurrent[21], &m_aCpCurrent[22], &m_aCpCurrent[23], &m_aCpCurrent[24],
|
||||
&m_NotEligibleForFinish,
|
||||
&m_HasTelegunGun, &m_HasTelegunLaser, &m_HasTelegunGrenade
|
||||
&m_HasTelegunGun, &m_HasTelegunLaser, &m_HasTelegunGrenade,
|
||||
&m_HookedPlayer, &m_NewHook,
|
||||
&m_InputDirection, &m_InputJump, &m_InputFire, &m_InputHook,
|
||||
&m_ReloadTimer
|
||||
);
|
||||
switch(Num) // Don't forget to update this when you save / load more / less.
|
||||
{
|
||||
|
@ -325,6 +367,17 @@ int CSaveTee::LoadString(const char* String)
|
|||
m_HasTelegunGun = 0;
|
||||
// fall through
|
||||
case 100:
|
||||
m_HookedPlayer = -1;
|
||||
m_NewHook = false;
|
||||
if(m_HookState == HOOK_GRABBED)
|
||||
m_HookState = HOOK_FLYING;
|
||||
m_InputDirection = 0;
|
||||
m_InputJump = 0;
|
||||
m_InputFire = 0;
|
||||
m_InputHook = 0;
|
||||
m_ReloadTimer = 0;
|
||||
// fall through
|
||||
case 107:
|
||||
return 0;
|
||||
default:
|
||||
dbg_msg("load", "failed to load tee-string");
|
||||
|
@ -333,6 +386,13 @@ int CSaveTee::LoadString(const char* String)
|
|||
}
|
||||
}
|
||||
|
||||
void CSaveTee::LoadHookedPlayer(const CSaveTeam *pTeam)
|
||||
{
|
||||
if(m_HookedPlayer == -1)
|
||||
return;
|
||||
m_HookedPlayer = pTeam->m_pSavedTees[m_HookedPlayer].GetClientID();
|
||||
}
|
||||
|
||||
CSaveTeam::CSaveTeam(IGameController* Controller)
|
||||
{
|
||||
m_pController = Controller;
|
||||
|
@ -373,17 +433,18 @@ int CSaveTeam::save(int Team)
|
|||
|
||||
m_pSavedTees = new CSaveTee[m_MembersCount];
|
||||
int j = 0;
|
||||
for (int i = 0; i < MAX_CLIENTS; i++)
|
||||
CCharacter *p = (CCharacter *)m_pController->GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER);
|
||||
for(; p; p = (CCharacter *)p->TypeNext())
|
||||
{
|
||||
if(Teams->m_Core.Team(i) == Team)
|
||||
{
|
||||
if(m_pController->GameServer()->m_apPlayers[i] && m_pController->GameServer()->m_apPlayers[i]->GetCharacter())
|
||||
m_pSavedTees[j].save(m_pController->GameServer()->m_apPlayers[i]->GetCharacter());
|
||||
else
|
||||
return 3;
|
||||
j++;
|
||||
}
|
||||
if(m_MembersCount == j)
|
||||
return 3;
|
||||
if(Teams->m_Core.Team(p->GetPlayer()->GetCID()) != Team)
|
||||
continue;
|
||||
m_pSavedTees[j].save(p);
|
||||
j++;
|
||||
}
|
||||
if(m_MembersCount != j)
|
||||
return 3;
|
||||
|
||||
if(m_pController->GameServer()->Collision()->m_NumSwitchers)
|
||||
{
|
||||
|
@ -439,7 +500,7 @@ void CSaveTeam::load(int Team)
|
|||
if(m_Practice)
|
||||
pTeams->EnablePractice(Team);
|
||||
|
||||
for (int i = 0; i < m_MembersCount; i++)
|
||||
for (int i = m_MembersCount; i-- > 0;)
|
||||
{
|
||||
int ClientID = m_pSavedTees[i].GetClientID();
|
||||
if(m_pController->GameServer()->m_apPlayers[ClientID] && pTeams->m_Core.Team(ClientID) == Team)
|
||||
|
@ -463,10 +524,8 @@ void CSaveTeam::load(int Team)
|
|||
|
||||
CCharacter* CSaveTeam::MatchCharacter(int ClientID, int SaveID)
|
||||
{
|
||||
if(m_pController->GameServer()->m_apPlayers[ClientID]->GetCharacter())
|
||||
return m_pController->GameServer()->m_apPlayers[ClientID]->GetCharacter();
|
||||
else
|
||||
return m_pController->GameServer()->m_apPlayers[ClientID]->ForceSpawn(m_pSavedTees[SaveID].GetPos());
|
||||
m_pController->GameServer()->m_apPlayers[ClientID]->KillCharacter(WEAPON_GAME);
|
||||
return m_pController->GameServer()->m_apPlayers[ClientID]->ForceSpawn(m_pSavedTees[SaveID].GetPos());
|
||||
}
|
||||
|
||||
char* CSaveTeam::GetString()
|
||||
|
@ -476,7 +535,7 @@ char* CSaveTeam::GetString()
|
|||
for(int i = 0; i < m_MembersCount; i++)
|
||||
{
|
||||
char aBuf[1024];
|
||||
str_format(aBuf, sizeof(aBuf), "\n%s", m_pSavedTees[i].GetString());
|
||||
str_format(aBuf, sizeof(aBuf), "\n%s", m_pSavedTees[i].GetString(this));
|
||||
str_append(m_aString, aBuf, sizeof(m_aString));
|
||||
}
|
||||
|
||||
|
@ -602,40 +661,40 @@ int CSaveTeam::LoadString(const char* String)
|
|||
m_pSwitchers = new SSimpleSwitchers[m_NumSwitchers+1];
|
||||
|
||||
for (int n = 1; n < m_NumSwitchers+1; n++)
|
||||
{
|
||||
while (m_aString[Pos] != '\n' && Pos < sizeof(m_aString) && m_aString[Pos]) // find next \n or \0
|
||||
Pos++;
|
||||
|
||||
CopyPos = m_aString + LastPos;
|
||||
StrSize = Pos - LastPos + 1;
|
||||
if(m_aString[Pos] == '\n')
|
||||
{
|
||||
while (m_aString[Pos] != '\n' && Pos < sizeof(m_aString) && m_aString[Pos]) // find next \n or \0
|
||||
Pos++;
|
||||
Pos++; // skip \n
|
||||
LastPos = Pos;
|
||||
}
|
||||
|
||||
CopyPos = m_aString + LastPos;
|
||||
StrSize = Pos - LastPos + 1;
|
||||
if(m_aString[Pos] == '\n')
|
||||
{
|
||||
Pos++; // skip \n
|
||||
LastPos = Pos;
|
||||
}
|
||||
if(StrSize <= 0)
|
||||
{
|
||||
dbg_msg("load", "savegame: wrong format (couldn't load switcher)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(StrSize <= 0)
|
||||
if(StrSize < sizeof(Switcher))
|
||||
{
|
||||
str_copy(Switcher, CopyPos, StrSize);
|
||||
int Num = sscanf(Switcher, "%d\t%d\t%d", &(m_pSwitchers[n].m_Status), &(m_pSwitchers[n].m_EndTime), &(m_pSwitchers[n].m_Type));
|
||||
if(Num != 3)
|
||||
{
|
||||
dbg_msg("load", "savegame: wrong format (couldn't load switcher)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(StrSize < sizeof(Switcher))
|
||||
{
|
||||
str_copy(Switcher, CopyPos, StrSize);
|
||||
int Num = sscanf(Switcher, "%d\t%d\t%d", &(m_pSwitchers[n].m_Status), &(m_pSwitchers[n].m_EndTime), &(m_pSwitchers[n].m_Type));
|
||||
if(Num != 3)
|
||||
{
|
||||
dbg_msg("load", "failed to load switcher");
|
||||
dbg_msg("load", "loaded %d vars", Num-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_msg("load", "savegame: wrong format (couldn't load switcher, too big)");
|
||||
return 1;
|
||||
dbg_msg("load", "failed to load switcher");
|
||||
dbg_msg("load", "loaded %d vars", Num-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_msg("load", "savegame: wrong format (couldn't load switcher, too big)");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -674,6 +733,7 @@ bool CSaveTeam::MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *
|
|||
{
|
||||
m_pSavedTees[i].SetClientID(pClientID[j]);
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!Found)
|
||||
|
@ -682,5 +742,8 @@ bool CSaveTeam::MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *
|
|||
return false;
|
||||
}
|
||||
}
|
||||
// match hook to correct ClientID
|
||||
for (int n = 0; n < m_MembersCount; n++)
|
||||
m_pSavedTees[n].LoadHookedPlayer(this);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
class IGameController;
|
||||
class CGameContext;
|
||||
class CCharacter;
|
||||
class CSaveTeam;
|
||||
|
||||
class CSaveTee
|
||||
{
|
||||
|
@ -16,8 +17,9 @@ public:
|
|||
~CSaveTee();
|
||||
void save(CCharacter* pchr);
|
||||
void load(CCharacter* pchr, int Team);
|
||||
char* GetString();
|
||||
char* GetString(const CSaveTeam *pTeam);
|
||||
int LoadString(const char* String);
|
||||
void LoadHookedPlayer(const CSaveTeam *pTeam);
|
||||
vec2 GetPos() const { return m_Pos; }
|
||||
const char* GetName() const { return m_aName; }
|
||||
int GetClientID() const { return m_ClientID; }
|
||||
|
@ -43,7 +45,6 @@ private:
|
|||
int m_Ammo;
|
||||
int m_Ammocost;
|
||||
int m_Got;
|
||||
|
||||
} m_aWeapons[NUM_WEAPONS];
|
||||
|
||||
int m_LastWeapon;
|
||||
|
@ -92,6 +93,16 @@ private:
|
|||
vec2 m_HookTeleBase;
|
||||
int m_HookTick;
|
||||
int m_HookState;
|
||||
int m_HookedPlayer;
|
||||
int m_NewHook;
|
||||
|
||||
// player input
|
||||
int m_InputDirection;
|
||||
int m_InputJump;
|
||||
int m_InputFire;
|
||||
int m_InputHook;
|
||||
|
||||
int m_ReloadTimer;
|
||||
|
||||
char m_aGameUuid[UUID_MAXSTRSIZE];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue