spidey-decomp/switch.cpp
krystalgamer f475ebca20 CSwitch::AI
Linux build
2024-07-19 19:22:12 +02:00

275 lines
4.7 KiB
C++

#include "switch.h"
#include "trig.h"
#include "baddy.h"
#include "spidey.h"
#include "validate.h"
extern CBaddy* ControlBaddyList;
extern CPlayer* MechList;
extern i32 NumNodes;
extern i16 **gTrigNodes;
// @Ok
// @Test
void CSwitch::AI(void)
{
if (this->field_44 & 1)
{
this->field_44 &= 0xFFFE;
switch (this->field_100)
{
case 0:
this->SwitchOff();
break;
case 1:
this->SwitchOn();
this->SignalAttachedItems();
break;
case 2:
this->SwitchInactive();
break;
default:
print_if_false(0, "invalid switch state");
break;
}
}
if (this->field_100 == 2 || this->field_100 == 3 || this->field_100 == 4)
{
if (this->field_FC)
{
this->field_F8 += this->field_80;
if (this->field_F8 > this->field_FC)
{
this->field_F8 = 0;
if (this->field_100 == 2)
{
this->SwitchOff();
}
else
{
this->PulseLFA1Node(this->field_124 == 0 ? 3 : 2);
this->field_100 = 5;
}
}
}
}
if (this->field_100 == 3 || this->field_100 == 4)
{
this->field_108->mFlags &= 0xFFFE;
u32 res;
u32 Int = this->field_108->field_24 & 0xFF;
if (Int < 0x80)
{
Int += this->field_80;
res = (((Int << 8 ) | Int) << 8) | Int;
}
else
{
res = 0x808080;
}
this->field_24 = res;
}
if (this->field_100 == 5)
{
u32 v18 = 4 * this->field_80;
u32 v19 = this->field_108->field_24 & 0xFF;
if (v19 > v18)
{
u32 diff = v19 - v18;
this->field_108->field_24 = (((diff << 8) | diff) << 8) | diff;
}
else
{
this->field_108->mFlags |= 0x21;
reinterpret_cast<CBody*>(this->field_108)->Die();
this->field_108->field_24 = 0;
}
}
}
// @Ok
void CSwitch::PulseLFA1Node(i32 a1)
{
CVector v3;
i32 nodeIndex = 1;
v3.vx = 0;
v3.vy = 0;
v3.vz = 0;
if (NumNodes > 1)
{
for (; nodeIndex < NumNodes; nodeIndex++)
{
if (*gTrigNodes[nodeIndex] != 1)
continue;
Trig_GetPosition(&v3, nodeIndex);
switch (a1)
{
case 0:
if ( (v3.vx & 0xFFFFF000) != 409600 || v3.vy || v3.vz)
break;
Trig_SendPulseToNode(nodeIndex);
return;
case 1:
if (v3.vx || v3.vy || v3.vz)
break;
Trig_SendPulseToNode(nodeIndex);
return;
case 2:
if ( (v3.vx & 0xFFFFF000) != 409600 || v3.vy || (v3.vz & 0xFFFFF000) != 409600)
break;
Trig_SendPulseToNode(nodeIndex);
return;
case 3:
if ( v3.vx || v3.vy || (v3.vz & 0xFFFFF000) != 409600)
break;
Trig_SendPulseToNode(nodeIndex);
return;
}
}
}
print_if_false(0, "Node not found?");
}
// @Ok
void CSwitch::Flick(void)
{
switch (this->field_100)
{
case 1:
this->SwitchOn();
this->SignalAttachedItems();
break;
case 2:
this->SwitchOff();
if (!this->field_FC)
this->SignalAttachedItems();
break;
case 3:
case 4:
if (MechList)
MechList->field_568 += this->field_124 ? -1 : 1;
this->PulseLFA1Node(this->field_124 == 0);
this->field_100 = 5;
break;
case 5:
if (MechList)
MechList->field_568 += this->field_124 ? -1 : 1;
break;
default:
return;
}
}
// @Ok
CSwitch* Switch_GetCSwitchObjectFromItem(CItem *pItem)
{
print_if_false(pItem != 0, "Bad item");
for (CItem *cur = ControlBaddyList; cur; cur = reinterpret_cast<CItem*>(cur->field_20))
{
if (cur->field_38 == 407)
{
CSwitch* pSwitch = reinterpret_cast<CSwitch*>(cur);
if (pSwitch->field_104 == pItem || pSwitch->field_108 == pItem)
return pSwitch;
}
}
return 0;
}
// @Ok
CSwitch::~CSwitch(void)
{
this->DeleteFrom(reinterpret_cast<CBody**>(&ControlBaddyList));
}
// @Ok
INLINE void CSwitch::SwitchOn(void)
{
this->field_F8 = 0;
this->field_100 = 2;
Switch_SetVisible(1, this->field_108);
Switch_SetVisible(0, this->field_104);
}
// @Ok
INLINE void CSwitch::SignalAttachedItems(void)
{
Trig_SendPulse(Trig_GetLinksPointer(this->field_DE));
}
// @Ok
void __inline CSwitch::SwitchInactive(void)
{
this->field_100 = 0;
}
// @Ok
CVector* CSwitch::GetAutoAimTargetPointer(void)
{
switch(this->field_100)
{
case 1:
return &this->field_10C;
case 2:
case 3:
case 4:
case 5:
return &this->field_118;
default:
return NULL;
}
}
// @Ok
void __inline Switch_SetVisible(bool a1, CItem* pItem)
{
print_if_false(pItem != 0, "Bad item");
if (a1)
pItem->mFlags &= 0xFFDE;
else
pItem->mFlags |= 0x21;
}
// @Ok
void __inline CSwitch::SwitchOff(void)
{
this->field_100 = 1;
Switch_SetVisible(false, this->field_108);
Switch_SetVisible(true, this->field_104);
}
void validate_CSwitch(void)
{
VALIDATE_SIZE(CSwitch, 0x128);
VALIDATE(CSwitch, field_F8, 0xF8);
VALIDATE(CSwitch, field_FC, 0xFC);
VALIDATE(CSwitch, field_100, 0x100);
VALIDATE(CSwitch, field_104, 0x104);
VALIDATE(CSwitch, field_108, 0x108);
VALIDATE(CSwitch, field_10C, 0x10C);
VALIDATE(CSwitch, field_118, 0x118);
VALIDATE(CSwitch, field_124, 0x124);
}