diff options
| author | robojumper <robojumper@gmail.com> | 2024-09-12 22:23:11 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-12 16:23:11 -0400 |
| commit | e2c4bb7be7fa731a335bce4bc22283d899133e39 (patch) | |
| tree | 91152d84cae384b376f4ce4c87e9e247255ec954 /src/toBeSorted | |
| parent | 9aa30ee4995be938e1ea05f6d476d63fcb8cc67e (diff) | |
Dowsing (#17)
* Dowsing.
* d_t_dowsing
* d_t_holy_water OK
Diffstat (limited to 'src/toBeSorted')
| -rw-r--r-- | src/toBeSorted/counters/counter.cpp | 29 | ||||
| -rw-r--r-- | src/toBeSorted/counters/rupee_counter.cpp | 7 | ||||
| -rw-r--r-- | src/toBeSorted/dowsing_target.cpp | 272 | ||||
| -rw-r--r-- | src/toBeSorted/sound_info.cpp | 13 |
4 files changed, 291 insertions, 30 deletions
diff --git a/src/toBeSorted/counters/counter.cpp b/src/toBeSorted/counters/counter.cpp index 2c388e44..42729f33 100644 --- a/src/toBeSorted/counters/counter.cpp +++ b/src/toBeSorted/counters/counter.cpp @@ -1,26 +1,5 @@ #include <toBeSorted/counters/counter.h> - -// TODO use the item flag manager once it exists -class ItemFlagManager { -public: - ItemFlagManager() {} - /** 0x08 */ virtual ~ItemFlagManager(); - /** 0x0C */ virtual void setFlagszptr(); - /** 0x10 */ virtual void onDirty(); - /** 0x14 */ virtual void copyFlagsFromSave() = 0; - /** 0x18 */ virtual void setupUnkFlagsStuff() = 0; - /** 0x1C */ virtual bool doCommit() = 0; - /** 0x20 */ virtual void setFlag(u16 flag); - /** 0x24 */ virtual void unsetFlag(u16 flag); - /** 0x28 */ virtual void setFlagOrCounterToValue(u16 flag, u16 value); - /** 0x2C */ virtual u16 getCounterOrFlag(u16 flag); - /** 0x30 */ virtual u16 getUncommittedValue(u16 flag); - /** 0x34 */ virtual void unk3(); - /** 0x38 */ virtual u16 *getSaveFlagSpace() = 0; -}; - -// TODO set up item flag manager -extern "C" ItemFlagManager *lbl_80575400; +#include <toBeSorted/item_story_flag_manager.h> /* 8016cc40 */ s32 Counter::checkedAdd(s32 num) { @@ -43,13 +22,13 @@ extern "C" ItemFlagManager *lbl_80575400; } /* 8016cd30 */ u16 Counter::getCommittedValue() { - return lbl_80575400->getCounterOrFlag(counterId | 0x4000); + return ItemFlagManager::sInstance->getCounterOrFlag(counterId | 0x4000); } /* 8016cd50 */ u16 Counter::getUncommittedValue() { - return lbl_80575400->getUncommittedValue(counterId | 0x4000); + return ItemFlagManager::sInstance->getUncommittedValue(counterId | 0x4000); } /* 8016cd70 */ void Counter::setValue(u16 num) { - lbl_80575400->setFlagOrCounterToValue(counterId | 0x4000, num); + ItemFlagManager::sInstance->setFlagOrCounterToValue(counterId | 0x4000, num); } diff --git a/src/toBeSorted/counters/rupee_counter.cpp b/src/toBeSorted/counters/rupee_counter.cpp index d1264a74..02f3cd0f 100644 --- a/src/toBeSorted/counters/rupee_counter.cpp +++ b/src/toBeSorted/counters/rupee_counter.cpp @@ -1,4 +1,5 @@ #include <toBeSorted/counters/counter.h> +#include <toBeSorted/item_story_flag_manager.h> static u16 getBaseCapacity(); static u16 getExtraWalletCapacity(); @@ -17,10 +18,6 @@ struct WalletStruct { u16 capacity; }; -// TODO set up item flag manager -extern "C" void *lbl_80575400; -extern "C" u16 fn_800BF5E0(void *data, u16 flag); - /* 8016DE10 */ static u16 getBaseCapacity() { int i = 0; /* 804E91B0 */ WalletStruct wallet_definitions[4] = { @@ -31,7 +28,7 @@ extern "C" u16 fn_800BF5E0(void *data, u16 flag); }; const WalletStruct *wallet = &wallet_definitions[3]; for (; i < 4; i++, wallet--) { - if (fn_800BF5E0(lbl_80575400, wallet->flag)) { + if (ItemFlagManager::sInstance->getFlag(wallet->flag)) { return wallet->capacity; } } diff --git a/src/toBeSorted/dowsing_target.cpp b/src/toBeSorted/dowsing_target.cpp new file mode 100644 index 00000000..84eea947 --- /dev/null +++ b/src/toBeSorted/dowsing_target.cpp @@ -0,0 +1,272 @@ +#include <c/c_math.h> +#include <m/m_mtx.h> +#include <nw4r/ut/ut_LinkList.h> +#include <toBeSorted/dowsing_target.h> +#include <toBeSorted/item_story_flag_manager.h> +#include <toBeSorted/tlist.h> + +typedef TList<DowsingTarget, 0> DowsingList; + +DowsingList DOWSING_LISTS[8]; + +static const int DOWSING_TARGET_STORY_FLAGS[8] = { + 100, + 105, + 100, + 104, + 108, + 110, + 109, + 102, +}; + +DowsingTarget::~DowsingTarget() { + doUnregister(); +} + +void DowsingTarget::initialize(DowsingSlot type, u16 unk, const mVec3_c *offset, f32 unk2) { + reinitialize(type); + field_0x0E = unk; + if (offset != nullptr) { + mOffset = *offset; + } +} + +static bool insertDowsingTarget(DowsingTarget *target); +static bool removeDowsingTarget(DowsingTarget *target); + +bool DowsingTarget::doRegister() { + return insertDowsingTarget(this); +} + +bool DowsingTarget::doUnregister() { + return removeDowsingTarget(this); +} + +void DowsingTarget::reinitialize(DowsingSlot type) { + bool res = doUnregister(); + mDowsingSlot = type; + if (res) { + doRegister(); + } +} + +void DowsingTarget::getPosition(mVec3_c &position) { + mMtx_c mtx; + mMtx_c mtx2; + PSMTXTrans(mtx.m, mpActor->position.x, mpActor->position.y, mpActor->position.z); + mtx.YrotM(mpActor->rotation.y); + PSMTXScale(mtx2.m, mpActor->scale.x, mpActor->scale.y, mpActor->scale.z); + PSMTXConcat(mtx.m, mtx2.m, mtx.m); + PSMTXMultVec(mtx.m, mOffset, position); +} + +bool DowsingTarget::hasZeldaDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(100); +} + +bool DowsingTarget::hasKikwiDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(56) && !StoryFlagManager::sInstance->getCounterOrFlag(57); +} + +bool DowsingTarget::hasKeyPieceDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(106) && !StoryFlagManager::sInstance->getCounterOrFlag(120); +} + +bool DowsingTarget::hasDesertNodeDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(107) && !StoryFlagManager::sInstance->getCounterOrFlag(8); +} + +bool DowsingTarget::hasAnyTrialDowsing() { + // TODO more complicated code + return ItemFlagManager::sInstance->getFlag(187) && !StoryFlagManager::sInstance->getCounterOrFlag(93) || + ItemFlagManager::sInstance->getFlag(188) && !StoryFlagManager::sInstance->getCounterOrFlag(97) || + ItemFlagManager::sInstance->getFlag(189) && !StoryFlagManager::sInstance->getCounterOrFlag(98) || + ItemFlagManager::sInstance->getFlag(193) && !StoryFlagManager::sInstance->getCounterOrFlag(99); +} + +bool DowsingTarget::hasSacredWaterDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(64) && !StoryFlagManager::sInstance->getCounterOrFlag(65); +} + +bool DowsingTarget::hasSandshipDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(271) && !StoryFlagManager::sInstance->getCounterOrFlag(14); +} + +bool DowsingTarget::hasTadtoneDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(81) && !StoryFlagManager::sInstance->getCounterOrFlag(18); +} + +bool DowsingTarget::hasPropellerDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(668); +} + +bool DowsingTarget::hasWaterBasinDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(669); +} + +bool DowsingTarget::hasCrystalBallDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(670); +} + +bool DowsingTarget::hasPumpkinDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(680); +} + +bool DowsingTarget::hasNewPlantSpeciesDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(681); +} + +bool DowsingTarget::hasPartyWheelDowsing() { + return StoryFlagManager::sInstance->getCounterOrFlag(682); +} + +bool DowsingTarget::hasDowsingInSlot(int slot) { + if (slot >= 8) { + return false; + } + + if (slot == 6) { + return true; + } + + if (slot == 0) { + return hasZeldaDowsing() || hasAnyTrialDowsing() || hasSacredWaterDowsing() || hasSandshipDowsing() || + hasTadtoneDowsing() || hasPropellerDowsing() || hasWaterBasinDowsing(); + } else if (slot == 2) { + return hasCrystalBallDowsing() || hasPumpkinDowsing() || hasNewPlantSpeciesDowsing() || hasKikwiDowsing() || + hasKeyPieceDowsing() || hasDesertNodeDowsing() || hasPartyWheelDowsing(); + } else if (StoryFlagManager::sInstance->getCounterOrFlag(DOWSING_TARGET_STORY_FLAGS[slot])) { + // TODO small instruction shuffle + return true; + } + + return false; +} + +#define MYCLAMP(low, high, x) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x))) + +DowsingTarget *DowsingTarget::getDowsingInfo(const mVec3_c &playerPosition, const mVec3_c &dowsingDirection, f32 *p3, + f32 *p4, f32 *intensity, int slot) { + if (slot >= 8) { + return nullptr; + } + mVec3_c dwsDir = dowsingDirection; + dwsDir.normalize(); + DowsingList *list = &DOWSING_LISTS[slot]; + DowsingTarget *best = nullptr; + + for (DowsingList::Iterator node = list->GetBeginIter(); node != list->GetEndIter(); ++node) { + mVec3_c targetPos; + node->getPosition(targetPos); + mVec3_c targetDir = mVec3_c(targetPos - playerPosition); + f32 proximity = nw4r::ut::Max(10000.0f - targetDir.mag(), 0.0f); + + targetDir.normalize(); + + f32 dot = dwsDir.dot(targetDir); + dot = MYCLAMP(-1.0f, 1.0f, dot); + f32 a = 1.0f - dot * dot <= 0.0f ? 0.0f : nw4r::math::FrSqrt(1.0f - dot * dot) * (1.0f - dot * dot); + + f32 f9 = (5461 - labs(cM::atan2s(a, dot))) * (1.0f / 5461.0f); + if (!(f9 < 0.0f)) { + f32 val; + f32 f10 = MYCLAMP(0.0f, 0.9f, proximity * 0.0001f) * 1.1111112f; + if (f9 > 0.85f) { + f9 = 0.85f; + } + + f9 = f9 * 1.1764705f; + f9 *= f9; + if (f9 > 1.0f) { + f9 = 1.0f; + } + + val = f9 * f10; + if (val > *intensity) { + *intensity = val; + *p3 = f10; + *p4 = f9; + best = &*node; + } + } + } + return best; +} + +void DowsingTarget::init() {} + +void DowsingTarget::execute() {} + +// Not sure what this is +inline static TListNode *getNode(u8 slot, DowsingTarget *t) { + if (t->mLink.mpNext == nullptr || t->mLink.mpPrev == nullptr) { + return &DOWSING_LISTS[slot].mNode; + } else { + return &t->mLink; + } +} + +static bool insertDowsingTarget(DowsingTarget *target) { + u8 slot = target->getSlot(); + if (slot == DowsingTarget::SLOT_NONE) { + return false; + } + + if (getNode(slot, target) != &DOWSING_LISTS[slot].mNode) { + return false; + } + DOWSING_LISTS[slot].insert(target); + return true; +} + +static bool removeDowsingTarget(DowsingTarget *target) { + u8 slot = target->getSlot(); + if (slot == DowsingTarget::SLOT_NONE) { + return false; + } + + if (getNode(slot, target) != &DOWSING_LISTS[slot].mNode) { + DOWSING_LISTS[slot].remove(target); + return true; + } + return false; +} + +u8 DowsingTarget::getTopDowsingIcon() { + if (hasZeldaDowsing()) { + return 19; + } else if (hasAnyTrialDowsing()) { + return 20; + } else if (hasSacredWaterDowsing()) { + return 5; + } else if (hasSandshipDowsing()) { + return 18; + } else if (hasTadtoneDowsing()) { + return 17; + } else if (hasPropellerDowsing()) { + return 10; + } else if (hasWaterBasinDowsing()) { + return 14; + } + return 19; +} + +u8 DowsingTarget::getLeftDowsingIcon() { + if (hasCrystalBallDowsing()) { + return 15; + } else if (hasPumpkinDowsing()) { + return 12; + } else if (hasNewPlantSpeciesDowsing()) { + return 21; + } else if (hasPartyWheelDowsing()) { + return 13; + } else if (hasKikwiDowsing()) { + return 8; + } else if (hasKeyPieceDowsing()) { + return 11; + } else if (hasDesertNodeDowsing()) { + return 7; + } + return 15; +} diff --git a/src/toBeSorted/sound_info.cpp b/src/toBeSorted/sound_info.cpp new file mode 100644 index 00000000..0009e3c7 --- /dev/null +++ b/src/toBeSorted/sound_info.cpp @@ -0,0 +1,13 @@ +#include <d/a/d_a_base.h> + +extern "C" SoundSource *soundForActorInitRelated_803889c0(int, fBase_c *, char *, u8); + +extern "C" bool fn_8002C250(SoundInfo *p1, int someNum, char *name, mVec3_c *position) { + p1->sound_source = soundForActorInitRelated_803889c0(someNum, p1->actor, name, 0); + if (!p1->sound_source) { + return false; + } + p1->actor->sound_list.insert(p1); + p1->obj_pos = position; + return true; +} |
