diff --git a/src/SB/Core/x/containers.h b/src/SB/Core/x/containers.h index 58773407f..05b894acf 100644 --- a/src/SB/Core/x/containers.h +++ b/src/SB/Core/x/containers.h @@ -51,6 +51,7 @@ template struct fixed_queue void push_front(const T& element); bool full() const; void pop_back(); + bool empty() const; }; #endif diff --git a/src/SB/Core/x/xListItem.h b/src/SB/Core/x/xListItem.h index ff2d4598f..6e0fe9a4a 100644 --- a/src/SB/Core/x/xListItem.h +++ b/src/SB/Core/x/xListItem.h @@ -9,7 +9,8 @@ template struct xListItem T* next; T* prev; - xListItem() { + xListItem() + { flg_travFilter = 0; prev = NULL; next = NULL; diff --git a/src/SB/Game/zDiscoFloor.h b/src/SB/Game/zDiscoFloor.h index 36f812a29..3b06d5e4a 100644 --- a/src/SB/Game/zDiscoFloor.h +++ b/src/SB/Game/zDiscoFloor.h @@ -42,6 +42,7 @@ struct z_disco_floor : xBase bool glow_culled; } flag; z_disco_floor_asset* asset; + U8** state_masks; U8* active_state_mask; U8* next_state_mask; diff --git a/src/SB/Game/zNPCTypePrawn.cpp b/src/SB/Game/zNPCTypePrawn.cpp index 52661b151..ae4f3deb9 100644 --- a/src/SB/Game/zNPCTypePrawn.cpp +++ b/src/SB/Game/zNPCTypePrawn.cpp @@ -204,18 +204,188 @@ void tweak_group::register_tweaks(bool init, xModelAssetParam* ap, U32 apsize) */ } + +void aqua_beam::reset() // I don't know whats wrong here. Probably a simple error +{ + firing = 0; + bool bvar; + + while (true) + { + bvar = ring.queue.empty(); + if (bvar) + break; + aqua_beam::kill_ring(); + } + ring_sounds = 0; + + // Ghidra output + // bool bVar1; + // *(undefined *)(param_1 + 0x3c) = 0; + // while( true ) { + // bVar1 = empty__42fixed_queue<>CFv((int *)(param_1 + 0xa4)); + // if (bVar1) break; + // kill_ring__9aqua_beamFv(param_1); + // } + // *(undefined4 *)(param_1 + 0xf54) = 0; + // return; +} + +void aqua_beam::start() //100% code match, data does not match +{ + firing = 1; + time = 0; + ring.emit_time = 0; +} + +void aqua_beam::stop() +{ + firing = 0; +} + +void aqua_beam::render() +{ +} + +void zNPCPrawn::NewTime(xScene* xscn, float dt) +{ + zNPCCommon::NewTime(xscn, dt); + zNPCPrawn::render_closeup(); +} + +void zNPCPrawn::SelfSetup() +{ + xBehaveMgr* bmgr; + xPsyche* psy; + + bmgr = xBehaveMgr_GetSelf(); + psy_instinct = bmgr->Subscribe(this, 0); + psy = psy_instinct; + psy->BrainBegin(); + psy->AddGoal(NPC_GOAL_PRAWNIDLE, NULL); + psy->AddGoal(NPC_GOAL_PRAWNBEAM, NULL); + psy->AddGoal(NPC_GOAL_PRAWNBOWL, NULL); + psy->AddGoal(NPC_GOAL_PRAWNDAMAGE, NULL); + psy->AddGoal(NPC_GOAL_PRAWNDEATH, NULL); + psy->AddGoal(NPC_GOAL_LIMBO, NULL); + psy->BrainEnd(); + psy->SetSafety(NPC_GOAL_PRAWNIDLE); +} + void zNPCPrawn::render_debug() { } +void zNPCPrawn::Render() +{ + xNPCBasic::Render(); + isCulled = 0; + beam.render(); + zNPCPrawn::render_debug(); +} + +void zNPCPrawn::update_round() +{ +} + +void zNPCPrawn::decompose() +{ +} + void zNPCPrawn::update_particles(float) { } +void zNPCPrawn::apply_pending() +{ + pending.change = 0; + disco->set_state_range(pending.pattern.min, pending.pattern.max, SM_NPC_DEAD); + disco->set_transition_delay(pending.transition_delay); + disco->set_state_delay(pending.state_delay); +} + +void zNPCPrawn::set_floor_state(zNPCPrawn::floor_state_enum, bool, bool) +{ +} + +// void zNPCPrawn::vanish() //Didn't figure out how to finish it +// { +// //0x18 is "flags" +// pflags = 0; //0x1b +// moreFlags = 0; //0x1c +// chkby = 0; //0x22 +// penby = 0; //0x23 +// flags2.flg_colCheck = 0; //0xf0 +// flags2.flg_penCheck = 0; // 0xf1 +// } + +void zNPCPrawn::reappear() +{ +} + +void zNPCPrawn::render_closeup() +{ +} + +void zNPCGoalPrawnBeam::update_aim(float dt) //Needs clrlwi and cntlzw to be finished +{ + zNPCPrawn& prawn = *((zNPCPrawn*)this->psyche->clt_owner); + prawn.turning(); +} + +S32 zNPCGoalPrawnDamage::Enter(float dt, void* updCtxt) +{ + zNPCPrawn& prawn = *(zNPCPrawn*)psyche->clt_owner; + prawn.set_floor_state(prawn.FS_DANGER, false, false); + zNPCGoalCommon::Enter(dt, updCtxt); +} + +// S32 zNPCGoalPrawnBowl::Enter(float dt, void* updCtxt) +// { +// zNPCPrawn& prawn = *(zNPCPrawn*)psyche->clt_owner; +// prawn.set_floor_state(prawn.FS_DANGER, false, false); +// zNPCGoalCommon::Enter(dt, updCtxt); +// } + +S32 zNPCGoalPrawnBowl::Exit(float dt, void* updCtxt) +{ + zNPCPrawn& prawn = *(zNPCPrawn*)psyche->clt_owner; + prawn.set_floor_state(prawn.FS_BEGIN, true, false); + xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalPrawnDamage::Exit(float dt, void* updCtxt) +{ + zNPCPrawn& prawn = *(zNPCPrawn*)this->psyche->clt_owner; + prawn.update_round(); + xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalPrawnDeath::Enter(float dt, void* updCtxt) +{ + zNPCPrawn& prawn = *(zNPCPrawn*)this->psyche->clt_owner; + prawn.decompose(); + zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalPrawnDeath::Exit(float dt, void* updCtxt) +{ + xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalPrawnDeath::Process(en_trantype* trantype, float dt, void* updCtxt, xScene* xscn) +{ + xGoal::Process(trantype, dt, updCtxt, xscn); +} + void xDebugAddTweak(const char*, xVec3*, const tweak_callback*, void*, U32) { } +void zNPCPrawn::turning() const +{ +} + U8 zNPCPrawn::PhysicsFlags() const { return 3; diff --git a/src/SB/Game/zNPCTypePrawn.h b/src/SB/Game/zNPCTypePrawn.h index 5743a69a8..290e2e82b 100644 --- a/src/SB/Game/zNPCTypePrawn.h +++ b/src/SB/Game/zNPCTypePrawn.h @@ -3,16 +3,21 @@ #include "zNPCTypeSubBoss.h" #include "zNPCGoalCommon.h" +#include "zNPCGoals.h" #include "zDiscoFloor.h" #include "zNPCSpawner.h" #include "containers.h" +#include "xBehaviour.h" struct sound_data_type { - U32 id; - U32 handle; - xVec3* loc; - F32 volume; + union + { + U32 id; + U32 handle; + xVec3* loc; + F32 volume; + }; }; struct range_type @@ -122,7 +127,7 @@ struct aqua_beam F32 vel; F32 accel; F32 emit_delay; - F32 grow; + F32 grow; //0x1c F32 fade_dist; F32 kill_dist; F32 follow; @@ -153,16 +158,16 @@ struct aqua_beam }; config cfg; - U8 firing; + U8 firing; //0x3c xVec3 loc; xVec3 dir; xMat4x3 mat; - F32 time; + F32 time; //0x98 struct { RpAtomic* model_data; - F32 emit_time; - fixed_queue queue; + F32 emit_time; //0xa0 + fixed_queue queue; //0xa4 } ring; struct { @@ -170,7 +175,12 @@ struct aqua_beam F32 alpha; F32 scale; } squiggle; - S32 ring_sounds; + S32 ring_sounds; //0xf54 + void reset(); + void start(); + void stop(); + bool kill_ring(); + void render(); }; struct zNPCPrawn : zNPCSubBoss @@ -187,22 +197,22 @@ struct zNPCPrawn : zNPCSubBoss struct range_type { - S32 min; - S32 max; + S32 min; //0x304 + S32 max; //0x308 }; struct { } flag; - S32 life; - S32 round; + S32 life; //0x2b8 + S32 round; //0x2bc U8 face_player; xVec2 look_dir; z_disco_floor* disco; zNPCSpawner* spawner[3]; - U32 danger_mask; + U32 danger_mask; //0x2dc floor_state_enum floor_state; - S32 floor_state_index; + S32 floor_state_index; //0x2e4 U32 floor_state_counter; F32 floor_time; F32 delay; @@ -210,9 +220,9 @@ struct zNPCPrawn : zNPCSubBoss U8 fighting; struct { - U8 change; + U8 change; //0x2f8 floor_state_enum floor_state; - U32 counter; + U32 counter; //0x300 range_type pattern; F32 transition_delay; F32 state_delay; @@ -235,7 +245,20 @@ struct zNPCPrawn : zNPCSubBoss zNPCPrawn(S32 myType); void render_debug(); + void Render(); void update_particles(float); + void NewTime(xScene*, float); + void SelfSetup(); + void apply_pending(); + void vanish(); + void reappear(); + void render_closeup(); + void turning() const; + void update_round(); + void decompose(); + void set_floor_state(zNPCPrawn::floor_state_enum, bool, bool); + void Damage(en_NPC_DAMAGE_TYPE, xBase*, const xVec3*); + U8 PhysicsFlags() const; U8 ColPenByFlags() const; U8 ColChkByFlags() const; @@ -266,6 +289,7 @@ struct zNPCGoalPrawnBeam : zNPCGoalCommon F32 sweep_dir; F32 delay; + void update_aim(float); zNPCGoalPrawnBeam(S32 goalID) : zNPCGoalCommon(goalID) { } @@ -274,6 +298,8 @@ struct zNPCGoalPrawnBeam : zNPCGoalCommon struct zNPCGoalPrawnBowl : zNPCGoalCommon { U8 aiming; + S32 Enter(float, void*); + S32 Exit(float, void*); zNPCGoalPrawnBowl(S32 goalID) : zNPCGoalCommon(goalID) { @@ -282,6 +308,9 @@ struct zNPCGoalPrawnBowl : zNPCGoalCommon struct zNPCGoalPrawnDamage : zNPCGoalCommon { + S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* xscn); + S32 Exit(float dt, void* updCtxt); + S32 Enter(F32 dt, void* updCtxt); zNPCGoalPrawnDamage(S32 goalID) : zNPCGoalCommon(goalID) { } @@ -289,6 +318,9 @@ struct zNPCGoalPrawnDamage : zNPCGoalCommon struct zNPCGoalPrawnDeath : zNPCGoalCommon { + S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* xscn); + S32 Exit(float dt, void* updCtxt); + S32 Enter(F32 dt, void* updCtxt); zNPCGoalPrawnDeath(S32 goalID) : zNPCGoalCommon(goalID) { }