mirror of https://github.com/AxioDL/metaforce.git
Finish CStateMachine
This commit is contained in:
parent
9512f6c98d
commit
94333e4726
|
@ -7,9 +7,9 @@ namespace urde
|
||||||
{
|
{
|
||||||
enum class EStateMsg
|
enum class EStateMsg
|
||||||
{
|
{
|
||||||
Zero = 0,
|
Activate = 0,
|
||||||
One = 1,
|
Update = 1,
|
||||||
Two = 2
|
Deactivate = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class CStateManager;
|
class CStateManager;
|
||||||
|
|
|
@ -157,7 +157,7 @@ void CPatterned::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState
|
||||||
break;
|
break;
|
||||||
case EScriptObjectMessage::Deleted:
|
case EScriptObjectMessage::Deleted:
|
||||||
if (x330_stateMachineState.GetActorState() != nullptr)
|
if (x330_stateMachineState.GetActorState() != nullptr)
|
||||||
x330_stateMachineState.GetActorState()->CallFunc(mgr, *this, EStateMsg::Two, 0.f);
|
x330_stateMachineState.GetActorState()->CallFunc(mgr, *this, EStateMsg::Deactivate, 0.f);
|
||||||
break;
|
break;
|
||||||
case EScriptObjectMessage::Damage:
|
case EScriptObjectMessage::Damage:
|
||||||
{
|
{
|
||||||
|
@ -787,7 +787,7 @@ void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
const auto& waypoints = search->GetWaypoints();
|
const auto& waypoints = search->GetWaypoints();
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case EStateMsg::Zero:
|
case EStateMsg::Activate:
|
||||||
{
|
{
|
||||||
if (search->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success)
|
if (search->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success)
|
||||||
{
|
{
|
||||||
|
@ -803,7 +803,7 @@ void CPatterned::PathFind(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EStateMsg::One:
|
case EStateMsg::Update:
|
||||||
{
|
{
|
||||||
if (curWp < waypoints.size() - 1)
|
if (curWp < waypoints.size() - 1)
|
||||||
{
|
{
|
||||||
|
@ -830,10 +830,10 @@ void CPatterned::Dead(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case EStateMsg::Zero:
|
case EStateMsg::Activate:
|
||||||
x31c_faceVec = zeus::CVector3f::skZero;
|
x31c_faceVec = zeus::CVector3f::skZero;
|
||||||
break;
|
break;
|
||||||
case EStateMsg::One:
|
case EStateMsg::Update:
|
||||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::Die));
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::Die));
|
||||||
if (!x400_27_fadeToDeath)
|
if (!x400_27_fadeToDeath)
|
||||||
{
|
{
|
||||||
|
@ -854,7 +854,7 @@ void CPatterned::Dead(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
|
|
||||||
void CPatterned::TargetPlayer(CStateManager& mgr, EStateMsg msg, float arg)
|
void CPatterned::TargetPlayer(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
{
|
{
|
||||||
if (msg == EStateMsg::Zero)
|
if (msg == EStateMsg::Activate)
|
||||||
{
|
{
|
||||||
x2dc_destObj = mgr.GetPlayer().GetUniqueId();
|
x2dc_destObj = mgr.GetPlayer().GetUniqueId();
|
||||||
SetDestPos(mgr.GetPlayer().GetTranslation());
|
SetDestPos(mgr.GetPlayer().GetTranslation());
|
||||||
|
@ -865,7 +865,7 @@ void CPatterned::TargetPlayer(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
|
|
||||||
void CPatterned::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg)
|
void CPatterned::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
{
|
{
|
||||||
if (msg == EStateMsg::Zero)
|
if (msg == EStateMsg::Activate)
|
||||||
{
|
{
|
||||||
x2dc_destObj = GetWaypointForState(mgr, EScriptObjectState::Patrol, EScriptObjectMessage::Follow);
|
x2dc_destObj = GetWaypointForState(mgr, EScriptObjectState::Patrol, EScriptObjectMessage::Follow);
|
||||||
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(x2dc_destObj))
|
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(x2dc_destObj))
|
||||||
|
@ -879,7 +879,7 @@ void CPatterned::FollowPattern(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case EStateMsg::Zero:
|
case EStateMsg::Activate:
|
||||||
SetupPattern(mgr);
|
SetupPattern(mgr);
|
||||||
if (x328_29_noPatternShagging || !IsPatternObstructed(mgr, GetTranslation(), x2e0_destPos))
|
if (x328_29_noPatternShagging || !IsPatternObstructed(mgr, GetTranslation(), x2e0_destPos))
|
||||||
{
|
{
|
||||||
|
@ -891,7 +891,7 @@ void CPatterned::FollowPattern(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
x400_30_patternShagged = true;
|
x400_30_patternShagged = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EStateMsg::One:
|
case EStateMsg::Update:
|
||||||
if (x328_24_inPosition)
|
if (x328_24_inPosition)
|
||||||
{
|
{
|
||||||
x39c_curPattern += 1;
|
x39c_curPattern += 1;
|
||||||
|
@ -917,7 +917,7 @@ void CPatterned::FollowPattern(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
}
|
}
|
||||||
ApproachDest(mgr);
|
ApproachDest(mgr);
|
||||||
break;
|
break;
|
||||||
case EStateMsg::Two:
|
case EStateMsg::Deactivate:
|
||||||
x38c_patterns.clear();
|
x38c_patterns.clear();
|
||||||
x400_30_patternShagged = false;
|
x400_30_patternShagged = false;
|
||||||
}
|
}
|
||||||
|
@ -927,7 +927,7 @@ void CPatterned::Patrol(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case EStateMsg::Zero:
|
case EStateMsg::Activate:
|
||||||
if (x3ac_lastPatrolDest == kInvalidUniqueId)
|
if (x3ac_lastPatrolDest == kInvalidUniqueId)
|
||||||
{
|
{
|
||||||
x2dc_destObj = GetWaypointForState(mgr, EScriptObjectState::Patrol, EScriptObjectMessage::Follow);
|
x2dc_destObj = GetWaypointForState(mgr, EScriptObjectState::Patrol, EScriptObjectMessage::Follow);
|
||||||
|
@ -951,7 +951,7 @@ void CPatterned::Patrol(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
x2d8_patrolState = EPatrolState::Patrol;
|
x2d8_patrolState = EPatrolState::Patrol;
|
||||||
x2f8_waypointPauseRemTime = 0.f;
|
x2f8_waypointPauseRemTime = 0.f;
|
||||||
break;
|
break;
|
||||||
case EStateMsg::One:
|
case EStateMsg::Update:
|
||||||
switch (x2d8_patrolState)
|
switch (x2d8_patrolState)
|
||||||
{
|
{
|
||||||
case EPatrolState::Patrol:
|
case EPatrolState::Patrol:
|
||||||
|
@ -983,7 +983,7 @@ void CPatterned::Patrol(CStateManager& mgr, EStateMsg msg, float arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EStateMsg::Two:
|
case EStateMsg::Deactivate:
|
||||||
x3ac_lastPatrolDest = x2dc_destObj;
|
x3ac_lastPatrolDest = x2dc_destObj;
|
||||||
x2d8_patrolState = EPatrolState::Invalid;
|
x2d8_patrolState = EPatrolState::Invalid;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -398,7 +398,6 @@ public:
|
||||||
const CKnockBackController& GetKnockBackController() const { return x460_knockBackController; }
|
const CKnockBackController& GetKnockBackController() const { return x460_knockBackController; }
|
||||||
void SetupPlayerCollision(bool);
|
void SetupPlayerCollision(bool);
|
||||||
|
|
||||||
|
|
||||||
void SetDestPos(const zeus::CVector3f& pos) { x2e0_destPos = pos; }
|
void SetDestPos(const zeus::CVector3f& pos) { x2e0_destPos = pos; }
|
||||||
void UpdateAlphaDelta(float dt, CStateManager& mgr);
|
void UpdateAlphaDelta(float dt, CStateManager& mgr);
|
||||||
void SetModelAlpha(float a) { x42c_color.a = a; }
|
void SetModelAlpha(float a) { x42c_color.a = a; }
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
#include "CStateMachine.hpp"
|
#include "CStateMachine.hpp"
|
||||||
#include "CAi.hpp"
|
#include "CAi.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
CStateMachine::CStateMachine(CInputStream& in)
|
CStateMachine::CStateMachine(CInputStream& in)
|
||||||
{
|
{
|
||||||
#if 0
|
CAiTrigger* lastTrig = nullptr;
|
||||||
u32 stateCount = in.readUint32Big();
|
u32 stateCount = in.readUint32Big();
|
||||||
|
|
||||||
x0_states.reserve(stateCount);
|
x0_states.reserve(stateCount);
|
||||||
|
|
||||||
for (u32 i = 0; i < stateCount; ++i)
|
for (u32 i = 0; i < stateCount; ++i)
|
||||||
{
|
{
|
||||||
std::string name = in.readString(31);
|
std::string name = in.readString(31, false);
|
||||||
CAiStateFunc func = CAi::GetStateFunc(name.c_str());
|
CAiStateFunc func = CAi::GetStateFunc(name.c_str());
|
||||||
x0_states.emplace_back(func, name);
|
x0_states.emplace_back(func, name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
x10_triggers.reserve(in.readUint32Big());
|
x10_triggers.reserve(in.readUint32Big());
|
||||||
|
@ -24,27 +25,43 @@ CStateMachine::CStateMachine(CInputStream& in)
|
||||||
x0_states[i].SetNumTriggers(in.readUint32Big());
|
x0_states[i].SetNumTriggers(in.readUint32Big());
|
||||||
if (x0_states[i].GetNumTriggers() == 0)
|
if (x0_states[i].GetNumTriggers() == 0)
|
||||||
continue;
|
continue;
|
||||||
for (u32 j = 0; j < x0_states[i].GetNumTriggers(); ++j)
|
CAiTrigger* firstTrig = x10_triggers.data() + x10_triggers.size();
|
||||||
x10_triggers.emplace_back();
|
x0_states[i].SetTriggers(firstTrig);
|
||||||
|
x10_triggers.resize(x10_triggers.size() + x0_states[i].GetNumTriggers());
|
||||||
|
|
||||||
for (u32 j = 0; j < x0_states[i].GetNumTriggers(); ++j)
|
for (u32 j = 0; j < x0_states[i].GetNumTriggers(); ++j)
|
||||||
{
|
{
|
||||||
u32 triggerCount = in.readUint32Big();
|
u32 triggerCount = in.readUint32Big();
|
||||||
u32 r19 = triggerCount - 1;
|
u32 lastTriggerIdx = triggerCount - 1;
|
||||||
for (u32 k = 0; k < triggerCount; ++k)
|
for (u32 k = 0; k < triggerCount; ++k)
|
||||||
{
|
{
|
||||||
std::string name = in.readString(31);
|
std::string name = in.readString(31, false);
|
||||||
CAiTriggerFunc func = CAi::GetTrigerFunc(name.c_str());
|
bool isNot = name.front() == '!';
|
||||||
float f31 = in.readFloatBig();
|
CAiTriggerFunc func = CAi::GetTrigerFunc(isNot ? name.c_str() + 1 : name.c_str());
|
||||||
|
float arg = in.readFloatBig();
|
||||||
|
CAiTrigger* newTrig;
|
||||||
|
if (k < lastTriggerIdx)
|
||||||
|
{
|
||||||
|
x10_triggers.emplace_back();
|
||||||
|
newTrig = &x10_triggers.back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newTrig = &firstTrig[j];
|
||||||
|
}
|
||||||
|
if (k == 0)
|
||||||
|
newTrig->Setup(func, isNot, arg, &x0_states[in.readUint32Big()]);
|
||||||
|
else
|
||||||
|
newTrig->Setup(func, isNot, arg, lastTrig);
|
||||||
|
lastTrig = newTrig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CStateMachine::GetStateIndex(std::string_view state) const
|
s32 CStateMachine::GetStateIndex(std::string_view state) const
|
||||||
{
|
{
|
||||||
auto it = std::find_if(x0_states.begin(), x0_states.end(), [&state](const CAiState& st) -> bool {
|
auto it = std::find_if(x0_states.begin(), x0_states.end(), [&state](const CAiState& st) {
|
||||||
return (strncmp(st.GetName(), state.data(), 31) == 0);
|
return (strncmp(st.GetName(), state.data(), 31) == 0);
|
||||||
});
|
});
|
||||||
if (it == x0_states.end())
|
if (it == x0_states.end())
|
||||||
|
@ -53,8 +70,54 @@ s32 CStateMachine::GetStateIndex(std::string_view state) const
|
||||||
return it - x0_states.begin();
|
return it - x0_states.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStateMachineState::SetState(CStateManager &, CAi &, s32 idx)
|
void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta)
|
||||||
{
|
{
|
||||||
|
if (x4_state)
|
||||||
|
{
|
||||||
|
x8_time += delta;
|
||||||
|
x4_state->CallFunc(mgr, ai, EStateMsg::Update, delta);
|
||||||
|
for (int i = 0; i < x4_state->GetNumTriggers(); ++i)
|
||||||
|
{
|
||||||
|
CAiTrigger* trig = x4_state->GetTrig(i);
|
||||||
|
CAiState* state = nullptr;
|
||||||
|
bool andPassed = true;
|
||||||
|
while (andPassed && trig)
|
||||||
|
{
|
||||||
|
andPassed = false;
|
||||||
|
if (trig->CallFunc(mgr, ai))
|
||||||
|
{
|
||||||
|
andPassed = true;
|
||||||
|
state = trig->GetState();
|
||||||
|
trig = trig->GetAnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (andPassed && state)
|
||||||
|
{
|
||||||
|
x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f);
|
||||||
|
x4_state = state;
|
||||||
|
x8_time = 0.f;
|
||||||
|
x18_24_ = false;
|
||||||
|
xc_random = mgr.GetActiveRandom()->Float();
|
||||||
|
x4_state->CallFunc(mgr, ai, EStateMsg::Activate, delta);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStateMachineState::SetState(CStateManager& mgr, CAi& ai, s32 idx)
|
||||||
|
{
|
||||||
|
CAiState* state = const_cast<CAiState*>(&x0_machine->GetStateVector()[idx]);
|
||||||
|
if (x4_state != state)
|
||||||
|
{
|
||||||
|
if (x4_state)
|
||||||
|
x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f);
|
||||||
|
x4_state = state;
|
||||||
|
x8_time = 0.f;
|
||||||
|
xc_random = mgr.GetActiveRandom()->Float();
|
||||||
|
x18_24_ = false;
|
||||||
|
x4_state->CallFunc(mgr, ai, EStateMsg::Activate, 0.f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStateMachineState::SetState(CStateManager& mgr, CAi& ai, const CStateMachine* machine, std::string_view state)
|
void CStateMachineState::SetState(CStateManager& mgr, CAi& ai, const CStateMachine* machine, std::string_view state)
|
||||||
|
|
|
@ -12,24 +12,39 @@ class CAiState;
|
||||||
class CStateManager;
|
class CStateManager;
|
||||||
class CAiTrigger
|
class CAiTrigger
|
||||||
{
|
{
|
||||||
u32 x0_ = 0;
|
CAiTriggerFunc x0_func;
|
||||||
u32 x4_ = 0;
|
float xc_arg = 0.f;
|
||||||
u32 x8_ = 0;
|
CAiTrigger* x10_andTrig = nullptr;
|
||||||
float xc_ = 0.f;
|
CAiState* x14_state = nullptr;
|
||||||
u32 x10_ = 0;
|
bool x18_lNot = false;
|
||||||
u32 x14_ = 0;
|
|
||||||
bool x18_ = false;
|
|
||||||
public:
|
public:
|
||||||
CAiTrigger() = default;
|
CAiTrigger() = default;
|
||||||
bool GetAnd();
|
CAiTrigger* GetAnd() const { return x10_andTrig; }
|
||||||
void GetState();
|
CAiState* GetState() const { return x14_state; }
|
||||||
bool CallFunc(CStateManager&, CAi&)
|
bool CallFunc(CStateManager& mgr, CAi& ai)
|
||||||
{
|
{
|
||||||
return false;
|
if (x0_func)
|
||||||
|
{
|
||||||
|
bool ret = (ai.*x0_func)(mgr, xc_arg);
|
||||||
|
return x18_lNot ? !ret : ret;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Setup(CAiTriggerFunc func, bool, float, CAiTrigger*);
|
void Setup(CAiTriggerFunc func, bool lnot, float arg, CAiTrigger* andTrig)
|
||||||
void Setup(CAiTriggerFunc func, bool, float, CAiState*);
|
{
|
||||||
|
x0_func = func;
|
||||||
|
x18_lNot = lnot;
|
||||||
|
xc_arg = arg;
|
||||||
|
x10_andTrig = andTrig;
|
||||||
|
}
|
||||||
|
void Setup(CAiTriggerFunc func, bool lnot, float arg, CAiState* state)
|
||||||
|
{
|
||||||
|
x0_func = func;
|
||||||
|
x18_lNot = lnot;
|
||||||
|
xc_arg = arg;
|
||||||
|
x14_state = state;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CAiState
|
class CAiState
|
||||||
|
@ -38,15 +53,18 @@ class CAiState
|
||||||
CAiStateFunc x0_func;
|
CAiStateFunc x0_func;
|
||||||
char xc_name[32];
|
char xc_name[32];
|
||||||
u32 x2c_numTriggers;
|
u32 x2c_numTriggers;
|
||||||
u32 x30_;
|
CAiTrigger* x30_firstTrigger;
|
||||||
public:
|
public:
|
||||||
CAiState(CAiStateFunc func, const char* name)
|
CAiState(CAiStateFunc func, const char* name)
|
||||||
{}
|
{
|
||||||
|
x0_func = func;
|
||||||
|
strncpy(xc_name, name, 32);
|
||||||
|
}
|
||||||
|
|
||||||
s32 GetNumTriggers() const;
|
s32 GetNumTriggers() const { return x2c_numTriggers; }
|
||||||
CAiTrigger& GetTrig(s32) const;
|
CAiTrigger* GetTrig(s32 i) const { return &x30_firstTrigger[i]; }
|
||||||
const char* GetName() const { return xc_name; }
|
const char* GetName() const { return xc_name; }
|
||||||
void SetTriggers(CAiTrigger* triggers);
|
void SetTriggers(CAiTrigger* triggers) { x30_firstTrigger = triggers; }
|
||||||
void SetNumTriggers(s32 numTriggers) { x2c_numTriggers = numTriggers; }
|
void SetNumTriggers(s32 numTriggers) { x2c_numTriggers = numTriggers; }
|
||||||
void CallFunc(CStateManager& mgr, CAi& ai, EStateMsg msg, float delta) const
|
void CallFunc(CStateManager& mgr, CAi& ai, EStateMsg msg, float delta) const
|
||||||
{
|
{
|
||||||
|
@ -88,12 +106,7 @@ public:
|
||||||
|
|
||||||
CAiState* GetActorState() const { return x4_state; }
|
CAiState* GetActorState() const { return x4_state; }
|
||||||
|
|
||||||
void Update(CStateManager& mgr, CAi& ai, float delta)
|
void Update(CStateManager& mgr, CAi& ai, float delta);
|
||||||
{
|
|
||||||
x8_time += delta;
|
|
||||||
if (x4_state)
|
|
||||||
x4_state->CallFunc(mgr, ai, EStateMsg::One, delta);
|
|
||||||
}
|
|
||||||
void SetState(CStateManager&, CAi&, s32);
|
void SetState(CStateManager&, CAi&, s32);
|
||||||
void SetState(CStateManager&, CAi&, const CStateMachine*, std::string_view);
|
void SetState(CStateManager&, CAi&, const CStateMachine*, std::string_view);
|
||||||
const std::vector<CAiState>* GetStateVector() const;
|
const std::vector<CAiState>* GetStateVector() const;
|
||||||
|
|
Loading…
Reference in New Issue