summaryrefslogtreecommitdiff
path: root/src/KingSystem/Ecosystem/ecoSystem.cpp
diff options
context:
space:
mode:
authortheo3 <arisstephenson2@gmail.com>2020-10-26 01:19:55 -0700
committertheo3 <arisstephenson2@gmail.com>2020-11-24 17:39:53 -0800
commit2c47c801f68c72cdda659772d88d9c164bf1afb1 (patch)
tree37d03b56e866be1ea2c8d5d92c1f7b129a355b82 /src/KingSystem/Ecosystem/ecoSystem.cpp
parent82eb75a4498ff2d237eb9f566ab7b4f91b7ec5ea (diff)
partially implement ecosystem
Diffstat (limited to 'src/KingSystem/Ecosystem/ecoSystem.cpp')
-rw-r--r--src/KingSystem/Ecosystem/ecoSystem.cpp198
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