2
#include "../Techno/Body.h"
6
DEFINE_HOOK(6FF5F5, TechnoClass_Fire, 6)
8
GET(WeaponTypeClass *, Source, EBX);
9
GET(TechnoClass *, Owner, ESI);
10
GET(TechnoClass *, Target, EDI);
12
WeaponTypeExt::ExtData *pData = WeaponTypeExt::ExtMap.Find(Source);
14
RET_UNLESS(Source->IsMagBeam || Source->IsSonic || pData->Wave_IsLaser || pData->Wave_IsBigLaser);
16
GET_BASE(byte, idxWeapon, 0xC);
18
TechnoExt::ExtMap.Find(Owner)->idxSlot_Wave = idxWeapon;
20
RET_UNLESS(pData->Wave_IsLaser || pData->Wave_IsBigLaser);
22
LEA_STACK(CoordStruct *, xyzSrc, 0x44);
23
LEA_STACK(CoordStruct *, xyzTgt, 0x88);
26
GAME_ALLOC(WaveClass, Wave, xyzSrc, xyzTgt, Owner, pData->Wave_IsBigLaser ? 2 : 1, Target);
28
WeaponTypeExt::WaveExt[Wave] = pData;
34
DEFINE_HOOK(75E963, WaveClass_CTOR, 6)
36
GET(WaveClass *, Wave, ESI);
37
GET(DWORD, Type, ECX);
38
if(Type == wave_Laser || Type == wave_BigLaser) {
41
GET(WeaponTypeClass *, Weapon, EBX);
44
WeaponTypeExt::ExtData *pData = WeaponTypeExt::ExtMap.Find(Weapon);
45
WeaponTypeExt::WaveExt[Wave] = pData;
51
// 75EB87, 0A // fsdblargh, a single instruction spanning 10 bytes
52
XPORT_FUNC(WaveClass_CTOR2)
54
GET(WaveClass *, Wave, ESI);
55
RET_UNLESS(CONTAINS(WeaponTypeExt::WaveExt, Wave));
56
WeaponTypeExt::WeaponTypeClassData *pData = WeaponTypeExt::WaveExt[Wave];
57
// Wave->set_WaveIntensity(pData->Wave_InitialIntensity);
63
DEFINE_HOOK(763226, WaveClass_DTOR, 6)
65
GET(WaveClass *, Wave, EDI);
66
hash_waveExt::iterator i = WeaponTypeExt::WaveExt.find(Wave);
67
if(i != WeaponTypeExt::WaveExt.end()) {
68
WeaponTypeExt::WaveExt.erase(i);
75
// complete replacement for WaveClass::Update
76
DEFINE_HOOK(760F50, WaveClass_Update, 6)
78
GET(WaveClass *, pThis, ECX);
80
WeaponTypeExt::ExtData *pData = WeaponTypeExt::WaveExt[pThis];
81
const WeaponTypeClass *Weap = pData->AttachedToObject;
87
if(Weap->AmbientDamage) {
89
// Debug::Log("Damaging Cells for weapon %X (Intensity = %d)\n", pData, pThis->WaveIntensity);
90
for(int i = 0; i < pThis->Cells.Count; ++i) {
91
CellClass *Cell = pThis->Cells.GetItem(i);
92
// Debug::Log("\t(%hd,%hd)\n", Cell->MapCoords.X, Cell->MapCoords.Y);
93
pThis->DamageArea(Cell->Get3DCoords3(&coords));
95
// Debug::Log("Done damaging %X\n", pData);
100
pThis->Update_Wave();
101
Intensity = pThis->WaveIntensity;
103
pThis->WaveIntensity = Intensity;
107
SET_REG32(ECX, pThis);
108
CALL(0x5F3E70); // ObjectClass::Update
113
Intensity = pThis->LaserIntensity;
115
pThis->LaserIntensity = Intensity;
121
pThis->Update_Wave();
122
Intensity = pThis->WaveIntensity;
124
pThis->WaveIntensity = Intensity;
128
SET_REG32(ECX, pThis);
129
CALL(0x5F3E70); // ObjectClass::Update
140
XPORT_FUNC(WaveClass_UpdateLaser)
142
GET(WaveClass *, Wave, ESI);
144
RET_UNLESS(CONTAINS(WeaponTypeExt::WaveExt, Wave));
145
WeaponTypeExt::WeaponTypeClassData *pData = WeaponTypeExt::WaveExt[Wave];
146
int intense = Wave->get_WaveIntensity() + pData->Wave_IntensityStep;
147
Wave->set_WaveIntensity(intense);
148
return intense >= pData->Wave_FinalIntensity ? 0x761016 : 0x76100C;
152
DEFINE_HOOK(760BC2, WaveClass_Draw2, 9)
154
GET(WaveClass *, Wave, EBX);
155
GET(WORD *, dest, EBP);
157
return (WeaponTypeExt::ModifyWaveColor(dest, dest, Wave->LaserIntensity, Wave))
164
DEFINE_HOOK(760DE2, WaveClass_Draw3, 9)
166
GET(WaveClass *, Wave, EBX);
167
GET(WORD *, dest, EDI);
169
return (WeaponTypeExt::ModifyWaveColor(dest, dest, Wave->LaserIntensity, Wave))
176
DEFINE_HOOK(75EE57, WaveClass_Draw_Sonic, 7)
178
GET_STACK(WaveClass *, Wave, 0x4);
179
GET(DWORD, src, EDI);
180
GET(DWORD, offset, ECX);
181
DWORD offs = src + offset * 2;
183
return (WeaponTypeExt::ModifyWaveColor((WORD *)offs, (WORD *)src, R->ESI(), Wave))
190
DEFINE_HOOK(7601FB, WaveClass_Draw_Magnetron, 0B)
192
GET_STACK(WaveClass *, Wave, 0x8);
193
GET(DWORD, src, EBX);
194
GET(DWORD, offset, ECX);
195
DWORD offs = src + offset * 2;
197
return (WeaponTypeExt::ModifyWaveColor((WORD *)offs, (WORD *)src, R->EBP(), Wave))
204
DEFINE_HOOK(760286, WaveClass_Draw_Magnetron2, 5)
209
bool WeaponTypeExt::ModifyWaveColor(WORD *src, WORD *dst, int Intensity, WaveClass *Wave)
211
WeaponTypeExt::ExtData *pData = WeaponTypeExt::WaveExt[Wave];
213
ColorStruct *CurrentColor = (pData->Wave_IsHouseColor && Wave->Owner)
214
? &Wave->Owner->Owner->Color
215
: &pData->Wave_Color;
217
if(*CurrentColor == ColorStruct(0, 0, 0)) {
221
ColorStruct initial = Drawing::WordColor(*src);
223
ColorStruct modified = initial;
225
// ugly hack to fix byte wraparound problems
227
int _ ## c = initial. c + (Intensity * CurrentColor-> c ) / 256; \
228
_ ## c = min(_ ## c, 255); \
229
modified. c = (BYTE)_ ## c;
235
WORD color = Drawing::Color16bit(&modified);
242
DEFINE_HOOK(762C5C, WaveClass_Update_Wave, 6)
244
GET(WaveClass *, Wave, ESI);
245
TechnoClass *Firer = Wave->Owner;
246
TechnoClass *Target = Wave->Target;
247
if(!Target || !Firer) {
251
RET_UNLESS(WeaponTypeExt::WaveExt.find(Wave) != WeaponTypeExt::WaveExt.end());
252
WeaponTypeExt::ExtData *pData = WeaponTypeExt::WaveExt[Wave];
253
int weaponIdx = TechnoExt::ExtMap.Find(Firer)->idxSlot_Wave;
255
CoordStruct xyzSrc, xyzTgt, xyzDummy = {0, 0, 0};
256
Firer->GetFLH(&xyzSrc, weaponIdx, xyzDummy);
257
Target->GetCoords__(&xyzTgt); // not GetCoords() !
259
char idx = WeaponTypeExt:: AbsIDtoIdx(Target->WhatAmI());
261
bool reversed = pData->Wave_Reverse[idx];
263
if(Wave->Type == wave_Magnetron) {
265
? Wave->Draw_Magnetic(&xyzTgt, &xyzSrc)
266
: Wave->Draw_Magnetic(&xyzSrc, &xyzTgt);
269
? Wave->Draw_NonMagnetic(&xyzTgt, &xyzSrc)
270
: Wave->Draw_NonMagnetic(&xyzSrc, &xyzTgt);
277
DEFINE_HOOK(75F38F, WaveClass_DamageCell, 6)
279
GET(WaveClass *, Wave, EBP);
280
WeaponTypeExt::ExtData *pData = WeaponTypeExt::WaveExt[Wave];
282
R->EBX(pData->AttachedToObject);
286
DEFINE_HOOK(7601C7, WaveClass_Draw_Purple, 8)