mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
Project/Action: Implement ActionFlagCtrl (#783)
This commit is contained in:
parent
ca8e7eb87a
commit
5539b5a52c
|
|
@ -288330,13 +288330,13 @@ Project/Action/ActionFlagCtrl.o:
|
|||
label:
|
||||
- _ZN2al20ActionSensorCtrlInfoC1Ev
|
||||
- _ZN2al20ActionSensorCtrlInfoC2Ev
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa377b0
|
||||
size: 12
|
||||
label:
|
||||
- _ZN2al18ActionFlagCtrlInfoC1Ev
|
||||
- _ZN2al18ActionFlagCtrlInfoC2Ev
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa377bc
|
||||
size: 276
|
||||
label: _ZN2al14ActionFlagCtrl9tryCreateEPNS_9LiveActorEPKc
|
||||
|
|
@ -288344,7 +288344,7 @@ Project/Action/ActionFlagCtrl.o:
|
|||
- offset: 0xa378d0
|
||||
size: 1180
|
||||
label: _ZN2al14ActionFlagCtrl8initPostEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa37d6c
|
||||
size: 144
|
||||
label: _ZN2al14ActionFlagCtrl5startEPKc
|
||||
|
|
@ -288356,11 +288356,11 @@ Project/Action/ActionFlagCtrl.o:
|
|||
- offset: 0xa37e64
|
||||
size: 472
|
||||
label: _ZN2al14ActionFlagCtrl13startCtrlFlagEv
|
||||
status: NotDecompiled
|
||||
status: NonMatchingMajor
|
||||
- offset: 0xa3803c
|
||||
size: 192
|
||||
label: _ZN2al14ActionFlagCtrl15startCtrlSensorEv
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa380fc
|
||||
size: 36
|
||||
label: _ZN2al14ActionFlagCtrl6updateEfffb
|
||||
|
|
@ -288368,7 +288368,7 @@ Project/Action/ActionFlagCtrl.o:
|
|||
- offset: 0xa38120
|
||||
size: 240
|
||||
label: _ZN2al14ActionFlagCtrl16updateCtrlSensorEfffb
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa38210
|
||||
size: 56
|
||||
label:
|
||||
|
|
@ -288378,11 +288378,11 @@ Project/Action/ActionFlagCtrl.o:
|
|||
- offset: 0xa38248
|
||||
size: 44
|
||||
label: _ZNK2al14ActionFlagCtrl13isFlagValidOnEib
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa38274
|
||||
size: 40
|
||||
label: _ZNK2al14ActionFlagCtrl14isFlagValidOffEib
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
Project/Action/ActionFunction.o:
|
||||
'.text':
|
||||
- offset: 0xa3829c
|
||||
|
|
|
|||
|
|
@ -1,12 +1,25 @@
|
|||
#include "Project/Action/ActionFlagCtrl.h"
|
||||
|
||||
#include "Library/Base/StringUtil.h"
|
||||
#include "Library/HitSensor/HitSensorKeeper.h"
|
||||
#include "Library/LiveActor/ActorClippingFunction.h"
|
||||
#include "Library/LiveActor/ActorCollisionFunction.h"
|
||||
#include "Library/LiveActor/ActorFlagFunction.h"
|
||||
#include "Library/LiveActor/ActorModelFunction.h"
|
||||
#include "Library/LiveActor/ActorResourceFunction.h"
|
||||
#include "Library/LiveActor/ActorSensorUtil.h"
|
||||
#include "Library/LiveActor/LiveActor.h"
|
||||
#include "Library/Yaml/ByamlIter.h"
|
||||
#include "Library/Yaml/ByamlUtil.h"
|
||||
#include "Project/Action/InitResourceDataActionAnim.h"
|
||||
#include "Project/HitSensor/HitSensor.h"
|
||||
|
||||
namespace al {
|
||||
ActionSensorCtrlInfo::ActionSensorCtrlInfo() = default;
|
||||
ActionFlagCtrlInfo::ActionFlagCtrlInfo() = default;
|
||||
|
||||
ActionFlagCtrl::ActionFlagCtrl(LiveActor* actor, const char* name)
|
||||
: mParentActor(actor), mName(createStringIfInStack(name)) {}
|
||||
: mParentActor(actor), mArchiveName(createStringIfInStack(name)) {}
|
||||
|
||||
ActionFlagCtrl* ActionFlagCtrl::tryCreate(LiveActor* actor, const char* name) {
|
||||
if (!isExistModelResource(actor))
|
||||
|
|
@ -22,10 +35,64 @@ ActionFlagCtrl* ActionFlagCtrl::tryCreate(LiveActor* actor, const char* name) {
|
|||
return new ActionFlagCtrl(actor, name);
|
||||
}
|
||||
|
||||
inline CtrlFlag getCtrlFlagByKey(ByamlIter iter, const char* name) {
|
||||
bool isValid = false;
|
||||
if (!iter.tryGetBoolByKey(&isValid, name))
|
||||
return CtrlFlag::NotFound;
|
||||
|
||||
return isValid ? CtrlFlag::ValidOn : CtrlFlag::ValidOff;
|
||||
}
|
||||
|
||||
void ActionFlagCtrl::initPost() {
|
||||
mHitSensorKeeper = mParentActor->getHitSensorKeeper();
|
||||
|
||||
sead::FixedSafeString<128> initFileName;
|
||||
tryGetActorInitFileName(&initFileName, mParentActor, "ActionFlagCtrl", mArchiveName);
|
||||
|
||||
ByamlIter fileIter;
|
||||
tryGetActorInitFileIter(&fileIter, mParentActor, initFileName.cstr(), mArchiveName);
|
||||
|
||||
mInfoCount = fileIter.getSize();
|
||||
mCtrlInfoArray = new ActionFlagCtrlInfo*[mInfoCount];
|
||||
for (s32 i = 0; i < mInfoCount; i++) {
|
||||
ByamlIter iter;
|
||||
fileIter.tryGetIterByIndex(&iter, i);
|
||||
ActionFlagCtrlInfo* flagCtrlInfo = new ActionFlagCtrlInfo();
|
||||
mCtrlInfoArray[i] = flagCtrlInfo;
|
||||
|
||||
iter.tryGetStringByKey(&flagCtrlInfo->actionName, "ActionName");
|
||||
|
||||
flagCtrlInfo->ctrlFlags = new CtrlFlag[5];
|
||||
flagCtrlInfo->ctrlFlags[0] = getCtrlFlagByKey(iter, "ShowModel");
|
||||
flagCtrlInfo->ctrlFlags[1] = getCtrlFlagByKey(iter, "CollisionParts");
|
||||
flagCtrlInfo->ctrlFlags[2] = getCtrlFlagByKey(iter, "Collider");
|
||||
flagCtrlInfo->ctrlFlags[3] = getCtrlFlagByKey(iter, "ClippingOff");
|
||||
flagCtrlInfo->ctrlFlags[4] = getCtrlFlagByKey(iter, "FaceCtrl");
|
||||
|
||||
ByamlIter sensorListIter;
|
||||
if (iter.tryGetIterByKey(&sensorListIter, "SensorList") && mHitSensorKeeper) {
|
||||
flagCtrlInfo->sensorCtrlInfoArray =
|
||||
new ActionSensorCtrlInfo[mHitSensorKeeper->getSensorNum()];
|
||||
|
||||
for (s32 j = 0; j < mHitSensorKeeper->getSensorNum(); j++) {
|
||||
ActionSensorCtrlInfo* sensorInfoArray = flagCtrlInfo->sensorCtrlInfoArray;
|
||||
sensorInfoArray[j].name = mHitSensorKeeper->getSensor(j)->getName();
|
||||
|
||||
ByamlIter sensorIter;
|
||||
if (sensorListIter.tryGetIterByKey(&sensorIter, sensorInfoArray[j].name)) {
|
||||
sensorInfoArray[j].state = getCtrlFlagByKey(sensorIter, "State");
|
||||
tryGetByamlS16(&sensorInfoArray[j].startFrame, sensorIter, "StartFrame");
|
||||
tryGetByamlS16(&sensorInfoArray[j].endFrame, sensorIter, "EndFrame");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionFlagCtrl::start(const char* name) {
|
||||
mLastFlag = findFlagInfo(name);
|
||||
mIsBool = false;
|
||||
if (!mLastFlag)
|
||||
mCurrentCtrlInfo = findFlagInfo(name);
|
||||
mIsUpdateNeeded = false;
|
||||
if (!mCurrentCtrlInfo)
|
||||
return;
|
||||
|
||||
startCtrlFlag();
|
||||
|
|
@ -34,19 +101,100 @@ void ActionFlagCtrl::start(const char* name) {
|
|||
|
||||
ActionFlagCtrlInfo* ActionFlagCtrl::findFlagInfo(const char* name) const {
|
||||
for (s32 i = 0; i < mInfoCount; i++) {
|
||||
ActionFlagCtrlInfo* flagInfo = mInfos[i];
|
||||
if (isEqualStringCase(flagInfo->name, name))
|
||||
ActionFlagCtrlInfo* flagInfo = mCtrlInfoArray[i];
|
||||
if (isEqualStringCase(flagInfo->actionName, name))
|
||||
return flagInfo;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ActionFlagCtrl::update(f32 frame, f32 frameRate, f32 frameMax, bool isStop) {
|
||||
if (!mLastFlag || !mIsBool)
|
||||
// NON_MATCHING: Wrong compiler optimization https://decomp.me/scratch/3VkWo
|
||||
void ActionFlagCtrl::startCtrlFlag() {
|
||||
if (isFlagValidOn(0, !isHideModel(mParentActor)))
|
||||
showModel(mParentActor);
|
||||
else if (isFlagValidOff(0, !isHideModel(mParentActor)))
|
||||
hideModel(mParentActor);
|
||||
|
||||
if (mParentActor->getCollisionParts()) {
|
||||
if (isFlagValidOn(1, isValidCollisionParts(mParentActor)))
|
||||
validateCollisionParts(mParentActor);
|
||||
else if (isFlagValidOff(1, isValidCollisionParts(mParentActor)))
|
||||
invalidateCollisionParts(mParentActor);
|
||||
}
|
||||
|
||||
if (mParentActor->getCollider()) {
|
||||
if (isFlagValidOn(2, !isNoCollide(mParentActor)))
|
||||
onCollide(mParentActor);
|
||||
else if (isFlagValidOff(2, !isNoCollide(mParentActor)))
|
||||
offCollide(mParentActor);
|
||||
}
|
||||
|
||||
if (isFlagValidOn(3, isInvalidClipping(mParentActor)))
|
||||
invalidateClipping(mParentActor);
|
||||
else if (isFlagValidOff(3, isInvalidClipping(mParentActor)))
|
||||
validateClipping(mParentActor);
|
||||
}
|
||||
|
||||
void ActionFlagCtrl::startCtrlSensor() {
|
||||
if (!mHitSensorKeeper)
|
||||
return;
|
||||
|
||||
for (s32 i = 0; i < mHitSensorKeeper->getSensorNum(); i++) {
|
||||
ActionSensorCtrlInfo* sensor = mCurrentCtrlInfo->sensorCtrlInfoArray;
|
||||
if (sensor[i].startFrame > 0) {
|
||||
mIsUpdateNeeded = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sensor[i].endFrame > 0)
|
||||
mIsUpdateNeeded = true;
|
||||
|
||||
switch (sensor[i].state) {
|
||||
case CtrlFlag::ValidOn:
|
||||
validateHitSensor(mParentActor, sensor[i].name);
|
||||
break;
|
||||
case CtrlFlag::ValidOff:
|
||||
invalidateHitSensor(mParentActor, sensor[i].name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionFlagCtrl::update(f32 frame, f32 frameRateMax, f32 frameRate, bool isStop) {
|
||||
if (!mCurrentCtrlInfo || !mIsUpdateNeeded)
|
||||
return;
|
||||
if (!mHitSensorKeeper)
|
||||
return;
|
||||
|
||||
updateCtrlSensor(frame, frameRate, frameMax, isStop);
|
||||
updateCtrlSensor(frame, frameRateMax, frameRate, isStop);
|
||||
}
|
||||
|
||||
void ActionFlagCtrl::updateCtrlSensor(f32 frame, f32 frameRateMax, f32 frameRate, bool isStop) {
|
||||
for (s32 i = 0; i < mHitSensorKeeper->getSensorNum(); i++) {
|
||||
ActionSensorCtrlInfo* ctrlInfo = mCurrentCtrlInfo->sensorCtrlInfoArray;
|
||||
|
||||
f32 startFrame = ctrlInfo[i].startFrame;
|
||||
if (startFrame > 0 &&
|
||||
alAnimFunction::checkPass(frame, frameRateMax, frameRate, isStop, startFrame))
|
||||
validateHitSensor(mParentActor, ctrlInfo[i].name);
|
||||
|
||||
f32 endFrame = ctrlInfo[i].endFrame;
|
||||
if (endFrame > 0 &&
|
||||
alAnimFunction::checkPass(frame, frameRateMax, frameRate, isStop, endFrame))
|
||||
invalidateHitSensor(mParentActor, ctrlInfo[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
bool ActionFlagCtrl::isFlagValidOn(s32 index, bool isEnabled) const {
|
||||
return mCurrentCtrlInfo && mCurrentCtrlInfo->ctrlFlags[index] == CtrlFlag::ValidOn &&
|
||||
!isEnabled;
|
||||
}
|
||||
|
||||
bool ActionFlagCtrl::isFlagValidOff(s32 index, bool isEnabled) const {
|
||||
return mCurrentCtrlInfo && mCurrentCtrlInfo->ctrlFlags[index] == CtrlFlag::ValidOff &&
|
||||
isEnabled;
|
||||
}
|
||||
|
||||
} // namespace al
|
||||
|
|
|
|||
|
|
@ -9,35 +9,58 @@ struct ActionAnimDataInfo;
|
|||
class HitSensorKeeper;
|
||||
class LiveActor;
|
||||
|
||||
struct ActionFlagCtrlInfo {
|
||||
const char* name;
|
||||
void* _8;
|
||||
void* _10;
|
||||
enum class CtrlFlag : s16 {
|
||||
NotFound = 0,
|
||||
ValidOff = 2,
|
||||
ValidOn = 3,
|
||||
};
|
||||
|
||||
struct ActionSensorCtrlInfo {
|
||||
ActionSensorCtrlInfo();
|
||||
|
||||
const char* name = nullptr;
|
||||
CtrlFlag state = CtrlFlag::NotFound;
|
||||
s16 startFrame = -1;
|
||||
s16 endFrame = -1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ActionSensorCtrlInfo) == 0x10);
|
||||
|
||||
struct ActionFlagCtrlInfo {
|
||||
ActionFlagCtrlInfo();
|
||||
|
||||
const char* actionName = nullptr;
|
||||
CtrlFlag* ctrlFlags = nullptr;
|
||||
ActionSensorCtrlInfo* sensorCtrlInfoArray = nullptr;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ActionFlagCtrlInfo) == 0x18);
|
||||
|
||||
class ActionFlagCtrl {
|
||||
public:
|
||||
static ActionFlagCtrl* tryCreate(LiveActor* actor, const char* name);
|
||||
|
||||
ActionFlagCtrl(LiveActor* actor, const char* name);
|
||||
|
||||
ActionFlagCtrlInfo* findFlagInfo(const char* name) const;
|
||||
void initPost();
|
||||
void start(const char* name);
|
||||
ActionFlagCtrlInfo* findFlagInfo(const char* name) const;
|
||||
void startCtrlFlag();
|
||||
void startCtrlSensor();
|
||||
void update(f32 frame, f32 frameRateMax, f32 frameRate, bool isStop);
|
||||
void updateCtrlSensor(f32, f32, f32, bool);
|
||||
bool isFlagValidOn(s32, bool);
|
||||
bool isFlagValidOff(s32, bool);
|
||||
void updateCtrlSensor(f32 frame, f32 frameRateMax, f32 frameRate, bool isStop);
|
||||
bool isFlagValidOn(s32 index, bool isEnabled) const;
|
||||
bool isFlagValidOff(s32 index, bool isEnabled) const;
|
||||
|
||||
private:
|
||||
LiveActor* mParentActor;
|
||||
const char* mName;
|
||||
const char* mArchiveName;
|
||||
HitSensorKeeper* mHitSensorKeeper = nullptr;
|
||||
s32 mInfoCount = 0;
|
||||
ActionFlagCtrlInfo** mInfos = nullptr;
|
||||
ActionFlagCtrlInfo* mLastFlag = nullptr;
|
||||
bool mIsBool = false;
|
||||
ActionFlagCtrlInfo** mCtrlInfoArray = nullptr;
|
||||
ActionFlagCtrlInfo* mCurrentCtrlInfo = nullptr;
|
||||
bool mIsUpdateNeeded = false;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ActionFlagCtrl) == 0x38);
|
||||
} // namespace al
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <basis/seadTypes.h>
|
||||
|
||||
namespace al {
|
||||
class AnimInfoTable;
|
||||
struct ActionAnimCtrlInfo;
|
||||
class InitResourceDataAnim;
|
||||
class Resource;
|
||||
|
|
@ -20,3 +21,8 @@ private:
|
|||
ActionAnimCtrlInfo** mAnimInfos = nullptr;
|
||||
};
|
||||
} // namespace al
|
||||
|
||||
namespace alAnimFunction {
|
||||
bool checkPass(f32, f32, f32, bool, f32);
|
||||
al::AnimInfoTable* createAnimInfoTableIfNeed(const al::AnimInfoTable*, const al::AnimInfoTable*);
|
||||
} // namespace alAnimFunction
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ public:
|
|||
void update();
|
||||
void addHitSensor(HitSensor* sensor);
|
||||
|
||||
const char* getName() const { return mName; }
|
||||
|
||||
void clearSensors() { mSensorCount = 0; }
|
||||
|
||||
const sead::Vector3f& getFollowPosOffset() const { return mFollowPosOffset; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue