From e6b609c817354d09f014bad8153841f0dd4e0922 Mon Sep 17 00:00:00 2001 From: rtw1x1 Date: Fri, 19 Dec 2025 15:38:13 +0000 Subject: [PATCH 1/4] fix: POS_FIGHTING state --- src/common/service.h | 7 +++++++ src/game/char.cpp | 18 ++++++++++++++++++ src/game/char.h | 10 ++++++++++ src/game/char_battle.cpp | 34 ++++++++++++++++++++++++++++++++++ src/game/char_skill.cpp | 7 +++++++ 5 files changed, 76 insertions(+) diff --git a/src/common/service.h b/src/common/service.h index 2d85760..d1b1c2f 100644 --- a/src/common/service.h +++ b/src/common/service.h @@ -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 \ No newline at end of file diff --git a/src/game/char.cpp b/src/game/char.cpp index 1b3dbfa..a501e2b 100644 --- a/src/game/char.cpp +++ b/src/game/char.cpp @@ -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; } diff --git a/src/game/char.h b/src/game/char.h index 6779b3a..667ae1c 100644 --- a/src/game/char.h +++ b/src/game/char.h @@ -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); diff --git a/src/game/char_battle.cpp b/src/game/char_battle.cpp index d962cff..5f6bde4 100644 --- a/src/game/char_battle.cpp +++ b/src/game/char_battle.cpp @@ -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); } diff --git a/src/game/char_skill.cpp b/src/game/char_skill.cpp index b68edbc..5c690bc 100644 --- a/src/game/char_skill.cpp +++ b/src/game/char_skill.cpp @@ -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; From 7748a50009f45db01c5dfa9c84995e11f1f212d0 Mon Sep 17 00:00:00 2001 From: rtw1x1 Date: Fri, 19 Dec 2025 15:44:17 +0000 Subject: [PATCH 2/4] Remove FIX_BATTLE_INACTIVITY_TIMEOUT preprocessor directive --- src/game/char_battle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/char_battle.cpp b/src/game/char_battle.cpp index 5f6bde4..58e44fa 100644 --- a/src/game/char_battle.cpp +++ b/src/game/char_battle.cpp @@ -1608,7 +1608,7 @@ void CHARACTER::EnterCombat() if (m_dwLastCombatTime == 0) m_dwLastCombatTime = get_dword_time(); } -#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT +#endif // // CHARACTER::Damage 메소드는 this가 데미지를 입게 한다. From fd4d5558af26a71b09a37ba5d6ca5f7cdddc2b4c Mon Sep 17 00:00:00 2001 From: d1str4ught <> Date: Fri, 19 Dec 2025 23:55:17 +0100 Subject: [PATCH 3/4] INT -> int32_t --- src/common/tables.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/tables.h b/src/common/tables.h index 4359033..6002e9c 100644 --- a/src/common/tables.h +++ b/src/common/tables.h @@ -380,14 +380,14 @@ typedef struct SPlayerTable int16_t st, ht, dx, iq; uint32_t exp; - INT gold; + int32_t gold; - uint8_t dir; - INT x, y, z; - INT lMapIndex; + uint8_t dir; + int32_t x, y, z; + int32_t lMapIndex; - int32_t lExitX, lExitY; - int32_t lExitMapIndex; + int32_t lExitX, lExitY; + int32_t lExitMapIndex; // int16_t hp; // int16_t sp; From d486caa4f7828ce1360ddbdd6e9b156c53c27561 Mon Sep 17 00:00:00 2001 From: d1str4ught <> Date: Sat, 20 Dec 2025 00:14:55 +0100 Subject: [PATCH 4/4] feature macros removed --- src/common/service.h | 7 ------- src/game/char.cpp | 4 ---- src/game/char.h | 2 -- src/game/char_battle.cpp | 4 ---- src/game/char_skill.cpp | 2 -- 5 files changed, 19 deletions(-) diff --git a/src/common/service.h b/src/common/service.h index d1b1c2f..2d85760 100644 --- a/src/common/service.h +++ b/src/common/service.h @@ -7,10 +7,3 @@ #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 \ No newline at end of file diff --git a/src/game/char.cpp b/src/game/char.cpp index a501e2b..b790528 100644 --- a/src/game/char.cpp +++ b/src/game/char.cpp @@ -361,9 +361,7 @@ void CHARACTER::Initialize() m_bIsLoadedAffect = false; cannot_dead = false; -#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT m_dwLastCombatTime = 0; -#endif #ifdef __PET_SYSTEM__ m_petSystem = 0; @@ -4064,7 +4062,6 @@ void CHARACTER::UpdateStateMachine(DWORD dwPulse) if (IsDead()) return; -#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT if (IsPC() && IsPosition(POS_FIGHTING)) { const DWORD now = get_dword_time(); @@ -4076,7 +4073,6 @@ void CHARACTER::UpdateStateMachine(DWORD dwPulse) if (now - m_dwLastCombatTime >= 10000) SetVictim(NULL); // triggers battle_end() -> POS_STANDING } -#endif Update(); m_dwNextStatePulse = dwPulse + m_dwStateDuration; diff --git a/src/game/char.h b/src/game/char.h index 667ae1c..4ff3f1f 100644 --- a/src/game/char.h +++ b/src/game/char.h @@ -2038,7 +2038,6 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider int m_iLastPMPulse; int m_iPMCounter; -#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT public: void EnterCombat(); void UpdateLastCombatTime() { m_dwLastCombatTime = get_dword_time(); } @@ -2046,7 +2045,6 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider private: DWORD m_dwLastCombatTime; -#endif }; ESex GET_SEX(LPCHARACTER ch); diff --git a/src/game/char_battle.cpp b/src/game/char_battle.cpp index 58e44fa..94892b7 100644 --- a/src/game/char_battle.cpp +++ b/src/game/char_battle.cpp @@ -1592,7 +1592,6 @@ void CHARACTER::SendDamagePacket(LPCHARACTER pAttacker, int Damage, BYTE DamageF } } -#ifdef FIX_BATTLE_INACTIVITY_TIMEOUT void CHARACTER::EnterCombat() { if (!IsPC()) @@ -1608,7 +1607,6 @@ void CHARACTER::EnterCombat() if (m_dwLastCombatTime == 0) m_dwLastCombatTime = get_dword_time(); } -#endif // // CHARACTER::Damage 메소드는 this가 데미지를 입게 한다. @@ -2305,7 +2303,6 @@ 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) { @@ -2320,7 +2317,6 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu pAttacker->EnterCombat(); } } -#endif PointChange(POINT_HP, -dam, false); } diff --git a/src/game/char_skill.cpp b/src/game/char_skill.cpp index 5c690bc..48392bb 100644 --- a/src/game/char_skill.cpp +++ b/src/game/char_skill.cpp @@ -2462,12 +2462,10 @@ 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;