Skip to content

Commit d54ce7d

Browse files
committed
Maniac CallCommand - Add ResolveEventCommand
Introduces the ResolveEventCommand method to process Maniac Patch @cmd (Call Command) event commands, resolving them into their actual form. Refactors interpreter logic to use this method where event commands are accessed, ensuring correct handling of Maniac Patch commands and improving compatibility. Updates function signatures and documentation accordingly.
1 parent 31de2a7 commit d54ce7d

File tree

2 files changed

+59
-37
lines changed

2 files changed

+59
-37
lines changed

src/game_interpreter.cpp

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ void Game_Interpreter::SkipToNextConditional(std::initializer_list<Cmd> codes, i
586586
}
587587

588588
for (++index; index < static_cast<int>(list.size()); ++index) {
589-
const auto& com = list[index];
589+
const auto& com = ResolveEventCommand(list[index]);
590590
if (com.indent > indent) {
591591
continue;
592592
}
@@ -870,17 +870,22 @@ std::vector<std::string> Game_Interpreter::GetChoices(int max_num_choices) {
870870
auto& index = frame.current_command;
871871

872872
// Let's find the choices
873-
int current_indent = list[index + 1].indent;
873+
if (index + 1 >= static_cast<int>(list.size())) return {};
874+
875+
auto first_opt = ResolveEventCommand(list[index + 1]);
876+
int current_indent = first_opt.indent;
877+
874878
std::vector<std::string> s_choices;
875879
for (int index_temp = index + 1; index_temp < static_cast<int>(list.size()); ++index_temp) {
876-
const auto& com = list[index_temp];
880+
auto com = ResolveEventCommand(list[index_temp]);
881+
877882
if (com.indent != current_indent) {
878883
continue;
879884
}
880885

881886
if (static_cast<Cmd>(com.code) == Cmd::ShowChoiceOption && com.parameters.size() > 0 && com.parameters[0] < max_num_choices) {
882887
// Choice found
883-
s_choices.push_back(ToString(list[index_temp].string));
888+
s_choices.push_back(ToString(com.string));
884889
}
885890

886891
if (static_cast<Cmd>(com.code) == Cmd::ShowChoiceEnd) {
@@ -920,29 +925,37 @@ bool Game_Interpreter::CommandShowMessage(lcf::rpg::EventCommand const& com) { /
920925
++index;
921926

922927
// Check for continued lines via ShowMessage_2
923-
while (index < static_cast<int>(list.size()) && static_cast<Cmd>(list[index].code) == Cmd::ShowMessage_2) {
924-
// Add second (another) line
925-
pm.PushLine(ToString(list[index].string));
926-
++index;
928+
while (index < static_cast<int>(list.size())) {
929+
auto next_cmd = ResolveEventCommand(list[index]);
930+
931+
if (static_cast<Cmd>(next_cmd.code) == Cmd::ShowMessage_2) {
932+
pm.PushLine(ToString(next_cmd.string));
933+
++index;
934+
}
935+
else {
936+
break;
937+
}
927938
}
928939

929940
// Handle Choices or number
930941
if (index < static_cast<int>(list.size())) {
931-
// If next event command is show choices
932-
if (static_cast<Cmd>(list[index].code) == Cmd::ShowChoice) {
942+
auto next_cmd = ResolveEventCommand(list[index]);
943+
944+
if (static_cast<Cmd>(next_cmd.code) == Cmd::ShowChoice) {
933945
std::vector<std::string> s_choices = GetChoices(4);
934946
// If choices fit on screen
935947
if (static_cast<int>(s_choices.size()) <= (4 - pm.NumLines())) {
936-
pm.SetChoiceCancelType(list[index].parameters[0]);
937-
SetupChoices(s_choices, com.indent, pm);
948+
pm.SetChoiceCancelType(next_cmd.parameters[0]);
949+
SetupChoices(s_choices, next_cmd.indent, pm);
938950
++index;
939951
}
940-
} else if (static_cast<Cmd>(list[index].code) == Cmd::InputNumber) {
941952
// If next event command is input number
942953
// If input number fits on screen
954+
}
955+
else if (static_cast<Cmd>(next_cmd.code) == Cmd::InputNumber) {
943956
if (pm.NumLines() < 4) {
944-
int digits = list[index].parameters[0];
945-
int variable_id = list[index].parameters[1];
957+
int digits = next_cmd.parameters[0];
958+
int variable_id = next_cmd.parameters[1];
946959
pm.PushNumInput(variable_id, digits);
947960
++index;
948961
}
@@ -2060,7 +2073,7 @@ std::optional<bool> Game_Interpreter::HandleDynRpgScript(const lcf::rpg::EventCo
20602073

20612074
// Concat everything that is not another command or a new comment block
20622075
for (size_t i = index + 1; i < list.size(); ++i) {
2063-
const auto& cmd = list[i];
2076+
const auto& cmd = ResolveEventCommand(list[i]);
20642077
if (cmd.code == static_cast<uint32_t>(Cmd::Comment_2) &&
20652078
!cmd.string.empty() && cmd.string[0] != '@') {
20662079
command += ToString(cmd.string);
@@ -3771,9 +3784,11 @@ bool Game_Interpreter::CommandJumpToLabel(lcf::rpg::EventCommand const& com) { /
37713784
int label_id = com.parameters[0];
37723785

37733786
for (int idx = 0; (size_t)idx < list.size(); idx++) {
3774-
if (static_cast<Cmd>(list[idx].code) != Cmd::Label)
3787+
auto scanned_cmd = ResolveEventCommand(list[idx]);
3788+
3789+
if (static_cast<Cmd>(scanned_cmd.code) != Cmd::Label)
37753790
continue;
3776-
if (list[idx].parameters.empty() || list[idx].parameters[0] != label_id)
3791+
if (scanned_cmd.parameters.empty() || scanned_cmd.parameters[0] != label_id)
37773792
continue;
37783793
index = idx;
37793794
break;
@@ -3853,19 +3868,19 @@ bool Game_Interpreter::CommandBreakLoop(lcf::rpg::EventCommand const& /* com */)
38533868

38543869
bool has_bug = !Player::IsPatchManiac();
38553870
if (!has_bug) {
3856-
SkipToNextConditional({ Cmd::EndLoop }, list[index].indent - 1);
3871+
SkipToNextConditional({ Cmd::EndLoop }, ResolveEventCommand(list[index]).indent - 1);
38573872
++index;
38583873
return true;
38593874
}
38603875

38613876
// This emulates an RPG_RT bug where break loop ignores scopes and
38623877
// unconditionally jumps to the next EndLoop command.
3863-
auto pcode = static_cast<Cmd>(list[index].code);
3878+
auto pcode = static_cast<Cmd>(ResolveEventCommand(list[index]).code);
38643879
for (++index; index < (int)list.size(); ++index) {
38653880
if (pcode == Cmd::EndLoop) {
38663881
break;
38673882
}
3868-
pcode = static_cast<Cmd>(list[index].code);
3883+
pcode = static_cast<Cmd>(ResolveEventCommand(list[index]).code);
38693884
}
38703885

38713886
return true;
@@ -3931,11 +3946,13 @@ bool Game_Interpreter::CommandEndLoop(lcf::rpg::EventCommand const& com) { // co
39313946

39323947
// Restart the loop
39333948
for (int idx = index; idx >= 0; idx--) {
3934-
if (list[idx].indent > indent)
3949+
auto scanned_cmd = ResolveEventCommand(list[idx]);
3950+
3951+
if (scanned_cmd.indent > indent)
39353952
continue;
3936-
if (list[idx].indent < indent)
3953+
if (scanned_cmd.indent < indent)
39373954
return false;
3938-
if (static_cast<Cmd>(list[idx].code) != Cmd::Loop)
3955+
if (static_cast<Cmd>(scanned_cmd.code) != Cmd::Loop)
39393956
continue;
39403957
index = idx;
39413958
break;
@@ -5288,9 +5305,9 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
52885305
return true;
52895306
}
52905307

5291-
bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& com) {
5292-
if (!Player::IsPatchManiac()) {
5293-
return true;
5308+
lcf::rpg::EventCommand Game_Interpreter::ResolveEventCommand(const lcf::rpg::EventCommand& com) {
5309+
if (static_cast<Cmd>(com.code) != Cmd::Maniac_CallCommand || !Player::IsPatchManiac()) {
5310+
return com;
52945311
}
52955312

52965313
enum class ProcessingMode {
@@ -5346,22 +5363,21 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& co
53465363
}
53475364
default:
53485365
Output::Warning("Call Command: Unsupported Processing Mode: {}", static_cast<int>(processing_mode));
5349-
return true;
5366+
return com;
53505367
}
53515368

53525369
// Finalize command parameters
53535370
cmd.parameters = lcf::DBArray<int32_t>(values.begin(), values.end());
53545371

5355-
// Debug output
5356-
/*Output::Warning("Processing mode: {}", static_cast<int>(processing_mode));
5357-
Output::Warning("Command code: {}", cmd.code);
5358-
Output::Warning("Command string: {}", cmd.string);
5359-
std::string params_str;
5360-
for (const auto& param : values) {
5361-
params_str += " " + std::to_string(param);
5372+
return cmd;
5373+
}
5374+
5375+
bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& com) {
5376+
if (!Player::IsPatchManiac()) {
5377+
return true;
53625378
}
5363-
Output::Warning("Command parameters:{}", params_str);
5364-
Output::Info("--------------------\n");*/
5379+
5380+
auto& cmd = ResolveEventCommand(com);
53655381

53665382
// Our implementation pushes a new frame containing the command instead of invoking it directly.
53675383
// This is incompatible to Maniacs but has a better compatibility with our code.

src/game_interpreter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ class Game_Interpreter : public Game_BaseInterpreterContext
305305
bool CommandManiacChangePictureId(lcf::rpg::EventCommand const& com);
306306
bool CommandManiacSetGameOption(lcf::rpg::EventCommand const& com);
307307
bool CommandManiacControlStrings(lcf::rpg::EventCommand const& com);
308+
/*
309+
* Resolves a Maniac Patch @cmd (Call Command) into the actual EventCommand it represents.
310+
* If the input is not a @cmd, it returns the input copy.
311+
* This handles variables, pointers, and expressions to build the final command.
312+
*/
313+
lcf::rpg::EventCommand ResolveEventCommand(const lcf::rpg::EventCommand& com);
308314
bool CommandManiacCallCommand(lcf::rpg::EventCommand const& com);
309315
bool CommandEasyRpgSetInterpreterFlag(lcf::rpg::EventCommand const& com);
310316
bool CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& com);

0 commit comments

Comments
 (0)