Merge pull request #50 from robojumper/state_system

Port and match the NSMBW state system, match 1½ RELs with that state system
This commit is contained in:
Elijah Thomas
2024-06-09 22:48:10 -04:00
committed by GitHub
34 changed files with 1141 additions and 149 deletions
+37
View File
@@ -0,0 +1,37 @@
#include <d/tg/d_t_rock_boat.h>
#include <d/a/obj/d_a_obj_base.h>
SPECIAL_ACTOR_PROFILE(TAG_ROCK_BOAT, dTgRockBoat_c, fProfile::TAG_ROCK_BOAT, 0x173, 0, 3);
STATE_DEFINE(dTgRockBoat_c, Wait);
int dTgRockBoat_c::create() {
mStateMgr.changeState(StateID_Wait);
cooldown = 1;
return 1;
}
int dTgRockBoat_c::doDelete() {
return 1;
}
int dTgRockBoat_c::actorExecute() {
mStateMgr.executeState();
return 1;
}
int dTgRockBoat_c::draw() {
return 1;
}
void dTgRockBoat_c::initializeState_Wait() {}
void dTgRockBoat_c::executeState_Wait() {
if (cooldown > 0 && --cooldown == 0) {
dAcObjBase_c::create(fProfile::OBJ_ROCK_BOAT, roomid, (boatNum << 0x1c) | 0xff, &position, 0, 0, -1);
cooldown = 0x259;
if (++boatNum == 0xf) {
boatNum = 0;
}
}
}
void dTgRockBoat_c::finalizeState_Wait() {}
+114
View File
@@ -0,0 +1,114 @@
#include <c/c_math.h>
#include <d/tg/d_t_tumble_weed.h>
#include <m/m_vec.h>
SPECIAL_ACTOR_PROFILE(TAG_TUMBLE_WEED, dTgTumbleWeed_c, fProfile::TUMBLE_WEED_TAG, 0x0244, 0, 0);
STATE_DEFINE(dTgTumbleWeed_c, AreaOut);
STATE_DEFINE(dTgTumbleWeed_c, AreaIn);
STATE_DEFINE(dTgTumbleWeed_c, Wind);
int dTgTumbleWeed_c::create() {
tumbleweedTimer = 0;
windTimer = 0x96;
mStateMgr.changeState(StateID_AreaOut);
return 1;
}
u16 decr(u16 *num);
int dTgTumbleWeed_c::doDelete() {
return 1;
}
int dTgTumbleWeed_c::actorExecute() {
mStateMgr.executeState();
decr(&tumbleweedTimer);
return 1;
}
u16 decr(u16 *num) {
if (*num != 0) {
(*num)--;
}
return *num;
}
int dTgTumbleWeed_c::draw() {
return 1;
}
void dTgTumbleWeed_c::initializeState_AreaOut() {}
void dTgTumbleWeed_c::executeState_AreaOut() {
if (decr(&windTimer) == 0) {
windTimer = 0x96;
if (shouldDoWind()) {
mStateMgr.changeState(StateID_Wind);
return;
}
}
if (isWithinPlayerRadius(scale.x)) {
mStateMgr.changeState(StateID_AreaIn);
}
}
void dTgTumbleWeed_c::finalizeState_AreaOut() {}
void dTgTumbleWeed_c::initializeState_AreaIn() {}
void dTgTumbleWeed_c::executeState_AreaIn() {
if (tumbleweedTimer == 0) {
if (shouldSpawnTumbleweed()) {
doSpawnTumbleweed();
}
tumbleweedTimer = 600;
}
if (decr(&windTimer) == 0) {
windTimer = 0x96;
if (shouldDoWind()) {
mStateMgr.changeState(StateID_Wind);
return;
}
}
if (!isWithinPlayerRadius(scale.x)) {
mStateMgr.changeState(StateID_AreaOut);
}
}
void dTgTumbleWeed_c::finalizeState_AreaIn() {}
extern "C" void fn_475_1B00(fBase_c *, mVec3_c&);
void dTgTumbleWeed_c::initializeState_Wind() {
mVec3_c vec;
getWind(&vec);
if (childTumbleweed.p_owner != nullptr) {
fn_475_1B00(childTumbleweed.p_owner, vec);
}
}
void dTgTumbleWeed_c::executeState_Wind() {
if (isWithinPlayerRadius(scale.x)) {
mStateMgr.changeState(StateID_AreaIn);
} else {
mStateMgr.changeState(StateID_AreaOut);
}
}
void dTgTumbleWeed_c::finalizeState_Wind() {}
bool dTgTumbleWeed_c::shouldSpawnTumbleweed() {
bool spawnAllowed = false;
if (childTumbleweed.p_owner == nullptr && cM::rnd() <= 0.8f) {
spawnAllowed = true;
}
if (spawnAllowed) {
return true;
}
return false;
}
bool dTgTumbleWeed_c::shouldDoWind() {
return childTumbleweed.p_owner != nullptr && cM::rnd() <= 0.5f;
}
void dTgTumbleWeed_c::doSpawnTumbleweed() {
}
void dTgTumbleWeed_c::getWind(mVec3_c*) {}
+2 -3
View File
@@ -24,7 +24,6 @@ void (*fBase_c::sUnloadCallback)();
fBase_c::fBase_c()
: unique_ID(m_rootUniqueID), params(m_tmpCtData.params), profile_name(m_tmpCtData.prof_name),
group_type(m_tmpCtData.group_type), manager(this) {
fManager_c *mgr = &manager;
m_rootUniqueID = (fBaseID_e)(m_rootUniqueID + 1);
if (m_rootUniqueID == INVALID) {
@@ -33,8 +32,8 @@ fBase_c::fBase_c()
}
}
fManager_c::m_connectManage.addTreeNode(&mgr->connect_node, m_tmpCtData.connect_parent);
int searchTableIdx = mgr->getSearchTableNum();
fManager_c::m_connectManage.addTreeNode(&manager.connect_node, m_tmpCtData.connect_parent);
int searchTableIdx = manager.getSearchTableNum();
fManager_c::m_searchManage[searchTableIdx].prepend(&manager.search_node);
const fProfile::fBaseProfile_c *profile = (*fProfile::sProfileList)[profile_name];
+31
View File
@@ -0,0 +1,31 @@
#include <s/s_Phase.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sPhase_c::sPhase_c(phaseMethod **methodList, int count) {
mpMethodList = methodList;
mPhaseLength = count;
mCurrMethod = 0;
}
sPhase_c::METHOD_RESULT_e sPhase_c::callMethod(void *thisPtr) {
if (mCurrMethod >= mPhaseLength) {
return DONE;
}
METHOD_RESULT_e result = OK;
while (result == OK) {
result = (mpMethodList[mCurrMethod])(thisPtr);
if (result == OK) {
// Go to the next method
mCurrMethod++;
if (mCurrMethod >= mPhaseLength) {
return DONE;
}
}
}
return result;
}
+56
View File
@@ -0,0 +1,56 @@
#include <common.h>
#include <s/s_StateInterfaces.hpp>
#include <s/s_StateID.hpp>
#include <s/s_StateMethodUsr_FI.hpp>
#include <s/s_StateIDChk.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sStateID_c::NumberMemo_c sStateID_c::sm_numberMemo;
sStateID_c sStateID::null(nullptr);
sStateID_c::sStateID_c(const char *name) {
mpName = name;
mNumber = (name != nullptr) ? sm_numberMemo.get() : 0;
}
sStateID_c::~sStateID_c() {}
bool sStateID_c::isNull() const {
return mNumber == 0;
}
bool sStateID_c::isEqual(const sStateIDIf_c &other) const {
return number() == other.number();
}
bool sStateID_c::operator==(const sStateIDIf_c &other) const {
return isEqual(other);
}
bool sStateID_c::operator!=(const sStateIDIf_c &other) const {
return !isEqual(other);
}
bool sStateID_c::isSameName(const char *name) const {
// Just return false, the full implementation is in sFStateID_c
return false;
}
const char *sStateID_c::name() const {
return mpName;
}
unsigned int sStateID_c::number() const {
return mNumber;
}
sStateFctIf_c::~sStateFctIf_c() {}
sStateIDChkIf_c::~sStateIDChkIf_c() {}
sStateIDChk_c::~sStateIDChk_c() {}
sStateIDIf_c::~sStateIDIf_c() {}
sStateIf_c::~sStateIf_c() {}
sStateMethodIf_c::~sStateMethodIf_c() {}
sStateMethodUsr_FI_c::~sStateMethodUsr_FI_c() {}
sStateMgrIf_c::~sStateMgrIf_c() {}
+78
View File
@@ -0,0 +1,78 @@
#include <common.h>
#include <s/s_StateInterfaces.hpp>
#include <s/s_StateMethod.hpp>
#include <s/s_StateID.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sStateMethod_c::sStateMethod_c(sStateIDChkIf_c &checker, sStateFctIf_c &factory, const sStateIDIf_c &initialState) :
mpStateChk(checker),
mpStateFct(factory),
mInitFinalizeLock(false),
mExecutionLock(false),
mIsValid(false),
mStateChanged(false),
mRefreshStateMethod(false),
mpNewStateID(&initialState),
mpOldStateID(&sStateID::null),
mpStateID(&initialState),
mpState(nullptr) {
}
sStateMethod_c::~sStateMethod_c() {}
void sStateMethod_c::initializeStateMethod() {
if (!mpNewStateID->isNull() && !mInitFinalizeLock && !mIsValid) {
mInitFinalizeLock = true;
mpStateID = mpNewStateID;
int ret = initializeStateLocalMethod();
if (ret != 0) {
mIsValid = true;
} else {
mIsValid = false;
}
mInitFinalizeLock = false;
}
}
void sStateMethod_c::executeStateMethod() {
if (!mExecutionLock) {
// Skyward Sword change: Prevent runaway state changes?
int i = 2;
do {
if (mRefreshStateMethod) {
i--;
}
mRefreshStateMethod = false;
// We only want to execute if we have a valid next state
if (!mpNewStateID->isNull()) {
mExecutionLock = true;
executeStateLocalMethod();
mExecutionLock = false;
}
} while (mRefreshStateMethod && mStateChanged && i);
}
}
void sStateMethod_c::finalizeStateMethod() {
if (!mpNewStateID->isNull() && mIsValid && !mInitFinalizeLock) {
mInitFinalizeLock = true;
mpOldStateID = mpStateID;
finalizeStateLocalMethod();
mIsValid = false;
mInitFinalizeLock = false;
}
}
void sStateMethod_c::changeStateMethod(const sStateIDIf_c &newID) {
if (!newID.isNull()) {
mpNewStateID = &newID;
changeStateLocalMethod(newID);
mStateChanged = true;
}
}
+30
View File
@@ -0,0 +1,30 @@
#include <common.h>
#include <s/s_StateMethodUsr_FI.hpp>
// Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib
// See include/s/README.txt for changes made
sStateMethodUsr_FI_c::sStateMethodUsr_FI_c(sStateIDChkIf_c &check, sStateFctIf_c &factory, const sStateIDIf_c &state) :
sStateMethod_c(check, factory, state) {
}
int sStateMethodUsr_FI_c::initializeStateLocalMethod() {
mpState = mpStateFct.build(*getNewStateID()); // Create new state holder with the next state ID
mpState->initialize();
return 1;
}
void sStateMethodUsr_FI_c::executeStateLocalMethod() {
initializeStateMethod(); // Ensure we are in a valid state (this only actually initializes the state if !mIsValid)
mpState->execute();
}
void sStateMethodUsr_FI_c::finalizeStateLocalMethod() {
mpState->finalize();
mpStateFct.dispose(mpState);
}
void sStateMethodUsr_FI_c::changeStateLocalMethod(const sStateIDIf_c &newID) {
finalizeStateMethod(); // Terminate the current state
initializeStateMethod(); // Initialize the new state
}