diff --git a/src/extensions/foot/footext_hooks.cpp b/src/extensions/foot/footext_hooks.cpp index 07d69678d..35b75dc8a 100644 --- a/src/extensions/foot/footext_hooks.cpp +++ b/src/extensions/foot/footext_hooks.cpp @@ -27,10 +27,14 @@ ******************************************************************************/ #include "footext_hooks.h" #include "foot.h" +#include "tibsun_globals.h" #include "technoext.h" #include "technotype.h" #include "technotypeext.h" #include "house.h" +#include "housetype.h" +#include "session.h" +#include "iomap.h" #include "extension.h" #include "fatal.h" #include "asserthandler.h" @@ -40,6 +44,76 @@ #include "hooker_macros.h" +/** + * #issue-680 + * + * Implements IsStupidHunt for TechnoTypes. + * + * @author: CCHyper + */ +static Coordinate &Foot_Get_Coord(FootClass *this_ptr) { return this_ptr->Get_Coord(); } +static CellClass *Get_House_Center_Cell(HouseClass *house) { return &Map[PlayerPtr->Center]; } +DECLARE_PATCH(_FootClass_Mission_Hunt_Stupid_Hunt_Patch) +{ + GET_REGISTER_STATIC(FootClass *, this_ptr, esi); + static TechnoTypeClassExtension *technotypeext; + + technotypeext = Extension::Fetch(this_ptr->Techno_Type_Class()); + + /** + * Should this unit just head towards the enemy without picking a target? + */ + if (technotypeext->IsStupidHunt) { + + /** + * Player controlled units don't abid by the "stupid hunt" rule, so + * tell them to randomly animate. Same goes for if this is a multiplayer + * game. + */ + if (this_ptr->House->Is_Player_Control() || Session.Type != GAME_NORMAL) { + this_ptr->Random_Animate(); + + /** + * AI controlled units in the campaign should head directly towards + * the player, not its current enemy. This ensures the units do not + * head towards a partner house that attacked them last. + */ + } else if (PlayerPtr->Center) { + this_ptr->Assign_Destination(Get_House_Center_Cell(PlayerPtr)); + this_ptr->Assign_Mission(MISSION_MOVE); + + } + + goto mission_return; + } + + /** + * Find a fresh target within my range. + */ + if (this_ptr->Target_Something_Nearby(Foot_Get_Coord(this_ptr), THREAT_NORMAL)) { + goto target_picked; + } + + /** + * Failed to pick a target, random animate and return. + */ +random_animate: + JMP(0x004A1C03); + + /** + * We picked a target, continue. + */ +target_picked: + JMP(0x004A1C12); + + /** + * Mission complete! + */ +mission_return: + JMP(0x004A1D28); +} + + /** * #issue-595 * @@ -334,4 +408,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(0x004A1BEB, &_FootClass_Mission_Hunt_Stupid_Hunt_Patch); } diff --git a/src/extensions/technotype/technotypeext.cpp b/src/extensions/technotype/technotypeext.cpp index da200c2d1..98f263d04 100644 --- a/src/extensions/technotype/technotypeext.cpp +++ b/src/extensions/technotype/technotypeext.cpp @@ -54,6 +54,7 @@ TechnoTypeClassExtension::TechnoTypeClassExtension(const TechnoTypeClass *this_p IsCanRetaliate(true), IsLegalTargetComputer(true), IsCanApproachTarget(true), + IsStupidHunt(false), ShakePixelYHi(0), ShakePixelYLo(0), ShakePixelXHi(0), @@ -252,6 +253,7 @@ bool TechnoTypeClassExtension::Read_INI(CCINIClass &ini) IsCanRetaliate = ini.Get_Bool(ini_name, "CanRetaliate", IsCanRetaliate); IsLegalTargetComputer = ini.Get_Bool(ini_name, "AILegalTarget", IsLegalTargetComputer); IsCanApproachTarget = ini.Get_Bool(ini_name, "CanApproachTarget", IsCanApproachTarget); + IsStupidHunt = ini.Get_Bool(ini_name, "StupidHunt", IsStupidHunt); 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 7385e84f7..e4346d1fa 100644 --- a/src/extensions/technotype/technotypeext.h +++ b/src/extensions/technotype/technotypeext.h @@ -107,6 +107,12 @@ class TechnoTypeClassExtension : public ObjectTypeClassExtension */ bool IsCanApproachTarget; + /** + * Should this unit just head towards the enemy if possible rather than + * assigning itself a nearby target (computer-controlled units only)? + */ + bool IsStupidHunt; + /** * These values are used to shake the screen when the object is destroyed. */