OdysseyDecomp/lib/al/Library/LiveActor/LiveActor.cpp
2025-05-10 16:57:49 +02:00

408 lines
13 KiB
C++

#include "Library/LiveActor/LiveActor.h"
#include "Library/Action/ActorActionKeeper.h"
#include "Library/Audio/System/AudioKeeper.h"
#include "Library/Collision/Collider.h"
#include "Library/Effect/EffectKeeper.h"
#include "Library/Execute/ActorExecuteInfo.h"
#include "Library/Execute/ExecuteUtil.h"
#include "Library/HitSensor/HitSensorKeeper.h"
#include "Library/LiveActor/ActorAnimFunction.h"
#include "Library/LiveActor/ActorClippingFunction.h"
#include "Library/LiveActor/ActorCollisionFunction.h"
#include "Library/LiveActor/ActorFlagFunction.h"
#include "Library/LiveActor/ActorInitInfo.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorModelFunction.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseKeeper.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSceneInfo.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/LiveActor/LiveActorFlag.h"
#include "Library/LiveActor/LiveActorFunction.h"
#include "Library/Matrix/MatrixUtil.h"
#include "Library/Model/ModelKeeper.h"
#include "Library/Nature/NatureDirector.h"
#include "Library/Nerve/NerveKeeper.h"
#include "Library/Placement/PlacementFunction.h"
#include "Library/Rail/RailKeeper.h"
#include "Library/Screen/ScreenPointKeeper.h"
#include "Library/Shader/ActorOcclusionKeeper.h"
#include "Library/Shadow/ActorShadowUtil.h"
#include "Library/Shadow/ShadowKeeper.h"
#include "Library/Stage/StageSwitchKeeper.h"
#include "Project/Action/ActionPadAndCameraCtrl.h"
#include "Project/Action/ActionSeCtrl.h"
#include "Project/Clipping/ClippingFunction.h"
#include "Project/Item/ActorItemKeeper.h"
#include "Project/Item/ActorScoreKeeper.h"
#include "Project/Light/ActorPrepassLightKeeper.h"
namespace al {
LiveActor::LiveActor(const char* actorName) : mName(actorName) {
mFlags = new LiveActorFlag();
mShadowKeeper = new ShadowKeeper();
}
CollisionDirector* LiveActor::getCollisionDirector() const {
return mSceneInfo->collisionDirector;
}
AreaObjDirector* LiveActor::getAreaObjDirector() const {
return mSceneInfo->areaObjDirector;
}
CameraDirector* LiveActor::getCameraDirector() const {
return mSceneInfo->cameraDirector;
}
NatureDirector* LiveActor::getNatureDirector() const {
return mSceneInfo->natureDirector;
}
SceneObjHolder* LiveActor::getSceneObjHolder() const {
return mSceneInfo->sceneObjHolder;
}
void LiveActor::draw() const {}
void LiveActor::initAfterPlacement() {
tryInitFixedModelGpuBuffer(this);
if (mPrePassLightKeeper)
mPrePassLightKeeper->initAfterPlacement();
}
void LiveActor::appear() {
makeActorAlive();
}
void LiveActor::makeActorAlive() {
if (mHitSensorKeeper)
mHitSensorKeeper->validateBySystem();
if (mScreenPointKeeper)
mScreenPointKeeper->validateBySystem();
mFlags->isDead = false;
if (isClipped(this))
endClipped();
if (!isHideModel(this) && mModelKeeper)
mModelKeeper->show();
resetPosition(this);
if (mCollisionParts)
validateCollisionPartsBySystem(this);
if (mHitSensorKeeper)
mHitSensorKeeper->update();
alClippingFunction::addToClippingTarget(this);
if (mExecuteInfo) {
alActorSystemFunction::addToExecutorMovement(this);
if (!isHideModel(this) && mExecuteInfo->getDrawerCount() >= 1)
alActorSystemFunction::addToExecutorDraw(this);
}
if (getAudioKeeper())
getAudioKeeper()->appear();
if (mPrePassLightKeeper)
mPrePassLightKeeper->appear(isHideModel(this));
if (mOcclusionKeeper)
mOcclusionKeeper->appear(isHideModel(this));
if (mShadowKeeper && !isHideModel(this))
mShadowKeeper->show();
if (mSubActorKeeper)
alSubActorFunction::trySyncAlive(mSubActorKeeper);
}
void LiveActor::kill() {
makeActorDead();
}
void LiveActor::makeActorDead() {
mFlags->isDead = true;
if (mModelKeeper)
mModelKeeper->hide();
if (mHitSensorKeeper)
mHitSensorKeeper->invalidateBySystem();
if (mPoseKeeper)
setVelocityZero(this);
if (mScreenPointKeeper)
mScreenPointKeeper->invalidateBySystem();
alClippingFunction::removeFromClippingTarget(this);
if (mCollider)
mCollider->onInvalidate();
if (mCollisionParts)
invalidateCollisionPartsBySystem(this);
if (getEffectKeeper())
getEffectKeeper()->deleteAndClearEffectAll();
if (getAudioKeeper())
getAudioKeeper()->kill();
if (mShadowKeeper)
hideShadow(this);
if (mActionKeeper) {
if (mActionKeeper->getPadAndCameraCtrl())
mActionKeeper->getPadAndCameraCtrl()->notifyActorDead();
if (mActionKeeper && mActionKeeper->getSeCtrl())
mActionKeeper->getSeCtrl()->resetAction(false);
}
if (mPrePassLightKeeper)
mPrePassLightKeeper->requestKill();
if (mOcclusionKeeper)
mOcclusionKeeper->requestKill();
if (mExecuteInfo) {
alActorSystemFunction::removeFromExecutorMovement(this);
if (mExecuteInfo->getDrawerCount() >= 1)
alActorSystemFunction::removeFromExecutorDraw(this);
}
if (mSubActorKeeper)
alSubActorFunction::trySyncDead(mSubActorKeeper);
}
void LiveActor::movement() {
if (mFlags->isDead || (mFlags->isClipped && !mFlags->isDrawClipped))
return;
if (mActionKeeper)
mActionKeeper->updatePrev();
if (mModelKeeper)
mModelKeeper->update();
if (mFlags->isMaterialCodeValid && isCollidedGround(this)) {
setMaterialCode(this, getCollidedFloorMaterialCodeName(this));
if (mFlags->isPuddleMaterialValid)
updateMaterialCodePuddle(this);
}
if (mHitSensorKeeper) {
mHitSensorKeeper->attackSensor();
if (mFlags->isDead)
return;
}
if (mNerveKeeper) {
mNerveKeeper->update();
if (mFlags->isDead)
return;
}
control();
if (mFlags->isDead)
return;
updateCollider();
if (isUpdateMovementEffectAudioCollisionSensor(this)) {
if (mEffectKeeper)
mEffectKeeper->update();
if (mCollisionParts) {
if (!mModelKeeper || !mModelKeeper->isFixedModel()) {
sead::Matrix34f baseMtx;
mPoseKeeper->calcBaseMtx(&baseMtx);
preScaleMtx(&baseMtx, mPoseKeeper->getScale());
syncCollisionMtx(this, &baseMtx);
}
}
if (mHitSensorKeeper)
mHitSensorKeeper->update();
}
if (mActionKeeper)
mActionKeeper->updatePost();
if (mShadowKeeper)
mShadowKeeper->update();
if (mScreenPointKeeper)
mScreenPointKeeper->update();
if (mModelKeeper)
mModelKeeper->updateLast();
}
void LiveActor::calcAnim() {
sead::Matrix34f baseMtx;
alActorPoseFunction::calcBaseMtx(&baseMtx, this);
if (mModelKeeper && mModelKeeper->isNeedSetBaseMtxAndCalcAnim())
setBaseMtxAndCalcAnim(this, baseMtx, getScale(this));
if (mCollisionParts) {
preScaleMtx(&baseMtx, getScale(this));
syncCollisionMtx(this, &baseMtx);
}
if (getEffectKeeper())
getEffectKeeper()->update();
if (mHitSensorKeeper)
mHitSensorKeeper->update();
if (mOcclusionKeeper)
mOcclusionKeeper->updateAndRequest();
}
void LiveActor::startClipped() {
mFlags->isClipped = true;
if (mModelKeeper)
mModelKeeper->hide();
if (!mFlags->isDrawClipped) {
if (mHitSensorKeeper)
mHitSensorKeeper->invalidateBySystem();
if (getAudioKeeper())
getAudioKeeper()->startClipped();
if (mActionKeeper && mActionKeeper->getPadAndCameraCtrl())
mActionKeeper->getPadAndCameraCtrl()->notifyActorStartClipped();
}
if (getEffectKeeper())
getEffectKeeper()->offCalcAndDraw();
if (mShadowKeeper)
mShadowKeeper->hide();
if (mScreenPointKeeper)
mScreenPointKeeper->invalidateBySystem();
if (mPrePassLightKeeper)
mPrePassLightKeeper->hideModel();
if (mOcclusionKeeper)
mOcclusionKeeper->hideModel();
if (mExecuteInfo) {
if (!mFlags->isDrawClipped)
alActorSystemFunction::removeFromExecutorMovement(this);
if (mExecuteInfo->getDrawerCount() >= 1)
alActorSystemFunction::removeFromExecutorDraw(this);
if (mFlags->isDrawClipped && mModelKeeper && mModelKeeper->isIgnoreUpdateDrawClipping())
setNeedSetBaseMtxAndCalcAnimFlag(this, false);
}
if (mSubActorKeeper)
alSubActorFunction::trySyncClippingStart(mSubActorKeeper);
}
void LiveActor::endClipped() {
mFlags->isClipped = false;
if (!mFlags->isDrawClipped) {
if (mHitSensorKeeper) {
mHitSensorKeeper->validateBySystem();
updateHitSensorsAll(this);
}
if (getAudioKeeper())
getAudioKeeper()->endClipped();
if (mActionKeeper && mActionKeeper->getPadAndCameraCtrl())
mActionKeeper->getPadAndCameraCtrl()->notifyActorEndClipped();
}
if (getEffectKeeper())
getEffectKeeper()->onCalcAndDraw();
if (mScreenPointKeeper)
mScreenPointKeeper->validateBySystem();
if (mExecuteInfo) {
if (!mFlags->isDrawClipped)
alActorSystemFunction::addToExecutorMovement(this);
if (mExecuteInfo->getDrawerCount() >= 1 && !isHideModel(this))
alActorSystemFunction::addToExecutorDraw(this);
if (mModelKeeper && mModelKeeper->isIgnoreUpdateDrawClipping())
setNeedSetBaseMtxAndCalcAnimFlag(this, true);
}
if (!isHideModel(this) && mModelKeeper)
mModelKeeper->show();
if (mShadowKeeper && !isHideModel(this))
mShadowKeeper->show();
if (mPrePassLightKeeper)
mPrePassLightKeeper->appear(isHideModel(this));
if (mOcclusionKeeper)
mOcclusionKeeper->appear(isHideModel(this));
if (mSubActorKeeper)
alSubActorFunction::trySyncClippingEnd(mSubActorKeeper);
}
const sead::Matrix34f* LiveActor::getBaseMtx() const {
if (mModelKeeper)
return mModelKeeper->getBaseMtx();
if (mPoseKeeper)
return mPoseKeeper->getMtxPtr();
return nullptr;
}
RailRider* LiveActor::getRailRider() const {
if (mRailKeeper)
return mRailKeeper->getRailRider();
return nullptr;
}
ActorSceneInfo* LiveActor::getSceneInfo() const {
return mSceneInfo;
}
void LiveActor::initHitSensor(s32 amount) {
mHitSensorKeeper = new HitSensorKeeper(amount);
}
void LiveActor::initCollider(f32 radius, f32 offsetY, u32 allocatedHitInfo) {
mCollider = new Collider(getCollisionDirector(), getBaseMtx(), &getTrans(this),
&getGravity(this), radius, offsetY, allocatedHitInfo);
mFlags->isCollideOff = false;
}
void LiveActor::initPoseKeeper(ActorPoseKeeperBase* poseKeeper) {
mPoseKeeper = poseKeeper;
}
void LiveActor::initExecuteInfo(ActorExecuteInfo* executeInfo) {
mExecuteInfo = executeInfo;
}
void LiveActor::initRailKeeper(const ActorInitInfo& info, const char* linkName) {
mRailKeeper = tryCreateRailKeeper(*info.placementInfo, linkName);
}
void LiveActor::initModelKeeper(ModelKeeper* modelKeeper) {
mModelKeeper = modelKeeper;
offUpdateMovementEffectAudioCollisionSensor(this);
}
void LiveActor::initScoreKeeper() {
mScoreKeeper = new ActorScoreKeeper();
}
void LiveActor::initStageSwitchKeeper() {
mStageSwitchKeeper = new StageSwitchKeeper();
}
void LiveActor::initItemKeeper(s32 itemAmount) {
mItemKeeper = new ActorItemKeeper(this, itemAmount);
}
void LiveActor::initActionKeeper(ActorActionKeeper* actionKeeper) {
mActionKeeper = actionKeeper;
}
void LiveActor::initScreenPointKeeper(ScreenPointKeeper* screenPointKeeper) {
mScreenPointKeeper = screenPointKeeper;
}
void LiveActor::initEffectKeeper(EffectKeeper* effectKeeper) {
mEffectKeeper = effectKeeper;
if (mModelKeeper)
alEffectKeeperInitFunction::setupModelToEffectKeeper(mEffectKeeper, mModelKeeper);
alEffectKeeperInitFunction::setupCameraToEffectKeeper(mEffectKeeper, this);
}
void LiveActor::initNerveKeeper(NerveKeeper* nerveKeeper) {
mNerveKeeper = nerveKeeper;
}
void LiveActor::initAudioKeeper(AudioKeeper* audioKeeper) {
mAudioKeeper = audioKeeper;
}
void LiveActor::initActorPrePassLightKeeper(ActorPrePassLightKeeper* lightKeeper) {
mPrePassLightKeeper = lightKeeper;
}
void LiveActor::initActorOcclusionKeeper(ActorOcclusionKeeper* occlusionKeeper) {
mOcclusionKeeper = occlusionKeeper;
}
void LiveActor::initSubActorKeeper(SubActorKeeper* subActorKeeper) {
mSubActorKeeper = subActorKeeper;
}
void LiveActor::initSceneInfo(ActorSceneInfo* sceneInfo) {
mSceneInfo = sceneInfo;
}
void LiveActor::updateCollider() {
if (!mPoseKeeper)
return;
const sead::Vector3f& velocity = getVelocity(this);
if (mCollider) {
if (mFlags->isCollideOff) {
*getTransPtr(this) += velocity;
mCollider->onInvalidate();
} else {
*getTransPtr(this) += mCollider->collide(velocity);
}
return;
}
*getTransPtr(this) += velocity;
}
} // namespace al