diff --git a/src/SB/Core/x/xBehaviour.h b/src/SB/Core/x/xBehaviour.h index 1485e0de..47c7bfd6 100644 --- a/src/SB/Core/x/xBehaviour.h +++ b/src/SB/Core/x/xBehaviour.h @@ -127,10 +127,10 @@ struct xPsyche : RyzMemData struct xGoal : xListItem, xFactoryInst { - xPsyche* psyche; + xPsyche* psyche; // 0x18 int32 goalID; en_GOALSTATE stat; - int32 flg_able; + int32 flg_able; // 0x24 xGoalProcessCallback fun_process; xGoalPreCalcCallback fun_precalc; xGoalChkRuleCallback fun_chkRule; @@ -197,4 +197,4 @@ struct xGoal : xListItem, xFactoryInst ~xGoal(); // prevents implicit destructors from being generated in subclasses of xGoal }; -#endif \ No newline at end of file +#endif diff --git a/src/SB/Core/x/xModel.h b/src/SB/Core/x/xModel.h index 36580ab3..741e97bd 100644 --- a/src/SB/Core/x/xModel.h +++ b/src/SB/Core/x/xModel.h @@ -46,11 +46,11 @@ struct xModelInstance // Offset: 0x40 void* Object; - uint16 Flags; - uint8 BoneCount; - uint8 BoneIndex; - uint8* BoneRemap; - RwMatrix* Mat; + uint16 Flags; // 0x44 + uint8 BoneCount; // 0x46 + uint8 BoneIndex; // 0x47 + uint8* BoneRemap; // 0x48 + RwMatrix* Mat; // 0x4C // Offset: 0x50 xVec3 Scale; diff --git a/src/SB/Game/zGlobals.h b/src/SB/Game/zGlobals.h index 1630e92b..557678bc 100644 --- a/src/SB/Game/zGlobals.h +++ b/src/SB/Game/zGlobals.h @@ -148,7 +148,7 @@ struct zPlayerGlobals // 0x16AC in globals uint32 Visible; - uint32 Health; + uint32 Health; // 0x16b0 int32 Speed; float32 SpeedMult; int32 Sneak; @@ -172,7 +172,7 @@ struct zPlayerGlobals float32 ScareTimer; xBase* ScareSource; float32 CowerTimer; - float32 DamageTimer; + float32 DamageTimer; // 0x1708 float32 SundaeTimer; float32 ControlOffTimer; float32 HelmetTimer; diff --git a/src/SB/Game/zNPCGoalCommon.h b/src/SB/Game/zNPCGoalCommon.h index 086b0bf2..5d3b6cf1 100644 --- a/src/SB/Game/zNPCGoalCommon.h +++ b/src/SB/Game/zNPCGoalCommon.h @@ -9,11 +9,11 @@ struct zNPCGoalCommon : xGoal { - int32 flg_npcgauto; + int32 flg_npcgauto; // 0x3c int32 flg_npcgable; uint32 anid_played; - int32 flg_info : 16; - int32 flg_user : 16; + int32 flg_info : 16; // 0x48 + int32 flg_user : 16; // 0x4a zNPCGoalCommon(int32 goalID); diff --git a/src/SB/Game/zNPCGoalRobo.cpp b/src/SB/Game/zNPCGoalRobo.cpp index 173ce6a0..9a2b0f17 100644 --- a/src/SB/Game/zNPCGoalRobo.cpp +++ b/src/SB/Game/zNPCGoalRobo.cpp @@ -1,8 +1,489 @@ #include "xVec3.h" #include "xMath3.h" #include "zNPCGoalRobo.h" +#include "zNPCTypeRobot.h" +#include "zNPCHazard.h" +#include "zGlobals.h" +#include "zNPCTypeCommon.h" +#include "zNPCGoalCommon.h" +#include "zNPCGoalStd.h" +#include "zNPCSupport.h" +#include "zNPCGoals.h" -#include +float32 f_0 = 0.0f; // needed at file level to change scheduling for + +int32 zNPCGoalAlertFodder::Enter(float32 dt, void* updCtxt) +{ + flg_attack = 0; + tmr_alertfod = f_0; // need non-const float to get scheduling right + alertfod = FODDER_ALERT_NOTICE; + zNPCGoalCommon::Enter(dt, updCtxt); +} + +int32 zNPCGoalAlertFodder::Process(en_trantype* trantype, float32 dt, void* updCtxt, xScene* scene) +{ + zNPCRobot* npc = (zNPCRobot*)this->psyche->clt_owner; + int32 nextgoal = 0; + + if (globals.player.Health < 1) + { + zNPCGoalTaunt* taunt = (zNPCGoalTaunt*)psyche->FindGoal(NPC_GOAL_TAUNT); + taunt->LoopCountSet(1000); + nextgoal = NPC_GOAL_TAUNT; + *trantype = GOAL_TRAN_PUSH; + } + else + { + if (globals.player.DamageTimer > 0.5f) + { + nextgoal = NPC_GOAL_TAUNT; + *trantype = GOAL_TRAN_PUSH; + } + else + { + if (npc->SomethingWonderful()) + { + *trantype = GOAL_TRAN_SET; + nextgoal = NPC_GOAL_NGN0; + } + else + { + // I don't understand this check + if (!npc->arena.IncludesPlayer(0.0f, NULL)) + { + nextgoal = NPC_GOAL_NGN0; + *trantype = GOAL_TRAN_SET; + } + } + } + } + + if (*trantype != GOAL_TRAN_NONE) + { + return nextgoal; + } + + en_alertfod old_alertfod = this->alertfod; + + int32 flag2 = this->flg_info & 2; + this->flg_info = this->flg_info & ~0x6; + + float32 pct = npc->arena.PctFromHome(npc->Pos()); + + if (pct > 1.0f) + { + flag2 = 1; + this->alertfod = FODDER_ALERT_ARENA; + } + else if (this->alertfod == FODDER_ALERT_ARENA && pct < 0.5f) + { + this->alertfod = FODDER_ALERT_BEGIN; + flag2 = 0x1; + } + + switch (this->alertfod) + { + case FODDER_ALERT_NOTICE: // 0x194 + { + this->alertfod = FODDER_ALERT_BEGIN; + nextgoal = NPC_GOAL_NOTICE; + *trantype = GOAL_TRAN_PUSH; + break; + } + case FODDER_ALERT_ARENA: // 0x1ac + { + if (flag2) + { + this->DoAutoAnim(NPC_GSPOT_STARTALT, 0); + } + + this->GetInArena(dt); + break; + } + case FODDER_ALERT_BEGIN: // 0x1d4 + { + this->alertfod = FODDER_ALERT_CHASE; + break; + } + case FODDER_ALERT_CHASE: // 0x1e0 + { + if (zNPCGoalAlertFodder::CheckSpot(dt) && !(globals.player.DamageTimer > 0.0f)) + { + this->alertfod = FODDER_ALERT_STABDONE; + nextgoal = 'NGRE'; + *trantype = GOAL_TRAN_PUSH; + break; + } + + if (flag2) + { + this->DoAutoAnim(NPC_GSPOT_STARTALT, 0); + } + + this->FlankPlayer(dt); + + break; + } + case FODDER_ALERT_STABDONE: // 0x250 + { + this->alertfod = FODDER_ALERT_CHASE; + break; + } + case FODDER_ALERT_EVADE: // 0x25c + { + if (flag2) + { + this->DoAutoAnim(NPC_GSPOT_STARTALT, 0); + this->tmr_alertfod = 0.25f; + } + + if (this->tmr_alertfod < 0.0f) + { + this->alertfod = FODDER_ALERT_BEGIN; + break; + } + + this->MoveEvade(dt); + + // needs to be a ternary expression to match + this->tmr_alertfod = (-1.0f > this->tmr_alertfod - dt) ? -1.0f : this->tmr_alertfod - dt; + + break; + } + } + + if (this->alertfod != old_alertfod) + { + this->flg_info |= 2; + } + + if (*trantype) + { + return nextgoal; + } + + return this->xGoal::Process(trantype, dt, updCtxt, NULL); +} + +void zNPCGoalAlertFodder::GetInArena(float32 dt) +{ + zNPCRobot* npc; + xVec3 vec1; + xVec3 dir_want; + xVec3 dir; + + npc = (zNPCRobot*)this->psyche->clt_owner; + + xVec3Sub(&vec1, npc->arena.Pos(), npc->zNPCCommon::Pos()); + + float32 rot = xVec3Length(&vec1); + + if (rot < 1.0f) + { + xVec3Copy(&vec1, NPCC_rightDir(npc)); + } + else + { + xVec3SMulBy(&vec1, 1.0f / rot); + } + + xVec3Copy(&dir_want, &vec1); + + npc->ThrottleAdjust(dt, 6.0f, -1.0f); + rot = npc->TurnToFace(dt, &dir_want, -1.0f); + NPCC_ang_toXZDir(npc->frame->rot.angle + rot, &dir); + npc->ThrottleApply(dt, &dir, 0); +} + +void zNPCGoalAlertFodBzzt::GetInArena(float32 dt) +{ + zNPCRobot* npc; + xVec3 dir; + + npc = (zNPCRobot*)this->psyche->clt_owner; + + xVec3Sub(&dir, npc->arena.Pos(), npc->zNPCCommon::Pos()); + + float32 rot = xVec3Length(&dir); + + if (rot < 1.0f) + { + xVec3Copy(&dir, NPCC_rightDir(npc)); + } + else + { + xVec3SMulBy(&dir, 1.0f / rot); + } + + npc->ThrottleAdjust(dt, 6.0f, -1.0f); + npc->ThrottleApply(dt, &dir, 0); +} + +void zNPCGoalAlertChomper::GetInArena(float32 dt) +{ + zNPCRobot* npc; + xVec3 vec1; + xVec3 dir_want; + xVec3 dir; + + npc = (zNPCRobot*)this->psyche->clt_owner; + + xVec3Sub(&vec1, npc->arena.Pos(), npc->zNPCCommon::Pos()); + + float32 rot = xVec3Length(&vec1); + + if (rot < 1.0f) + { + xVec3Copy(&vec1, NPCC_rightDir(npc)); + } + else + { + xVec3SMulBy(&vec1, 1.0f / rot); + } + + xVec3Copy(&dir_want, &vec1); + + npc->ThrottleAdjust(dt, 2.5f, -1.0f); + rot = npc->TurnToFace(dt, &dir_want, -1.0f); + NPCC_ang_toXZDir(npc->frame->rot.angle + rot, &dir); + npc->ThrottleApply(dt, &dir, 0); +} + +void zNPCGoalAlertTarTar::GetInArena(float32 dt) +{ + zNPCRobot* npc; + xVec3 vec1; + xVec3 dir_want; + xVec3 dir; + + npc = (zNPCRobot*)this->psyche->clt_owner; + + xVec3Sub(&vec1, npc->arena.Pos(), npc->zNPCCommon::Pos()); + + float32 rot = xVec3Length(&vec1); + + if (rot < 1.0f) + { + xVec3Copy(&vec1, NPCC_rightDir(npc)); + } + else + { + xVec3SMulBy(&vec1, 1.0f / rot); + } + + xVec3Copy(&dir_want, &vec1); + + npc->ThrottleAdjust(dt, 2.0f, -1.0f); + rot = npc->TurnToFace(dt, &dir_want, -1.0f); + NPCC_ang_toXZDir(npc->frame->rot.angle + rot, &dir); + npc->ThrottleApply(dt, &dir, 0); +} + +void zNPCGoalAlertChuck::GetInArena(float32 dt) +{ + zNPCRobot* npc; + xVec3 vec1; + xVec3 dir_want; + xVec3 dir; + + npc = (zNPCRobot*)this->psyche->clt_owner; + + xVec3Sub(&vec1, npc->arena.Pos(), npc->zNPCCommon::Pos()); + + float32 rot = xVec3Length(&vec1); + + if (rot < 1.0f) + { + xVec3Copy(&vec1, NPCC_rightDir(npc)); + } + else + { + xVec3SMulBy(&vec1, 1.0f / rot); + } + + xVec3Copy(&dir_want, &vec1); + + npc->ThrottleAdjust(dt, 4.0f, -1.0f); + rot = npc->TurnToFace(dt, &dir_want, -1.0f); + NPCC_ang_toXZDir(npc->frame->rot.angle + rot, &dir); + npc->ThrottleApply(dt, &dir, 0); +} + +void zNPCGoalAlertSlick::GetInArena(float32 dt) +{ + zNPCRobot* npc; + xVec3 vec1; + xVec3 dir_want; + xVec3 dir; + + npc = (zNPCRobot*)this->psyche->clt_owner; + + xVec3Sub(&vec1, npc->arena.Pos(), npc->zNPCCommon::Pos()); + + float32 rot = xVec3Length(&vec1); + + if (rot < 1.0f) + { + xVec3Copy(&vec1, NPCC_rightDir(npc)); + } + else + { + xVec3SMulBy(&vec1, 1.0f / rot); + } + + xVec3Copy(&dir_want, &vec1); + + npc->ThrottleAdjust(dt, 2.0f, -1.0f); + rot = npc->TurnToFace(dt, &dir_want, -1.0f); + NPCC_ang_toXZDir(npc->frame->rot.angle + rot, &dir); + npc->ThrottleApply(dt, &dir, 0); +} + +void zNPCGoalDogLaunch::SilentSwimout(xVec3* unk1, xVec3* unk2, zMovePoint* unk3) +{ + this->ViciousAttack(unk1, unk2, unk3, 1); +} + +uint8 zNPCGoalPatThrow::CollReview(void*) +{ + return 0; +} + +uint8 zNPCGoalDogLaunch::CollReview(void*) +{ + return 0; +} + +void zNPCGoalDead::DieWithAWhimper() +{ + flg_deadinfo &= ~1; + flg_deadinfo |= 2; +} + +void zNPCGoalDead::DieWithABang() +{ + flg_deadinfo &= ~1; + flg_deadinfo &= ~2; +} + +void xGoal::AddFlags(int32 flags) +{ + this->flg_able |= flags; +} + +xPsyche* xGoal::GetPsyche() const +{ + return psyche; +} + +xVec3* zNPCCommon::XZVecToPlayer(xVec3* unk1, float32* unk2) +{ + return zNPCCommon::XZVecToPos(unk1, xEntGetPos(&globals.player.ent), unk2); +} + +RwMatrix* zNPCCommon::BoneMat(int32 unk) const +{ + return &this->model->Mat[unk]; +} + +RwV3d* zNPCCommon::BonePos(int32 unk) const +{ + return &this->model->Mat[unk].pos; +} + +// Return type is probably wrong +int32 zNPCCommon::XYZDstSqToPlayer(xVec3* unk) +{ + return XYZDstSqToPos(xEntGetPos(&globals.player.ent), unk); +} + +void zNPCCommon::DuploNotice(en_SM_NOTICES, void*) +{ +} + +xVec3* zNPCCommon::Center() +{ + return xEntGetCenter(this); +} + +void zNPCCommon::ModelScaleSet(float32 unk) +{ + ModelScaleSet(unk, unk, unk); +} + +void NPCC_DrawPlayerPredict(int, float, float) +{ +} + +void NPCLaser::ColorSet(const RwRGBA* unk1, const RwRGBA* unk2) +{ + // unk2->alpha = unk1->alpha; +} + +void xDrawCyl(const xVec3*, float, float, unsigned int) +{ +} + +float32 NPCArena::Radius(float32 unk) +{ + return unk * rad_arena; +} + +xVec3* NPCArena::Pos() +{ + return &pos_arena; +} + +void NPCBattle::JoinBattle(zNPCRobot*) +{ +} + +int32 NPCArena::IncludesPlayer(float32 rad_thresh, xVec3* vec) +{ + if (NPCC_LampStatus()) + { + xVec3* pos = xEntGetPos(&globals.player.ent); + return NPCArena::IncludesPos(pos, rad_thresh, vec); + } + + return 0; +} + +int32 NPCArena::IsReady() +{ + // TODO: not matching, not sure what this is + return this->rad_arena == 1.0f; // @1130 check this float value +} + +void NPCBattle::LeaveBattle(zNPCRobot*) +{ +} + +float32 zNPCRobot::FacePlayer(float32 dt, float32 spd_turn) +{ + xVec3* pos = xEntGetPos(&globals.player.ent); + return FacePos(pos, dt, spd_turn); +} + +void NPCArena::DBG_Draw(zNPCCommon*) +{ +} + +zMovePoint* zNPCArfArf::GetTelepoint(int32 unk) +{ + return nav_dest; +} + +/* +void zNPCHazard::SetNPCOwner(zNPCCommon* owner) +{ +} +*/ + +int32 HAZNotify::Notify(en_haznote note, NPCHazard* haz) +{ + return 0; +} void xMat3x3RMulVec(xVec3* o, const xMat3x3* m, const xVec3* v) { diff --git a/src/SB/Game/zNPCGoalStd.h b/src/SB/Game/zNPCGoalStd.h index a1251bf8..13833f57 100644 --- a/src/SB/Game/zNPCGoalStd.h +++ b/src/SB/Game/zNPCGoalStd.h @@ -3,6 +3,223 @@ #include "zNPCGoalCommon.h" +enum en_alertbzzt +{ + FODBZZT_ALERT_NOTICE, + FODBZZT_ALERT_ARENA, + FODBZZT_ALERT_CHASE, + FODBZZT_ALERT_NOMORE, + FODBZZT_ALERT_FORCE = 0x7fffffff +}; + +enum en_alertslik +{ + SLICK_ALERT_NOTICE, + SLICK_ALERT_BEGIN, + SLICK_ALERT_ARENA, + SLICK_ALERT_READY, + SLICK_ALERT_NOMORE, + SLICK_ALERT_FORCE = 0x7fffffff +}; + +enum en_hoppy +{ + HOPPY_PATTERN_START, + HOPPY_PATTERN_SHOOT, + HOPPY_PATTERN_HOPLEFT, + HOPPY_PATTERN_HOPRIGHT, + HOPPY_PATTERN_HOPSHOOT, + HOPPY_PATTERN_NOMORE, + HOPPY_PATTERN_FORCE = 0x7fffffff +}; + +enum en_alerttart +{ + TARTAR_ALERT_NOTICE, + TARTAR_ALERT_BEGIN, + TARTAR_ALERT_ARENA, + TARTAR_ALERT_READY, + TARTAR_ALERT_NOMORE, + TARTAR_ALERT_FORCE = 0x7fffffff +}; + +enum en_alertchomp +{ + CHOMPER_ALERT_NOTICE, + CHOMPER_ALERT_ARENA, + CHOMPER_ALERT_CHASE, + CHOMPER_ALERT_EVADE, + CHOMPER_ALERT_NOMORE, + CHOMPER_ALERT_FORCE = 0x7fffffff +}; + +enum en_alertfod +{ + FODDER_ALERT_NOTICE, + FODDER_ALERT_ARENA, + FODDER_ALERT_BEGIN, + FODDER_ALERT_CHASE, + FODDER_ALERT_STABDONE, + FODDER_ALERT_EVADE, + FODDER_ALERT_NOMORE, + FODDER_ALERT_FORCE = 0x7fffffff +}; + +struct zNPCGoalLoopAnim : zNPCGoalCommon +{ + int32 flg_loopanim; + uint32 anid_stage[3]; + int32 cnt_loop; + float32 lastAnimTime; + uint32 origAnimFlags; + uint32 animWeMolested; + + // void* __ct(int32 myType); + void LoopCountSet(int32 unk); // return type might be wrong +}; + +struct zNPCGoalTaunt : zNPCGoalLoopAnim +{ + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt, xScene* xscn); + int32 Enter(float32 dt, void* updCtxt); +}; + +struct zNPCGoalPatThrow : zNPCGoalCommon +{ + int32 Enter(float32 dt, void* updCtxt); + uint8 CollReview(void*); +}; + +enum en_alertchuk +{ + CHUCK_ALERT_NOTICE, + CHUCK_ALERT_BEGIN, + CHUCK_ALERT_ARENA, + CHUCK_ALERT_READY, + CHUCK_ALERT_BACKAWAY, + CHUCK_ALERT_ZOOMPAST, + CHUCK_ALERT_DIDTHROW, + CHUCK_ALERT_NOMORE, + CHUCK_ALERT_FORCE = 0x7fffffff +}; + +struct zNPCGoalAlertSlick : zNPCGoalCommon +{ + int32 flg_alert; + en_alertslik alertslik; + float32 tmr_reload; + xVec3 pos_corner; + + void MoveCorner(float32 dt); + void GetInArena(float32 dt); + int32 NPCMessage(NPCMsg* mail); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt); + int32 Resume(float32 dt, void* updCtxt); + int32 Enter(float32 dt, void* updCtxt); +}; + +struct zNPCGoalAlertChuck : zNPCGoalCommon +{ + xVec3 dir_attack; + int32 flg_attack; + en_alertchuk alertchuk; + float32 tmr_reload; + float32 tmr_hover; + xVec3 dir_zoom; + float32 dst_zoom; + + int32 ZoomMove(float32 dt); + void GetInArena(float32 dt); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt); + int32 Resume(float32 dt, void* updCtxt); + int32 Enter(float32 dt, void* updCtxt); +}; + +struct zNPCGoalAlertTarTar : zNPCGoalCommon +{ + int32 flg_attack; + en_alerttart alerttart; + en_hoppy hoppy; + float32 tmr_reload; + + void GetInArena(float32 dt); + int32 HoppyUpdate(en_trantype* trantype, float32 dt); + int32 NPCMessage(NPCMsg* mail); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt); + int32 Resume(float32 dt, void* updCtxt); + int32 Enter(float32 dt, void* updCtxt); +}; + +struct zNPCGoalAlertChomper : zNPCGoalCommon +{ + en_alertchomp alertchomp; + xVec3 pos_evade; + float32 tmr_evade; + + int32 CheckSpot(); + int32 MoveEvadePos(xVec3* pos, float32 dt); + int32 CalcEvadePos(xVec3* pos); + void GetInArena(float32 dt); + void CirclePlayer(float32 dt); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt); + int32 Enter(float32 dt, void* updCtxt); +}; + +struct zNPCGoalAlertFodBzzt : zNPCGoalCommon +{ + int32 flg_alert; + en_alertbzzt alertbzzt; + float32 tmr_warmup; + int32 cnt_nextlos; + float32 len_laser; + xVec3 pos_laserSource; + xVec3 pos_laserTarget; + RwRGBA rgba_deathRay; + int32 cnt_inContact; + + void DeathRayRender(); + void DeathRayUpdate(float32 dt); + void OrbitPlayer(float32 dt); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt); + int32 Resume(float32 dt, void* updCtxt); + int32 Suspend(); + int32 Exit(); + int32 Enter(float32 dt, void* updCtxt); + void GetInArena(float32 dt); +}; + +struct zNPCGoalAlertFodder : zNPCGoalCommon +{ + int32 flg_attack; // 0x4c + en_alertfod alertfod; // 0x50 + float32 tmr_alertfod; // 0x54 + + void MoveEvade(float32 dt); + void GetInArena(float32 dt); + void FlankPlayer(float32 dt); + int32 CheckSpot(float32 dt); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt, xScene* scene); + int32 Enter(float32 dt, void* updCtxt); +}; + +struct zNPCGoalDogLaunch : zNPCGoalCommon +{ + int32 flg_launch; + xVec3 pos_src; + xVec3 pos_tgt; + xParabola parabinfo; + float32 tmr_remain; + + void BubTrailCone(xVec3* pos, int32 num, xVec3* pos_rand, xVec3* vel_rand, xMat3x3* mat); + int32 BallisticUpdate(float32 dt); + void PreCollide(); + int32 Process(en_trantype* trantype, float32 dt, void* updCtxt, xScene* xscn); + int32 Enter(float32 dt, void* updCtxt); + uint8 CollReview(void*); + void SilentSwimout(xVec3* unk1, xVec3* unk2, zMovePoint* unk3); + void ViciousAttack(xVec3* unk1, xVec3* unk2, zMovePoint* unk3, int32 unk4); +}; + struct zNPCGoalDead : zNPCGoalCommon { int32 flg_deadinfo; @@ -14,6 +231,8 @@ struct zNPCGoalDead : zNPCGoalCommon virtual int32 Exit(float32 dt, void* updCtxt); void DieQuietly(); + void DieWithAWhimper(); + void DieWithABang(); protected: ~zNPCGoalDead(); @@ -22,4 +241,4 @@ struct zNPCGoalDead : zNPCGoalCommon xFactoryInst* GOALCreate_Standard(int32 who, RyzMemGrow* grow, void*); void GOALDestroy_Goal(xFactoryInst* inst); -#endif \ No newline at end of file +#endif diff --git a/src/SB/Game/zNPCGoals.h b/src/SB/Game/zNPCGoals.h index 174e62d1..da73930d 100644 --- a/src/SB/Game/zNPCGoals.h +++ b/src/SB/Game/zNPCGoals.h @@ -62,6 +62,7 @@ enum en_NPCGOALS NPC_GOAL_BOSSPATFUDGE, NPC_GOAL_DUPLOLIVE = 'NGD0', NPC_GOAL_DUPLODEAD, + NPC_GOAL_NGN0 = 'NGN0', // unknown NPC_GOAL_NOTICE = 'NGR0', NPC_GOAL_TAUNT, NPC_GOAL_EVADE, @@ -189,4 +190,4 @@ struct xFactory; void zNPCGoals_RegisterTypes(xFactory* fac); -#endif \ No newline at end of file +#endif diff --git a/src/SB/Game/zNPCSupport.h b/src/SB/Game/zNPCSupport.h index 5465413d..b1199b76 100644 --- a/src/SB/Game/zNPCSupport.h +++ b/src/SB/Game/zNPCSupport.h @@ -42,5 +42,8 @@ void NPCSupport_Timestep(float32 dt); void NPCSupport_SceneReset(); void NPCSupport_Shutdown(); void NPCSupport_ScenePostInit(); +int32 NPCC_LampStatus(); +xVec3* NPCC_rightDir(xEnt* ent); +void NPCC_ang_toXZDir(float32 angle, xVec3* dir); -#endif \ No newline at end of file +#endif diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index f6b9f58f..4e88cedc 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -361,7 +361,7 @@ struct zNPCCommon : xNPCBasic zNPCSettings npcset; zMovePoint* nav_past; zMovePoint* nav_curr; - zMovePoint* nav_dest; + zMovePoint* nav_dest; // 0x210 zMovePoint* nav_lead; xSpline3* spl_mvptspline; float32 len_mvptspline; @@ -381,6 +381,11 @@ struct zNPCCommon : xNPCBasic zNPCCommon(int32 myType); + float32 TurnToFace(float32 dt, const xVec3* dir_want, float32 useTurnRate); + float32 ThrottleApply(float32 dt, const xVec3* dir, int32 force3D); + float32 ThrottleAccel(float32 dt, int32 speedup, float32 pct_max); + float32 ThrottleAdjust(float32 dt, float32 spd_want, float32 accel); + void VelStop(); static void ConfigSceneDone(); uint32 LassoInit(); @@ -393,6 +398,7 @@ struct zNPCCommon : xNPCBasic bool IsMountableType(en_ZBASETYPE type); void MvptReset(zMovePoint* nav_goto); void ModelScaleSet(float32 x, float32 y, float32 z); + void ModelScaleSet(float32 unk); void ModelScaleSet(const xVec3* vec); int32 AnimStart(uint32 animID, int32 forceRestart); uint32 AnimCurStateID(); @@ -416,6 +422,17 @@ struct zNPCCommon : xNPCBasic int (*)(xGoal*, void*, en_trantype*, float, void*), int (*)(xGoal*, void*, en_trantype*, float, void*)); + // defined from zNPCGoalRobo.cpp + xVec3* Center(); + xVec3* Pos(); + RwMatrix* BoneMat(int32 unk) const; + RwV3d* BonePos(int32 unk) const; + xVec3* XZVecToPlayer(xVec3* unk1, float32* unk2); // might have wrong return type + xVec3* XZVecToPos(xVec3* unk1, const xVec3* unk2, float32* unk3); // ? return type + int32 XYZDstSqToPlayer(xVec3* unk); // return type is probably wrong + int32 XYZDstSqToPos(xVec3* unk1, xVec3* unk2); // return type is probably wrong + int32 SomethingWonderful(); + // vTable (xNPCBasic) virtual void Init(xEntAsset* asset); diff --git a/src/SB/Game/zNPCTypeRobot.h b/src/SB/Game/zNPCTypeRobot.h index df4b3d53..b5f887b5 100644 --- a/src/SB/Game/zNPCTypeRobot.h +++ b/src/SB/Game/zNPCTypeRobot.h @@ -27,11 +27,29 @@ struct NPCArena float32 DstSqFromHome(xVec3* pos, xVec3* delt); float32 PctFromHome(xVec3* pos); int32 IncludesPos(xVec3* pos, float32 rad_thresh, xVec3* vec); + float32 Radius(float32 unk); + xVec3* Pos(); + int32 IncludesPlayer(float32 rad_thresh, xVec3* vec); + int32 IsReady(); + void DBG_Draw(zNPCCommon*); +}; + +struct NPCLaser +{ + RwRaster* rast_laser; + float32 radius[2]; + float32 uv_scroll[2]; + RwRGBA rgba[2]; + float32 uv_base[2]; + + void ColorSet(const RwRGBA*, const RwRGBA*); }; struct NPCBattle { zNPCRobot* members[5]; + void JoinBattle(zNPCRobot*); + void LeaveBattle(zNPCRobot*); }; struct zNPCRobot : zNPCCommon @@ -121,6 +139,8 @@ struct zNPCRobot : zNPCCommon zNPCLassoInfo* PRIV_GetLassoData(); int32 LassoSetup(); + float32 FacePlayer(float32 dt, float32 spd_turn); + // vTable (zNPCRobot) virtual int32 RoboHandleMail(NPCMsg* mail); virtual int32 IsDying(); @@ -209,6 +229,7 @@ struct zNPCArfArf : zNPCRobot zNPCArfDog* pup_kennel[5]; zNPCArfArf(int32 myType); + zMovePoint* GetTelepoint(int32 unk); }; struct zNPCChuck : zNPCRobot