#ifndef _CSCRIPTMAZENODE #define _CSCRIPTMAZENODE #include "types.h" #include "MetroidPrime/CActor.hpp" #include "Kyoto/CRandom16.hpp" #include "Kyoto/Math/CVector3f.hpp" #include "rstl/vector.hpp" #define skMazeCols 9 #define skMazeRows 7 #define skEnterCol 4 #define skEnterRow 4 #define skTargetCol 5 #define skTargetRow 3 #define NUM_MAZE_CELLS (skMazeRows * skMazeCols) struct SMazeCell { bool x0_24_openTop : 1; bool x0_25_openRight : 1; bool x0_26_openBottom : 1; bool x0_27_openLeft : 1; bool x0_28_gateTop : 1; bool x0_29_gateRight : 1; bool x0_30_gateBottom : 1; bool x0_31_gateLeft : 1; bool x1_24_puddle : 1; bool x1_25_onPath : 1; bool x1_26_checked : 1; SMazeCell() { x0_24_openTop = x0_25_openRight = x0_26_openBottom = x0_27_openLeft = x0_28_gateTop = x0_29_gateRight = x0_30_gateBottom = x0_31_gateLeft = x1_24_puddle = x1_25_onPath = x1_26_checked = false; } inline bool IsClosed() const { return !x0_24_openTop && !x0_25_openRight && !x0_26_openBottom && !x0_27_openLeft; } }; class CSinglePathMaze { CRandom16 x0_rand; SMazeCell x4_cells[skMazeRows * skMazeCols]; int x84_enterCol; int x88_enterRow; int x8c_targetCol; int x90_targetRow; bool x94_24_initialized : 1; public: enum ESide { kS_Invalid = -1, kS_Top = 0, kS_Right = 1, kS_Bottom = 2, kS_Left = 3, }; CSinglePathMaze(int enterCol, int enterRow, int targetCol, int targetRow); void CreateMaze(int seed); void SolveMaze(); void AddGimmicks(); SMazeCell& MazePoint(uint col, uint row); const SMazeCell& GetMazePoint(uint col, uint row) const; SMazeCell& MazePointInline(uint col, uint row) { return x4_cells[col + row * skMazeCols]; } // ???? inline SMazeCell& MazePoint(uint idx) { return x4_cells[idx]; } }; class CScriptMazeNode : public CActor { public: CScriptMazeNode(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf, bool active, int col, int row, int side, const CVector3f& actorPos, const CVector3f& triggerPos, const CVector3f& effectPos); ~CScriptMazeNode() override; void Accept(IVisitor& visitor) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void Think(float dt, CStateManager& mgr) override; static void LoadMazeSeeds(); private: enum ESide { Invalid = -1, Top = 0, Right = 1, Bottom = 2, Left = 3, }; int xe8_col; int xec_row; ESide xf0_side; TUniqueId xf4_gateEffectId; float xf8_msgTimer; TUniqueId xfc_actorId; CVector3f x100_actorPos; TUniqueId x10c_triggerId; CVector3f x110_triggerPos; TUniqueId x11c_effectId; CVector3f x120_effectPos; rstl::vector< TUniqueId > x12c_puddleObjectIds; bool x13c_24_hasPuddle : 1; bool x13c_25_hasGate : 1; bool x13c_26_gateActive : 1; void GenerateBarrier(CStateManager& mgr); void DeleteBarrier(CStateManager& mgr); void SendBarrierMsg(CStateManager& mgr, EScriptObjectMessage msg); static uint sMazeSeeds[300]; // hack for SendBarrierMsg static inline void DeliverScriptMsg(CStateManager& mgr, CEntity* to, TUniqueId sender, EScriptObjectMessage msg) { mgr.DeliverScriptMsg(to, sender, msg); } }; #endif // _CSCRIPTMAZENODE