Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Command 2054 - Get ID By Name #3214

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Search by Name - Support to different database formats.
It mirrors ManiacPatch::GetLcfName structure.

Update game_interpreter.cpp
  • Loading branch information
jetrotal committed Apr 28, 2024
commit e04a433fb2766fda32c92313dbc5bb7d5b500a0c
154 changes: 127 additions & 27 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
@@ -68,7 +68,6 @@
#include "baseui.h"
#include "algo.h"
#include "rand.h"
#include <variant>

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<int>(targetData.size())) rangeMin = static_cast<int>(targetData.size());
if (rangeMax <= 0 || rangeMax >= static_cast<int>(targetData.size())) rangeMax = static_cast<int>(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<decltype(obj)>;

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<T, Game_Event>) {
return ToString(obj.GetName());
}
else if constexpr (std::is_same_v<T, Game_Actor*>) {
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<int>(vec.size())) rangeMin = static_cast<int>(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<int>(vec.size())) rangeMax = static_cast<int>(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;
}

2 changes: 1 addition & 1 deletion src/game_interpreter.h
Original file line number Diff line number Diff line change
@@ -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<int32_t>::const_iterator& it);
const std::string DecodeString(lcf::DBArray<int32_t>::const_iterator& it);