diff options
| author | theo3 <arisstephenson2@gmail.com> | 2020-10-26 01:19:55 -0700 |
|---|---|---|
| committer | theo3 <arisstephenson2@gmail.com> | 2020-11-24 17:39:53 -0800 |
| commit | 2c47c801f68c72cdda659772d88d9c164bf1afb1 (patch) | |
| tree | 37d03b56e866be1ea2c8d5d92c1f7b129a355b82 /src/KingSystem/Ecosystem/ecoSystem.cpp | |
| parent | 82eb75a4498ff2d237eb9f566ab7b4f91b7ec5ea (diff) | |
partially implement ecosystem
Diffstat (limited to 'src/KingSystem/Ecosystem/ecoSystem.cpp')
| -rw-r--r-- | src/KingSystem/Ecosystem/ecoSystem.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/KingSystem/Ecosystem/ecoSystem.cpp b/src/KingSystem/Ecosystem/ecoSystem.cpp new file mode 100644 index 00000000..96680112 --- /dev/null +++ b/src/KingSystem/Ecosystem/ecoSystem.cpp @@ -0,0 +1,198 @@ +#include "KingSystem/Ecosystem/ecoSystem.h" + +namespace ksys::eco { + +static const char* sStatusEffectNames[22] = {"StatusEffect", + "LifeRecover", + "LifeMaxUp", + "GutsPerformance", + "ResistHot", + "ResistCold", + "ResistElectric", + "MovingSpeed", + "SwimingSpeed", + "SwimingAnimRate", + "ClimbingSpeed", + "AttackUp", + "DefenseUp", + "Quietness", + "DesertMovingSpeed", + "ThrowingPower", + "SnowMovingSpeed", + "GutsRecoverSpeed", + "ResistThunder", + "ArmorChargeAttackAddLevel", + "ReduceAncientEnemyDamge", + "MaterSwordAttackUp"}; + +SEAD_SINGLETON_DISPOSER_IMPL(Ecosystem) + +void Ecosystem::calc() {} + +// NON_MATCHING: FP instructions rearranged. +s32 Ecosystem::getCurrentAreaNum(EcoMapInfo* info, f32 posX, f32 posZ) const { + posX = sead::clamp(posX, -5000.0F, 4999.0F); + posZ = sead::clamp(posZ, -4000.0F, 4000.0F); + f32 epsilon1 = (posX + 5000.0F >= 0.0F) ? 0.5F : -0.5F; + f32 epsilon2 = (posZ + 4000.0F >= 0.0F) ? 0.5F : -0.5F; + s32 x = posX + 5000.0F + epsilon1; + s32 z = (posZ + 4000.0F + epsilon2) / info->mHeader->divisor; + + s32 row = sead::clamp(z, (s32)0, info->mHeader->num_rows - 2); + + if (info->mHeader->divisor == 10) + x = x / 10; + + s32* offsets = (s32*)info->mRowOffsets + row; + s32 val0 = offsets[0]; + s32 val1 = offsets[1]; + + if (val0 >= val1) + return -1; + + Segment* segmentEnd = reinterpret_cast<Segment*>((char*)info->mRows + 2 * val1); + Segment* segment = reinterpret_cast<Segment*>((char*)info->mRows + 2 * val0); + s32 totalLength = 0; + while (true) { + totalLength += segment->length; + if (x < totalLength) + return segment->value; + ++segment; + if (segment >= segmentEnd) + return -1; + } +} + +void Ecosystem::getAreaNameByNum(s32 areaNum, const char** out) const { + *out = nullptr; + + if (areaNum < 0 || (s32)mAreaDataSize <= areaNum) + return; + + al::ByamlIter iter; + + if (mAreaDataIter->tryGetIterByIndex(&iter, areaNum)) + iter.tryGetStringByKey(out, "Area"); +} + +// NON_MATCHING: Equivalent, minor conditional differences and register usage +void Ecosystem::getStatusEffectInfo(StatusEffect statusEffectIdx, s32 idx, + eco::StatusEffectInfo* out) const { + al::ByamlIter listIter; + if (!mStatusEffectListIter->tryGetIterByIndex(&listIter, 0)) + return; + + al::ByamlIter iter; + if (!listIter.tryGetIterByKey(&iter, sStatusEffectNames[statusEffectIdx])) { + out->ng = true; + out->val._s32 = 0; + return; + } + + bool special = false; + al::ByamlIter result; + if (iter.tryGetIterByIndex(&result, 0)) { + result.tryGetBoolByKey(&special, "special"); + if (special) { + out->ng = true; + out->val._s32 = 0; + return; + } + } + + al::ByamlIter result2; + if (!iter.tryGetIterByIndex(&result2, 1)) + return; + + al::ByamlIter a1; + result2.tryGetIterByIndex(&a1, 0); + s32 numLevels = a1.getSize(); + if (numLevels > 0) { + if (idx > numLevels - 1) { + idx = numLevels - 1; + } + } else { + out->ng = true; + out->val._s32 = 0; + return; + } + + al::ByamlIter dict; + if (!a1.tryGetIterByIndex(&dict, idx)) + return; + + f32 val = 0; + s32 val2 = 0; + + if (dict.tryGetFloatByKey(&val, "val")) { + out->ng = false; + out->val._f32 = val; + return; + } + + if (dict.tryGetIntByKey(&val2, "val")) { + out->ng = false; + out->val._f32 = val2; + } +} + +void Ecosystem::getClimateNameByNum(s32 areaNum, const char** out) const { + *out = nullptr; + + if (areaNum < 0 || (s32)mAreaDataSize <= areaNum) + return; + + al::ByamlIter iter; + + if (mAreaDataIter->tryGetIterByIndex(&iter, areaNum)) + iter.tryGetStringByKey(out, "Climate"); +} + +void Ecosystem::getEnvSoundNameByNum(s32 areaNum, const char** out) const { + *out = nullptr; + + if (areaNum < 0 || (s32)mAreaDataSize <= areaNum) + return; + + al::ByamlIter iter; + + if (mAreaDataIter->tryGetIterByIndex(&iter, areaNum)) + iter.tryGetStringByKey(out, "EnvSound"); +} + +void Ecosystem::getEcoTraitsByNum(s32 areaNum, EcosystemTraits* out) const { + out->idx = 0; + + if (areaNum < 0 || (s32)mAreaDataSize <= areaNum) + return; + + al::ByamlIter areaIter; + if (!mAreaDataIter->tryGetIterByIndex(&areaIter, areaNum)) + return; + + al::ByamlIter iter; + if (!areaIter.tryGetIterByKey(&iter, "Procedural")) + return; + + s32 size = iter.getSize(); + if (size < 0) + return; + + for (s32 i = 0; i != size; ++i) { + if (++out->idx > 3) + out->idx = 0; + + EcoTraitGrp* grp = &out->grps[i]; + grp->terrain_material._int = -1; + grp->vegetation._int = -1; + grp->geology._int = -1; + grp->defoliation._int = -1; + + iter.tryGetIntByKey(&grp->terrain_material._int, "terrain_material"); + iter.tryGetIntByKey(&grp->vegetation._int, "vegetation"); + iter.tryGetIntByKey(&grp->geology._int, "geology"); + iter.tryGetIntByKey(&grp->defoliation._int, "defoliation"); + } +} + +} // namespace ksys::eco |
