1
#include <InfantryClass.h>
2
#include <BuildingClass.h>
3
#include <SpecificStructures.h>
4
#include "../Building/Body.h"
5
#include "../BuildingType/Body.h"
6
#include "../Techno/Body.h"
8
#include "../Rules/Body.h"
9
#include <Misc/Actions.h>
11
// #664: Advanced Rubble - reconstruction part: Check
13
A_FINE_HOOK(51E635, InfantryClass_GetCursorOverObject_EngineerOverFriendlyBuilding, 5)
15
GET(BuildingClass *, Target, ESI);
16
GET(InfantryClass *, pThis, EDI);
17
FPUControl fp(R->get_EAX()); // (Target->GetHealthPercentage() == RulesClass::Instance->ConditionIdeal)
20
// fall through - not decided about UI handling yet
31
// #664: Advanced Rubble - reconstruction part: Reconstruction
32
DEFINE_HOOK(519FAF, InfantryClass_UpdatePosition_EngineerRepairsFriendly, 6)
34
GET(InfantryClass *, pThis, ESI);
35
GET(BuildingClass *, Target, EDI);
37
BuildingExt::ExtData* TargetExtData = BuildingExt::ExtMap.Find(Target);
38
BuildingTypeExt::ExtData* TargetTypeExtData = BuildingTypeExt::ExtMap.Find(Target->Type);
39
bool do_normal_repair = true;
41
if(TargetTypeExtData->RubbleIntact) {
42
do_normal_repair = false;
43
bool wasSelected = pThis->IsSelected;
45
TargetExtData->RubbleYell(true);
47
pThis->GetMapCoords(&Cell);
48
Target->KickOutUnit(pThis, &Cell);
54
return do_normal_repair ? 0 : 0x51A65D; //0x51A010 eats the Engineer, 0x51A65D hopefully does not
57
DEFINE_HOOK(51DF38, InfantryClass_Remove, A)
59
GET(InfantryClass *, pThis, ESI);
60
TechnoExt::ExtData* pData = TechnoExt::ExtMap.Find(pThis);
62
if(BuildingClass *Garrison = pData->GarrisonedIn) {
63
signed int idx = Garrison->Occupants.FindItemIndex(&pThis);
65
Debug::Log("Infantry %s was garrisoned in building %s, but building didn't find it. WTF?", pThis->Type->ID, Garrison->Type->ID);
67
Garrison->Occupants.RemoveItem(idx);
71
pData->GarrisonedIn = NULL;
76
DEFINE_HOOK(51DFFD, InfantryClass_Put, 5)
78
GET(InfantryClass *, pThis, EDI);
79
TechnoExt::ExtData* pData = TechnoExt::ExtMap.Find(pThis);
80
pData->GarrisonedIn = NULL;
85
DEFINE_HOOK(518434, InfantryClass_ReceiveDamage_SkipDeathAnim, 7)
87
GET(InfantryClass *, pThis, ESI);
88
GET_STACK(ObjectClass *, pAttacker, 0xE0);
89
// InfantryExt::ExtData* trooperAres = InfantryExt::ExtMap.Find(pThis);
90
// bool skipInfDeathAnim = false; // leaving this default in case this is expanded in the future
92
// there is not InfantryExt ExtMap yet!
93
// too much space would get wasted since there is only four bytes worth of data we need to store per object
94
// so those four bytes get stashed in Techno Map instead. they will get their own map if there's ever enough data to warrant it
95
TechnoExt::ExtData* pData = TechnoExt::ExtMap.Find(pThis);
97
return pData->GarrisonedIn ? 0x5185F1 : 0;
100
// should correct issue #743
101
DEFINE_HOOK(51D799, InfantryClass_PlayAnim_WaterSound, 7)
103
GET(InfantryClass *, I, ESI);
104
return (I->Transporter || I->Type->MovementZone != mz_AmphibiousDestroyer)
110
DEFINE_HOOK(51E5BB, InfantryClass_GetCursorOverObject_MultiEngineerA, 7) {
111
// skip old logic's way to determine the cursor
115
DEFINE_HOOK(51E5E1, InfantryClass_GetCursorOverObject_MultiEngineerB, 7) {
116
GET(BuildingClass *, pBld, ECX);
117
eAction ret = InfantryExt::GetEngineerEnterEnemyBuildingAction(pBld);
119
// use a dedicated cursor
120
if(ret == act_Damage) {
121
Actions::Set(RulesExt::Global()->EngineerDamageCursor);
124
//// return our action
129
DEFINE_HOOK(519DB6, InfantryClass_UpdatePosition_MultiEngineer, 7) {
130
GET(InfantryClass *, pEngi, ESI);
131
GET(BuildingClass *, pBld, EDI);
134
eAction action = InfantryExt::GetEngineerEnterEnemyBuildingAction(pBld);
135
if(action == act_Damage) {
136
int Damage = ceil(pBld->Type->Strength * RulesExt::Global()->EngineerDamage);
137
pBld->ReceiveDamage(&Damage, 0, RulesClass::Global()->C4Warhead, pEngi, 1, 0, 0);
b'\\ No newline at end of file'