diff --git a/data/file_list.yml b/data/file_list.yml index 02b1515138..1bf88a716d 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -154897,7 +154897,7 @@ Util/ItemUtil.o: - offset: 0x556124 size: 196 label: _ZN2rs23appearRandomItemFromObjEPN2al9LiveActorEPNS0_9HitSensorEf - status: NotDecompiled + status: Matching - offset: 0x5561e8 size: 184 label: _ZN2rs25tryAppearMultiCoinFromObjEPN2al9LiveActorERKN4sead7Vector3IfEEif @@ -154969,11 +154969,11 @@ Util/ItemUtil.o: - offset: 0x556a78 size: 24 label: _ZN2rs20addDemoRacePrizeCoinEPN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x556a90 size: 96 label: _ZN18StageSceneFunction20appearPlayerDeadCoinEPN2al9LiveActorE - status: NotDecompiled + status: Matching Util/JudgeUtil.o: '.text': - offset: 0x556af0 diff --git a/lib/al/Library/Scene/ItemDirectorBase.h b/lib/al/Library/Scene/ItemDirectorBase.h index d014cd0c68..df62ba1143 100644 --- a/lib/al/Library/Scene/ItemDirectorBase.h +++ b/lib/al/Library/Scene/ItemDirectorBase.h @@ -12,9 +12,9 @@ class LiveActor; class ItemDirectorBase { public: - virtual void appearItem(const char*, const sead::Vector3f&, const sead::Quatf&, - const HitSensor*) = 0; - virtual void acquireItem(const LiveActor*, HitSensor*, const char*) = 0; + virtual LiveActor* appearItem(const char*, const sead::Vector3f&, const sead::Quatf&, + const HitSensor*) = 0; + virtual void acquireItem(const LiveActor*, HitSensor*, const char*) const = 0; virtual void declareItem(const char*, const ActorInitInfo&) = 0; virtual void endInit() = 0; }; diff --git a/src/Item/RandomItemSelector.h b/src/Item/RandomItemSelector.h index 3646966ac2..8e22d227d3 100644 --- a/src/Item/RandomItemSelector.h +++ b/src/Item/RandomItemSelector.h @@ -2,6 +2,7 @@ #include "Library/Scene/ISceneObj.h" +#include "Scene/SceneObjFactory.h" #include "Util/ItemUtil.h" namespace al { @@ -10,8 +11,10 @@ class IUseSceneObjHolder; class RandomItemSelector : public al::ISceneObj { public: + static constexpr s32 sSceneObjId = SceneObjID_RandomItemSelector; + RandomItemSelector(); - rs::ItemType::ValueType getRandomItemType(); + rs::ItemType::ValueType getRandomItemType(const al::IUseSceneObjHolder*); private: char filler[0x10]; diff --git a/src/MapObj/BlockQuestion.cpp b/src/MapObj/BlockQuestion.cpp index 22317e8969..82cc23cafb 100644 --- a/src/MapObj/BlockQuestion.cpp +++ b/src/MapObj/BlockQuestion.cpp @@ -46,14 +46,14 @@ void BlockQuestion::init(const al::ActorInitInfo& initInfo) { al::initMapPartsActor(this, initInfo, suffix); mItemType = rs::getItemType(initInfo); - if (mItemType > rs::ItemType::ValueType::None) + if (mItemType > rs::ItemType::None) rs::initItemByPlacementInfo(this, initInfo, false); al::tryAddDisplayOffset(this, initInfo); mShadowLength = rs::setShadowDropLength(this, initInfo, "本体"); al::expandClippingRadiusByShadowLength(this, &_134, mShadowLength); - if (mItemType == rs::ItemType::ValueType::Coin10) { + if (mItemType == rs::ItemType::Coin10) { mBlockStateTenCoin = new BlockStateTenCoin(this, false); al::initNerve(this, &NrvBlockQuestion.TenCoin, 1); al::initNerveState(this, mBlockStateTenCoin, &NrvBlockQuestion.TenCoin, "10コイン"); @@ -61,7 +61,7 @@ void BlockQuestion::init(const al::ActorInitInfo& initInfo) { mBlockStateSingleItem = new BlockStateSingleItem(this, mItemType, false); al::initNerve(this, &NrvBlockQuestion.SingleItem, 1); al::initNerveState(this, mBlockStateSingleItem, &NrvBlockQuestion.SingleItem, "アイテム"); - if (mItemType == rs::ItemType::ValueType::Random) + if (mItemType == rs::ItemType::Random) rs::createRandomItemSelector(this); } @@ -137,7 +137,7 @@ bool BlockQuestion::receiveMsg(const al::SensorMsg* message, al::HitSensor* othe const sead::Vector3f& selfPos = al::getSensorPos(self); if (al::isNerve(this, &NrvBlockQuestion.SingleItem) && mBlockStateSingleItem->isEnableAppearItem()) { - if (mItemType != rs::ItemType::ValueType::None) + if (mItemType != rs::ItemType::None) mBlockStateSingleItem->setItemOffsetY(150.0f); if (rs::isMsgCapAttack(message)) { diff --git a/src/Scene/ProjectItemDirector.h b/src/Scene/ProjectItemDirector.h new file mode 100644 index 0000000000..8c67c32665 --- /dev/null +++ b/src/Scene/ProjectItemDirector.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#include "Library/HostIO/HioNode.h" +#include "Library/Scene/ItemDirectorBase.h" + +namespace al { +struct ActorInitInfo; +class HitSensor; +class LiveActor; +} // namespace al + +class GameDataHolder; + +class ProjectItemDirector : public al::HioNode, public al::ItemDirectorBase { +public: + ProjectItemDirector(); + ProjectItemDirector(const al::ActorInitInfo&); + + al::LiveActor* appearItem(const char*, const sead::Vector3f&, const sead::Quatf&, + const al::HitSensor*) override; + + void tryAppearPlayerDeadCoin(const al::LiveActor*, const sead::Vector3f&); + void acquireItem(const al::LiveActor*, al::HitSensor*, const char*) const override; + void declareItem(const char*, const al::ActorInitInfo&) override; + void endInit() override; + void tryAddDemoCountUpCoin(); + void initPlayerDeadCoin(GameDataHolder*, const al::ActorInitInfo&); + void setCoinTransForDeadPlayer(GameDataHolder*); + void tryHidePlayerDeadCoinForDemo(); + void tryShowPlayerDeadCoinForDemo(); + +private: + char filler[0x60]; +}; + +static_assert(sizeof(ProjectItemDirector) == 0x68); diff --git a/src/Util/ItemUtil.cpp b/src/Util/ItemUtil.cpp index 0654fa896c..a62d9ebfbe 100644 --- a/src/Util/ItemUtil.cpp +++ b/src/Util/ItemUtil.cpp @@ -20,10 +20,13 @@ #include "Library/Scene/SceneObjUtil.h" #include "Library/Stage/StageRhythm.h" +#include "Item/RandomItemSelector.h" #include "Item/Shine.h" +#include "Scene/ProjectItemDirector.h" #include "System/GameDataFunction.h" #include "System/GameDataHolder.h" #include "System/WorldList.h" +#include "Util/PlayerUtil.h" #include "Util/SensorMsgFunction.h" const char* sItem2DNames[] = { @@ -517,8 +520,24 @@ void appearItemFromObjGravity(al::LiveActor* actor, al::HitSensor* sensor, al::appearItem(actor, al::getTrans(actor), quat, nullptr); } -// TODO: Requires RandomItemSelector -// void appearRandomItemFromObj(al::LiveActor* actor, al::HitSensor* sensor, f32 offset) {} +void appearRandomItemFromObj(al::LiveActor* actor, al::HitSensor* sensor, f32 offset) { + sead::Vector3f upDir = {0.0f, 0.0f, 0.0f}; + al::calcUpDir(&upDir, actor); + + al::setAppearItemOffset(actor, upDir * offset); + al::setAppearItemAttackerSensor(actor, sensor); + + switch (al::getSceneObj(actor)->getRandomItemType(actor)) { + case rs::ItemType::Coin: + al::appearItemTiming(actor, "コイン"); + return; + case rs::ItemType::LifeUpItem: + al::appearItemTiming(actor, "ライフアップ"); + return; + default: + return; + } +} bool tryAppearMultiCoinFromObj(al::LiveActor* actor, const sead::Vector3f& trans, s32 step, f32 offsetAbove) { @@ -670,11 +689,21 @@ void setProjectionMtxAsEmptyModel2d(al::LiveActor* actor, const sead::Vector2f& al::setModelProjMtx0(actor->getModelKeeper(), matrix); } -// void addDemoRacePrizeCoin(al::LiveActor* actor); TODO +void addDemoRacePrizeCoin(al::LiveActor* actor) { + ProjectItemDirector* itemDirector = + static_cast(actor->getSceneInfo()->itemDirector); + + itemDirector->tryAddDemoCountUpCoin(); +} } // namespace rs namespace StageSceneFunction { -// void appearPlayerDeadCoin(al::LiveActor* actor); TODO +void appearPlayerDeadCoin(al::LiveActor* actor) { + ProjectItemDirector* itemDirector = + static_cast(actor->getSceneInfo()->itemDirector); + itemDirector->appearItem("コイン[プレイヤー死亡]", rs::getPlayerPos(actor), sead::Quatf::unit, + nullptr); +} } // namespace StageSceneFunction