fix: POS_FIGHTING state

This commit is contained in:
rtw1x1
2025-12-19 15:38:13 +00:00
committed by GitHub
parent da619922cb
commit e6b609c817
5 changed files with 76 additions and 0 deletions

View File

@@ -7,3 +7,10 @@
#define __PET_SYSTEM__
#define __UDP_BLOCK__
#endif
/*
This fixes the POS_FIGHTING state, when a character will enter POS_FIGHTING state,
after 10s of no damage dealt, should've been switched to POS_STANDING state.
Files affected: char.cpp, char.h, char_battle.cpp, char_skill.cpp
*/
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT

View File

@@ -361,6 +361,10 @@ void CHARACTER::Initialize()
m_bIsLoadedAffect = false;
cannot_dead = false;
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
m_dwLastCombatTime = 0;
#endif
#ifdef __PET_SYSTEM__
m_petSystem = 0;
m_bIsPet = false;
@@ -4060,6 +4064,20 @@ void CHARACTER::UpdateStateMachine(DWORD dwPulse)
if (IsDead())
return;
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
if (IsPC() && IsPosition(POS_FIGHTING))
{
const DWORD now = get_dword_time();
// If we never set a combat time yet, set it now so timer can start.
if (m_dwLastCombatTime == 0)
m_dwLastCombatTime = now;
if (now - m_dwLastCombatTime >= 10000)
SetVictim(NULL); // triggers battle_end() -> POS_STANDING
}
#endif
Update();
m_dwNextStatePulse = dwPulse + m_dwStateDuration;
}

View File

@@ -2037,6 +2037,16 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider
protected:
int m_iLastPMPulse;
int m_iPMCounter;
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
public:
void EnterCombat();
void UpdateLastCombatTime() { m_dwLastCombatTime = get_dword_time(); }
DWORD GetLastCombatTime() const { return m_dwLastCombatTime; }
private:
DWORD m_dwLastCombatTime;
#endif
};
ESex GET_SEX(LPCHARACTER ch);

View File

@@ -1592,6 +1592,24 @@ void CHARACTER::SendDamagePacket(LPCHARACTER pAttacker, int Damage, BYTE DamageF
}
}
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
void CHARACTER::EnterCombat()
{
if (!IsPC())
return;
if (!IsPosition(POS_FIGHTING))
{
SetPosition(POS_FIGHTING);
SetNextStatePulse(1);
}
// Start the 10s window if it hasn't started yet.
if (m_dwLastCombatTime == 0)
m_dwLastCombatTime = get_dword_time();
}
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
//
// CHARACTER::Damage 메소드는 this가 데미지를 입게 한다.
//
@@ -2287,6 +2305,22 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu
//
if (!cannot_dead)
{
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
// REAL combat activity only: final damage > 0
if (dam > 0)
{
// Victim received real damage
UpdateLastCombatTime();
EnterCombat();
// Attacker dealt real damage
if (pAttacker)
{
pAttacker->UpdateLastCombatTime();
pAttacker->EnterCombat();
}
}
#endif
PointChange(POINT_HP, -dam, false);
}

View File

@@ -2462,6 +2462,13 @@ bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaste
if (!pkSk)
return false;
#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT
if (IsPC() && IS_SET(pkSk->dwFlag, SKILL_FLAG_ATTACK))
{
EnterCombat();
}
#endif
if (bCanUseHorseSkill && pkSk->dwType != SKILL_TYPE_HORSE)
return BATTLE_NONE;