From 349232db1d1c47ecea9739c8d9af9c2a102bd990 Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:49:20 -0300 Subject: [PATCH 1/4] GetInfo - Support Tile ID --- src/game_interpreter.cpp | 25 ++++++++++++++++++++++--- src/game_map.cpp | 19 +++++++++++++++++++ src/game_map.h | 3 +++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 4ce1d2092d..2e32757dc9 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -4081,15 +4081,34 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co int event_id; int var = com.parameters[2]; + struct rect { + int x, y, w, h; + }; + switch (com.parameters[1]) { case 0: // Get map size Main_Data::game_variables->Set(var, Game_Map::GetTilesX()); Main_Data::game_variables->Set(var + 1, Game_Map::GetTilesY()); break; - case 1: // Get tile info - // FIXME: figure out how 'Tile Info' works - Output::Warning("GetGameInfo: Option 'Tile Info' not implemented."); + case 1: { // Get tile info + + var = com.parameters[7]; + + auto tile_layer = com.parameters[2]; // 0: Lower || 1: Upper + auto tile_coords = rect{}; + + tile_coords.x = ValueOrVariableBitfield(com.parameters[0], 1, com.parameters[3]); + tile_coords.y = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[4]); + tile_coords.w = ValueOrVariableBitfield(com.parameters[0], 3, com.parameters[5]); + tile_coords.h = ValueOrVariableBitfield(com.parameters[0], 4, com.parameters[6]); + + auto tiles = Game_Map::GetTilesIdAt(tile_coords.x, tile_coords.y, tile_coords.w, tile_coords.h, tile_layer); + + for (int i = 0; i < tile_coords.w * tile_coords.h; i++) { + Main_Data::game_variables->Set(var + i, tiles[i]); + } break; + } case 2: // Get window size Main_Data::game_variables->Set(var, Player::screen_width); Main_Data::game_variables->Set(var + 1, Player::screen_height); diff --git a/src/game_map.cpp b/src/game_map.cpp index 6efd76765f..4c72959cab 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -1885,6 +1885,25 @@ void Game_Map::ReplaceTileAt(int x, int y, int new_id, int layer) { layer_vec[pos] = static_cast(new_id); } +int Game_Map::GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex) { + auto pos = x + y * map->width; + auto& layer_vec = layer >= 1 ? map->upper_layer : map->lower_layer; + + int tile_output = chipIdOrIndex ? layer_vec[pos] : ChipIdToIndex(layer_vec[pos]); + if (layer >= 1) tile_output -= BLOCK_F_INDEX; + return tile_output; +} + +std::vector Game_Map::GetTilesIdAt(int x, int y, int width, int height, int layer, bool chipIdOrIndex) { + std::vector tiles_collection; + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { + tiles_collection.emplace_back(Game_Map::GetTileIdAt(x + j, y + i, layer, chipIdOrIndex)); + } + } + return tiles_collection; +} + std::string Game_Map::ConstructMapName(int map_id, bool is_easyrpg) { std::stringstream ss; ss << "Map" << std::setfill('0') << std::setw(4) << map_id; diff --git a/src/game_map.h b/src/game_map.h index 95d6ce5389..fe10028d99 100644 --- a/src/game_map.h +++ b/src/game_map.h @@ -643,6 +643,9 @@ namespace Game_Map { int SubstituteUp(int old_id, int new_id); void ReplaceTileAt(int x, int y, int new_id, int layer); + int GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex = false); + std::vector GetTilesIdAt(int x, int y, int width, int height, int layer, bool chipIdOrIndex = false); + /** * Checks if its possible to step onto the tile at (x,y) * The check includes tile graphic events checks. From a6f98cb4225d9c7f771d849b6f958bf63a552633 Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:49:25 -0300 Subject: [PATCH 2/4] Get Info/Tile ID - Add Sanity Checks Now the behaviors are similar both in Maniacs and EasyRPG. --- src/game_interpreter.cpp | 2 ++ src/game_map.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 2e32757dc9..6657dd0250 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -4102,6 +4102,8 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co tile_coords.w = ValueOrVariableBitfield(com.parameters[0], 3, com.parameters[5]); tile_coords.h = ValueOrVariableBitfield(com.parameters[0], 4, com.parameters[6]); + if (tile_coords.w <= 0 || tile_coords.h <= 0) return true; + auto tiles = Game_Map::GetTilesIdAt(tile_coords.x, tile_coords.y, tile_coords.w, tile_coords.h, tile_layer); for (int i = 0; i < tile_coords.w * tile_coords.h; i++) { diff --git a/src/game_map.cpp b/src/game_map.cpp index 4c72959cab..dab3f8354e 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -1886,6 +1886,10 @@ void Game_Map::ReplaceTileAt(int x, int y, int new_id, int layer) { } int Game_Map::GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex) { + if (x < 0 || x >= map->width || y < 0 || y >= map->height) { + return 0; // Return 0 for out-of-bounds coordinates + } + auto pos = x + y * map->width; auto& layer_vec = layer >= 1 ? map->upper_layer : map->lower_layer; From 0cc19c1c35400a22d4414c80052a257b3e01a105 Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Wed, 8 Jan 2025 20:45:42 -0300 Subject: [PATCH 3/4] Get Info/Tile ID - Using Rect Class --- src/game_interpreter.cpp | 16 ++++++---------- src/game_map.cpp | 8 ++++---- src/game_map.h | 2 +- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 6657dd0250..9ae1070991 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -4080,10 +4080,6 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co int event_id; int var = com.parameters[2]; - - struct rect { - int x, y, w, h; - }; switch (com.parameters[1]) { case 0: // Get map size @@ -4095,18 +4091,18 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co var = com.parameters[7]; auto tile_layer = com.parameters[2]; // 0: Lower || 1: Upper - auto tile_coords = rect{}; + Rect tile_coords; tile_coords.x = ValueOrVariableBitfield(com.parameters[0], 1, com.parameters[3]); tile_coords.y = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[4]); - tile_coords.w = ValueOrVariableBitfield(com.parameters[0], 3, com.parameters[5]); - tile_coords.h = ValueOrVariableBitfield(com.parameters[0], 4, com.parameters[6]); + tile_coords.width = ValueOrVariableBitfield(com.parameters[0], 3, com.parameters[5]); + tile_coords.height = ValueOrVariableBitfield(com.parameters[0], 4, com.parameters[6]); - if (tile_coords.w <= 0 || tile_coords.h <= 0) return true; + if (tile_coords.width <= 0 || tile_coords.height <= 0) return true; - auto tiles = Game_Map::GetTilesIdAt(tile_coords.x, tile_coords.y, tile_coords.w, tile_coords.h, tile_layer); + auto tiles = Game_Map::GetTilesIdAt(tile_coords, tile_layer); - for (int i = 0; i < tile_coords.w * tile_coords.h; i++) { + for (int i = 0; i < tile_coords.width * tile_coords.height; i++) { Main_Data::game_variables->Set(var + i, tiles[i]); } break; diff --git a/src/game_map.cpp b/src/game_map.cpp index dab3f8354e..23e599ec5a 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -1898,11 +1898,11 @@ int Game_Map::GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex) { return tile_output; } -std::vector Game_Map::GetTilesIdAt(int x, int y, int width, int height, int layer, bool chipIdOrIndex) { +std::vector Game_Map::GetTilesIdAt(Rect coords, int layer, bool chipIdOrIndex) { std::vector tiles_collection; - for (int i = 0; i < height; ++i) { - for (int j = 0; j < width; ++j) { - tiles_collection.emplace_back(Game_Map::GetTileIdAt(x + j, y + i, layer, chipIdOrIndex)); + for (int i = 0; i < coords.height; ++i) { + for (int j = 0; j < coords.width; ++j) { + tiles_collection.emplace_back(Game_Map::GetTileIdAt(coords.x + j, coords.y + i, layer, chipIdOrIndex)); } } return tiles_collection; diff --git a/src/game_map.h b/src/game_map.h index fe10028d99..edac9d0cb1 100644 --- a/src/game_map.h +++ b/src/game_map.h @@ -644,7 +644,7 @@ namespace Game_Map { void ReplaceTileAt(int x, int y, int new_id, int layer); int GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex = false); - std::vector GetTilesIdAt(int x, int y, int width, int height, int layer, bool chipIdOrIndex = false); + std::vector GetTilesIdAt(Rect coords, int layer, bool chipIdOrIndex = false); /** * Checks if its possible to step onto the tile at (x,y) From ecddd23aa021c2ca6c80d70166a349ab702dfa11 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Fri, 10 Jan 2025 02:23:34 +0100 Subject: [PATCH 4/4] GetInfo/TileID - Minor cleanup --- src/game_interpreter.cpp | 7 +++---- src/game_map.cpp | 9 +++++---- src/game_map.h | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 9ae1070991..1d18d6b843 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -4080,17 +4080,16 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co int event_id; int var = com.parameters[2]; - + switch (com.parameters[1]) { case 0: // Get map size Main_Data::game_variables->Set(var, Game_Map::GetTilesX()); Main_Data::game_variables->Set(var + 1, Game_Map::GetTilesY()); break; case 1: { // Get tile info - var = com.parameters[7]; - auto tile_layer = com.parameters[2]; // 0: Lower || 1: Upper + int32_t tile_layer = com.parameters[2]; // 0: Lower || 1: Upper Rect tile_coords; tile_coords.x = ValueOrVariableBitfield(com.parameters[0], 1, com.parameters[3]); @@ -4101,7 +4100,7 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co if (tile_coords.width <= 0 || tile_coords.height <= 0) return true; auto tiles = Game_Map::GetTilesIdAt(tile_coords, tile_layer); - + for (int i = 0; i < tile_coords.width * tile_coords.height; i++) { Main_Data::game_variables->Set(var + i, tiles[i]); } diff --git a/src/game_map.cpp b/src/game_map.cpp index 23e599ec5a..c4068c5d44 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -1885,7 +1885,7 @@ void Game_Map::ReplaceTileAt(int x, int y, int new_id, int layer) { layer_vec[pos] = static_cast(new_id); } -int Game_Map::GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex) { +int Game_Map::GetTileIdAt(int x, int y, int layer, bool chip_id_or_index) { if (x < 0 || x >= map->width || y < 0 || y >= map->height) { return 0; // Return 0 for out-of-bounds coordinates } @@ -1893,16 +1893,17 @@ int Game_Map::GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex) { auto pos = x + y * map->width; auto& layer_vec = layer >= 1 ? map->upper_layer : map->lower_layer; - int tile_output = chipIdOrIndex ? layer_vec[pos] : ChipIdToIndex(layer_vec[pos]); + int tile_output = chip_id_or_index ? layer_vec[pos] : ChipIdToIndex(layer_vec[pos]); if (layer >= 1) tile_output -= BLOCK_F_INDEX; + return tile_output; } -std::vector Game_Map::GetTilesIdAt(Rect coords, int layer, bool chipIdOrIndex) { +std::vector Game_Map::GetTilesIdAt(Rect coords, int layer, bool chip_id_or_index) { std::vector tiles_collection; for (int i = 0; i < coords.height; ++i) { for (int j = 0; j < coords.width; ++j) { - tiles_collection.emplace_back(Game_Map::GetTileIdAt(coords.x + j, coords.y + i, layer, chipIdOrIndex)); + tiles_collection.emplace_back(Game_Map::GetTileIdAt(coords.x + j, coords.y + i, layer, chip_id_or_index)); } } return tiles_collection; diff --git a/src/game_map.h b/src/game_map.h index edac9d0cb1..a5f37b7b8b 100644 --- a/src/game_map.h +++ b/src/game_map.h @@ -643,8 +643,8 @@ namespace Game_Map { int SubstituteUp(int old_id, int new_id); void ReplaceTileAt(int x, int y, int new_id, int layer); - int GetTileIdAt(int x, int y, int layer, bool chipIdOrIndex = false); - std::vector GetTilesIdAt(Rect coords, int layer, bool chipIdOrIndex = false); + int GetTileIdAt(int x, int y, int layer, bool chip_id_or_index = false); + std::vector GetTilesIdAt(Rect coords, int layer, bool chip_id_or_index = false); /** * Checks if its possible to step onto the tile at (x,y)