diff --git a/config/SOUE01/rels/d_t_tumble_weedNP/symbols.txt b/config/SOUE01/rels/d_t_tumble_weedNP/symbols.txt index 383f069b..5dbe3d62 100644 --- a/config/SOUE01/rels/d_t_tumble_weedNP/symbols.txt +++ b/config/SOUE01/rels/d_t_tumble_weedNP/symbols.txt @@ -28,7 +28,7 @@ finalizeState_Wind__15dTgTumbleWeed_cFv = .text:0x000007B0; // type:function siz shouldSpawnTumbleweed__15dTgTumbleWeed_cFv = .text:0x000007C0; // type:function size:0x98 shouldDoWind__15dTgTumbleWeed_cFv = .text:0x00000860; // type:function size:0x54 doSpawnTumbleweed__15dTgTumbleWeed_cFv = .text:0x000008C0; // type:function size:0x288 -getWind__15dTgTumbleWeed_cFP7mVec3_c = .text:0x00000B50; // type:function size:0x114 +getWind__15dTgTumbleWeed_cFR7mVec3_c = .text:0x00000B50; // type:function size:0x114 __dt__15dTgTumbleWeed_cFv = .text:0x00000C70; // type:function size:0xD8 getStateID__84sStateMgr_c<15dTgTumbleWeed_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00000D50; // type:function size:0x10 build__31sFStateFct_c<15dTgTumbleWeed_c>FRC12sStateIDIf_c = .text:0x00000D60; // type:function size:0x60 @@ -45,25 +45,27 @@ getOldStateID__84sStateMgr_c<15dTgTumbleWeed_c,20sStateMethodUsr_FI_c,12sFStateF finalizeState__30sFStateID_c<15dTgTumbleWeed_c>CFR15dTgTumbleWeed_c = .text:0x00000E90; // type:function size:0x30 executeState__30sFStateID_c<15dTgTumbleWeed_c>CFR15dTgTumbleWeed_c = .text:0x00000EC0; // type:function size:0x30 initializeState__30sFStateID_c<15dTgTumbleWeed_c>CFR15dTgTumbleWeed_c = .text:0x00000EF0; // type:function size:0x30 -__sinit_\d_t_tumble_weed_cpp = .text:0x00000F20; // type:function size:0x27C +__sinit_\d_t_tumble_weed_cpp = .text:0x00000F20; // type:function size:0x27C scope:local __dt__30sFStateID_c<15dTgTumbleWeed_c>Fv = .text:0x000011A0; // type:function size:0x58 isSameName__30sFStateID_c<15dTgTumbleWeed_c>CFPCc = .text:0x00001200; // type:function size:0x88 _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global -lbl_476_rodata_0 = .rodata:0x00000000; // type:object size:0x1C data:float -lbl_476_rodata_1C = .rodata:0x0000001C; // type:object size:0x4 align:4 data:float -lbl_476_rodata_20 = .rodata:0x00000020; // type:object size:0x44 align:4 data:float +lbl_476_rodata_0 = .rodata:0x00000000; // type:object size:0x1C scope:local data:float +lbl_476_rodata_1C = .rodata:0x0000001C; // type:object size:0x4 scope:local align:4 data:float +lbl_476_rodata_20 = .rodata:0x00000020; // type:object size:0x44 scope:local align:4 data:float g_profile_TUMBLE_WEED_TAG = .data:0x00000000; // type:object size:0x10 data:4byte __vt__15dTgTumbleWeed_c = .data:0x00000010; // type:object size:0x74 __vt__54sFStateMgr_c<15dTgTumbleWeed_c,20sStateMethodUsr_FI_c> = .data:0x00000088; // type:object size:0x30 __vt__84sStateMgr_c<15dTgTumbleWeed_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x000000B8; // type:object size:0x30 __vt__31sFStateFct_c<15dTgTumbleWeed_c> = .data:0x000000E8; // type:object size:0x14 __vt__28sFState_c<15dTgTumbleWeed_c> = .data:0x00000100; // type:object size:0x18 -lbl_476_data_118 = .data:0x00000118; // type:object size:0x148 +lbl_476_data_118 = .data:0x00000118; // type:object size:0x148 scope:local __vt__30sFStateID_c<15dTgTumbleWeed_c> = .data:0x00000260; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global -lbl_476_bss_8 = .bss:0x00000008; // type:object size:0x10 data:4byte +lbl_476_bss_8 = .bss:0x00000008; // type:object size:0xC scope:local data:4byte StateID_AreaOut__15dTgTumbleWeed_c = .bss:0x00000018; // type:object size:0x30 data:4byte -TgTumbleWeed__StateID_AreaIn = .bss:0x00000058; // type:object size:0x30 data:4byte -TgTumbleWeed__StateID_Wind = .bss:0x00000098; // type:object size:0x30 data:4byte +lbl_476_bss_48 = .bss:0x00000048; // type:object size:0xC scope:local data:4byte +StateID_AreaIn__15dTgTumbleWeed_c = .bss:0x00000058; // type:object size:0x30 data:4byte +lbl_476_bss_88 = .bss:0x00000088; // type:object size:0xC scope:local data:4byte +StateID_Wind__15dTgTumbleWeed_c = .bss:0x00000098; // type:object size:0x30 data:4byte diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 8ae50f71..a4bfd30e 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -10720,7 +10720,7 @@ fn_8019E120 = .text:0x8019E120; // type:function size:0xC4 fn_8019E1F0 = .text:0x8019E1F0; // type:function size:0x10 fn_8019E200 = .text:0x8019E200; // type:function size:0x18C fn_8019E390 = .text:0x8019E390; // type:function size:0xC -getCameraYRot = .text:0x8019E3A0; // type:function size:0x8 +getYRot__9dCamera_cCFv = .text:0x8019E3A0; // type:function size:0x8 fn_8019E3B0__9dCamera_cCFv = .text:0x8019E3B0; // type:function size:0xC fn_8019E3C0 = .text:0x8019E3C0; // type:function size:0x44 fn_8019E410__9dCamera_cFv = .text:0x8019E410; // type:function size:0x1C diff --git a/include/d/d_camera.h b/include/d/d_camera.h index ef2cf73d..2bbdf40b 100644 --- a/include/d/d_camera.h +++ b/include/d/d_camera.h @@ -3,6 +3,7 @@ #include "common.h" #include "d/d_base.h" +#include "m/m_angle.h" #include "m/m_vec.h" extern "C" bool fn_80081FE0(void *, const char *); @@ -28,6 +29,7 @@ public: const mVec3_c &getField_0x78() const { return field_0x78; } + mAng getYRot() const; bool doFn_800918E0(s32 a1, s16 a2) { return fn_800918E0(field_0xDA0, a1, a2); diff --git a/include/d/t/d_t_tumble_weed.h b/include/d/t/d_t_tumble_weed.h index 9dc5f39e..85fb4193 100644 --- a/include/d/t/d_t_tumble_weed.h +++ b/include/d/t/d_t_tumble_weed.h @@ -1,13 +1,13 @@ #ifndef D_T_TUMBLE_WEED_H #define D_T_TUMBLE_WEED_H -#include "d/a/obj/d_a_obj_tumble_weed.h" #include "d/t/d_tg.h" #include "s/s_State.hpp" +class dAcOTumbleWeed_c; class dTgTumbleWeed_c : public dTg_c { public: - dTgTumbleWeed_c() : mStateMgr(*this, sStateID::null), childTumbleweed(nullptr) {} + dTgTumbleWeed_c() : mStateMgr(*this, sStateID::null) {} virtual ~dTgTumbleWeed_c() {} virtual int create() override; virtual int actorExecute() override; @@ -22,13 +22,13 @@ private: bool shouldSpawnTumbleweed(); bool shouldDoWind(); void doSpawnTumbleweed(); - void getWind(mVec3_c *); + void getWind(mVec3_c &); STATE_MGR_DECLARE(dTgTumbleWeed_c); - u16 tumbleweedTimer; + u16 mSpawnTimer; u16 padding; - u16 windTimer; - dAcRef_c childTumbleweed; + u16 mWindTimer; + dAcRef_c mSpawnedTumbleWeed; u16 someField; }; diff --git a/src/REL/d/t/d_t_tumble_weed.cpp b/src/REL/d/t/d_t_tumble_weed.cpp index f11c2e1c..48525354 100644 --- a/src/REL/d/t/d_t_tumble_weed.cpp +++ b/src/REL/d/t/d_t_tumble_weed.cpp @@ -1,7 +1,14 @@ #include "d/t/d_t_tumble_weed.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/obj/d_a_obj_tumble_weed.h" +#include "d/col/bg/d_bg_s_gnd_chk.h" +#include "d/d_sc_game.h" +#include "f/f_profile_name.h" #include "m/m_vec.h" #include "s/s_Math.h" +#include "toBeSorted/event_manager.h" SPECIAL_ACTOR_PROFILE(TUMBLE_WEED_TAG, dTgTumbleWeed_c, fProfile::TUMBLE_WEED_TAG, 0x0244, 0, 0); @@ -9,9 +16,13 @@ STATE_DEFINE(dTgTumbleWeed_c, AreaOut); STATE_DEFINE(dTgTumbleWeed_c, AreaIn); STATE_DEFINE(dTgTumbleWeed_c, Wind); +void rodata_floats() { + const f32 arr[] = {0.f, 0.8f, 20.f, 20.f, 5.f, 0.5f, 7.f}; +} + int dTgTumbleWeed_c::create() { - tumbleweedTimer = 0; - windTimer = 0x96; + mSpawnTimer = 0; + mWindTimer = 150; mStateMgr.changeState(StateID_AreaOut); return SUCCEEDED; } @@ -22,7 +33,7 @@ int dTgTumbleWeed_c::doDelete() { int dTgTumbleWeed_c::actorExecute() { mStateMgr.executeState(); - sLib::calcTimer(&tumbleweedTimer); + sLib::calcTimer(&mSpawnTimer); return SUCCEEDED; } @@ -32,8 +43,8 @@ int dTgTumbleWeed_c::draw() { void dTgTumbleWeed_c::initializeState_AreaOut() {} void dTgTumbleWeed_c::executeState_AreaOut() { - if (sLib::calcTimer(&windTimer) == 0) { - windTimer = 0x96; + if (sLib::calcTimer(&mWindTimer) == 0) { + mWindTimer = 150; if (shouldDoWind()) { mStateMgr.changeState(StateID_Wind); return; @@ -47,14 +58,14 @@ void dTgTumbleWeed_c::finalizeState_AreaOut() {} void dTgTumbleWeed_c::initializeState_AreaIn() {} void dTgTumbleWeed_c::executeState_AreaIn() { - if (tumbleweedTimer == 0) { + if (mSpawnTimer == 0) { if (shouldSpawnTumbleweed()) { doSpawnTumbleweed(); } - tumbleweedTimer = 600; + mSpawnTimer = 600; } - if (sLib::calcTimer(&windTimer) == 0) { - windTimer = 0x96; + if (sLib::calcTimer(&mWindTimer) == 0) { + mWindTimer = 150; if (shouldDoWind()) { mStateMgr.changeState(StateID_Wind); return; @@ -68,9 +79,9 @@ void dTgTumbleWeed_c::finalizeState_AreaIn() {} void dTgTumbleWeed_c::initializeState_Wind() { mVec3_c vec; - getWind(&vec); - if (childTumbleweed.get() != nullptr) { - childTumbleweed.get()->setWind(vec); + getWind(vec); + if (mSpawnedTumbleWeed.isLinked()) { + mSpawnedTumbleWeed.get()->setWind(vec); } } @@ -84,20 +95,82 @@ void dTgTumbleWeed_c::executeState_Wind() { void dTgTumbleWeed_c::finalizeState_Wind() {} bool dTgTumbleWeed_c::shouldSpawnTumbleweed() { - bool spawnAllowed = false; - if (childTumbleweed.get() == nullptr && cM::rnd() <= 0.8f) { - spawnAllowed = true; - } - - if (spawnAllowed) { - return true; - } - - return false; + return !mSpawnedTumbleWeed.isLinked() && cM::rnd() <= 0.8f && !EventManager::isInEvent(); } bool dTgTumbleWeed_c::shouldDoWind() { - return childTumbleweed.get() != nullptr && cM::rnd() <= 0.5f; + return mSpawnedTumbleWeed.isLinked() && cM::rnd() <= 0.5f; +} + +void dTgTumbleWeed_c::doSpawnTumbleweed() { + mVec3_c pos = mVec3_c::Ez; + + dCamera_c *pCam = dScGame_c::getCamera(0); + if (pCam != nullptr) { + mAng angle = pCam->getYRot(); + + f32 change; + if (cM::rnd() < 0.5f) { + change = cM::rndFX(5.f) * 182.f + 10923.f; + } else { + change = cM::rndFX(5.f) * 182.f + -10923.f; + } + angle += change; + pos.rotY(angle); + + pos *= 600.f; + pos += pCam->getPositionMaybe(); + + if (dBgS_ObjGndChk::CheckPos(pos + mVec3_c::Ey * 100.f)) { + pos.y = dBgS_ObjGndChk::GetGroundHeight() + 10.f; + } + } + + dAcOTumbleWeed_c *pTumble = static_cast( + dAcObjBase_c::create(fProfile::OBJ_TUMBLE_WEED, mRoomID, 0, &pos, nullptr, nullptr, 0xFFFFFFFF) + ); + if (pTumble == nullptr) { + return; + } + + mSpawnedTumbleWeed.link(pTumble); + if (pCam != nullptr) { + mAng rot = mAng::fromVec(mPosition - pos); + + f32 change; + if (cM::rnd() < 0.5f) { + change = cM::rndFX(5.f) * 182.f; + } else { + change = cM::rndFX(5.f) * -182.f; + } + rot += change; + + pTumble->mAngle.y = rot; + pTumble->mSpeed = cM::rndFX(1.f) + 20.f; + pTumble->mVelocity.y = 0.f; + } +} + +void dTgTumbleWeed_c::getWind(mVec3_c &pWind) { + mVec3_c wind = mVec3_c::Ez; + + // @bug dir may not be initialized + mAng dir; + + if (mSpawnedTumbleWeed.isLinked()) { + dir = mSpawnedTumbleWeed.get()->getAngle().y; + } + + f32 change; + if (cM::rnd() < 0.5f) { + change = cM::rndFX(15.f) * 182.f + 8192.f; + } else { + change = cM::rndFX(15.f) * 182.f + -8192.f; + } + + dir += change; + wind.rotY(dir); + wind *= cM::rndFX(3.f) + 7.f; + + pWind = wind; } -void dTgTumbleWeed_c::doSpawnTumbleweed() {} -void dTgTumbleWeed_c::getWind(mVec3_c *) {}