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.

master
Zed A. Shaw 1 week ago
parent 2b57552152
commit 2e79cf8781
  1. 6
      assets/devices.json
  2. 10
      assets/enemies.json
  3. 12
      assets/items.json
  4. 6
      assets/tiles.json
  5. 2
      components.hpp
  6. 30
      map_view.cpp
  7. 48
      systems.cpp
  8. 2
      systems.hpp
  9. 5
      textures.cpp
  10. 5
      tilemap.cpp
  11. 15
      worldbuilder.cpp

@ -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]
},

@ -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]
},

@ -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]
},

@ -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
}
}

@ -30,7 +30,7 @@ namespace components {
};
struct Tile {
std::string display;
wchar_t display;
std::array<uint8_t, 3> foreground;
std::array<uint8_t, 3> background;
};

@ -5,6 +5,7 @@
#include "components.hpp"
#include "rand.hpp"
#include "animation.hpp"
#include "systems.hpp"
#include "rand.hpp"
#include <codecvt>
#include <iostream>
@ -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<guecs::WideText>(grid, {L"Loading...", 45, ColorValue::DARK_LIGHT, 10});
$gui.set<guecs::WideText>(grid,
{L"Loading...", 45, ColorValue::DARK_LIGHT, 10});
$gui.set<guecs::Sprite>(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<Position>($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<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring map_wstr = converter.from_bytes(map);
std::wstring map_out = System::draw_map($level, 13, 6);
auto& map_text = $gui.get<guecs::WideText>(grid);
map_text.update(map_wstr);
map_text.update(map_out);
$gui.render(window);
}

@ -11,6 +11,8 @@
#include "sound.hpp"
#include "ai.hpp"
#include "ai_debug.hpp"
#include "shiterator.hpp"
#include <iostream>
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<Position>(level.player).location;
Point cam_orig = map.center_camera(player_pos, view_x, view_y);
auto &tiles = map.tiles();
world.query<Position, Tile>([&](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<wchar_t>(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<Position, Tile>([&](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;
}

@ -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);

@ -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;
}
}

@ -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>(tile_conf);
$tile_ids[y][x] = tile_id[0];
$tile_ids[y][x] = tile.display;
$display[y][x] = tile;
}

@ -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<Player>();
dbc::check(player.entity != entity, "player shouldn't be added to world");
auto tile = world.get<Tile>(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) {

Loading…
Cancel
Save