From 2904b4e9bcd96fcdb81fdff5d639091b1920691e Mon Sep 17 00:00:00 2001 From: german77 <5944268+german77@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:12:01 -0600 Subject: [PATCH] item: Implement CoinCollect2D --- data/odyssey_functions.csv | 36 +++---- src/Item/CoinCollect2D.cpp | 162 ++++++++++++++++++++++++++++++++ src/Item/CoinCollect2D.h | 44 +++++++++ src/MapObj/CapMessageShowInfo.h | 9 ++ 4 files changed, 233 insertions(+), 18 deletions(-) create mode 100644 src/Item/CoinCollect2D.cpp create mode 100644 src/Item/CoinCollect2D.h create mode 100644 src/MapObj/CapMessageShowInfo.h diff --git a/data/odyssey_functions.csv b/data/odyssey_functions.csv index f5d12c73..a1856ad5 100644 --- a/data/odyssey_functions.csv +++ b/data/odyssey_functions.csv @@ -10843,24 +10843,24 @@ Address,Quality,Size,Name 0x00000071001c06d8,U,000028,_ZNK2al10FunctorV0MIP11CoinCollectMS1_FvvEEclEv 0x00000071001c06f4,U,000076,_ZNK2al10FunctorV0MIP11CoinCollectMS1_FvvEE5cloneEv 0x00000071001c0740,U,000004,_ZN2al10FunctorV0MIP11CoinCollectMS1_FvvEED0Ev -0x00000071001c0744,U,000152,_ZN13CoinCollect2DC2EPKc -0x00000071001c07dc,U,000148,_ZN13CoinCollect2DC1EPKc -0x00000071001c0870,U,000456,_ZN13CoinCollect2D4initERKN2al13ActorInitInfoE -0x00000071001c0a38,U,000028,_ZN13CoinCollect2D18initAfterPlacementEv -0x00000071001c0a54,U,000136,_ZN13CoinCollect2D10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_ -0x00000071001c0adc,U,000044,_ZN13CoinCollect2D10endClippedEv -0x00000071001c0b08,U,000064,_ZN13CoinCollect2D16appearHintEffectEv -0x00000071001c0b48,U,000008,_ZN13CoinCollect2D16deleteHintEffectEv -0x00000071001c0b50,U,000008,_ZN13CoinCollect2D18reappearHintEffectEv -0x00000071001c0b58,U,000064,_ZNK13CoinCollect2D12isEnableHintEv -0x00000071001c0b98,U,000068,_ZN13CoinCollect2D7exeWaitEv -0x00000071001c0bdc,U,000080,_ZN13CoinCollect2D11exeWaitHintEv -0x00000071001c0c2c,U,000180,_ZN13CoinCollect2D6exeGotEv -0x00000071001c0ce0,U,000008,_ZNK13CoinCollect2D23getActorDimensionKeeperEv -0x00000071001c0ce8,U,000008,_ZThn264_NK13CoinCollect2D23getActorDimensionKeeperEv -0x00000071001c0cf0,U,000072,_ZNK12_GLOBAL__N_120CoinCollect2DNrvWait7executeEPN2al11NerveKeeperE -0x00000071001c0d38,U,000080,_ZNK12_GLOBAL__N_124CoinCollect2DNrvWaitHint7executeEPN2al11NerveKeeperE -0x00000071001c0d88,U,000008,_ZNK12_GLOBAL__N_119CoinCollect2DNrvGot7executeEPN2al11NerveKeeperE +0x00000071001c0744,O,000152,_ZN13CoinCollect2DC2EPKc +0x00000071001c07dc,O,000148,_ZN13CoinCollect2DC1EPKc +0x00000071001c0870,O,000456,_ZN13CoinCollect2D4initERKN2al13ActorInitInfoE +0x00000071001c0a38,O,000028,_ZN13CoinCollect2D18initAfterPlacementEv +0x00000071001c0a54,O,000136,_ZN13CoinCollect2D10receiveMsgEPKN2al9SensorMsgEPNS0_9HitSensorES5_ +0x00000071001c0adc,O,000044,_ZN13CoinCollect2D10endClippedEv +0x00000071001c0b08,O,000064,_ZN13CoinCollect2D16appearHintEffectEv +0x00000071001c0b48,O,000008,_ZN13CoinCollect2D16deleteHintEffectEv +0x00000071001c0b50,O,000008,_ZN13CoinCollect2D18reappearHintEffectEv +0x00000071001c0b58,O,000064,_ZNK13CoinCollect2D12isEnableHintEv +0x00000071001c0b98,O,000068,_ZN13CoinCollect2D7exeWaitEv +0x00000071001c0bdc,O,000080,_ZN13CoinCollect2D11exeWaitHintEv +0x00000071001c0c2c,O,000180,_ZN13CoinCollect2D6exeGotEv +0x00000071001c0ce0,O,000008,_ZNK13CoinCollect2D23getActorDimensionKeeperEv +0x00000071001c0ce8,O,000008,_ZThn264_NK13CoinCollect2D23getActorDimensionKeeperEv +0x00000071001c0cf0,O,000072,_ZNK12_GLOBAL__N_120CoinCollect2DNrvWait7executeEPN2al11NerveKeeperE +0x00000071001c0d38,O,000080,_ZNK12_GLOBAL__N_124CoinCollect2DNrvWaitHint7executeEPN2al11NerveKeeperE +0x00000071001c0d88,O,000008,_ZNK12_GLOBAL__N_119CoinCollect2DNrvGot7executeEPN2al11NerveKeeperE 0x00000071001c0d90,O,000124,_ZN16CoinCollectDummyC2EPKc 0x00000071001c0e0c,O,000136,_ZN16CoinCollectDummyC1EPKc 0x00000071001c0e94,O,000184,_ZN16CoinCollectDummy4initERKN2al13ActorInitInfoE diff --git a/src/Item/CoinCollect2D.cpp b/src/Item/CoinCollect2D.cpp new file mode 100644 index 00000000..f9c8eb88 --- /dev/null +++ b/src/Item/CoinCollect2D.cpp @@ -0,0 +1,162 @@ +#include "Item/CoinCollect2D.h" + +#include + +#include "Library/Collision/PartsConnector.h" +#include "Library/Controller/PadRumbleFunction.h" +#include "Library/Layout/LayoutActionFunction.h" +#include "Library/LiveActor/ActorActionFunction.h" +#include "Library/LiveActor/ActorClippingFunction.h" +#include "Library/LiveActor/ActorDrawFunction.h" +#include "Library/LiveActor/ActorInitInfo.h" +#include "Library/LiveActor/ActorSensorMsgFunction.h" +#include "Library/Nerve/NerveSetupUtil.h" +#include "Library/Nerve/NerveUtil.h" +#include "Library/Placement/PlacementFunction.h" +#include "Library/Scene/SceneUtil.h" + +#include "Item/CoinCollectEmpty2D.h" +#include "Item/CoinCollectHintState.h" +#include "Item/CoinCollectHolder.h" +#include "Item/CoinCollectWatcher.h" +#include "MapObj/CapMessageShowInfo.h" +#include "Scene/SceneObjFactory.h" +#include "System/GameDataFunction.h" +#include "Util/ActorDimensionKeeper.h" +#include "Util/ActorDimensionUtil.h" +#include "Util/ItemUtil.h" +#include "Util/SensorMsgFunction.h" + +namespace { +NERVE_IMPL(CoinCollect2D, Wait); +NERVE_IMPL(CoinCollect2D, WaitHint); +NERVE_IMPL(CoinCollect2D, Got); + +NERVES_MAKE_STRUCT(CoinCollect2D, Wait, WaitHint, Got); +} // namespace + +CoinCollect2D::CoinCollect2D(const char* name) : al::LiveActor(name) {} + +void CoinCollect2D::init(const al::ActorInitInfo& initInfo) { + al::initActorSceneInfo(this, initInfo); + rs::createCoinCollectWatcher(this); + rs::createCoinCollectHolder(this); + CoinCollectHolder* holder = + (CoinCollectHolder*)al::getSceneObj(this, SceneObjID_CoinCollectHolder); + holder->registerCoinCollect2D(this); + GameDataHolderAccessor gameData(this); + + if (!GameDataFunction::isGotCoinCollect(gameData, initInfo)) { + al::initActorWithArchiveName(this, initInfo, rs::getStageCoinCollect2DArchiveName(this), + nullptr); + makeActorAlive(); + CoinCollectWatcher* watcher = + (CoinCollectWatcher*)al::getSceneObj(this, SceneObjID_CoinCollectWatcher); + watcher->registerCoin(false); + al::initNerve(this, &NrvCoinCollect2D.Wait, 1); + + mHintState = new CoinCollectHintState(this); + al::initNerveState(this, mHintState, &NrvCoinCollect2D.WaitHint, "ヒント"); + + al::tryAddDisplayOffset(this, initInfo); + mMtxConnector = al::tryCreateMtxConnector(this, initInfo); + mDimensionKeeper = rs::createDimensionKeeper(this); + rs::updateDimensionKeeper(mDimensionKeeper); + rs::snap2DParallelizeFront(this, this, 500.0f); + al::startAction(this, "Wait"); + mPlacementId = al::createPlacementId(initInfo); + + } else { + makeActorDead(); + const char* archiveName = rs::getStageCoinCollect2DEmptyArchiveName(this); + CoinCollectWatcher* watcher = + (CoinCollectWatcher*)al::getSceneObj(this, SceneObjID_CoinCollectWatcher); + watcher->registerCoin(true); + + CoinCollectEmpty2D* coinCollectEmpty2d = + new CoinCollectEmpty2D("コレクトコイン空2D", archiveName); + al::initCreateActorWithPlacementInfo(coinCollectEmpty2d, initInfo); + } +} + +void CoinCollect2D::initAfterPlacement() { + if (mMtxConnector != nullptr) + al::attachMtxConnectorToCollision(mMtxConnector, this, false); +} + +bool CoinCollect2D::receiveMsg(const al::SensorMsg* message, al::HitSensor* other, + al::HitSensor* self) { + if (rs::isMsgItemGet2D(message) && (al::isNerve(this, &NrvCoinCollect2D.Wait) || + al::isNerve(this, &NrvCoinCollect2D.WaitHint))) { + al::invalidateClipping(this); + al::setNerve(this, &NrvCoinCollect2D.Got); + return true; + } + + if (al::isMsgPlayerDisregard(message)) + return true; + + return false; +} + +void CoinCollect2D::endClipped() { + rs::syncCoin2DAnimFrame(this, "Wait"); + al::LiveActor::endClipped(); +} + +ActorDimensionKeeper* CoinCollect2D::getActorDimensionKeeper() const { + return mDimensionKeeper; +} + +void CoinCollect2D::appearHintEffect() { + al::invalidateClipping(this); + al::setNerve(this, &NrvCoinCollect2D.WaitHint); + al::startHitReaction(this, "発光"); +} + +void CoinCollect2D::deleteHintEffect() { + mHintState->deleteHintEffect(); +} + +void CoinCollect2D::reappearHintEffect() { + mHintState->appearHintEffect(); +} + +bool CoinCollect2D::isEnableHint() const { + if (al::isDead(this)) + return true; + + return al::isNerve(this, &NrvCoinCollect2D.Wait); +} + +void CoinCollect2D::exeWait() { + if (al::isFirstStep(this)) + al::validateClipping(this); + + if (mMtxConnector != nullptr) + al::connectPoseQT(this, mMtxConnector); +} + +void CoinCollect2D::exeWaitHint() { + if (mMtxConnector != nullptr) + al::connectPoseQT(this, mMtxConnector); + + if (al::updateNerveState(this)) + al::setNerve(this, &NrvCoinCollect2D.Wait); +} + +void CoinCollect2D::exeGot() { + if (al::isFirstStep(this)) { + al::startAction(this, "Got"); + CoinCollectWatcher* watcher = + (CoinCollectWatcher*)al::getSceneObj(this, SceneObjID_CoinCollectWatcher); + watcher->countup(this); + + GameDataFunction::addCoinCollect(this, mPlacementId); + rs::tryShowCapMsgCollectCoinGetFirst(this); + alPadRumbleFunction::startPadRumble(this, "コッ(弱)", 1000.0f, 3000.0f, -1); + } + + if (al::isActionEnd(this)) + kill(); +} diff --git a/src/Item/CoinCollect2D.h b/src/Item/CoinCollect2D.h new file mode 100644 index 00000000..7442430f --- /dev/null +++ b/src/Item/CoinCollect2D.h @@ -0,0 +1,44 @@ +#pragma once + +#include "Library/LiveActor/LiveActor.h" + +#include "Util/IUseDimension.h" + +namespace al { +class ActorInitInfo; +class HitSensor; +class MtxConnector; +class PlacementId; +class SensorMsg; +} // namespace al + +class ActorDimensionKeeper; +class CoinCollectHintState; + +class CoinCollect2D : public al::LiveActor, public IUseDimension { +public: + CoinCollect2D(const char* name); + + void init(const al::ActorInitInfo& initInfo) override; + void initAfterPlacement() override; + bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other, + al::HitSensor* self) override; + void endClipped() override; + + ActorDimensionKeeper* getActorDimensionKeeper() const override; + + void appearHintEffect(); + void deleteHintEffect(); + void reappearHintEffect(); + bool isEnableHint() const; + + void exeWait(); + void exeWaitHint(); + void exeGot(); + +private: + CoinCollectHintState* mHintState = nullptr; + al::PlacementId* mPlacementId = nullptr; + al::MtxConnector* mMtxConnector = nullptr; + ActorDimensionKeeper* mDimensionKeeper = nullptr; +}; diff --git a/src/MapObj/CapMessageShowInfo.h b/src/MapObj/CapMessageShowInfo.h new file mode 100644 index 00000000..99427573 --- /dev/null +++ b/src/MapObj/CapMessageShowInfo.h @@ -0,0 +1,9 @@ +#pragma once + +namespace al { +class IUseSceneObjHolder; +} // namespace al + +namespace rs { +bool tryShowCapMsgCollectCoinGetFirst(const al::IUseSceneObjHolder*); +} // namespace rs