From 8bc649ce72cbc1542f02b523fb99d5e1ea22ecad Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Sun, 28 Apr 2024 00:10:36 -0300 Subject: [PATCH 1/2] New Command 2054 - Get ID By Name Through it you can store the ID of a database asset through by searching for its name. Syntax (Maniacs): ```js @raw 2054, "", // name to search 0, 11, // type of database Asset 0, 5, // variable where it will be stored 0, 0, // Min Range 0, 0, // maxRange 1, 1 // use stringVar `` New Command 2054 - Get ID By Name Through it you can store the ID of a database asset through by searching for its name. Syntax (Maniacs): ```js @raw 2054, "", // name to search 0, 11, // type of database Asset 0, 5, // variable where it will be stored 0, 0, // Min Range 0, 0, // maxRange 1, 1 // use stringVar `` --- src/game_interpreter.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ src/game_interpreter.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 6ba3086518..63905aa198 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -68,6 +68,7 @@ #include "baseui.h" #include "algo.h" #include "rand.h" +#include enum BranchSubcommand { eOptionBranchElse = 1 @@ -826,6 +827,8 @@ bool Game_Interpreter::ExecuteCommand(lcf::rpg::EventCommand const& com) { return CommandManiacControlStrings(com); case Cmd::Maniac_CallCommand: return CommandManiacCallCommand(com); + case static_cast (2054) : // Easyrpg_GetIdByName + return CommandGetIdByName(com); default: return true; } @@ -5107,6 +5110,49 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& co return true; } +bool Game_Interpreter::CommandGetVarByName(lcf::rpg::EventCommand const& com) { + auto& targetData = lcf::Data::variables; + + int stringVarParam = 6; // string var is detected at com.parameters[n] + const std::string targetName = ToString(CommandStringOrVariable(com, stringVarParam, stringVarParam + 1)); + if (targetName.empty()) { + Output::Warning("The variable name to search is empty."); + return true; + } + + const int outputVar = ValueOrVariable(com.parameters[0], com.parameters[1]); + if (outputVar <= 0) { + Output::Warning("This command requires a valid variable."); + return true; + } + + int rangeMin = ValueOrVariable(com.parameters[2], com.parameters[3]); + int rangeMax = ValueOrVariable(com.parameters[4], com.parameters[5]); + + if (rangeMin <= 0) rangeMin = 1; + if (rangeMin > static_cast(targetData.size())) rangeMin = static_cast(targetData.size()); + if (rangeMax <= 0 || rangeMax >= static_cast(targetData.size())) rangeMax = static_cast(targetData.size()); + + if (rangeMax < rangeMin) std::swap(rangeMin, rangeMax); + + auto it = std::find_if(targetData.begin() + rangeMin - 1, targetData.begin() + rangeMax, + [&](const auto& entry) { return entry.name == targetName; }); + + if (it != targetData.end()) { + const int id = std::distance(targetData.begin(), it) + 1; + + if (id >= rangeMin && id <= rangeMax) { + Output::Debug(" Variable \"{}\" found at ID: {}. Storing ID in variable {}.", targetName, id, outputVar); + + Main_Data::game_variables->Set(outputVar, id); + Game_Map::SetNeedRefresh(true); + return true; + } + } + + Output::Warning("Variable \"{}\" not found within the range of variables {} to {}.", targetName, rangeMin, rangeMax); + return true; +} Game_Interpreter& Game_Interpreter::GetForegroundInterpreter() { return Game_Battle::IsBattleRunning() diff --git a/src/game_interpreter.h b/src/game_interpreter.h index f349b39188..29b340d2b5 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -290,6 +290,8 @@ class Game_Interpreter bool CommandManiacControlStrings(lcf::rpg::EventCommand const& com); bool CommandManiacCallCommand(lcf::rpg::EventCommand const& com); + bool CommandGetVarByName(lcf::rpg::EventCommand const& com); + int DecodeInt(lcf::DBArray::const_iterator& it); const std::string DecodeString(lcf::DBArray::const_iterator& it); lcf::rpg::MoveCommand DecodeMove(lcf::DBArray::const_iterator& it); From e04a433fb2766fda32c92313dbc5bb7d5b500a0c Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Sun, 28 Apr 2024 03:10:26 -0300 Subject: [PATCH 2/2] Search by Name - Support to different database formats. It mirrors ManiacPatch::GetLcfName structure. Update game_interpreter.cpp --- src/game_interpreter.cpp | 154 ++++++++++++++++++++++++++++++++------- src/game_interpreter.h | 2 +- 2 files changed, 128 insertions(+), 28 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 63905aa198..5d07ec94b3 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -68,7 +68,6 @@ #include "baseui.h" #include "algo.h" #include "rand.h" -#include enum BranchSubcommand { eOptionBranchElse = 1 @@ -5110,47 +5109,148 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& co return true; } -bool Game_Interpreter::CommandGetVarByName(lcf::rpg::EventCommand const& com) { - auto& targetData = lcf::Data::variables; +bool Game_Interpreter::CommandGetIdByName(lcf::rpg::EventCommand const& com) { + const int dataType = ValueOrVariable(com.parameters[0], com.parameters[1]); - int stringVarParam = 6; // string var is detected at com.parameters[n] - const std::string targetName = ToString(CommandStringOrVariable(com, stringVarParam, stringVarParam + 1)); - if (targetName.empty()) { - Output::Warning("The variable name to search is empty."); - return true; - } - - const int outputVar = ValueOrVariable(com.parameters[0], com.parameters[1]); + const int outputVar = ValueOrVariable(com.parameters[2], com.parameters[3]); if (outputVar <= 0) { Output::Warning("This command requires a valid variable."); return true; } - int rangeMin = ValueOrVariable(com.parameters[2], com.parameters[3]); - int rangeMax = ValueOrVariable(com.parameters[4], com.parameters[5]); + int rangeMin = ValueOrVariable(com.parameters[4], com.parameters[5]); + int rangeMax = ValueOrVariable(com.parameters[6], com.parameters[7]); - if (rangeMin <= 0) rangeMin = 1; - if (rangeMin > static_cast(targetData.size())) rangeMin = static_cast(targetData.size()); - if (rangeMax <= 0 || rangeMax >= static_cast(targetData.size())) rangeMax = static_cast(targetData.size()); + const std::string targetName = ToString(CommandStringOrVariable(com, 8, 9)); + if (targetName.empty()) { + Output::Warning("The name to search is empty."); + return true; + } - if (rangeMax < rangeMin) std::swap(rangeMin, rangeMax); + auto GetName = [](const auto& obj) -> std::string { + using T = std::decay_t; - auto it = std::find_if(targetData.begin() + rangeMin - 1, targetData.begin() + rangeMax, - [&](const auto& entry) { return entry.name == targetName; }); + if constexpr (std::is_same_v) { + return ToString(obj.GetName()); + } + else if constexpr (std::is_same_v) { + return ToString(obj->GetName()); + } + else { + return ToString(obj.name); + } + }; - if (it != targetData.end()) { - const int id = std::distance(targetData.begin(), it) + 1; + auto find_by_name = [&](const auto& vec) -> int { + if (rangeMin <= 0) rangeMin = 1; + if (rangeMin > static_cast(vec.size())) rangeMin = static_cast(vec.size()); - if (id >= rangeMin && id <= rangeMax) { - Output::Debug(" Variable \"{}\" found at ID: {}. Storing ID in variable {}.", targetName, id, outputVar); + if (rangeMax <= 0 || rangeMax >= static_cast(vec.size())) rangeMax = static_cast(vec.size()); + if (rangeMax < rangeMin) std::swap(rangeMin, rangeMax); - Main_Data::game_variables->Set(outputVar, id); - Game_Map::SetNeedRefresh(true); - return true; + for (int i = rangeMin - 1; i < rangeMax; ++i) { + if (GetName(vec[i]) == targetName) { + return i + 1; + } } + return 0; + }; + + std::string typeName = "Unknown"; + int id = 0; + switch (dataType) { + case 0: + typeName = "Actor"; + id = find_by_name(lcf::Data::actors); + break; + case 1: + typeName = "Skill"; + id = find_by_name(lcf::Data::skills); + break; + case 2: + typeName = "Item"; + id = find_by_name(lcf::Data::items); + break; + case 3: + typeName = "Enemy"; + id = find_by_name(lcf::Data::enemies); + break; + case 4: + typeName = "Troop"; + id = find_by_name(lcf::Data::troops); + break; + case 5: + typeName = "Terrain"; + id = find_by_name(lcf::Data::terrains); + break; + case 6: + typeName = "Attribute"; + id = find_by_name(lcf::Data::attributes); + break; + case 7: + typeName = "State"; + id = find_by_name(lcf::Data::states); + break; + case 8: + typeName = "Animation"; + id = find_by_name(lcf::Data::animations); + break; + case 9: + typeName = "Tileset"; + id = find_by_name(lcf::Data::chipsets); + break; + case 10: + typeName = "Switch"; + id = find_by_name(lcf::Data::switches); + break; + case 11: + typeName = "Variable"; + id = find_by_name(lcf::Data::variables); + break; + case 12: + typeName = "String Variable"; + Output::Warning("{} names are not supported yet.", typeName); // FIXME: .t[a].name? - String variables don't support name yet + return true; + // Main_Data::game_strings->GetLcfData(); + // break; + case 13: + typeName = "Common Event"; + id = find_by_name(lcf::Data::commonevents); + break; + case 14: + typeName = "Class"; + id = find_by_name(lcf::Data::classes); + break; + case 15: + typeName = "Battler Animation"; + id = find_by_name(lcf::Data::battleranimations); + break; + case 16: + typeName = "Map"; + id = find_by_name(lcf::Data::treemap.maps); + break; + case 17: + typeName = "Map Event"; + id = find_by_name(Game_Map::GetEvents()); + break; + case 18: + typeName = "Party Member"; + id = find_by_name(Main_Data::game_party.get()->GetActors()); + break; + default: + Output::Warning("Unsupported data type: {}({})", typeName, dataType); + return true; + } + + if (id > 0) { + Output::Debug(" {} \"{}\" found at ID: {}. Storing ID in variable {}.", typeName, targetName, id, outputVar); + Main_Data::game_variables->Set(outputVar, id); + Game_Map::SetNeedRefresh(true); + } + else { + Output::Warning("{} \"{}\" not found within the range {} to {}.", typeName, targetName, rangeMin, rangeMax); } - Output::Warning("Variable \"{}\" not found within the range of variables {} to {}.", targetName, rangeMin, rangeMax); return true; } diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 29b340d2b5..ab671385a1 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -290,7 +290,7 @@ class Game_Interpreter bool CommandManiacControlStrings(lcf::rpg::EventCommand const& com); bool CommandManiacCallCommand(lcf::rpg::EventCommand const& com); - bool CommandGetVarByName(lcf::rpg::EventCommand const& com); + bool CommandGetIdByName(lcf::rpg::EventCommand const& com); int DecodeInt(lcf::DBArray::const_iterator& it); const std::string DecodeString(lcf::DBArray::const_iterator& it);