From 49231202f0cf3c70bedbb1bfe6ac2e44e1be7139 Mon Sep 17 00:00:00 2001 From: CCHyper <73803386+CCHyper@users.noreply.github.com> Date: Wed, 29 Sep 2021 16:34:29 +0100 Subject: [PATCH 1/3] Implements IsCanApproachTarget for TechnoTypes. --- src/extensions/foot/footext_hooks.cpp | 51 +++++++++++++++++++++ src/extensions/technotype/technotypeext.cpp | 2 + src/extensions/technotype/technotypeext.h | 6 +++ 3 files changed, 59 insertions(+) diff --git a/src/extensions/foot/footext_hooks.cpp b/src/extensions/foot/footext_hooks.cpp index f90213244..8c7cafe8a 100644 --- a/src/extensions/foot/footext_hooks.cpp +++ b/src/extensions/foot/footext_hooks.cpp @@ -30,6 +30,7 @@ #include "technoext.h" #include "technotype.h" #include "technotypeext.h" +#include "house.h" #include "fatal.h" #include "asserthandler.h" #include "debughandler.h" @@ -38,6 +39,55 @@ #include "hooker_macros.h" +/** + * #issue-595 + * + * Implements IsCanApproachTarget for TechnoTypes. + * + * @author: CCHyper + */ +DECLARE_PATCH(_FootClass_Approach_Target_Can_Approach_Patch) +{ + GET_REGISTER_STATIC(FootClass *, this_ptr, ebp); + static TechnoTypeClassExtension *technotypeext; + + technotypeext = TechnoTypeClassExtensions.find(this_ptr->Techno_Type_Class()); + + /** + * Stolen bytes/code. + */ + if (this_ptr->Mission == MISSION_STICKY) { + goto assign_null_target_return; + } + + /** + * + */ + if (technotypeext && !technotypeext->IsCanApproachTarget) { + + static bool force_approach; + force_approach = false; + + if (this_ptr->Mission == MISSION_ATTACK) { + force_approach = true; + } + if (this_ptr->Mission == MISSION_GUARD_AREA && this_ptr->House->Is_Player_Control()) { + force_approach = true; + } + if ((this_ptr->Mission != MISSION_HUNT || this_ptr->House->Is_Player_Control()) && !force_approach) { + goto assign_null_target_return; + } + + } + +continue_checks: + JMP(0x004A1ED2); + +assign_null_target_return: + JMP(0x004A1EAE); +} + + /** * #issue-593 * @@ -284,4 +334,5 @@ void FootClassExtension_Hooks() Patch_Jump(0x004A2BE7, &_FootClass_Mission_Guard_Area_Can_Passive_Acquire_Patch); Patch_Jump(0x004A1AAE, &_FootClass_Mission_Guard_Can_Passive_Acquire_Patch); Patch_Jump(0x004A102F, &_FootClass_Mission_Move_Can_Passive_Acquire_Patch); + Patch_Jump(0x004A1EA8, &_FootClass_Approach_Target_Can_Approach_Patch); } diff --git a/src/extensions/technotype/technotypeext.cpp b/src/extensions/technotype/technotypeext.cpp index 00a618e2a..0257eb4f7 100644 --- a/src/extensions/technotype/technotypeext.cpp +++ b/src/extensions/technotype/technotypeext.cpp @@ -57,6 +57,7 @@ TechnoTypeClassExtension::TechnoTypeClassExtension(TechnoTypeClass *this_ptr) : IsImmuneToEMP(false), IsCanPassiveAcquire(true), IsCanRetaliate(true), + IsCanApproachTarget(true), ShakePixelYHi(0), ShakePixelYLo(0), ShakePixelXHi(0), @@ -259,6 +260,7 @@ bool TechnoTypeClassExtension::Read_INI(CCINIClass &ini) IsImmuneToEMP = ini.Get_Bool(ini_name, "ImmuneToEMP", IsImmuneToEMP); IsCanPassiveAcquire = ini.Get_Bool(ini_name, "CanPassiveAcquire", IsCanPassiveAcquire); IsCanRetaliate = ini.Get_Bool(ini_name, "CanRetaliate", IsCanRetaliate); + IsCanApproachTarget = ini.Get_Bool(ini_name, "CanApproachTarget", IsCanApproachTarget); ShakePixelYHi = ini.Get_Int(ini_name, "ShakeYhi", ShakePixelYHi); ShakePixelYLo = ini.Get_Int(ini_name, "ShakeYlo", ShakePixelYLo); ShakePixelXHi = ini.Get_Int(ini_name, "ShakeXhi", ShakePixelXHi); diff --git a/src/extensions/technotype/technotypeext.h b/src/extensions/technotype/technotypeext.h index 233791d87..43845ddd5 100644 --- a/src/extensions/technotype/technotypeext.h +++ b/src/extensions/technotype/technotypeext.h @@ -89,6 +89,12 @@ class TechnoTypeClassExtension final : public Extension */ bool IsCanRetaliate; + /** + * Can this unit can continually move towards its intended target with + * the intention of gaining more accuracy? + */ + bool IsCanApproachTarget; + /** * These values are used to shake the screen when the object is destroyed. */ From 5c094ae3a5d77f84b95efbbfcd61ef13f4b39308 Mon Sep 17 00:00:00 2001 From: CCHyper <73803386+CCHyper@users.noreply.github.com> Date: Wed, 20 Oct 2021 00:48:39 +0100 Subject: [PATCH 2/3] Adds ApproachTargetResetMultiplier to RulesClass. --- src/extensions/rules/rulesext.cpp | 5 ++++- src/extensions/rules/rulesext.h | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/extensions/rules/rulesext.cpp b/src/extensions/rules/rulesext.cpp index 4aaaa7797..8428a828a 100644 --- a/src/extensions/rules/rulesext.cpp +++ b/src/extensions/rules/rulesext.cpp @@ -48,7 +48,8 @@ RulesClassExtension::RulesClassExtension(RulesClass *this_ptr) : IsMPAutoDeployMCV(false), IsMPPrePlacedConYards(false), IsBuildOffAlly(true), - IsShowSuperWeaponTimers(true) + IsShowSuperWeaponTimers(true), + ApproachTargetResetMultiplier(1.0) { ASSERT(ThisPtr != nullptr); //EXT_DEBUG_TRACE("RulesClassExtension constructor - 0x%08X\n", (uintptr_t)(ThisPtr)); @@ -291,6 +292,8 @@ bool RulesClassExtension::General(CCINIClass &ini) return false; } + ApproachTargetResetMultiplier = ini.Get_Float(GENERAL, "ApproachTargetResetMultiplier", ApproachTargetResetMultiplier); + return true; } diff --git a/src/extensions/rules/rulesext.h b/src/extensions/rules/rulesext.h index bc25e05b4..882d664d2 100644 --- a/src/extensions/rules/rulesext.h +++ b/src/extensions/rules/rulesext.h @@ -110,6 +110,12 @@ class RulesClassExtension final : public Extension * on the tactical view? */ bool IsShowSuperWeaponTimers; + + /** + * The "approach target" position should be recalculated if the target is + * now more than weapon range times this value. + */ + double ApproachTargetResetMultiplier; }; From 291f00b905b11688672dee7f5a942f1824c55072 Mon Sep 17 00:00:00 2001 From: CCHyper <73803386+CCHyper@users.noreply.github.com> Date: Wed, 20 Oct 2021 00:28:50 +0100 Subject: [PATCH 3/3] Implements IsCanRecalcApproachTarget for TechnoTypes. --- src/extensions/foot/footext_hooks.cpp | 64 +++++++++++++++++++++ src/extensions/technotype/technotypeext.cpp | 2 + src/extensions/technotype/technotypeext.h | 6 ++ 3 files changed, 72 insertions(+) diff --git a/src/extensions/foot/footext_hooks.cpp b/src/extensions/foot/footext_hooks.cpp index 8c7cafe8a..e9d35c476 100644 --- a/src/extensions/foot/footext_hooks.cpp +++ b/src/extensions/foot/footext_hooks.cpp @@ -30,7 +30,11 @@ #include "technoext.h" #include "technotype.h" #include "technotypeext.h" +#include "tibsun_inline.h" #include "house.h" +#include "rules.h" +#include "rulesext.h" +#include "target.h" #include "fatal.h" #include "asserthandler.h" #include "debughandler.h" @@ -39,6 +43,65 @@ #include "hooker_macros.h" +/** + * #issue-595 + * + * Implements IsCanRecalcApproachTarget for TechnoTypes. + * + * @author: CCHyper + */ +static short NavCom_TarCom_Distance(FootClass *this_ptr) { return Distance(this_ptr->NavCom->Center_Coord(), this_ptr->TarCom->Center_Coord()); } +static int Multiply_Integer(int a, double b) { return (a * b); } +DECLARE_PATCH(_FootClass_Approach_Target_Can_Recalc_Approach_Target_Patch) +{ + GET_REGISTER_STATIC(FootClass *, this_ptr, ebp); + GET_REGISTER_STATIC(bool, in_range, bl); + GET_STACK_STATIC(int, maxrange, esp, 0x34); + static TechnoTypeClassExtension *technotypeext; + + if (Target_Legal(this_ptr->NavCom)) { + + if (Target_Legal(this_ptr->TarCom)) { + + technotypeext = TechnoTypeClassExtensions.find(this_ptr->Techno_Type_Class()); + if (technotypeext && technotypeext->IsCanRecalcApproachTarget) { + + //DEV_DEBUG_INFO("Approach_Target: CanRecalcApproachTarget branch.\n"); + + if (!in_range) { + + static double reset_multiplier = 1.0; + if (RulesExtension) { + reset_multiplier = RulesExtension->ApproachTargetResetMultiplier; + } + + if (NavCom_TarCom_Distance(this_ptr) > Multiply_Integer(maxrange, reset_multiplier)) { + DEV_DEBUG_INFO("Approach_Target: Clearing NavCom.\n"); + this_ptr->NavCom = nullptr; + } + + } + + } + + } + + if (Target_Legal(this_ptr->NavCom)) { + if (!this_ptr->In_Air()) { + goto function_return; + } + } + } + + _asm { mov bl, byte ptr [in_range] } // restore BL register. + + JMP(0x004A2004); + +function_return: + JMP(0x004A2813); +} + + /** * #issue-595 * @@ -335,4 +398,5 @@ void FootClassExtension_Hooks() Patch_Jump(0x004A1AAE, &_FootClass_Mission_Guard_Can_Passive_Acquire_Patch); Patch_Jump(0x004A102F, &_FootClass_Mission_Move_Can_Passive_Acquire_Patch); Patch_Jump(0x004A1EA8, &_FootClass_Approach_Target_Can_Approach_Patch); + Patch_Jump(0x004A1FEA, &_FootClass_Approach_Target_Can_Recalc_Approach_Target_Patch); } diff --git a/src/extensions/technotype/technotypeext.cpp b/src/extensions/technotype/technotypeext.cpp index 0257eb4f7..bc91c9133 100644 --- a/src/extensions/technotype/technotypeext.cpp +++ b/src/extensions/technotype/technotypeext.cpp @@ -58,6 +58,7 @@ TechnoTypeClassExtension::TechnoTypeClassExtension(TechnoTypeClass *this_ptr) : IsCanPassiveAcquire(true), IsCanRetaliate(true), IsCanApproachTarget(true), + IsCanRecalcApproachTarget(true), ShakePixelYHi(0), ShakePixelYLo(0), ShakePixelXHi(0), @@ -261,6 +262,7 @@ bool TechnoTypeClassExtension::Read_INI(CCINIClass &ini) IsCanPassiveAcquire = ini.Get_Bool(ini_name, "CanPassiveAcquire", IsCanPassiveAcquire); IsCanRetaliate = ini.Get_Bool(ini_name, "CanRetaliate", IsCanRetaliate); IsCanApproachTarget = ini.Get_Bool(ini_name, "CanApproachTarget", IsCanApproachTarget); + IsCanRecalcApproachTarget = ini.Get_Bool(ini_name, "CanRecalcApproachTarget", IsCanRecalcApproachTarget); ShakePixelYHi = ini.Get_Int(ini_name, "ShakeYhi", ShakePixelYHi); ShakePixelYLo = ini.Get_Int(ini_name, "ShakeYlo", ShakePixelYLo); ShakePixelXHi = ini.Get_Int(ini_name, "ShakeXhi", ShakePixelXHi); diff --git a/src/extensions/technotype/technotypeext.h b/src/extensions/technotype/technotypeext.h index 43845ddd5..daa71a2c0 100644 --- a/src/extensions/technotype/technotypeext.h +++ b/src/extensions/technotype/technotypeext.h @@ -95,6 +95,12 @@ class TechnoTypeClassExtension final : public Extension */ bool IsCanApproachTarget; + /** + * Can this unit recalculate what its next target will be when conducting + * its threat scan if its current target is out of range? + */ + bool IsCanRecalcApproachTarget; + /** * These values are used to shake the screen when the object is destroyed. */