diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 1ac890a87d..95a9d50476 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -1060,15 +1060,12 @@ bool Game_Interpreter::CommandControlSwitches(lcf::rpg::EventCommand const& com) } bool Game_Interpreter::CommandControlVariables(lcf::rpg::EventCommand const& com) { // code 10220 - int value = 0; - int operand = com.parameters[4]; - if (EP_UNLIKELY(operand >= 9 && !Player::IsPatchManiac())) { - Output::Warning("ControlVariables: Unsupported operand {}", operand); - return true; - } + //FIXME: If dynamic changing of patch flags mid-game was enabled, then the jump tables would need to be rebuilt + static const auto dispatch_table = DispatchTable_VarOp::BuildDispatchTable(Player::IsPatchManiac(), false, false); - if (!EvalControlVarOp(value, operand, com)) + int value = 0; + if (!dispatch_table.Execute(value, com, *this)) return true; int start, end; @@ -1087,194 +1084,190 @@ bool Game_Interpreter::CommandControlVariables(lcf::rpg::EventCommand const& com return true; } -bool Game_Interpreter::EvalControlVarOp(int&value, int operand, lcf::rpg::EventCommand const& com) { - switch (operand) { - case 0: - // Constant - value = com.parameters[5]; - break; - case 1: - // Var A ops B - value = Main_Data::game_variables->Get(com.parameters[5]); - break; - case 2: - // Number of var A ops B - value = Main_Data::game_variables->GetIndirect(com.parameters[5]); - break; - case 3: { - // Random between range - int32_t arg1 = com.parameters[5]; - int32_t arg2 = com.parameters[6]; - if (Player::IsPatchManiac() && com.parameters.size() >= 8) { - arg1 = ValueOrVariableBitfield(com.parameters[7], 0, arg1); - arg2 = ValueOrVariableBitfield(com.parameters[7], 1, arg2); - } +namespace EvalControlVarOp { + using Main_Data::game_switches, Main_Data::game_variables; - value = ControlVariables::Random(arg1, arg2); - break; - } - case 4: { - // Items - int item = com.parameters[5]; - if (Player::IsPatchManiac() && com.parameters.size() >= 8) { - item = ValueOrVariable(com.parameters[7], item); - } + template + int Constant(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + return com.parameters[param_offset]; + } - value = ControlVariables::Item(com.parameters[6], item); - break; - } - case 5: { // Hero - int actor_id = com.parameters[5]; - if (Player::IsPatchManiac() && com.parameters.size() >= 8) { - actor_id = ValueOrVariable(com.parameters[7], actor_id); - } - if (Player::IsPatchManiac()) { - value = ControlVariables::Actor(com.parameters[6], actor_id); - } else { - value = ControlVariables::Actor(com.parameters[6], actor_id); + template + int Variable(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + return game_variables->Get(com.parameters[param_offset]); + } + + template + int VariableIndirect(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + return game_variables->GetIndirect(com.parameters[param_offset]); + } + + template + int Random(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int32_t arg1 = com.parameters[param_offset]; + int32_t arg2 = com.parameters[param_offset + 1]; + if constexpr (Maniac) { + if (com.parameters.size() >= (param_offset + 3)) { + arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, arg1, interpreter); + arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 1, arg2, interpreter); } - break; } - case 6: { - // Characters - int event_id = com.parameters[5]; - if (Player::IsPatchManiac() && com.parameters.size() >= 8) { - event_id = ValueOrVariable(com.parameters[7], event_id); - } - if (Player::IsPatchManiac()) { - value = ControlVariables::Event(com.parameters[6], event_id, *this); - } else { - value = ControlVariables::Event(com.parameters[6], event_id, *this); + + return ControlVariables::Random(arg1, arg2); + } + + template + int Item(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int item = com.parameters[param_offset]; + if constexpr (Maniac) { + if (com.parameters.size() >= (param_offset + 3)) { + item = ValueOrVariable(com.parameters[param_offset + 2], item, interpreter); } - break; } - case 7: - // More - if (Player::IsPatchManiac()) { - value = ControlVariables::Other(com.parameters[5]); - } else { - value = ControlVariables::Other(com.parameters[5]); - } - break; - case 8: { - int enemy_id = com.parameters[5]; - if (Player::IsPatchManiac() && com.parameters.size() >= 8) { - enemy_id = ValueOrVariable(com.parameters[7], enemy_id); - } - // Battle related - if (Player::IsPatchManiac()) { - value = ControlVariables::Enemy(com.parameters[6], enemy_id); - } else { - value = ControlVariables::Enemy(com.parameters[6], enemy_id); + return ControlVariables::Item(com.parameters[param_offset + 1], item); + } + + template + int Actor(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int actor_id = com.parameters[param_offset]; + if constexpr (Maniac) { + if (com.parameters.size() >= (param_offset + 3)) { + actor_id = ValueOrVariable(com.parameters[param_offset + 2], actor_id, interpreter); } - break; } - case 9: { // Party Member (Maniac) - int party_idx = com.parameters[5]; - if (Player::IsPatchManiac() && com.parameters.size() >= 8) { - party_idx = ValueOrVariable(com.parameters[7], party_idx); + return ControlVariables::Actor(com.parameters[param_offset + 1], actor_id); + } + + template + int Event(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int event_id = com.parameters[param_offset]; + if constexpr (Maniac) { + if (com.parameters.size() >= (param_offset + 3)) { + event_id = ValueOrVariable(com.parameters[param_offset + 2], event_id, interpreter); } - value = ControlVariables::Party(com.parameters[6], party_idx); - break; } - case 10: { - // Switch (Maniac) - value = com.parameters[5]; - if (com.parameters[6] == 1) { - value = Main_Data::game_switches->GetInt(value); - } else { - value = Main_Data::game_switches->GetInt(Main_Data::game_variables->Get(value)); + return ControlVariables::Event(com.parameters[param_offset + 1], event_id, interpreter); + } + + template + int Other(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + return ControlVariables::Other(com.parameters[param_offset]); + } + + template + int Enemy(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int enemy_id = com.parameters[param_offset]; + if constexpr (Maniac) { + if (com.parameters.size() >= (param_offset + 3)) { + enemy_id = ValueOrVariable(com.parameters[param_offset + 2], enemy_id, interpreter); } - break; } - case 11: { - // Pow (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[7], 0, com.parameters[5]); - int arg2 = ValueOrVariableBitfield(com.parameters[7], 1, com.parameters[6]); - value = ControlVariables::Pow(arg1, arg2); - break; - } - case 12: { - // Sqrt (Maniac) - int arg = ValueOrVariableBitfield(com.parameters[7], 0, com.parameters[5]); - int mul = com.parameters[6]; - value = ControlVariables::Sqrt(arg, mul); - break; - } - case 13: { - // Sin (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[7], 0, com.parameters[5]); - int arg2 = ValueOrVariableBitfield(com.parameters[7], 1, com.parameters[8]); - float mul = static_cast(com.parameters[6]); - value = ControlVariables::Sin(arg1, arg2, mul); - break; - } - case 14: { - // Cos (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[7], 0, com.parameters[5]); - int arg2 = ValueOrVariableBitfield(com.parameters[7], 1, com.parameters[8]); - int mul = com.parameters[6]; - value = ControlVariables::Cos(arg1, arg2, mul); - break; - } - case 15: { - // Atan2 (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[8], 0, com.parameters[5]); - int arg2 = ValueOrVariableBitfield(com.parameters[8], 1, com.parameters[6]); - int mul = com.parameters[7]; - value = ControlVariables::Atan2(arg1, arg2, mul); - break; - } - case 16: { - // Min (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[7], 0, com.parameters[5]); - int arg2 = ValueOrVariableBitfield(com.parameters[7], 1, com.parameters[6]); - value = ControlVariables::Min(arg1, arg2); - break; - } - case 17: { - // Max (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[7], 0, com.parameters[5]); - int arg2 = ValueOrVariableBitfield(com.parameters[7], 1, com.parameters[6]); - value = ControlVariables::Max(arg1, arg2); - break; - } - case 18: { - // Abs (Maniac) - int arg = ValueOrVariableBitfield(com.parameters[6], 0, com.parameters[5]); - value = ControlVariables::Abs(arg); - break; + + return ControlVariables::Event(com.parameters[param_offset + 1], enemy_id, interpreter); + } + + template + int Party(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int party_idx = com.parameters[param_offset]; + if (com.parameters.size() >= (param_offset + 3)) { + party_idx = ValueOrVariable(com.parameters[param_offset + 2], party_idx, interpreter); } - case 19: { - // Binary (Maniac) - int arg1 = ValueOrVariableBitfield(com.parameters[8], 0, com.parameters[6]); - int arg2 = ValueOrVariableBitfield(com.parameters[8], 1, com.parameters[7]); - value = ControlVariables::Binary(com.parameters[5], arg1, arg2); - break; + return ControlVariables::Party(com.parameters[param_offset + 1], party_idx); + } + + template + int Switch(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int value = com.parameters[param_offset]; + if (com.parameters[param_offset + 1] == 1) { + value = game_switches->GetInt(value); + } else { + value = game_switches->GetInt(game_variables->Get(value)); } - case 20: { - // Ternary (Maniac) - int mode = com.parameters[10]; - int arg1 = ValueOrVariableBitfield(mode, 0, com.parameters[6]); - int arg2 = ValueOrVariableBitfield(mode, 1, com.parameters[7]); - int op = com.parameters[5]; - if (CheckOperator(arg1, arg2, op)) { - value = ValueOrVariableBitfield(mode, 2, com.parameters[8]); - } else { - value = ValueOrVariableBitfield(mode, 3, com.parameters[9]); - } - break; + return value; + } + + template + int Pow(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, com.parameters[param_offset], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 1, com.parameters[param_offset + 1], interpreter); + return ControlVariables::Pow(arg1, arg2); + } + + template + int Sqrt(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, com.parameters[param_offset], interpreter); + int mul = com.parameters[param_offset + 1]; + return ControlVariables::Sqrt(arg, mul); + } + + template + int Sin(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, com.parameters[param_offset], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 1, com.parameters[param_offset + 3], interpreter); + float mul = static_cast(com.parameters[param_offset + 1]); + return ControlVariables::Sin(arg1, arg2, mul); + } + + template + int Cos(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, com.parameters[param_offset], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 1, com.parameters[param_offset + 3], interpreter); + int mul = com.parameters[param_offset + 1]; + return ControlVariables::Cos(arg1, arg2, mul); + } + + template + int Atan2(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 3], 0, com.parameters[param_offset], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 3], 1, com.parameters[param_offset + 1], interpreter); + int mul = com.parameters[param_offset + 2]; + return ControlVariables::Atan2(arg1, arg2, mul); + } + + template + int Min(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, com.parameters[param_offset], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 1, com.parameters[param_offset + 1], interpreter); + return ControlVariables::Min(arg1, arg2); + } + + template + int Max(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 0, com.parameters[param_offset], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 2], 1, com.parameters[param_offset + 1], interpreter); + return ControlVariables::Max(arg1, arg2); + } + + template + int Abs(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg = ValueOrVariableBitfield(com.parameters[param_offset + 1], 0, com.parameters[param_offset], interpreter); + return ControlVariables::Abs(arg); + } + + template + int Binary(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int arg1 = ValueOrVariableBitfield(com.parameters[param_offset + 3], 0, com.parameters[param_offset + 1], interpreter); + int arg2 = ValueOrVariableBitfield(com.parameters[param_offset + 3], 1, com.parameters[param_offset + 2], interpreter); + return ControlVariables::Binary(com.parameters[param_offset], arg1, arg2); + } + + template + int Ternary(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + int mode = com.parameters[param_offset + 5]; + int arg1 = ValueOrVariableBitfield(mode, 0, com.parameters[param_offset + 1], interpreter); + int arg2 = ValueOrVariableBitfield(mode, 1, com.parameters[param_offset + 2], interpreter); + int op = com.parameters[param_offset]; + if (CheckOperator(arg1, arg2, op)) { + return ValueOrVariableBitfield(mode, 2, com.parameters[param_offset + 3], interpreter); } - case 21: - // Expression (Maniac) - value = ManiacPatch::ParseExpression(MakeSpan(com.parameters).subspan(6, com.parameters[5]), *this); - break; - default: - Output::Warning("ControlVariables: Unsupported operand {}", operand); - return false; + return ValueOrVariableBitfield(mode, 3, com.parameters[param_offset + 4], interpreter); + } + + template + static inline int Expression(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) { + return ManiacPatch::ParseExpression(MakeSpan(com.parameters).subspan(param_offset + 1, com.parameters[param_offset]), interpreter); } - return true; } void Game_Interpreter::PerformVarOp(int value, int start, int end, lcf::rpg::EventCommand const& com) { @@ -5544,3 +5537,124 @@ int Game_Interpreter::ManiacBitmask(int value, int mask) const { return value; } + +namespace DispatchTable_VarOp { + static bool dispatch_table_default_case_triggered = false; + + std::array tables = {}; + + constexpr StringView get_op_name(CommandType op_type) { + switch (op_type) { + case CommandType::eControlVarOp_Default: + return "ControlVariables"; + case CommandType::eControlVarOp_Ex: + return "ControlVariablesEx"; + case CommandType::eControlVarOp_Scoped: + return "ControlScopedVariables"; + default: + return ""; + } + }; + + constexpr int get_param_operand(CommandType op_type) { + switch (op_type) { + case CommandType::eControlVarOp_Default: + return 4; + case CommandType::eControlVarOp_Ex: + return 4; + case CommandType::eControlVarOp_Scoped: + return 4; + default: + return 4; + } + }; + + constexpr int get_param_offset(CommandType op_type) { + switch (op_type) { + case CommandType::eControlVarOp_Default: + return 5; + case CommandType::eControlVarOp_Ex: + return 5; + case CommandType::eControlVarOp_Scoped: + return 8; + default: + return 5; + } + }; + + template + int varOperand_DefaultCase(lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const&) { + dispatch_table_default_case_triggered = true; + Output::Warning("{}: Unsupported operand {}", get_op_name(op_type), com.parameters[get_param_operand(op_type)]); + return 0; + }; + + EP_ALWAYS_INLINE bool dispatch_table_varoperand::Execute(int& value_out, lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) const { + const std::byte operand = static_cast(com.parameters[param_operand]); + value_out = ops[std::to_integer(operand)](com, interpreter); + + if (EP_UNLIKELY(dispatch_table_default_case_triggered)) { + dispatch_table_default_case_triggered = false; + return false; + } + return true; + } + + template + const dispatch_table_varoperand& BuildDispatchTable(const bool includeManiacs_200128, const bool includeManiacs24xxxx, const bool includeEasyRpgEx) { + + static_assert(op_type >= eControlVarOp_Default && op_type < eControlVarOp_LAST); + assert(tables[static_cast(op_type)] == nullptr); + + std::bitset<16> patch_flags; + patch_flags.set(1, includeManiacs_200128); + patch_flags.set(2, includeManiacs24xxxx); + patch_flags.set(3, includeEasyRpgEx); + + std::map ops; + + using namespace EvalControlVarOp; + + // Vanilla operands + ops[eVarOperand_Constant] = &Constant; + ops[eVarOperand_Variable] = &Variable; + ops[eVarOperand_VariableIndirect] = &VariableIndirect; + if (includeManiacs_200128) { + ops[eVarOperand_RandomBetweenRange] = &Random; + ops[eVarOperand_Items] = &Item; + ops[eVarOperand_Actors] = &Actor; + ops[eVarOperand_Events] = &Event; + ops[eVarOperand_Other] = &Other; + ops[eVarOperand_Battle_Enemies] = &Enemy; + } else { + ops[eVarOperand_RandomBetweenRange] = &Random; + ops[eVarOperand_Items] = &Item; + ops[eVarOperand_Actors] = &Actor; + ops[eVarOperand_Events] = &Event; + ops[eVarOperand_Other] = &Other; + ops[eVarOperand_Battle_Enemies] = &Enemy; + } + // end Vanilla operands + + if (includeManiacs_200128) { + ops[eVarOperand_Maniacs_Party] = &Party; + ops[eVarOperand_Maniacs_Switch] = &Switch; + ops[eVarOperand_Maniacs_Pow] = &Pow; + ops[eVarOperand_Maniacs_Sqrt] = &Sqrt; + ops[eVarOperand_Maniacs_Sin] = &Sin; + ops[eVarOperand_Maniacs_Cos] = &Cos; + ops[eVarOperand_Maniacs_Atan2] = &Atan2; + ops[eVarOperand_Maniacs_Min] = &Min; + ops[eVarOperand_Maniacs_Max] = &Max; + ops[eVarOperand_Maniacs_Abs] = &Abs; + ops[eVarOperand_Maniacs_Binary] = &Binary; + ops[eVarOperand_Maniacs_Ternary] = &Ternary; + ops[eVarOperand_Maniacs_Expression] = &Expression; + } + + dispatch_table_varoperand* dispatch_table = new dispatch_table_varoperand(get_param_operand(op_type), (int)patch_flags.to_ulong(), ops, &varOperand_DefaultCase); + tables[static_cast(op_type)] = dispatch_table; + + return *dispatch_table; + } +} diff --git a/src/game_interpreter.h b/src/game_interpreter.h index b71b1649c0..6dff2be66f 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -310,7 +310,6 @@ class Game_Interpreter : public Game_BaseInterpreterContext void ForegroundTextPush(PendingMessage pm); void EndEventProcessing(); - bool EvalControlVarOp(int& value, int operand, lcf::rpg::EventCommand const& com); void PerformVarOp(int value, int start, int end, lcf::rpg::EventCommand const& com); bool EvalCondBranch(lcf::rpg::EventCommand const& com); @@ -356,6 +355,51 @@ class Game_Interpreter : public Game_BaseInterpreterContext friend class Scene_Debug; }; +namespace DispatchTable_VarOp { + enum CommandType { + eControlVarOp_Default = 0, + eControlVarOp_Ex, + eControlVarOp_Scoped, + eControlVarOp_LAST + }; + + using namespace Game_Interpreter_Shared; + using varOperand_Func = int (*)(lcf::rpg::EventCommand const&, Game_BaseInterpreterContext const&); + + //dispatch table + class dispatch_table_varoperand { + public: + inline dispatch_table_varoperand(const int param_operand, const int patch_flags, const std::map defined_ops, varOperand_Func default_case) : param_operand(param_operand), patch_flags(patch_flags), ops(InitOps(defined_ops, default_case)) { } + + bool Execute(int& value_out, lcf::rpg::EventCommand const& com, Game_BaseInterpreterContext const& interpreter) const; + + inline int GetPatchFlags() const { return patch_flags; } + private: + static constexpr int table_size = { (int)std::numeric_limits::max() }; + + static inline std::array InitOps(const std::map defined_ops, varOperand_Func default_case) { + std::array ret; + + for (int i = 0; i < table_size; i++) { + auto it = defined_ops.find(static_cast(std::byte(i))); + if (it == defined_ops.end()) { + ret[i] = default_case; + } else { + ret[i] = it->second; + } + } + + return ret; + } + + const int param_operand, patch_flags; + const std::array ops; + }; + + template + const dispatch_table_varoperand& BuildDispatchTable(const bool includeManiacs_200128, const bool includeManiacs24xxxx, const bool includeEasyRpgEx); +} + inline const lcf::rpg::SaveEventExecFrame* Game_Interpreter::GetFramePtr() const { return !_state.stack.empty() ? &_state.stack.back() : nullptr; } diff --git a/src/game_interpreter_control_variables.cpp b/src/game_interpreter_control_variables.cpp index 385e5ffcda..306511b354 100644 --- a/src/game_interpreter_control_variables.cpp +++ b/src/game_interpreter_control_variables.cpp @@ -15,12 +15,12 @@ * along with EasyRPG Player. If not, see . */ +#include "compiler.h" #include "game_interpreter_shared.h" #include "game_interpreter_control_variables.h" #include "game_actors.h" #include "game_enemyparty.h" #include "game_ineluki.h" -#include "game_interpreter.h" #include "game_party.h" #include "game_player.h" #include "game_system.h" @@ -28,8 +28,10 @@ #include "output.h" #include "player.h" #include "rand.h" +#include "util_macro.h" #include "utils.h" #include "audio.h" +#include "baseui.h" #include #include #include diff --git a/src/game_interpreter_shared.h b/src/game_interpreter_shared.h index 42c27990de..a6eab90d5d 100644 --- a/src/game_interpreter_shared.h +++ b/src/game_interpreter_shared.h @@ -28,6 +28,83 @@ class Game_Character; class Game_BaseInterpreterContext; namespace Game_Interpreter_Shared { + enum ControlVarOperand : std::uint8_t { + // Constant + eVarOperand_Constant = 0, + // Var A ops B + eVarOperand_Variable, + // Number of var A ops B + eVarOperand_VariableIndirect, + // Random between range + eVarOperand_RandomBetweenRange, + // Items + eVarOperand_Items, + // Hero + eVarOperand_Actors, + // Characters + eVarOperand_Events, + // More + eVarOperand_Other, + // Battle related + eVarOperand_Battle_Enemies, + eVarOperand_Maniacs_Party = 9, + eVarOperand_Maniacs_Switch, + eVarOperand_Maniacs_Pow, + eVarOperand_Maniacs_Sqrt, + eVarOperand_Maniacs_Sin, + eVarOperand_Maniacs_Cos, + eVarOperand_Maniacs_Atan2, + eVarOperand_Maniacs_Min, + eVarOperand_Maniacs_Max, + eVarOperand_Maniacs_Abs, + eVarOperand_Maniacs_Binary, + eVarOperand_Maniacs_Ternary, + eVarOperand_Maniacs_Expression, + + // Reserved / Maniacs 2024-xx-xx (not yet implemented - need to determine encoding/functionality + actual op ids) + eVarOperand_Maniacs_Clamp, + eVarOperand_Maniacs_MulDiv, + eVarOperand_Maniacs_DivMul, + eVarOperand_Maniacs_Between, + eVarOperand_Maniacs_Lerp, + eVarOperand_Maniacs_SumRange, + eVarOperand_Maniacs_AMin, + eVarOperand_Maniacs_AMax, + // + + eVarOperand_EasyRpg_FrameSwitch = 200, + eVarOperand_EasyRpg_ScopedSwitch_Map, + eVarOperand_EasyRpg_ScopedSwitch_MapEvent, + eVarOperand_EasyRpg_FrameVariable, + eVarOperand_EasyRpg_ScopedVariable_Map, + eVarOperand_EasyRpg_ScopedVariable_MapEvent, + // Count Switches [id] matching condition (ON/OFF) or defined (arg>=2) (Scope: Map) + eVarOperand_EasyRpg_CountScopedSwitchesMatchingCondition_Map, + // Count Switches [id] matching condition (ON/OFF) or defined (arg>=2) for map [map_id] (Scope: MapEvent) + eVarOperand_EasyRpg_CountScopedSwitchesMatchingCondition_MapEvent, + // Count Variables [id] matching condition or defined (op>=6) (Scope: Map) + eVarOperand_EasyRpg_CountScopedVarsMatchingCondition_Map, + // Count Variables [id] matching condition or defined (op>=6) for map [map_id] (Scope: MapEvent) + eVarOperand_EasyRpg_CountScopedVarsMatchingCondition_MapEvent, + + // Reserved / Not yet implemented + eVarOperand_EasyRpg_DateTime, // jetrotals new dt operations + eVarOperand_EasyRpg_MapInfo, // jetrotals planned ops for Map/Screen ? + eVarOperand_EasyRpg_MessageState, // get info about active message windows + eVarOperand_EasyRpg_RngFixedSeed, // reproducible rng (+ options for rng dependent on map/event ?) + // + + eVarOperand_Vanilla_FIRST = eVarOperand_Constant, + eVarOperand_Vanilla_LAST = eVarOperand_Battle_Enemies, + eVarOperand_Maniacs_FIRST = eVarOperand_Maniacs_Party, + eVarOperand_Maniacs_LAST = eVarOperand_Maniacs_Expression, + eVarOperand_Maniacs24xxxx_FIRST = eVarOperand_Maniacs_Clamp, + eVarOperand_Maniacs24xxxx_LAST = eVarOperand_Maniacs_AMax, + eVarOperand_EasyRpg_FIRST = eVarOperand_EasyRpg_FrameSwitch, + eVarOperand_EasyRpg_LAST = eVarOperand_EasyRpg_RngFixedSeed, + + eVarOperand_MAX = eVarOperand_EasyRpg_LAST + }; /* * Indicates how the target of an interpreter operation (lvalue) should be evaluated.