From 9dffc8fd7643d182017d47927c881fad80c79f42 Mon Sep 17 00:00:00 2001 From: Tool Man Date: Sat, 30 Nov 2024 13:57:40 -0500 Subject: [PATCH 1/2] Created new command (GetGameInfo) Currently added the following: 0: Get Map size 2: Window Size 5: Tileset ID 6: Face ID (partial) only for actors, not messages --- src/game_interpreter.cpp | 67 ++++++++++++++++++++++++++++++++++++++++ src/game_interpreter.h | 1 + 2 files changed, 68 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index e3fca05e25..4a1bb13066 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -796,6 +796,8 @@ bool Game_Interpreter::ExecuteCommand(lcf::rpg::EventCommand const& com) { return CommandEasyRpgCloneMapEvent(com); case Cmd::EasyRpg_DestroyMapEvent: return CommandEasyRpgDestroyMapEvent(com); + case static_cast(3021): //Maniac_GetGameInfo + return CommandManiacGetGameInfo(com); default: return true; } @@ -4050,6 +4052,71 @@ bool Game_Interpreter::CommandOpenVideoOptions(lcf::rpg::EventCommand const& /* return false; } +bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& com) { + if (!Player::IsPatchManiac()) { + return true; + } + + for (int i = 0; i < com.parameters.size(); i++) { + Output::Debug("GetGameInfo, Param {} = {}", i, com.parameters[i]); + } + + // Com 0 seems to be for bitfield var CharAirship + // Com 1 is the type of function + // Com 2 onward are the arguments for value + + switch (com.parameters[1]) { + case 0: // Get map size + Main_Data::game_variables->Set(com.parameters[2], Game_Map::GetMap().width); + Main_Data::game_variables->Set(com.parameters[2] + 1, Game_Map::GetMap().height); + return true; + case 1: // Get tile info + Output::Warning("Maniac_GetGameInfo - Option 'Tile Info' not implemented."); + return true; + case 2: // Get window size + Output::Debug("Maniac_GetGameInfo - Screen Size: {} - {}", Player::screen_width, Player::screen_height); + Main_Data::game_variables->Set(com.parameters[2], Player::screen_width); + Main_Data::game_variables->Set(com.parameters[2] + 1, Player::screen_height); + return true; + case 4: // Get command interpreter state + Output::Warning("Maniac_GetGameInfo - Option 'Command Interpreter State' not implemented."); + return true; + case 5: // Get tileset ID + Output::Debug("Maniac_GetGameInfo - Tileset ID: {}", Game_Map::GetChipset()); + Main_Data::game_variables->Set(com.parameters[2], Game_Map::GetChipset()); + return true; + case 6: // Get Face ID + // Param 2: String index + // Param 3: ID index + // Param 4: Window avatar? + // Param 5: Actor ID + // Param 6: Dynamic? + if (com.parameters[4] == 1) { + + } else { + int actor_id = ValueOrVariableBitfield(com.parameters[0], 0, com.parameters[5]); + Game_Strings::Str_Params param = {com.parameters[2], 0, 0}; + if (com.parameters[6] == 1) { + // Dynamic + auto* actor = Main_Data::game_actors->GetActor(actor_id); + Main_Data::game_strings->Asg(param, actor->GetFaceName()); + Main_Data::game_variables->Set(com.parameters[3], actor->GetFaceIndex()); + } else { + // Default one + auto* dbActor = lcf::ReaderUtil::GetElement(lcf::Data::actors, actor_id); + Main_Data::game_strings->Asg(param, StringView(dbActor->face_name)); + Main_Data::game_variables->Set(com.parameters[3], dbActor->face_index); + } + } + return true; + default: + Output::Warning("Maniac_GetGameInfo - Option {} not implemented.", com.parameters[1]); + return true; + } + return true; +} + + bool Game_Interpreter::CommandManiacGetSaveInfo(lcf::rpg::EventCommand const& com) { if (!Player::IsPatchManiac()) { return true; diff --git a/src/game_interpreter.h b/src/game_interpreter.h index 4956ebb44d..c80ff276fa 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -301,6 +301,7 @@ class Game_Interpreter : public Game_BaseInterpreterContext bool CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& com); bool CommandEasyRpgCloneMapEvent(lcf::rpg::EventCommand const& com); bool CommandEasyRpgDestroyMapEvent(lcf::rpg::EventCommand const& com); + bool CommandManiacGetGameInfo(lcf::rpg::EventCommand const& com); void SetSubcommandIndex(int indent, int idx); uint8_t& ReserveSubcommandIndex(int indent); From 4c28f23a871e8dd539df416a5f0e9078222b06b2 Mon Sep 17 00:00:00 2001 From: Tool Man Date: Tue, 3 Dec 2024 15:38:22 -0500 Subject: [PATCH 2/2] Implemented more functions Added new functions for the following: 6: Get player/message portrait 7: Get player/event sprite 8: Get Screen position 9: Get Screen shake offset 10: Get Current BGM --- src/game_interpreter.cpp | 160 +++++++++++++++++++++++++++++++-------- 1 file changed, 129 insertions(+), 31 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 4a1bb13066..987eb91544 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -4057,61 +4057,159 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co return true; } - for (int i = 0; i < com.parameters.size(); i++) { - Output::Debug("GetGameInfo, Param {} = {}", i, com.parameters[i]); - } - - // Com 0 seems to be for bitfield var CharAirship - // Com 1 is the type of function - // Com 2 onward are the arguments for value + int event_id; + const Game_Strings::Str_Params param = {com.parameters[2], 0, 0}; switch (com.parameters[1]) { case 0: // Get map size Main_Data::game_variables->Set(com.parameters[2], Game_Map::GetMap().width); Main_Data::game_variables->Set(com.parameters[2] + 1, Game_Map::GetMap().height); - return true; + break; case 1: // Get tile info - Output::Warning("Maniac_GetGameInfo - Option 'Tile Info' not implemented."); - return true; + // FIXME: figure out how 'Tile Info' works + Output::Warning("GetGameInfo: Option 'Tile Info' not implemented."); + break; case 2: // Get window size - Output::Debug("Maniac_GetGameInfo - Screen Size: {} - {}", Player::screen_width, Player::screen_height); Main_Data::game_variables->Set(com.parameters[2], Player::screen_width); Main_Data::game_variables->Set(com.parameters[2] + 1, Player::screen_height); - return true; + break; + case 3: // Get pixel info + // FIXME: figure out how 'Pixel info' works + Output::Warning("GetGameInfo: Option 'Pixel Info' not implemented."); + break; case 4: // Get command interpreter state - Output::Warning("Maniac_GetGameInfo - Option 'Command Interpreter State' not implemented."); - return true; + // FIXME: figure out how 'command interpreter state' works + Output::Warning("GetGameInfo: Option 'Command Interpreter State' not implemented."); + break; case 5: // Get tileset ID - Output::Debug("Maniac_GetGameInfo - Tileset ID: {}", Game_Map::GetChipset()); Main_Data::game_variables->Set(com.parameters[2], Game_Map::GetChipset()); - return true; - case 6: // Get Face ID - // Param 2: String index - // Param 3: ID index - // Param 4: Window avatar? - // Param 5: Actor ID - // Param 6: Dynamic? + break; + case 6: // Get actor/message face graphic if (com.parameters[4] == 1) { - + // Message + Main_Data::game_strings->Asg(param, Main_Data::game_system->GetMessageFaceName()); + Main_Data::game_variables->Set(com.parameters[3], Main_Data::game_system->GetMessageFaceIndex()); } else { - int actor_id = ValueOrVariableBitfield(com.parameters[0], 0, com.parameters[5]); - Game_Strings::Str_Params param = {com.parameters[2], 0, 0}; + // Actor + event_id = ValueOrVariableBitfield(com.parameters[0], 0, com.parameters[5]); if (com.parameters[6] == 1) { // Dynamic - auto* actor = Main_Data::game_actors->GetActor(actor_id); + auto* actor = Main_Data::game_actors->GetActor(event_id); Main_Data::game_strings->Asg(param, actor->GetFaceName()); Main_Data::game_variables->Set(com.parameters[3], actor->GetFaceIndex()); } else { // Default one - auto* dbActor = lcf::ReaderUtil::GetElement(lcf::Data::actors, actor_id); + auto* dbActor = lcf::ReaderUtil::GetElement(lcf::Data::actors, event_id); Main_Data::game_strings->Asg(param, StringView(dbActor->face_name)); Main_Data::game_variables->Set(com.parameters[3], dbActor->face_index); } } - return true; - default: - Output::Warning("Maniac_GetGameInfo - Option {} not implemented.", com.parameters[1]); - return true; + break; + case 7: // Get actor/event body graphic + event_id = ValueOrVariableBitfield(com.parameters[0], 0, com.parameters[5]); + Game_Event *event; + Game_Vehicle *vehicle; + Game_Character *character; + if (com.parameters[4] == 1) { + // Get event graphic + // Bug: .static 10001 gives current sprite of Player. .dynamic 10001 gives out nothing. + // Bug: Cannot get .static 10005 sprite of self. .dynamic 10005 works however + if (com.parameters[6] == 1) { + // Dynamic + if (event_id == Game_Character::CharPlayer) { + // Return nothing as per Maniac Patch + Main_Data::game_strings->Asg(param, ""); + Main_Data::game_variables->Set(com.parameters[3], 0); + break; + } + character = GetCharacter(event_id); + if (character == nullptr) { + Output::Warning("GetGameInfo: Requested invalid event id ({})", event_id); + break; + } + Main_Data::game_strings->Asg(param, StringView(character->GetSpriteName())); + Main_Data::game_variables->Set(com.parameters[3], character->GetSpriteIndex()); + break; + } else { + // Static + switch (event_id) { + case Game_Character::CharPlayer: + // Return dyamic player sprite + character = GetCharacter(event_id); + Main_Data::game_strings->Asg(param, StringView(character->GetSpriteName())); + Main_Data::game_variables->Set(com.parameters[3], character->GetSpriteIndex()); + break; + case Game_Character::CharBoat: + Main_Data::game_strings->Asg(param, StringView(lcf::Data::system.boat_name)); + Main_Data::game_variables->Set(com.parameters[3], lcf::Data::system.boat_index); + break; + case Game_Character::CharShip: + Main_Data::game_strings->Asg(param, StringView(lcf::Data::system.ship_name)); + Main_Data::game_variables->Set(com.parameters[3], lcf::Data::system.ship_index); + break; + case Game_Character::CharAirship: + Main_Data::game_strings->Asg(param, StringView(lcf::Data::system.airship_name)); + Main_Data::game_variables->Set(com.parameters[3], lcf::Data::system.airship_index); + break; + case Game_Character::CharThisEvent: + default: + if (event_id == Game_Character::CharThisEvent) { + event_id = GetThisEventId(); + // Is a common event + if (event_id == 0) { + // With no map parent + break; + } + } + event = Game_Map::GetEvent(event_id); + if (event == nullptr ) { + Output::Warning("GetGameInfo: Requested invalid event id ({})", event_id); + break; + } + auto *page = event->GetActivePage(); + if (page == nullptr) { + // return nothing + Main_Data::game_strings->Asg(param, ""); + Main_Data::game_variables->Set(com.parameters[3], 0); + } else { + Main_Data::game_strings->Asg(param, StringView(event->GetActivePage()->character_name)); + Main_Data::game_variables->Set(com.parameters[3], event->GetActivePage()->character_index); + } + } + } + } else { + // Get actor graphic + if (com.parameters[6] == 1) { + // Dynamic + auto* actor = Main_Data::game_actors->GetActor(event_id); + Main_Data::game_strings->Asg(param, actor->GetSpriteName()); + Main_Data::game_variables->Set(com.parameters[3], actor->GetSpriteIndex()); + } else { + // Default one + auto* dbActor = lcf::ReaderUtil::GetElement(lcf::Data::actors, event_id); + Main_Data::game_strings->Asg(param, StringView(dbActor->character_name)); + Main_Data::game_variables->Set(com.parameters[3], dbActor->character_index); + } + } + break; + case 8: + // Screen position + Main_Data::game_variables->Set(com.parameters[2], Game_Map::GetPositionX() >> 4); + Main_Data::game_variables->Set(com.parameters[2] + 1, Game_Map::GetPositionY() >> 4); + break; + case 9: + // Screen shake + Main_Data::game_variables->Set(com.parameters[2], Main_Data::game_screen->GetShakeOffsetX()); + Main_Data::game_variables->Set(com.parameters[2] + 1, 0); // Maniac probably supports ShakeOffsetY in its code + break; + case 10: + // Current BGM + Main_Data::game_strings->Asg(param, Main_Data::game_system->GetCurrentBGM().name); + Main_Data::game_variables->Set(com.parameters[3], Main_Data::game_system->GetCurrentBGM().fadein); + Main_Data::game_variables->Set(com.parameters[3] + 1, Main_Data::game_system->GetCurrentBGM().volume); + Main_Data::game_variables->Set(com.parameters[3] + 2, Main_Data::game_system->GetCurrentBGM().tempo); + Main_Data::game_variables->Set(com.parameters[3] + 3, Main_Data::game_system->GetCurrentBGM().balance); + break; } return true; }