diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 4ce1d2092d..1d18d6b843 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -4086,10 +4086,26 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co 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]; + + 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]); + tile_coords.y = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[4]); + 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.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]); + } 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..c4068c5d44 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -1885,6 +1885,30 @@ 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 chip_id_or_index) { + 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; + + 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 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, chip_id_or_index)); + } + } + 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..a5f37b7b8b 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 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) * The check includes tile graphic events checks.