mirror of
https://github.com/krystalgamer/spidey-decomp.git
synced 2024-11-23 13:29:48 +00:00
1078 lines
19 KiB
C++
1078 lines
19 KiB
C++
#include "baddy.h"
|
|
#include "validate.h"
|
|
#include "utils.h"
|
|
#include "mem.h"
|
|
#include "message.h"
|
|
#include "web.h"
|
|
#include <cmath>
|
|
#include "trig.h"
|
|
#include "ai.h"
|
|
|
|
EXPORT CBaddy* ControlBaddyList;
|
|
EXPORT CBaddy* BaddyList;
|
|
|
|
extern i16** gTrigNodes;
|
|
|
|
// @Ok
|
|
void CBaddy::GetWaypointNearTarget(
|
|
CVector* a2,
|
|
i32 a3,
|
|
i32 a4,
|
|
CVector* a5)
|
|
{
|
|
i32 unk;
|
|
i32 v5; // eax
|
|
i32 v6; // edi
|
|
i32 v7; // ecx
|
|
|
|
unk = a4 & 0x3F;
|
|
v5 = 1 << (unk & 7);
|
|
*a5 = *a2;
|
|
v6 = unk & 8 ? 2 : 1;
|
|
v7 = unk & 0x10 ? 2 : 1;
|
|
|
|
if ( unk > 0x1F )
|
|
{
|
|
v6 += 2;
|
|
v7 += 2;
|
|
}
|
|
if ( (v5 & 0xEE) != 0 )
|
|
a5->vx += a3 * v6 * (v5 > 8 ? -1 : 1);
|
|
if ( (v5 & 0xBB) != 0 )
|
|
a5->vz += a3 * v7 * ((v5 & 0x83) != 0 ? 1 : -1);
|
|
}
|
|
|
|
// @NotOk
|
|
// check when pathcheck is done <3
|
|
i32 CBaddy::AddPointToPath(
|
|
CVector* pVec,
|
|
i32 a3)
|
|
{
|
|
CVector v21;
|
|
v21.vx = 0;
|
|
v21.vy = 0;
|
|
v21.vz = 0;
|
|
|
|
CVector v20;
|
|
v20 = *pVec;
|
|
v20.vy = this->mPos.vy;
|
|
|
|
if (this->field_1F4 > 0)
|
|
{
|
|
Trig_GetPosition(&v21, this->field_1F4);
|
|
v21.vy = this->field_29C;
|
|
|
|
if ((!a3 || Utils_CrapDist(v21, v20) < a3) && this->PathCheck(&v21, &v20, 0, 55))
|
|
{
|
|
this->field_1F0 = 1;
|
|
this->field_1B4[0] = v20;
|
|
this->field_2A8 |= 0x20000000;
|
|
return 1;
|
|
}
|
|
}
|
|
else if (!this->field_1F0)
|
|
{
|
|
this->field_1F0 = 1;
|
|
this->field_1B4[0] = v20;
|
|
return 1;
|
|
}
|
|
|
|
for (i32 i = 0; i<4 && i < this->field_1F0; i++)
|
|
{
|
|
if ( (!a3 || Utils_CrapDist(this->field_1B4[i], v20) < a3)
|
|
&& this->PathCheck(&this->field_1B4[i], &v20, 0, 55))
|
|
{
|
|
this->field_1F0 = i + 2;
|
|
this->field_1B4[i+1] = v20;
|
|
this->field_2A8 |= 0x20000000;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// @Ok
|
|
i32 CBaddy::GetNextWaypoint(void)
|
|
{
|
|
if (this->field_1F4 >= 0)
|
|
{
|
|
u16 *LinksPointer = reinterpret_cast<u16*>(Trig_GetLinksPointer(this->field_1F4));
|
|
if (!*LinksPointer)
|
|
return 0;
|
|
|
|
this->field_1F4 = LinksPointer[1];
|
|
|
|
u16* v4 = reinterpret_cast<u16*>(gTrigNodes[this->field_1F4]);
|
|
this->field_2F0 = 0;
|
|
|
|
if (*v4 == 1000 || *v4 == 1002)
|
|
{
|
|
CVector v9;
|
|
v9.vx = 0;
|
|
v9.vy = 0;
|
|
v9.vz = 0;
|
|
|
|
u16 *position = Trig_GetPosition(&v9, this->field_1F4);
|
|
this->field_2F4 = 0;
|
|
|
|
this->ParseScript(&position[3]);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// @NotOk
|
|
// Revisit, slightly different assembly, related to zx
|
|
void CBaddy::RunAppropriateAnim(void)
|
|
{
|
|
if (this->field_2AC & 0x40000)
|
|
{
|
|
u8 v2 = this->field_294.Bytes[0];
|
|
u8 v3 = this->field_294.Bytes[1];
|
|
|
|
if (v2 != v3)
|
|
{
|
|
if (this->field_12A != v3
|
|
&& this->field_12A != v2)
|
|
{
|
|
this->RunAnim(this->field_294.Bytes[0], 0, -1);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (v2 == v3
|
|
|| this->field_12A != v2
|
|
|| this->field_142)
|
|
{
|
|
this->CycleAnim(this->field_294.Bytes[1], 1);
|
|
}
|
|
}
|
|
else if (this->field_2AC & 0x10000)
|
|
{
|
|
if (this->field_12A != this->field_294.Bytes[2] || this->field_142)
|
|
this->RunAnim(this->field_294.Bytes[2], 0, -1);
|
|
}
|
|
else if (this->field_2AC & 0x20000)
|
|
{
|
|
if (this->field_12A != this->field_294.Bytes[3] || this->field_142)
|
|
this->RunAnim(this->field_294.Bytes[3], 0, -1);
|
|
}
|
|
else
|
|
{
|
|
this->CycleAnim(this->field_298.Bytes[0], 1);
|
|
}
|
|
}
|
|
|
|
// @MEDIUMTODO
|
|
int CBaddy::SmackSpidey(int, CVector*, int, int)
|
|
{
|
|
return 0x06062024;
|
|
}
|
|
|
|
// @NotOk
|
|
// Global
|
|
int CBaddy::DistanceToPlayer(int a2){
|
|
int v3; // eax
|
|
int result; // eax
|
|
v3 = this->field_208;
|
|
|
|
int dwordRead = *dword_5FCCF4;
|
|
|
|
if ( v3 && dwordRead - v3 <= a2 )
|
|
return this->field_204;
|
|
|
|
this->field_208 = dwordRead;
|
|
result = Utils_CrapXZDist(this->mPos, globalSuper->mPos);
|
|
this->field_204 = result;
|
|
return result;
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::TrapWeb(void){
|
|
if((this->field_2A8 & 0x10000) || (this->field_E2 <= 0)){
|
|
return 0;
|
|
}
|
|
|
|
new CMessage(NULL, this, 5, 0);
|
|
|
|
return 1;
|
|
}
|
|
|
|
// @Ok
|
|
INLINE void CBaddy::CleanUpMessages(i32 a2, i32 a3)
|
|
{
|
|
|
|
CMessage *pMessage = this->pMessage;
|
|
while (pMessage)
|
|
{
|
|
CMessage *curMessage = pMessage;
|
|
pMessage = pMessage->mNext;
|
|
if (
|
|
curMessage->field_10 & 1
|
|
|| a2
|
|
|| curMessage->field_14 == a3)
|
|
{
|
|
delete curMessage;
|
|
}
|
|
}
|
|
}
|
|
|
|
// @Ok
|
|
u16 CBaddy::CheckStateFlags(SStateFlags *sFlags, int a3){
|
|
|
|
if(this->field_314 < 0){
|
|
if (this->field_31C.bothFlags == -this->field_314)
|
|
return 0;
|
|
}
|
|
else if(this->field_31C.bothFlags == sFlags[this->field_314].flags[0]){
|
|
print_if_false(sFlags[this->field_314].flags[1] != 0, "This shouldn't be zero. Remove state from table.");
|
|
return sFlags[this->field_314].flags[1];
|
|
}
|
|
|
|
for (int i = 0; i< a3; i++){
|
|
|
|
if (this->field_31C.bothFlags != (unsigned __int16) sFlags[i].flags[0]){
|
|
continue;
|
|
}
|
|
|
|
this->field_314 = i;
|
|
print_if_false(sFlags[i].flags[1] != 0, "This shouldn't be zero. Remove state from table.");
|
|
return sFlags[i].flags[1];
|
|
}
|
|
|
|
this->field_314 = -this->field_31C.flags[0];
|
|
return 0;
|
|
}
|
|
|
|
// Revisit??
|
|
int CBaddy::YawTowards(int a2, int a3){
|
|
|
|
int vy; // edi
|
|
int v4; // eax
|
|
int v5; // edx
|
|
|
|
|
|
vy = this->mAngles.vy;
|
|
v4 = a2 - vy;
|
|
|
|
if ( a2 - vy < -2048 )
|
|
v4 += 4096;
|
|
if ( v4 > 2048 )
|
|
v4 -= 4096;
|
|
|
|
if ( !v4 )
|
|
{
|
|
this->field_8E.vy = 0;
|
|
this->csVector1.vy = 0;
|
|
return v4;
|
|
}
|
|
|
|
v5 = (a3 * v4) >> 8;
|
|
this->mAngles.vy += v5;
|
|
if ( v5 && ((int)this->mAngles.vy - a2 > 0) != (vy - a2> 0))
|
|
{
|
|
return v4;
|
|
}
|
|
|
|
this->mAngles.vy = a2;
|
|
this->field_8E.vy = 0;
|
|
this->csVector1.vy = 0;
|
|
return 0;
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::RunTimer(int *a2)
|
|
{
|
|
*a2 -= this->field_80;
|
|
if ( *a2 < 0 )
|
|
*a2 = 0;
|
|
return *a2;
|
|
}
|
|
|
|
// @BIGTODO
|
|
int CBaddy::PathCheckGuts(CVector*, CVector*, CVector*, int)
|
|
{
|
|
return 0x14141414;
|
|
}
|
|
|
|
static int * const dword_5FBEE0 = (int*)0x5FBEE0;;
|
|
// @NotOk
|
|
// Globals (rest is matching)
|
|
int CBaddy::PathCheck(CVector* a2, CVector* a3, CVector* a4, int a5)
|
|
{
|
|
|
|
int v5 = *dword_5FBEE0;
|
|
|
|
if ( (this->field_2A8 & 0x2000))
|
|
*dword_5FBEE0 = 1;
|
|
|
|
int result = this->PathCheckGuts(a2, a3, a4, a5);
|
|
*dword_5FBEE0 = v5;
|
|
return result;
|
|
}
|
|
|
|
|
|
static CBody** const dword_56E990 = (CBody**)0x56E990;
|
|
|
|
// @Ok
|
|
CBody* CBaddy::StruckGameObject(int a2, int a3)
|
|
{
|
|
CBody *result;
|
|
if ( !a2
|
|
|| (result = Utils_CheckObjectCollision(
|
|
&this->field_2FC,
|
|
&this->mPos,
|
|
globalSuper,
|
|
this)) == 0 )
|
|
{
|
|
if (a3 && (result = Utils_CheckObjectCollision(&this->field_2FC, &this->mPos, *dword_56E990, this)))
|
|
{
|
|
print_if_false(result != this, "smoething's wrong in the state of denmark");
|
|
return result;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::Neutralize(void)
|
|
{
|
|
this->MarkAIProcList(1, 0, 0);
|
|
|
|
this->gVec.vz = 0;
|
|
this->gVec.vy = 0;
|
|
this->gVec.vz = 0;
|
|
|
|
this->mAccellorVel.vz = 0;
|
|
this->mAccellorVel.vy = 0;
|
|
this->mAccellorVel.vx = 0;
|
|
|
|
this->gVec.vz = 0;
|
|
this->gVec.vy = 0;
|
|
this->gVec.vx = 0;
|
|
|
|
this->csVector1.vz = 0;
|
|
this->csVector1.vy = 0;
|
|
this->csVector1.vx = 0;
|
|
|
|
this->field_8E.vz = 0;
|
|
this->field_8E.vy = 0;
|
|
this->field_8E.vx = 0;
|
|
|
|
this->field_27C.vz = 0;
|
|
this->field_27C.vy = 0;
|
|
this->field_27C.vx = 0;
|
|
|
|
this->field_2A8 &= 0xB7FFFFFB;
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::TugWeb(void)
|
|
{
|
|
if ( (this->field_2A8 & 0x200) || this->field_E2 <= 0)
|
|
{
|
|
|
|
CTrapWebEffect *trapWeb = reinterpret_cast<CTrapWebEffect*>(
|
|
Mem_RecoverPointer(reinterpret_cast<SHandle*>(&this->field_10C)));
|
|
|
|
if (trapWeb)
|
|
trapWeb->Burst();
|
|
|
|
return 0;
|
|
}
|
|
|
|
new CMessage(0, this, 6, 0);
|
|
return 1;
|
|
}
|
|
|
|
// @Ok
|
|
void __inline CBaddy::GetLocalPos(CVector *a2, CVector *a3, CSVector *a4)
|
|
{
|
|
MATRIX v7;
|
|
|
|
if (a4)
|
|
{
|
|
M3dMaths_RotMatrixYXZ(
|
|
reinterpret_cast<SVECTOR*>(a4),
|
|
&v7);
|
|
}
|
|
else
|
|
{
|
|
M3dMaths_RotMatrixYXZ(
|
|
reinterpret_cast<SVECTOR*>(&this->mAngles),
|
|
&v7);
|
|
}
|
|
|
|
gte_SetRotMatrix(&v7);
|
|
*a3 = *a2;
|
|
gte_ldlvl(reinterpret_cast<VECTOR*>(a3));
|
|
gte_rtir();
|
|
gte_stlvnl(reinterpret_cast<VECTOR*>(a3));
|
|
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::MakeSpriteRing(CVector* arg0)
|
|
{
|
|
CVector mPos;
|
|
mPos.vx = 0;
|
|
mPos.vy = 0;
|
|
mPos.vz = 0;
|
|
|
|
if (!arg0)
|
|
{
|
|
mPos = this->mPos;
|
|
}
|
|
else
|
|
{
|
|
CVector tmp = *arg0;
|
|
|
|
tmp >>= 12;
|
|
this->GetLocalPos(&tmp, &mPos, 0);
|
|
|
|
mPos <<= 12;
|
|
mPos += this->mPos;
|
|
}
|
|
|
|
mPos.vy = Utils_GetGroundHeight(&this->mPos, 300, 600, 0) - 0xA000;
|
|
return Bit_MakeSpriteRing(&mPos, 24, 8, 1, 512, 32, 16, 0);
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::SetHeight(int a2, int a3, int a4)
|
|
{
|
|
int v5 = this->field_2A8;
|
|
if (v5 & 0x8000)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int *v7 = &this->field_2A4;
|
|
if (this->field_2A4
|
|
|| a2
|
|
|| (v5 & 0x40000) != 0
|
|
|| (v5 & 0x8000000) != 0 && ((v5 & 0x20000000) != 0 || (this->field_2F0 & 4) != 0) )
|
|
{
|
|
unsigned char v9;
|
|
|
|
if (a2 || (
|
|
v9 = this->field_80, v9 += this->field_213,
|
|
v9 >= this->field_212))
|
|
{
|
|
CVector v16;
|
|
v16.vx = this->mPos.vx;
|
|
v16.vy = (this->field_21E << 12) + this->mPos.vy;
|
|
v16.vz = this->mPos.vz;
|
|
|
|
int height = Utils_GetGroundHeight(&v16, a3, a4, reinterpret_cast<CBody**>(&this->field_2A4));
|
|
if (height == -1)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int v7Value = *v7;
|
|
if (v7Value)
|
|
{
|
|
int v12 = *reinterpret_cast<int*>(v7Value + 0x64);
|
|
if (!v12)
|
|
{
|
|
*v7 = v12;
|
|
}
|
|
else
|
|
{
|
|
height += v12;
|
|
}
|
|
}
|
|
|
|
this->field_2A0 = height;
|
|
if (!this->field_212)
|
|
this->field_212 = 30;
|
|
this->field_213 = 0;
|
|
}
|
|
}
|
|
|
|
// label 21
|
|
int v13 = this->field_2A0 - (this->field_21E << 12);
|
|
int vy = this->mPos.vy;
|
|
|
|
if (v13 != vy)
|
|
{
|
|
int v15 = ((v13 - vy) >> 2) + vy;
|
|
this->mPos.vy = v15;
|
|
if ( abs(v15 - v13) <= (*v7 != 0 ? 122880 : 12888))
|
|
{
|
|
this->mPos.vy = v13;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
|
|
|
|
// @Ok
|
|
void __inline CBaddy::SendDeathPulse(void)
|
|
{
|
|
|
|
if (!this->field_211 && this->field_DE != (__int16)0xFFFF)
|
|
{
|
|
this->field_211 = 1;
|
|
Trig_SendPulse(
|
|
reinterpret_cast<unsigned __int16*>(Trig_GetLinksPointer(this->field_DE & 0xFFFF)));
|
|
}
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::Die(int a2)
|
|
{
|
|
if(!this->IsDead())
|
|
{
|
|
int v8;
|
|
int v9;
|
|
switch (a2)
|
|
{
|
|
case 0:
|
|
if (!(this->field_2A8 & 0x4000))
|
|
{
|
|
this->SendDeathPulse();
|
|
}
|
|
case 3:
|
|
this->mCBodyFlags |= 0x40;
|
|
this->mFlags |= 1;
|
|
break;
|
|
case 1:
|
|
if (!(this->field_2A8 & 0x4000))
|
|
{
|
|
this->SendDeathPulse();
|
|
}
|
|
|
|
this->mFlags |= 0x800;
|
|
this->field_30 = 128;
|
|
this->KillShadow();
|
|
|
|
this->mFlags |= 0x400;
|
|
this->field_24 = 0x404040;
|
|
this->field_1F8 = 0;
|
|
break;
|
|
case 2:
|
|
v8 = this->field_1F8;
|
|
v9 = v8 + 1;
|
|
this->field_1F8 = v9;
|
|
if ( v8 >= 40 )
|
|
return 1;
|
|
|
|
v9 = ((6553 * (40 - v9)) >> 12);
|
|
v8 = v9;
|
|
|
|
v8 <<= 8;
|
|
v8 |= v9;
|
|
v8 <<= 8;
|
|
v8 |= v9;
|
|
|
|
this->field_24 = v8;
|
|
break;
|
|
|
|
|
|
default:
|
|
print_if_false(0, "Unknown die state");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// @Ok
|
|
INLINE void CBaddy::CleanUpAIProcList(i32 a2)
|
|
{
|
|
CAIProc *pProc = this->mAIProcList;
|
|
while (pProc)
|
|
{
|
|
CAIProc *curProc = pProc;
|
|
pProc = pProc->mNext;
|
|
if (
|
|
a2
|
|
|| curProc->field_10 & 1)
|
|
{
|
|
delete curProc;
|
|
}
|
|
}
|
|
}
|
|
|
|
// @NotOk
|
|
// Gloabsl
|
|
// and vz
|
|
int CBaddy::BumpedIntoSpidey(int a2)
|
|
{
|
|
int v3 = this->field_208;
|
|
int v4;
|
|
|
|
if (v3 && *dword_5FCCF4 <= 4)
|
|
{
|
|
v4 = this->field_204;
|
|
}
|
|
else
|
|
{
|
|
this->field_208 = *dword_5FCCF4;
|
|
v4 = Utils_CrapXZDist(this->mPos, globalSuper->mPos);
|
|
this->field_204 = v4;
|
|
}
|
|
|
|
if (v4 < a2)
|
|
{
|
|
__int16 vz = *reinterpret_cast<__int16*>(globalSuper + 0x754); // wrong
|
|
int twoOneE = this->field_21E;
|
|
|
|
int res = twoOneE - vz - (globalSuper->mPos.vy >> 12) + (this->mPos.vy >> 12);
|
|
int shifted = res >> 31;
|
|
|
|
if ( (((shifted) ^ res) - shifted) < 200)
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// @Ok
|
|
int CBaddy::PlayerIsVisible()
|
|
{
|
|
if (!globalSuper->IsDead() &&
|
|
Utils_LineOfSight(&this->mPos, &globalSuper->mPos, 0, 0)
|
|
)
|
|
{
|
|
if (!this->PathCheck( &this->mPos, &globalSuper->mPos, 0, 55))
|
|
{
|
|
this->field_1A8 = globalSuper->mPos;
|
|
this->field_2A8 |= 0x800;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// @Ok
|
|
int CBaddy::ShouldFall(int a2, int a3)
|
|
{
|
|
int GroundHeight = Utils_GetGroundHeight(&this->mPos, a2, 4096, 0);
|
|
if (GroundHeight == -1)
|
|
{
|
|
this->field_308 = this->mPos.vy - 100;
|
|
this->KillShadow();
|
|
|
|
this->field_2A8 &= 0xFFFFFBFF;
|
|
|
|
return GroundHeight;
|
|
}
|
|
|
|
int v7 = GroundHeight - (this->field_21E << 12);
|
|
|
|
if (v7 - this->mPos.vy > a3)
|
|
{
|
|
this->KillShadow();
|
|
|
|
this->field_308 = v7;
|
|
this->field_2A8 |= 0x400;
|
|
|
|
return v7 - this->mPos.vy;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// @NotOk
|
|
// Globals
|
|
int CBaddy::CheckSightCone(int a2, int a3, int a4, int a5, CBody *a6)
|
|
{
|
|
CSVector v16;
|
|
v16.vx = 0;
|
|
v16.vy = 0;
|
|
v16.vz = 0;
|
|
|
|
if (!a3)
|
|
return 0;
|
|
|
|
int v12 = a6->mPos.vy - this->mPos.vy;
|
|
if (abs(v12) > (a3 << 12))
|
|
return 0;
|
|
|
|
int v13;
|
|
if (a6 == globalSuper)
|
|
{
|
|
v13 = this->DistanceToPlayer(2);
|
|
}
|
|
else
|
|
{
|
|
v13 = Utils_CrapXZDist(this->mPos, a6->mPos);
|
|
}
|
|
|
|
if (v13 < a5)
|
|
return 1;
|
|
|
|
if (v13 > a4)
|
|
return 0;
|
|
|
|
Utils_CalcAim(&v16, &this->mPos, &a6->mPos);
|
|
int v14 = v16.vy - this->mAngles.vy;
|
|
if (v14 < -2048)
|
|
{
|
|
v14 += 4096;
|
|
}
|
|
else if (v14 >= -2048)
|
|
{
|
|
if (v14 > 2048)
|
|
{
|
|
v14 -= 4096;
|
|
}
|
|
}
|
|
|
|
|
|
return abs(v14) <= (a2 >> 1);
|
|
}
|
|
|
|
// @MEDIUMTODO
|
|
void CBaddy::ParseScript(unsigned __int16*)
|
|
{}
|
|
|
|
i32 NumBaddies;
|
|
|
|
// @NotOk
|
|
// Globals
|
|
CBaddy::CBaddy(void)
|
|
{
|
|
this->field_1A8.vx = 0;
|
|
this->field_1A8.vy = 0;
|
|
this->field_1A8.vz = 0;
|
|
|
|
for(int i=0; i<5; i++)
|
|
{
|
|
this->field_1B4[i].vx = 0;
|
|
this->field_1B4[i].vy = 0;
|
|
this->field_1B4[i].vz = 0;
|
|
}
|
|
|
|
this->field_240.vx = 0;
|
|
this->field_240.vy = 0;
|
|
this->field_240.vz = 0;
|
|
this->field_27C.vx = 0;
|
|
this->field_27C.vy = 0;
|
|
this->field_27C.vz = 0;
|
|
this->field_2B8.vx = 0;
|
|
this->field_2B8.vy = 0;
|
|
this->field_2B8.vz = 0;
|
|
this->field_2C4 = 0;
|
|
this->field_2C8 = 0;
|
|
this->field_2CC = 0;
|
|
this->field_2D0.vx = 0;
|
|
this->field_2D0.vy = 0;
|
|
this->field_2D0.vz = 0;
|
|
this->field_2DC = 0;
|
|
this->field_2DE = 0;
|
|
this->field_2E0 = 0;
|
|
this->field_2E2 = 0;
|
|
this->field_2E4 = 0;
|
|
this->field_2E6 = 0;
|
|
this->field_2E8.vx = 0;
|
|
this->field_2E8.vy = 0;
|
|
this->field_2E8.vz = 0;
|
|
this->field_2FC.vx = 0;
|
|
this->field_2FC.vy = 0;
|
|
this->field_2FC.vz = 0;
|
|
|
|
this->field_21D = NumBaddies++;
|
|
this->mCBodyFlags |= 0x200;
|
|
|
|
this->field_DC = 128;
|
|
this->field_F4 = 128;
|
|
this->field_DE = -1;
|
|
this->field_216 = 32;
|
|
this->field_D8 = 64;
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::CreateCombatImpactEffect(CVector*, int)
|
|
{
|
|
}
|
|
|
|
// @Ok
|
|
u8 CBaddy::TugImpulse(CVector*, CVector*, CVector* a4)
|
|
{
|
|
if (a4)
|
|
Mem_Delete(a4);
|
|
return 0;
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::Victorious()
|
|
{
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::SetParamByIndex(i32, i32)
|
|
{
|
|
}
|
|
|
|
// @Ok
|
|
u8 CBaddy::Grab(CVector*)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::Shouldnt_DoPhysics_Be_Virtual(void)
|
|
{
|
|
this->DoPhysics(0);
|
|
}
|
|
|
|
// @NotOk
|
|
// Figure out name
|
|
void CBaddy::UnknownCBaddyFunctionFive(int)
|
|
{
|
|
}
|
|
|
|
// @Ok
|
|
CBaddy* CBaddy::GetClosest(i32 baddyType, i32 inSight)
|
|
{
|
|
i32 distance = 10656;
|
|
CBaddy* result = 0;
|
|
|
|
for ( CBaddy* i = BaddyList; i; i = reinterpret_cast<CBaddy*>(i->field_20))
|
|
{
|
|
if ( (!baddyType || i->field_38 == baddyType) && i != this )
|
|
{
|
|
i32 v9 = Utils_CrapXZDist(this->mPos, i->mPos);
|
|
if ( distance > v9
|
|
&& (!inSight || Utils_LineOfSight(&i->mPos, &this->mPos, 0, 0)) )
|
|
{
|
|
distance = v9;
|
|
result = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// @BIGTODO
|
|
int CBaddy::ExecuteCommand(unsigned __int16)
|
|
{
|
|
return 0x21052025;
|
|
}
|
|
|
|
// @MEDIUMTODO
|
|
void CBaddy::SetVariable(unsigned __int16)
|
|
{
|
|
printf("test");
|
|
}
|
|
|
|
// @MEDIUMTODO
|
|
unsigned __int16 CBaddy::GetVariable(unsigned __int16)
|
|
{
|
|
return 0x696940;
|
|
}
|
|
|
|
// @BIGTODO
|
|
void CBaddy::DoPhysics(i32)
|
|
{
|
|
printf("void CBaddy::DoPhysics(int)");
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::Baddy_SendSignal(void)
|
|
{
|
|
unsigned __int16 *ptr = reinterpret_cast<unsigned __int16*>(
|
|
Trig_GetLinksPointer((unsigned __int16)this->field_DE));
|
|
if (ptr)
|
|
Trig_SendSignalToLinks(ptr);
|
|
}
|
|
|
|
static CBaddy* gBaddylist;
|
|
|
|
// @Ok
|
|
CBaddy* FindBaddyOfType(int type)
|
|
{
|
|
CBaddy *current = gBaddylist;
|
|
|
|
if (current)
|
|
{
|
|
while (current)
|
|
{
|
|
if (current->field_38 == type)
|
|
{
|
|
return current;
|
|
}
|
|
|
|
current = reinterpret_cast<CBaddy*>(current->field_20);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// @Ok
|
|
void CBaddy::MarkAIProcList(int a2, int a3, int a4)
|
|
{
|
|
unsigned int *head = reinterpret_cast<u32*>(this->mAIProcList);
|
|
while (head)
|
|
{
|
|
unsigned int *v5 = head;
|
|
head = reinterpret_cast<unsigned int*>(head[7]);
|
|
|
|
unsigned int v6;
|
|
if (a2 && !(v5[2] & 0x20000) || a3 && (v5[2] & 0xFF00) == a3)
|
|
{
|
|
v6 = v5[4] | 1;
|
|
}
|
|
else
|
|
{
|
|
if (!a4 || (v5[2] & 0xFF00) != a4)
|
|
continue;
|
|
|
|
v6 = v5[4] | 4;
|
|
}
|
|
|
|
v5[4] = v6;
|
|
}
|
|
}
|
|
|
|
// @Ok
|
|
CBaddy::~CBaddy(void)
|
|
{
|
|
print_if_false(NumBaddies > 0, "Negative NumBaddies");
|
|
--NumBaddies;
|
|
|
|
this->CleanUpAIProcList(1);
|
|
this->CleanUpMessages(1, 0);
|
|
}
|
|
|
|
void validate_CBaddy(void){
|
|
VALIDATE_SIZE(CBaddy, 0x324);
|
|
|
|
VALIDATE(CBaddy, field_194, 0x194);
|
|
VALIDATE(CBaddy, field_198, 0x198);
|
|
|
|
VALIDATE(CBaddy, field_1A8, 0x1A8);
|
|
VALIDATE(CBaddy, field_1B4, 0x1B4);
|
|
|
|
VALIDATE(CBaddy, field_1F0, 0x1F0);
|
|
VALIDATE(CBaddy, field_1F4, 0x1F4);
|
|
VALIDATE(CBaddy, field_1F8, 0x1F8);
|
|
VALIDATE(CBaddy, field_1FC, 0x1FC);
|
|
VALIDATE(CBaddy, field_1FE, 0x1FE);
|
|
|
|
VALIDATE(CBaddy, field_204, 0x204);
|
|
VALIDATE(CBaddy, field_208, 0x208);
|
|
VALIDATE(CBaddy, field_20C, 0x20C);
|
|
VALIDATE(CBaddy, field_20F, 0x20F);
|
|
VALIDATE(CBaddy, field_210, 0x210);
|
|
|
|
|
|
VALIDATE(CBaddy, field_211, 0x211);
|
|
VALIDATE(CBaddy, field_212, 0x212);
|
|
VALIDATE(CBaddy, field_213, 0x213);
|
|
|
|
VALIDATE(CBaddy, field_216, 0x216);
|
|
VALIDATE(CBaddy, field_218, 0x218);
|
|
VALIDATE(CBaddy, field_21D, 0x21D);
|
|
VALIDATE(CBaddy, field_21E, 0x21E);
|
|
VALIDATE(CBaddy, registerArr, 0x220);
|
|
|
|
VALIDATE(CBaddy, field_230, 0x230);
|
|
VALIDATE(CBaddy, field_234, 0x234);
|
|
VALIDATE(CBaddy, field_23C, 0x23C);
|
|
|
|
VALIDATE(CBaddy, field_240, 0x240);
|
|
|
|
VALIDATE(CBaddy, field_24C, 0x24C);
|
|
|
|
|
|
VALIDATE(CBaddy, attributeArr, 0x270);
|
|
VALIDATE(CBaddy, field_27C, 0x27C);
|
|
|
|
VALIDATE(CBaddy, field_288, 0x288);
|
|
|
|
VALIDATE(CBaddy, mAIProcList, 0x28C);
|
|
VALIDATE(CBaddy, pMessage, 0x290);
|
|
|
|
VALIDATE(CBaddy, field_294, 0x294);
|
|
VALIDATE(CBaddy, field_298, 0x298);
|
|
VALIDATE(CBaddy, field_29C, 0x29C);
|
|
|
|
VALIDATE(CBaddy, field_2A0, 0x2A0);
|
|
VALIDATE(CBaddy, field_2A4, 0x2A4);
|
|
VALIDATE(CBaddy, field_2A8, 0x2A8);
|
|
VALIDATE(CBaddy, field_2AC, 0x2AC);
|
|
|
|
VALIDATE(CBaddy, field_2B0, 0x2B0);
|
|
VALIDATE(CBaddy, field_2B4, 0x2B4);
|
|
VALIDATE(CBaddy, field_2B8, 0x2B8);
|
|
|
|
|
|
VALIDATE(CBaddy, field_2C4, 0x2C4);
|
|
VALIDATE(CBaddy, field_2C8, 0x2C8);
|
|
VALIDATE(CBaddy, field_2CC, 0x2CC);
|
|
|
|
VALIDATE(CBaddy, field_2D0, 0x2D0);
|
|
|
|
VALIDATE(CBaddy, field_2DC, 0x2DC);
|
|
VALIDATE(CBaddy, field_2DE, 0x2DE);
|
|
|
|
VALIDATE(CBaddy, field_2E0, 0x2E0);
|
|
VALIDATE(CBaddy, field_2E2, 0x2E2);
|
|
VALIDATE(CBaddy, field_2E4, 0x2E4);
|
|
VALIDATE(CBaddy, field_2E6, 0x2E6);
|
|
VALIDATE(CBaddy, field_2E8, 0x2E8);
|
|
|
|
|
|
VALIDATE(CBaddy, field_2F0, 0x2F0);
|
|
VALIDATE(CBaddy, field_2F4, 0x2F4);
|
|
VALIDATE(CBaddy, field_2F8, 0x2F8);
|
|
VALIDATE(CBaddy, field_2FC, 0x2FC);
|
|
|
|
|
|
VALIDATE(CBaddy, field_308, 0x308);
|
|
VALIDATE(CBaddy, field_310, 0x310);
|
|
VALIDATE(CBaddy, field_314, 0x314);
|
|
VALIDATE(CBaddy, field_318, 0x318);
|
|
VALIDATE(CBaddy, field_31C, 0x31C);
|
|
VALIDATE(CBaddy, dumbAssPad, 0x320);
|
|
|
|
VALIDATE_VTABLE(CBaddy, AI, 2);
|
|
VALIDATE_VTABLE(CBaddy, Hit, 3);
|
|
VALIDATE_VTABLE(CBaddy, PlayerIsVisible, 5);
|
|
VALIDATE_VTABLE(CBaddy, CreateCombatImpactEffect, 6);
|
|
VALIDATE_VTABLE(CBaddy, TugImpulse, 7);
|
|
VALIDATE_VTABLE(CBaddy, Victorious, 8);
|
|
|
|
VALIDATE_VTABLE(CBaddy, SetParamByIndex, 9);
|
|
VALIDATE_VTABLE(CBaddy, Grab, 10);
|
|
|
|
VALIDATE_VTABLE(CBaddy, Shouldnt_DoPhysics_Be_Virtual, 11);
|
|
VALIDATE_VTABLE(CBaddy, GetClosest, 13);
|
|
}
|
|
|
|
|
|
void validate_CScriptOnlyBaddy(void){
|
|
|
|
VALIDATE_SIZE(CScriptOnlyBaddy, 0x330);
|
|
VALIDATE(CScriptOnlyBaddy, field_328, 0x328);
|
|
VALIDATE(CScriptOnlyBaddy, field_32C, 0x32C);
|
|
VALIDATE(CScriptOnlyBaddy, field_32E, 0x32E);
|
|
}
|
|
|
|
void validate_SStateFlags(void){
|
|
VALIDATE_SIZE(SStateFlags, 0x4);
|
|
}
|