From 2e79cf8781c3bfba88b7ba3270fbb4cde1559526 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sat, 22 Mar 2025 02:10:56 -0400 Subject: [PATCH] Map is way better and components::Tile is _vastly_ improved by switching to a wchar_t on display and letting nlohmann::json auto convert it for me. --- assets/devices.json | 6 +++--- assets/enemies.json | 10 +++++----- assets/items.json | 12 ++++++------ assets/tiles.json | 6 +++--- components.hpp | 2 +- map_view.cpp | 30 +++++++++------------------- systems.cpp | 48 ++++++++++++++++++++++++++++++++++----------- systems.hpp | 2 +- textures.cpp | 5 +---- tilemap.cpp | 5 ++--- worldbuilder.cpp | 15 ++------------ 11 files changed, 70 insertions(+), 71 deletions(-) diff --git a/assets/devices.json b/assets/devices.json index 44482fc..d0d2335 100644 --- a/assets/devices.json +++ b/assets/devices.json @@ -7,7 +7,7 @@ "inventory_count": 0, "randomized": false, "components": [ - {"_type": "Tile", "display": "\u2ac5", + {"_type": "Tile", "display": 10949, "foreground": [24, 205, 189], "background": [24, 205, 189] }, @@ -24,7 +24,7 @@ "inventory_count": 0, "placement": "fixed", "components": [ - {"_type": "Tile", "display": "\u2259", + {"_type": "Tile", "display": 8793, "foreground": [24, 205, 189], "background": [24, 205, 189] }, @@ -40,7 +40,7 @@ "description": "Watch where you're going.", "inventory_count": 0, "components": [ - {"_type": "Tile", "display": "\u1ac7", + {"_type": "Tile", "display": 6855, "foreground": [24, 205, 189], "background": [24, 205, 189] }, diff --git a/assets/enemies.json b/assets/enemies.json index e1d8b48..192d224 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -2,7 +2,7 @@ "PLAYER_TILE": { "placement": "fixed", "components": [ - {"_type": "Tile", "display": "\ua66b", + {"_type": "Tile", "display": 42603, "foreground": [255, 200, 125], "background": [30, 20, 75] }, @@ -13,7 +13,7 @@ }, "KNIGHT": { "components": [ - {"_type": "Tile", "display": "\u088d", + {"_type": "Tile", "display": 2189, "foreground": [131, 213, 238], "background": [30, 20, 75] }, @@ -28,7 +28,7 @@ }, "AXE_RANGER": { "components": [ - {"_type": "Tile", "display": "\u076a", + {"_type": "Tile", "display": 1898, "foreground": [156, 172, 197], "background": [30, 20, 75] }, @@ -43,7 +43,7 @@ }, "RAT_GIANT": { "components": [ - {"_type": "Tile", "display": "\u08ac", + {"_type": "Tile", "display": 2220, "foreground": [205, 164, 246], "background": [30, 20, 75] }, @@ -58,7 +58,7 @@ }, "SPIDER_GIANT_HAIRY": { "components": [ - {"_type": "Tile", "display": "\u08ea", + {"_type": "Tile", "display": 2282, "foreground": [205, 164, 246], "background": [30, 20, 75] }, diff --git a/assets/items.json b/assets/items.json index 5bb7d4d..53df9a8 100644 --- a/assets/items.json +++ b/assets/items.json @@ -6,7 +6,7 @@ "inventory_count": 1, "components": [ {"_type": "LightSource", "strength": 50, "radius": 2.5}, - {"_type": "Tile", "display": "\u0f08", + {"_type": "Tile", "display": 3848, "foreground": [24, 120, 189], "background": [230,120, 120] }, @@ -21,7 +21,7 @@ "inventory_count": 1, "components": [ {"_type": "Weapon", "damage": 15}, - {"_type": "Tile", "display": "\u1e37", + {"_type": "Tile", "display": 7735, "foreground": [24, 120, 189], "background": [24, 120, 189] }, @@ -34,7 +34,7 @@ "name": "Small Barrel", "description": "A small rotten barrel that may hold things.", "components": [ - {"_type": "Tile", "display": "\uaaea", + {"_type": "Tile", "display": 43754, "foreground": [150, 100, 189], "background": [150, 100, 189] }, @@ -50,7 +50,7 @@ "description": "Light Hanging from Ceiling", "inventory_count": 0, "components": [ - {"_type": "Tile", "display": "\u077e", + {"_type": "Tile", "display": 1918, "foreground": [24, 205, 210], "background": [24, 205, 210] }, @@ -65,7 +65,7 @@ "description": "A small healing potion.", "inventory_count": 1, "components": [ - {"_type": "Tile", "display": "\u03eb", + {"_type": "Tile", "display": 1003, "foreground": [255, 205, 189], "background": [255, 205, 189] }, @@ -80,7 +80,7 @@ "description": "Something died here. Was this your doing?", "inventory_count": 1, "components": [ - {"_type": "Tile", "display": "\u21ef", + {"_type": "Tile", "display": 8687, "foreground": [32, 123, 164], "background": [24, 205, 189] }, diff --git a/assets/tiles.json b/assets/tiles.json index a1528a8..b586dab 100644 --- a/assets/tiles.json +++ b/assets/tiles.json @@ -4,20 +4,20 @@ "foreground": [40, 15, 125], "background": [200, 15, 75], "collision": false, - "display":"." + "display": 10398 }, "WALL_PLAIN": { "texture": "assets/wall_texture_test-256.png", "foreground": [230, 20, 30], "background": [230, 20, 120], "collision": true, - "display": "#" + "display": 9608 }, "WALL_VINES": { "texture": "assets/wall_with_vines-256.png", "foreground": [230, 20, 30], "background": [230, 20, 120], "collision": false, - "display":"|" + "display": 35 } } diff --git a/components.hpp b/components.hpp index 23341c0..55a96aa 100644 --- a/components.hpp +++ b/components.hpp @@ -30,7 +30,7 @@ namespace components { }; struct Tile { - std::string display; + wchar_t display; std::array foreground; std::array background; }; diff --git a/map_view.cpp b/map_view.cpp index b9015f3..1844083 100644 --- a/map_view.cpp +++ b/map_view.cpp @@ -5,6 +5,7 @@ #include "components.hpp" #include "rand.hpp" #include "animation.hpp" +#include "systems.hpp" #include "rand.hpp" #include #include @@ -13,7 +14,9 @@ namespace gui { using namespace components; MapViewUI::MapViewUI(GameLevel &level) : - $level(level), $tiles(level.map->width(), level.map->height()) + $level(level), + $tiles(level.map->width(), + level.map->height()) { } @@ -26,7 +29,9 @@ namespace gui { $gui.layout("[map_grid]"); auto grid = $gui.entity("map_grid"); - $gui.set(grid, {L"Loading...", 45, ColorValue::DARK_LIGHT, 10}); + $gui.set(grid, + {L"Loading...", 45, ColorValue::DARK_LIGHT, 10}); + $gui.set(grid, {"paper_ui_background"}); $gui.init(); @@ -35,28 +40,11 @@ namespace gui { void MapViewUI::render(sf::RenderWindow &window) { $tiles = $level.map->tiles(); auto grid = $gui.entity("map_grid"); - auto player_pos = $level.world->get($level.player).location; - - std::string map; - - matrix::box it{$level.map->walls(), player_pos.x, player_pos.y, 7, 3}; - - while(it.next()) - { - if(it.x == player_pos.x && it.y == player_pos.y) { - map += "@"; - } else { - map += $tiles.at(it.x, it.y).display; - } - - if(it.x == it.right - 1) map += "\n"; - } - std::wstring_convert> converter; - std::wstring map_wstr = converter.from_bytes(map); + std::wstring map_out = System::draw_map($level, 13, 6); auto& map_text = $gui.get(grid); - map_text.update(map_wstr); + map_text.update(map_out); $gui.render(window); } diff --git a/systems.cpp b/systems.cpp index b40a54c..e0f1b97 100644 --- a/systems.cpp +++ b/systems.cpp @@ -11,6 +11,8 @@ #include "sound.hpp" #include "ai.hpp" #include "ai_debug.hpp" +#include "shiterator.hpp" +#include using std::string; using namespace fmt; @@ -332,21 +334,45 @@ void System::plan_motion(DinkyECS::World& world, Point move_to) { * This one is called inside the MapViewUI very often so * just avoid GameMap unlike the others. */ -void System::draw_entities(DinkyECS::World &world, Map &map, const Matrix &lights, const Point &cam_orig, size_t view_x, size_t view_y) { +std::wstring System::draw_map(GameLevel level, size_t view_x, size_t view_y) { + DinkyECS::World &world = *level.world; + Map &map = *level.map; + + auto player_pos = world.get(level.player).location; + Point cam_orig = map.center_camera(player_pos, view_x, view_y); auto &tiles = map.tiles(); - world.query([&](auto, auto &pos, auto &tile) { - if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x - && pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) { - Point loc = map.map_to_camera(pos.location, cam_orig); + // make a grid of chars to work with + auto grid = shiterator::make(view_x+1, view_y+1); - float light_value = lights[pos.location.y][pos.location.x] * PERCENT; - const Tile& cell = tiles.at(pos.location.x, pos.location.y); + // first fill it with the map cells + for(shiterator::each_cell_t it{grid}; it.next();) { + size_t tile_y = size_t(it.y) + cam_orig.y; + size_t tile_x = size_t(it.x) + cam_orig.x; - (void)loc; // not used yet, this after ripping out map so needs rewrite - (void)light_value; - (void)cell; - (void)tile; + if(tile_x < tiles.$width && tile_y < tiles.$height) { + grid[it.y][it.x] = tiles.at(tile_x, tile_y).display; + } else { + grid[it.y][it.x] = ' '; + } + } + + // then get the enemy/item/device tiles and fill those in + world.query([&](auto, auto &pos, auto &entity_glyph) { + if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x + && pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) { + Point view_pos = map.map_to_camera(pos.location, cam_orig); + grid[view_pos.y][view_pos.x] = entity_glyph.display; } }); + + // then generate the string to display, but this goes away soon + std::wstring result; + + for(shiterator::each_row_t it{grid}; it.next();) { + result += grid[it.y][it.x]; + if(it.row) result += '\n'; + } + + return result; } diff --git a/systems.hpp b/systems.hpp index 9e5f1eb..74225f6 100644 --- a/systems.hpp +++ b/systems.hpp @@ -17,7 +17,7 @@ namespace System { void init_positions(DinkyECS::World &world, SpatialMap &collider); void device(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::Entity item); void plan_motion(DinkyECS::World& world, Point move_to); - void draw_entities(DinkyECS::World &world, Map &map, const Matrix &lights, const Point &cam_orig, size_t view_x, size_t view_y); + std::wstring draw_map(GameLevel level, size_t view_x, size_t view_y); void enemy_ai(GameLevel &level); void combat(GameLevel &level); diff --git a/textures.cpp b/textures.cpp index 52fd84d..354041c 100644 --- a/textures.cpp +++ b/textures.cpp @@ -37,11 +37,8 @@ namespace textures { for(auto &el : tiles.items()) { auto &config = el.value(); TMGR.surfaces.emplace_back(load_image(config["texture"])); - - std::wstring display = assets.wstring(el.key(), "display"); + wchar_t tid = config["display"]; int surface_i = TMGR.surfaces.size() - 1; - wchar_t tid = display[0]; - TMGR.char_to_texture[tid] = surface_i; } } diff --git a/tilemap.cpp b/tilemap.cpp index 1a3f4e8..180eecc 100644 --- a/tilemap.cpp +++ b/tilemap.cpp @@ -11,7 +11,7 @@ TileMap::TileMap(size_t width, size_t height) : $width(width), $height(height), $tile_ids(height, matrix::Row(width, SPACE_VALUE)), - $display(height, TileRow(width, {"", {0,0,0}, {0,0,0}})) + $display(height, TileRow(width, {L'#', {0,0,0}, {0,0,0}})) { } @@ -38,10 +38,9 @@ void TileMap::dump(int show_x, int show_y) { } void TileMap::set_tile(size_t x, size_t y, string tile_name) { - std::wstring tile_id = $config.wstring(tile_name, "display"); json tile_conf = $config[tile_name]; auto tile = components::convert(tile_conf); - $tile_ids[y][x] = tile_id[0]; + $tile_ids[y][x] = tile.display; $display[y][x] = tile; } diff --git a/worldbuilder.cpp b/worldbuilder.cpp index 78fb64a..ae121b3 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -8,15 +8,6 @@ using namespace fmt; using namespace components; -inline void check_player(DinkyECS::World &world, DinkyECS::Entity entity) { - auto player = world.get_the(); - dbc::check(player.entity != entity, "player shouldn't be added to world"); - - auto tile = world.get(player.entity); - - // dbc::check(tile.chr == "\ua66b", format("PLAYER TILE CHANGED {} != {}", tile.chr, "\ua66b")); -} - inline int make_split(Room &cur, bool horiz) { size_t dimension = horiz ? cur.height : cur.width; int min = dimension / WORLDBUILD_DIVISION; @@ -238,8 +229,7 @@ void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config auto entity_data = entity_db[key]; // pass that to the config as it'll be a generic json - auto entity = configure_entity_in_map(world, entity_data, room_num); - check_player(world, entity); + configure_entity_in_map(world, entity_data, room_num); } } @@ -247,8 +237,7 @@ void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) { auto& device_config = config.devices.json(); auto entity_data = device_config["STAIRS_DOWN"]; int last_room = $map.room_count() - 1; - auto entity = configure_entity_in_map(world, entity_data, last_room); - check_player(world, entity); + configure_entity_in_map(world, entity_data, last_room); } void WorldBuilder::place_entities(DinkyECS::World &world) {