summaryrefslogtreecommitdiff
path: root/src/KingSystem/Ecosystem/ecoLevelSensor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/KingSystem/Ecosystem/ecoLevelSensor.cpp')
-rw-r--r--src/KingSystem/Ecosystem/ecoLevelSensor.cpp235
1 files changed, 235 insertions, 0 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(&not_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;