mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-29 20:14:41 +00:00
408 lines
13 KiB
C++
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
|