diff options
| author | Adrián <38050447+oxixes@users.noreply.github.com> | 2026-11-03 03:47:18 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-11-03 02:47:18 +0000 |
| commit | dcad8b499e1397fa145d3348a387b6339c00bb34 (patch) | |
| tree | d7b7b5aba5df46ebdc2f560a836e6cf1b6588855 /src | |
| parent | d7a8694143c2677534ffaffe5ab130764bc76d31 (diff) | |
Match ksys::eco::LevelSensor::scaleActor and scaleWeapon (#222)
Diffstat (limited to 'src')
| -rw-r--r-- | src/KingSystem/Ecosystem/ecoLevelSensor.cpp | 235 | ||||
| -rw-r--r-- | src/KingSystem/Ecosystem/ecoLevelSensor.h | 8 |
2 files changed, 242 insertions, 1 deletions
diff --git a/src/KingSystem/Ecosystem/ecoLevelSensor.cpp b/src/KingSystem/Ecosystem/ecoLevelSensor.cpp index 201efafc..e326f933 100644 --- a/src/KingSystem/Ecosystem/ecoLevelSensor.cpp +++ b/src/KingSystem/Ecosystem/ecoLevelSensor.cpp @@ -1,7 +1,12 @@ #include "KingSystem/Ecosystem/ecoLevelSensor.h" + +#include "KingSystem/ActorSystem/actActor.h" +#include "KingSystem/ActorSystem/actInstParamPack.h" +#include "KingSystem/Ecosystem/ecoSystem.h" #include "KingSystem/GameData/gdtManager.h" #include "KingSystem/Resource/resLoadRequest.h" #include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/World/worldManager.h" namespace ksys::eco { @@ -21,6 +26,236 @@ void LevelSensor::init(sead::Heap* heap) { mRootIter = new (heap) al::ByamlIter(res->getRawData()); } +bool LevelSensor::isScalingAllowed(const sead::Vector3f& position) const { + const auto* world_mgr = world::Manager::instance(); + if (world_mgr->getStageType() == StageType::OpenWorld && + world_mgr->getFieldType() == world::FieldType::AocField && + world_mgr->getScalingMode() == world::ScalingMode::Disabled) { + return false; + } + + return Ecosystem::instance()->getFieldMapArea(position.x, position.z) != 28; +} + +bool LevelSensor::isScalingAllowed(const act::Actor& actor) const { + if (const auto* map_obj = actor.getMapObject()) { + const sead::Vector3f position = map_obj->getTranslate(); + return isScalingAllowed(position); + } + + sead::Vector3f position; + actor.getMtx().getTranslation(position); + return isScalingAllowed(position); +} + +bool LevelSensor::scaleWeapon(const sead::SafeString& weapon, WeaponModifier min_modifier, + const char** scaled_weapon, WeaponModifier* scaled_modifier, + const act::Actor* actor) const { + if (actor && !isScalingAllowed(*actor)) + return false; + + al::ByamlIter weapons_iter; + if (!mRootIter->tryGetIterByKey(&weapons_iter, "weapon")) + return false; + + for (s32 i = 0; i < weapons_iter.getSize(); ++i) { + al::ByamlIter weapon_iter; + if (!weapons_iter.tryGetIterByIndex(&weapon_iter, i)) + return false; + + al::ByamlIter actors_iter; + if (!weapon_iter.tryGetIterByKey(&actors_iter, "actors")) + return false; + + for (s32 j = 0; j < actors_iter.getSize() - 1; ++j) { + al::ByamlIter actor_iter; + if (!actors_iter.tryGetIterByIndex(&actor_iter, j)) + return false; + + const char* actor_name; + if (!actor_iter.tryGetStringByKey(&actor_name, "name")) + return false; + + f32 actor_value; + if (!actor_iter.tryGetFloatByKey(&actor_value, "value")) + return false; + + s32 actor_plus; + if (!actor_iter.tryGetIntByKey(&actor_plus, "plus")) + return false; + + bool modifier_matches = false; + if (min_modifier == WeaponModifier::None) { + if (actor_plus == -1) + modifier_matches = true; + } else if (min_modifier == WeaponModifier::Blue) { + if (actor_plus == 0) + modifier_matches = true; + } else if (min_modifier == WeaponModifier::Yellow) { + if (actor_plus == 1) + modifier_matches = true; + } + + if (modifier_matches && actor_value < mWeaponPoints && weapon == actor_name) { + bool not_rank_up = false; + if (!weapon_iter.tryGetBoolByKey(¬_rank_up, "not_rank_up")) + return false; + + al::ByamlIter next_iter; + f32 next_value = 0.0f; + s32 found_index = -1; + for (s32 k = j + 1; k < actors_iter.getSize(); ++k) { + if (!actors_iter.tryGetIterByIndex(&next_iter, k) || + !next_iter.tryGetFloatByKey(&next_value, "value")) { + return false; + } + + const char* next_name; + bool same_weapon = true; + if (not_rank_up) { + if (!next_iter.tryGetStringByKey(&next_name, "name")) + return false; + + same_weapon = weapon == next_name; + } + + if (same_weapon) { + found_index = k; + if (mWeaponPoints <= next_value) + break; + } + } + + if (found_index < 0) + return false; + + const char* found_name; + const char* series; + const char* actor_type; + s32 found_plus; + if (!actors_iter.tryGetIterByIndex(&next_iter, found_index) || + !next_iter.tryGetStringByKey(&found_name, "name") || + !weapon_iter.tryGetStringByKey(&series, "series") || + !weapon_iter.tryGetStringByKey(&actor_type, "actorType") || + !next_iter.tryGetIntByKey(&found_plus, "plus")) { + return false; + } + + *scaled_weapon = found_name; + switch (found_plus) { + case 0: + *scaled_modifier = WeaponModifier::Blue; + break; + case 1: + *scaled_modifier = WeaponModifier::Yellow; + break; + default: + *scaled_modifier = WeaponModifier::None; + break; + } + return true; + } + } + } + + return false; +} + +bool LevelSensor::scaleActor(const sead::SafeString& name, map::Object* obj, + const char** scaled_weapon, act::InstParamPack* pack, + const sead::Vector3f& position) const { + if (!isScalingAllowed(position)) + return false; + + if (name.startsWith("Enemy")) { + const auto& mubin_iter = obj->getMubinIter(); + s32 mode = 0; + if (mubin_iter.tryGetParamIntByKey(&mode, "LevelSensorMode") && mode >= 1) { + al::ByamlIter enemies_iter; + if (!mRootIter->tryGetIterByKey(&enemies_iter, "enemy")) + return false; + + for (s32 i = 0; i < enemies_iter.getSize(); ++i) { + al::ByamlIter enemy_iter; + if (!enemies_iter.tryGetIterByIndex(&enemy_iter, i)) + return false; + + al::ByamlIter actors_iter; + if (!enemy_iter.tryGetIterByKey(&actors_iter, "actors")) + return false; + + for (s32 j = 0; j < actors_iter.getSize() - 1; ++j) { + al::ByamlIter actor_iter; + if (!actors_iter.tryGetIterByIndex(&actor_iter, j)) + return false; + + const char* actor_name; + if (!actor_iter.tryGetStringByKey(&actor_name, "name")) + return false; + + f32 actor_value; + if (!actor_iter.tryGetFloatByKey(&actor_value, "value")) + return false; + + if (actor_value < mEnemyPoints && name == actor_name) { + al::ByamlIter next_actor_iter; + f32 next_actor_value; + for (s32 k = j + 1; k < actors_iter.getSize(); ++k) { + if (!actors_iter.tryGetIterByIndex(&next_actor_iter, k)) + return false; + + if (!next_actor_iter.tryGetFloatByKey(&next_actor_value, "value")) + return false; + + if (mEnemyPoints <= next_actor_value) + break; + } + + const char* next_actor_name; + if (!next_actor_iter.tryGetStringByKey(&next_actor_name, "name")) + return false; + + const char* enemy_species; + if (!enemy_iter.tryGetStringByKey(&enemy_species, "species")) + return false; + + *scaled_weapon = next_actor_name; + return true; + } + } + } + } + } + + if (name.startsWith("Weapon")) { + const auto& mubin_iter = obj->getMubinIter(); + WeaponModifier scaled_modifier; + s32 mode = 0; + s32 sharp_weapon_judge_type; + if (mubin_iter.tryGetParamIntByKey(&mode, "LevelSensorMode") && mode >= 1) { + sharp_weapon_judge_type = 0; + if (!mubin_iter.tryGetParamIntByKey(&sharp_weapon_judge_type, "SharpWeaponJudgeType")) + return false; + + const char* scaled_weapon_result; + WeaponModifier weapon_modifier = + getRandomWeaponModifier(sharp_weapon_judge_type, obj->getUnitConfigName()); + if (!scaleWeapon(obj->getUnitConfigName(), weapon_modifier, &scaled_weapon_result, + &scaled_modifier, nullptr)) { + return false; + } + + auto val = int(scaled_modifier); + pack->getBuffer().add(val, "SharpWeaponJudgeType"); + + *scaled_weapon = scaled_weapon_result; + return true; + } + } + + return false; +} + void LevelSensor::calculatePoints() { if (mDefaultPoints >= 0) { mPoints = mDefaultPoints; diff --git a/src/KingSystem/Ecosystem/ecoLevelSensor.h b/src/KingSystem/Ecosystem/ecoLevelSensor.h index 6d6d3fbb..54169e81 100644 --- a/src/KingSystem/Ecosystem/ecoLevelSensor.h +++ b/src/KingSystem/Ecosystem/ecoLevelSensor.h @@ -30,6 +30,9 @@ enum class WeaponModifier { NoneForced = 4, }; +// TODO Find out where this goes. It is currently used by ksys::eco::LevelSensor::scaleActor. +WeaponModifier getRandomWeaponModifier(s32 judge_type, const sead::SafeString& unit_config_name); + class LevelSensor { public: LevelSensor(); @@ -39,7 +42,7 @@ public: bool scaleWeapon(const sead::SafeString& weapon, WeaponModifier min_modifier, const char** scaled_weapon, WeaponModifier* scaled_modifier, - act::Actor* actor) const; + const act::Actor* actor) const; bool scaleActor(const sead::SafeString& name, map::Object* obj, const char** scaled_weapon, act::InstParamPack* pack, const sead::Vector3f& position) const; @@ -47,6 +50,9 @@ public: void calculatePoints(); private: + bool isScalingAllowed(const sead::Vector3f& position) const; + bool isScalingAllowed(const act::Actor& actor) const; + f32 mPoints{}; f32 mWeaponPoints{}; f32 mEnemyPoints{}; |
