Did a full code review to identify things to fix and either fixed them or noted BUG where I should come back.
This commit is contained in:
parent
ae43dad499
commit
9abb39a3bf
14 changed files with 72 additions and 35 deletions
|
@ -7,7 +7,7 @@ using namespace nlohmann;
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
json $config;
|
json $config;
|
||||||
std::string $src_path = "./config.json";
|
std::string $src_path;
|
||||||
|
|
||||||
Config(const std::string src_path);
|
Config(const std::string src_path);
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,6 @@ namespace DinkyECS {
|
||||||
template <typename Comp>
|
template <typename Comp>
|
||||||
bool has(Entity ent) {
|
bool has(Entity ent) {
|
||||||
EntityMap &map = entity_map_for<Comp>();
|
EntityMap &map = entity_map_for<Comp>();
|
||||||
// use .at for bounds checking
|
|
||||||
return map.contains(ent);
|
return map.contains(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +115,6 @@ namespace DinkyECS {
|
||||||
EventQueue &queue = queue_map_for<Comp>();
|
EventQueue &queue = queue_map_for<Comp>();
|
||||||
Event evt = queue.front();
|
Event evt = queue.front();
|
||||||
queue.pop();
|
queue.pop();
|
||||||
// I could use tie here to auto extract the any
|
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
gui.cpp
10
gui.cpp
|
@ -179,6 +179,7 @@ bool GUI::handle_ui_events() {
|
||||||
|
|
||||||
while($renderer.poll_event(event)) {
|
while($renderer.poll_event(event)) {
|
||||||
if(event.type == sf::Event::Closed) {
|
if(event.type == sf::Event::Closed) {
|
||||||
|
// BUG: This should call a GUI::shutdown so I can do saves and stuff.
|
||||||
$renderer.close();
|
$renderer.close();
|
||||||
} else if(event.type == sf::Event::KeyPressed) {
|
} else if(event.type == sf::Event::KeyPressed) {
|
||||||
|
|
||||||
|
@ -209,8 +210,11 @@ bool GUI::handle_ui_events() {
|
||||||
sf::Vector2i pos = MOUSE::getPosition($renderer.$window);
|
sf::Vector2i pos = MOUSE::getPosition($renderer.$window);
|
||||||
Mouse mev;
|
Mouse mev;
|
||||||
mev.button = Mouse::Button::Left,
|
mev.button = Mouse::Button::Left,
|
||||||
mev.x=pos.x / $renderer.$ui_bounds.width; // this needs to be in...panel coordinates?
|
// BUG: renderer should have a function that handles mouse coordinates
|
||||||
|
// BUG: optionally maybe have it in panel? Seems to work though.
|
||||||
|
mev.x=pos.x / $renderer.$ui_bounds.width;
|
||||||
mev.y=pos.y / $renderer.$ui_bounds.height;
|
mev.y=pos.y / $renderer.$ui_bounds.height;
|
||||||
|
// BUG: maybe also handle mouse motion events?
|
||||||
$status_ui.$component->OnEvent(Event::Mouse("", mev));
|
$status_ui.$component->OnEvent(Event::Mouse("", mev));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,8 +234,8 @@ void GUI::run_systems() {
|
||||||
|
|
||||||
void GUI::shake() {
|
void GUI::shake() {
|
||||||
for(int i = 0; i < 10; ++i) {
|
for(int i = 0; i < 10; ++i) {
|
||||||
int x = Random::uniform<int>(-20,20);
|
int x = Random::uniform<int>(-10,10);
|
||||||
int y = Random::uniform<int>(-20,20);
|
int y = Random::uniform<int>(-10,10);
|
||||||
// add x/y back to draw screen
|
// add x/y back to draw screen
|
||||||
$renderer.draw($map_view, x, y);
|
$renderer.draw($map_view, x, y);
|
||||||
$renderer.display();
|
$renderer.display();
|
||||||
|
|
12
lights.cpp
12
lights.cpp
|
@ -15,7 +15,7 @@ namespace lighting {
|
||||||
|
|
||||||
for(size_t y = min.y; y <= max.y; ++y) {
|
for(size_t y = min.y; y <= max.y; ++y) {
|
||||||
auto &light_row = $lightmap[y];
|
auto &light_row = $lightmap[y];
|
||||||
auto &path_row = $light.$paths[y];
|
auto &path_row = $paths.$paths[y];
|
||||||
|
|
||||||
for(size_t x = min.x; x <= max.x; ++x) {
|
for(size_t x = min.x; x <= max.x; ++x) {
|
||||||
if(path_row[x] != UNPATH) {
|
if(path_row[x] != UNPATH) {
|
||||||
|
@ -28,7 +28,7 @@ namespace lighting {
|
||||||
const int wall_light = source.strength + WALL_LIGHT_LEVEL;
|
const int wall_light = source.strength + WALL_LIGHT_LEVEL;
|
||||||
for(auto point : has_light) {
|
for(auto point : has_light) {
|
||||||
for(int j = -1;point.y+j >= 0 && j <= 1 && point.y+j < $height; j++) {
|
for(int j = -1;point.y+j >= 0 && j <= 1 && point.y+j < $height; j++) {
|
||||||
auto &path_row = $light.$paths[point.y+j];
|
auto &path_row = $paths.$paths[point.y+j];
|
||||||
auto &light_row = $lightmap[point.y+j];
|
auto &light_row = $lightmap[point.y+j];
|
||||||
|
|
||||||
for(int i = -1; point.x+i >= 0 && i <= 1 && point.x+i < $width; i++) {
|
for(int i = -1; point.x+i >= 0 && i <= 1 && point.x+i < $width; i++) {
|
||||||
|
@ -41,7 +41,7 @@ namespace lighting {
|
||||||
}
|
}
|
||||||
|
|
||||||
int LightRender::light_level(int level, size_t x, size_t y) {
|
int LightRender::light_level(int level, size_t x, size_t y) {
|
||||||
size_t at = level + $light.$paths[y][x];
|
size_t at = level + $paths.$paths[y][x];
|
||||||
int cur_level = $lightmap[y][x];
|
int cur_level = $lightmap[y][x];
|
||||||
int new_level = at < lighting::LEVELS.size() ? lighting::LEVELS[at] : lighting::MIN;
|
int new_level = at < lighting::LEVELS.size() ? lighting::LEVELS[at] : lighting::MIN;
|
||||||
return cur_level < new_level ? new_level : cur_level;
|
return cur_level < new_level ? new_level : cur_level;
|
||||||
|
@ -55,15 +55,15 @@ namespace lighting {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightRender::clear_light_target(const Point &at) {
|
void LightRender::clear_light_target(const Point &at) {
|
||||||
$light.clear_target(at);
|
$paths.clear_target(at);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightRender::set_light_target(const Point &at, int value) {
|
void LightRender::set_light_target(const Point &at, int value) {
|
||||||
$light.set_target(at, value);
|
$paths.set_target(at, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightRender::path_light(Matrix &walls) {
|
void LightRender::path_light(Matrix &walls) {
|
||||||
$light.compute_paths(walls);
|
$paths.compute_paths(walls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightRender::light_box(LightSource source, Point from, Point &min_out, Point &max_out) {
|
void LightRender::light_box(LightSource source, Point from, Point &min_out, Point &max_out) {
|
||||||
|
|
|
@ -36,14 +36,14 @@ namespace lighting {
|
||||||
size_t $width;
|
size_t $width;
|
||||||
size_t $height;
|
size_t $height;
|
||||||
Matrix $lightmap;
|
Matrix $lightmap;
|
||||||
Pathing $light;
|
Pathing $paths;
|
||||||
|
|
||||||
LightRender(size_t width, size_t height, int limit) :
|
LightRender(size_t width, size_t height, int limit) :
|
||||||
$limit(limit),
|
$limit(limit),
|
||||||
$width(width),
|
$width(width),
|
||||||
$height(height),
|
$height(height),
|
||||||
$lightmap(height, MatrixRow(width, 0)),
|
$lightmap(height, MatrixRow(width, 0)),
|
||||||
$light(width, height, limit)
|
$paths(width, height, limit)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void reset_light();
|
void reset_light();
|
||||||
|
|
3
map.cpp
3
map.cpp
|
@ -66,6 +66,7 @@ Point Map::place_entity(size_t room_index) {
|
||||||
dbc::check(room_index < $rooms.size(), "room_index is out of bounds, not enough rooms");
|
dbc::check(room_index < $rooms.size(), "room_index is out of bounds, not enough rooms");
|
||||||
|
|
||||||
Room &start = $rooms[room_index];
|
Room &start = $rooms[room_index];
|
||||||
|
// BUG: this can place someone in a wall on accident, move them if they're stuck
|
||||||
return {start.x+1, start.y+1};
|
return {start.x+1, start.y+1};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,12 +143,14 @@ bool Map::neighbors(Point &out, bool random) {
|
||||||
int cur = paths[out.y][out.x];
|
int cur = paths[out.y][out.x];
|
||||||
|
|
||||||
// pick a random start of directions
|
// pick a random start of directions
|
||||||
|
// BUG: is uniform inclusive of the dir.size()?
|
||||||
int rand_start = Random::uniform<int>(0, dirs.size());
|
int rand_start = Random::uniform<int>(0, dirs.size());
|
||||||
|
|
||||||
// go through all possible directions
|
// go through all possible directions
|
||||||
for(size_t i = 0; i < dirs.size(); i++) {
|
for(size_t i = 0; i < dirs.size(); i++) {
|
||||||
// but start at the random start, effectively randomizing
|
// but start at the random start, effectively randomizing
|
||||||
// which valid direction to go
|
// which valid direction to go
|
||||||
|
// BUG: this might be wrong given the above ranom from 0-size
|
||||||
Point dir = dirs[(i + rand_start) % dirs.size()];
|
Point dir = dirs[(i + rand_start) % dirs.size()];
|
||||||
if(!inmap(dir.x, dir.y)) continue; //skip unpathable stuff
|
if(!inmap(dir.x, dir.y)) continue; //skip unpathable stuff
|
||||||
int weight = cur - paths[dir.y][dir.x];
|
int weight = cur - paths[dir.y][dir.x];
|
||||||
|
|
|
@ -16,6 +16,7 @@ inline void add_neighbors(PointList &neighbors, Matrix &closed, size_t y, size_t
|
||||||
(0 <= col && col < w) &&
|
(0 <= col && col < w) &&
|
||||||
closed[row][col] == 0)
|
closed[row][col] == 0)
|
||||||
{
|
{
|
||||||
|
// BUG: maybe value here?
|
||||||
closed[row][col] = 1;
|
closed[row][col] = 1;
|
||||||
neighbors.push_back({.x=col, .y=row});
|
neighbors.push_back({.x=col, .y=row});
|
||||||
}
|
}
|
||||||
|
@ -43,8 +44,8 @@ void Pathing::compute_paths(Matrix &walls) {
|
||||||
size_t y = counter / $width;
|
size_t y = counter / $width;
|
||||||
if($input[y][x] == 0) {
|
if($input[y][x] == 0) {
|
||||||
$paths[y][x] = 0;
|
$paths[y][x] = 0;
|
||||||
closed[y][x] = 1;
|
closed[y][x] = 1; // BUG: value here?
|
||||||
starting_pixels.push_back({.x=x,.y=y});
|
starting_pixels.push_back({x,y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ void Pathing::compute_paths(Matrix &walls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pathing::set_target(const Point &at, int value) {
|
void Pathing::set_target(const Point &at, int value) {
|
||||||
|
// BUG: not using value here but it can be < 0 for deeper slopes
|
||||||
$input[at.y][at.x] = 0;
|
$input[at.y][at.x] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
render.cpp
14
render.cpp
|
@ -6,6 +6,7 @@
|
||||||
#include "map.hpp"
|
#include "map.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -65,7 +66,8 @@ void SFMLRender::resize_grid(int new_size, Panel &panel_out) {
|
||||||
panel_out.resize(view_x, view_y);
|
panel_out.resize(view_x, view_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void configure_tile(const sf::Sprite &sprite, sf::FloatRect &sp_bounds, sf::FloatRect bg_bounds, float &width_delta, float &height_delta) {
|
inline void configure_tile(const sf::Sprite &sprite, sf::FloatRect &sp_bounds, sf::FloatRect bg_bounds, float &width_delta, float &height_delta) {
|
||||||
|
// BUG: I think I could create a struct that kept this info for all sprites loaded
|
||||||
// should look into caching all this instead of calcing it each time
|
// should look into caching all this instead of calcing it each time
|
||||||
sp_bounds = sprite.getLocalBounds();
|
sp_bounds = sprite.getLocalBounds();
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ inline void configure_tile(const sf::Sprite &sprite, sf::FloatRect &sp_bounds,
|
||||||
}
|
}
|
||||||
|
|
||||||
void SFMLRender::render_grid(const std::wstring &text, sf::Color default_fg, sf::Color default_bg, float x, float y) {
|
void SFMLRender::render_grid(const std::wstring &text, sf::Color default_fg, sf::Color default_bg, float x, float y) {
|
||||||
wchar_t last_tile = '#';
|
wchar_t last_tile = $config.bg_tile;
|
||||||
sf::FloatRect sp_bounds;
|
sf::FloatRect sp_bounds;
|
||||||
float width_delta = 0;
|
float width_delta = 0;
|
||||||
float height_delta = 0;
|
float height_delta = 0;
|
||||||
|
@ -86,7 +88,7 @@ void SFMLRender::render_grid(const std::wstring &text, sf::Color default_fg, sf:
|
||||||
sf::Color cur_bg = default_bg;
|
sf::Color cur_bg = default_bg;
|
||||||
|
|
||||||
// make a copy so we don't modify the cached one
|
// make a copy so we don't modify the cached one
|
||||||
$ansi.parse(text, [&](sf::Color fg, sf::Color bg) {
|
$ansi.parse(text, [&](auto fg, auto bg) {
|
||||||
cur_fg = fg;
|
cur_fg = fg;
|
||||||
cur_bg = bg;
|
cur_bg = bg;
|
||||||
},
|
},
|
||||||
|
@ -104,9 +106,9 @@ void SFMLRender::render_grid(const std::wstring &text, sf::Color default_fg, sf:
|
||||||
|
|
||||||
// only get a new sprite if the tile changed
|
// only get a new sprite if the tile changed
|
||||||
if(last_tile != tile) {
|
if(last_tile != tile) {
|
||||||
last_tile = tile; // update last tile seen
|
|
||||||
sprite = get_text_sprite(tile);
|
sprite = get_text_sprite(tile);
|
||||||
configure_tile(sprite, sp_bounds, $bg_bounds, width_delta, height_delta);
|
configure_tile(sprite, sp_bounds, $bg_bounds, width_delta, height_delta);
|
||||||
|
last_tile = tile; // update last tile seen
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.setPosition({x+width_delta, y+height_delta});
|
sprite.setPosition({x+width_delta, y+height_delta});
|
||||||
|
@ -135,6 +137,7 @@ inline sf::FloatRect draw_chunk(sf::RenderWindow& window,
|
||||||
text.setPosition({x, y});
|
text.setPosition({x, y});
|
||||||
// get a base character for the cell size
|
// get a base character for the cell size
|
||||||
sf::FloatRect bounds(x, y, ui_bounds.width * out.size(), ui_bounds.height);
|
sf::FloatRect bounds(x, y, ui_bounds.width * out.size(), ui_bounds.height);
|
||||||
|
|
||||||
if(default_bg != bgcolor) {
|
if(default_bg != bgcolor) {
|
||||||
sf::RectangleShape backing({bounds.width, bounds.height});
|
sf::RectangleShape backing({bounds.width, bounds.height});
|
||||||
backing.setFillColor(bgcolor);
|
backing.setFillColor(bgcolor);
|
||||||
|
@ -157,7 +160,7 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_fg, sf:
|
||||||
$ui_text.setFillColor(default_fg);
|
$ui_text.setFillColor(default_fg);
|
||||||
|
|
||||||
$ansi.parse(text,
|
$ansi.parse(text,
|
||||||
[&](sf::Color fg, sf::Color bg) {
|
[&](auto fg, auto bg) {
|
||||||
if(out.size() > 0 ) {
|
if(out.size() > 0 ) {
|
||||||
auto bounds = draw_chunk($window,
|
auto bounds = draw_chunk($window,
|
||||||
$ui_bounds, $ui_text,
|
$ui_bounds, $ui_text,
|
||||||
|
@ -232,6 +235,5 @@ void SFMLRender::init_terminal() {
|
||||||
_setmode(_fileno(stdout), _O_U16TEXT);
|
_setmode(_fileno(stdout), _O_U16TEXT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the parser only handles full color so force it
|
|
||||||
ftxui::Terminal::SetColorSupport(ftxui::Terminal::Color::TrueColor);
|
ftxui::Terminal::SetColorSupport(ftxui::Terminal::Color::TrueColor);
|
||||||
}
|
}
|
||||||
|
|
9
save.cpp
9
save.cpp
|
@ -21,8 +21,11 @@ void save::to_file(fs::path path, DinkyECS::World &world, Map &map) {
|
||||||
tser::BinaryArchive archive;
|
tser::BinaryArchive archive;
|
||||||
|
|
||||||
save_data.facts.player = world.get_the<Player>();
|
save_data.facts.player = world.get_the<Player>();
|
||||||
save_data.map = MapData{map.$rooms, map.$walls, map.$limit};
|
save_data.map = MapData{
|
||||||
|
map.$limit, map.$width, map.$height,
|
||||||
|
map.$rooms, map.$walls};
|
||||||
|
|
||||||
|
// BUG: lights aren't saved/restored
|
||||||
extract<Position>(world, save_data.position);
|
extract<Position>(world, save_data.position);
|
||||||
extract<Combat>(world, save_data.combat);
|
extract<Combat>(world, save_data.combat);
|
||||||
extract<Motion>(world, save_data.motion);
|
extract<Motion>(world, save_data.motion);
|
||||||
|
@ -71,8 +74,8 @@ void save::from_file(fs::path path, DinkyECS::World &world_out, Map &map_out) {
|
||||||
inject<Tile>(world_out, save_data.tile);
|
inject<Tile>(world_out, save_data.tile);
|
||||||
inject<Inventory>(world_out, save_data.inventory);
|
inject<Inventory>(world_out, save_data.inventory);
|
||||||
|
|
||||||
size_t width = save_data.map.walls[0].size();
|
size_t width = save_data.map.width;
|
||||||
size_t height = save_data.map.walls.size();
|
size_t height = save_data.map.height;
|
||||||
int limit = save_data.map.limit;
|
int limit = save_data.map.limit;
|
||||||
|
|
||||||
Pathing paths(width, height, limit);
|
Pathing paths(width, height, limit);
|
||||||
|
|
6
save.hpp
6
save.hpp
|
@ -11,11 +11,13 @@ namespace save {
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
struct MapData {
|
struct MapData {
|
||||||
|
int limit;
|
||||||
|
size_t width;
|
||||||
|
size_t height;
|
||||||
std::vector<Room> rooms;
|
std::vector<Room> rooms;
|
||||||
Matrix walls;
|
Matrix walls;
|
||||||
int limit;
|
|
||||||
|
|
||||||
DEFINE_SERIALIZABLE(MapData, rooms, walls);
|
DEFINE_SERIALIZABLE(MapData, limit, width, height, rooms, walls);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Facts {
|
struct Facts {
|
||||||
|
|
|
@ -6,6 +6,15 @@ TODAY'S GOAL:
|
||||||
* Lua integration
|
* Lua integration
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
* $limit is pointless, just use a constant.
|
||||||
|
* Pathing::compute_paths can take a starting level to implement lower directions, or possibly setting a value lower?
|
||||||
|
* Pathing::set_target isn't using value, but that implements the above.
|
||||||
|
https://www.roguebasin.com/index.php/Dijkstra_Maps_Visualized
|
||||||
|
|
||||||
|
* When fighting two enemies with lots of attacks it crashes because one dies and isn't there. Test by making enemies immortal.
|
||||||
|
* LightRender can just use the Dijkstra map paths to calculate light strenght from the point rather than doing the box thing.
|
||||||
|
* $paths.$paths is annoying.
|
||||||
|
* Format of pre/post in dbc isn't consistent with the rest of the lib but I also maybe don't need the function version?
|
||||||
* I can do headless windows in renderer for testing.
|
* I can do headless windows in renderer for testing.
|
||||||
- renderer.$window.setVisible(false);
|
- renderer.$window.setVisible(false);
|
||||||
* Think up an enemy system.
|
* Think up an enemy system.
|
||||||
|
|
14
systems.cpp
14
systems.cpp
|
@ -25,6 +25,7 @@ void System::lighting(DinkyECS::World &world, Map &game_map, LightRender &light,
|
||||||
light.set_light_target(position.location);
|
light.set_light_target(position.location);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// BUG: some light doesn't move, can I not path those?
|
||||||
light.path_light(game_map.walls());
|
light.path_light(game_map.walls());
|
||||||
|
|
||||||
world.query<Position, LightSource>([&](const auto &ent, auto &position, auto &lightsource) {
|
world.query<Position, LightSource>([&](const auto &ent, auto &position, auto &lightsource) {
|
||||||
|
@ -44,6 +45,7 @@ void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player
|
||||||
if(ent != player.entity) {
|
if(ent != player.entity) {
|
||||||
Point out = position.location; // copy
|
Point out = position.location; // copy
|
||||||
if(game_map.distance(out) < config.HEARING_DISTANCE) {
|
if(game_map.distance(out) < config.HEARING_DISTANCE) {
|
||||||
|
// BUG: is neighbors really the best name for this?
|
||||||
game_map.neighbors(out);
|
game_map.neighbors(out);
|
||||||
motion = { int(out.x - position.location.x), int(out.y - position.location.y)};
|
motion = { int(out.x - position.location.x), int(out.y - position.location.y)};
|
||||||
}
|
}
|
||||||
|
@ -55,6 +57,8 @@ void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player
|
||||||
void System::init_positions(DinkyECS::World &world) {
|
void System::init_positions(DinkyECS::World &world) {
|
||||||
auto &collider = world.get_the<spatial_map>();
|
auto &collider = world.get_the<spatial_map>();
|
||||||
|
|
||||||
|
// BUG: instead of separate things maybe just one
|
||||||
|
// BUG: Collision component that references what is collide
|
||||||
world.query<Position, Combat>([&](const auto &ent, auto &pos, auto &combat) {
|
world.query<Position, Combat>([&](const auto &ent, auto &pos, auto &combat) {
|
||||||
if(!combat.dead) {
|
if(!combat.dead) {
|
||||||
collider.insert(pos.location, ent);
|
collider.insert(pos.location, ent);
|
||||||
|
@ -95,6 +99,10 @@ void System::motion(DinkyECS::World &world, Map &game_map) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::death(DinkyECS::World &world) {
|
void System::death(DinkyECS::World &world) {
|
||||||
|
// BUG: this is where entities can die on top of
|
||||||
|
// BUG: eachother and overlap their corpse
|
||||||
|
// BUG: maybe that can be allowed and looting just shows
|
||||||
|
// BUG: all dead things there?
|
||||||
auto &collider = world.get_the<spatial_map>();
|
auto &collider = world.get_the<spatial_map>();
|
||||||
|
|
||||||
world.query<Position, Combat>([&](const auto &ent, auto &position, auto &combat) {
|
world.query<Position, Combat>([&](const auto &ent, auto &position, auto &combat) {
|
||||||
|
@ -119,7 +127,6 @@ void System::collision(DinkyECS::World &world, Player &player) {
|
||||||
auto [found, nearby] = collider.neighbors(player_position.location);
|
auto [found, nearby] = collider.neighbors(player_position.location);
|
||||||
|
|
||||||
if(found) {
|
if(found) {
|
||||||
|
|
||||||
for(auto entity : nearby) {
|
for(auto entity : nearby) {
|
||||||
if(world.has<Combat>(entity)) {
|
if(world.has<Combat>(entity)) {
|
||||||
auto& enemy_combat = world.get<Combat>(entity);
|
auto& enemy_combat = world.get<Combat>(entity);
|
||||||
|
@ -134,6 +141,7 @@ void System::collision(DinkyECS::World &world, Player &player) {
|
||||||
auto loot = world.get<Loot>(entity);
|
auto loot = world.get<Loot>(entity);
|
||||||
auto &loot_pos = world.get<Position>(entity);
|
auto &loot_pos = world.get<Position>(entity);
|
||||||
auto &inventory = world.get<Inventory>(player.entity);
|
auto &inventory = world.get<Inventory>(player.entity);
|
||||||
|
// BUG: this should go away and be a part of inventory
|
||||||
auto &light = world.get<LightSource>(player.entity);
|
auto &light = world.get<LightSource>(player.entity);
|
||||||
|
|
||||||
world.send<Events::GUI>(Events::GUI::LOOT, entity, loot);
|
world.send<Events::GUI>(Events::GUI::LOOT, entity, loot);
|
||||||
|
@ -148,7 +156,9 @@ void System::collision(DinkyECS::World &world, Player &player) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BUG: this is kind of massive, need to maybe rethink how systems are designed. I mean...can each system be a callable class instead?
|
||||||
void System::draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &lighting, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) {
|
void System::draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &lighting, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) {
|
||||||
|
|
||||||
world.query<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) {
|
world.query<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) {
|
||||||
if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x
|
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) {
|
&& pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) {
|
||||||
|
@ -156,6 +166,8 @@ void System::draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &
|
||||||
|
|
||||||
int light_value = lighting[pos.location.y][pos.location.x];
|
int light_value = lighting[pos.location.y][pos.location.x];
|
||||||
|
|
||||||
|
// BUG: foreground color needs to come from entity and background color from the surface they're on
|
||||||
|
|
||||||
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
|
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
|
||||||
canvas.DrawText(loc.x*2, loc.y*4, tile.chr, [light_value](auto &pixel) {
|
canvas.DrawText(loc.x*2, loc.y*4, tile.chr, [light_value](auto &pixel) {
|
||||||
pixel.foreground_color = Color::HSV(255, 200, light_value + 20);
|
pixel.foreground_color = Color::HSV(255, 200, light_value + 20);
|
||||||
|
|
|
@ -13,7 +13,6 @@ TEST_CASE("bsp algo test", "[builder]") {
|
||||||
Map map(20, 20);
|
Map map(20, 20);
|
||||||
WorldBuilder builder(map);
|
WorldBuilder builder(map);
|
||||||
builder.generate();
|
builder.generate();
|
||||||
REQUIRE(map.$rooms.size() >= 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("dumping and debugging", "[builder]") {
|
TEST_CASE("dumping and debugging", "[builder]") {
|
||||||
|
@ -21,8 +20,6 @@ TEST_CASE("dumping and debugging", "[builder]") {
|
||||||
WorldBuilder builder(map);
|
WorldBuilder builder(map);
|
||||||
builder.generate();
|
builder.generate();
|
||||||
|
|
||||||
REQUIRE(map.$rooms.size() >= 2);
|
|
||||||
|
|
||||||
dump_map("GENERATED", map.paths());
|
dump_map("GENERATED", map.paths());
|
||||||
map.dump();
|
map.dump();
|
||||||
}
|
}
|
||||||
|
@ -31,7 +28,6 @@ TEST_CASE("pathing", "[builder]") {
|
||||||
Map map(20, 20);
|
Map map(20, 20);
|
||||||
WorldBuilder builder(map);
|
WorldBuilder builder(map);
|
||||||
builder.generate();
|
builder.generate();
|
||||||
REQUIRE(map.$rooms.size() >= 2);
|
|
||||||
|
|
||||||
REQUIRE(map.can_move({0,0}) == false);
|
REQUIRE(map.can_move({0,0}) == false);
|
||||||
REQUIRE(map.iswall(0,0) == true);
|
REQUIRE(map.iswall(0,0) == true);
|
||||||
|
|
|
@ -6,6 +6,7 @@ using namespace fmt;
|
||||||
|
|
||||||
inline int make_split(Room &cur, bool horiz) {
|
inline int make_split(Room &cur, bool horiz) {
|
||||||
size_t dimension = horiz ? cur.height : cur.width;
|
size_t dimension = horiz ? cur.height : cur.width;
|
||||||
|
// BUG: this might be better as a configurable 4 number
|
||||||
int min = dimension / 4;
|
int min = dimension / 4;
|
||||||
int max = dimension - min;
|
int max = dimension - min;
|
||||||
|
|
||||||
|
@ -77,11 +78,13 @@ void WorldBuilder::partition_map(Room &cur, int depth) {
|
||||||
right.width = size_t(cur.width - split);
|
right.width = size_t(cur.width - split);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BUG: min room size should be configurable
|
||||||
if(depth > 0 && left.width > 2 && left.height > 2) {
|
if(depth > 0 && left.width > 2 && left.height > 2) {
|
||||||
left.depth = depth - 1;
|
left.depth = depth - 1;
|
||||||
partition_map(left, depth-1);
|
partition_map(left, depth-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BUG: min room size should be configurable
|
||||||
if(depth > 0 && right.width > 2 && right.height > 2) {
|
if(depth > 0 && right.width > 2 && right.height > 2) {
|
||||||
right.depth = depth - 1;
|
right.depth = depth - 1;
|
||||||
partition_map(right, depth-1);
|
partition_map(right, depth-1);
|
||||||
|
@ -104,6 +107,7 @@ void WorldBuilder::tunnel_doors(PointList &holes, Room &src, Room &target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBuilder::generate() {
|
void WorldBuilder::generate() {
|
||||||
|
PointList holes;
|
||||||
Room root{
|
Room root{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
|
@ -111,13 +115,11 @@ void WorldBuilder::generate() {
|
||||||
.height = $map.$height
|
.height = $map.$height
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// BUG: depth should be configurable
|
||||||
partition_map(root, 10);
|
partition_map(root, 10);
|
||||||
$map.INVARIANT();
|
|
||||||
|
|
||||||
place_rooms();
|
place_rooms();
|
||||||
|
|
||||||
PointList holes;
|
|
||||||
|
|
||||||
for(size_t i = 0; i < $map.$rooms.size() - 1; i++) {
|
for(size_t i = 0; i < $map.$rooms.size() - 1; i++) {
|
||||||
tunnel_doors(holes, $map.$rooms[i], $map.$rooms[i+1]);
|
tunnel_doors(holes, $map.$rooms[i], $map.$rooms[i+1]);
|
||||||
}
|
}
|
||||||
|
@ -159,6 +161,8 @@ void WorldBuilder::place_rooms() {
|
||||||
cur.width -= 4;
|
cur.width -= 4;
|
||||||
cur.height -= 4;
|
cur.height -= 4;
|
||||||
|
|
||||||
|
// BUG: should I do this each time I connect rooms
|
||||||
|
// BUG: rather than once when the room is created?
|
||||||
add_door(cur);
|
add_door(cur);
|
||||||
make_room(cur.x, cur.y, cur.width, cur.height);
|
make_room(cur.x, cur.y, cur.width, cur.height);
|
||||||
}
|
}
|
||||||
|
@ -166,6 +170,8 @@ void WorldBuilder::place_rooms() {
|
||||||
|
|
||||||
bool WorldBuilder::dig_tunnel(PointList &holes, Point &src, Point &target) {
|
bool WorldBuilder::dig_tunnel(PointList &holes, Point &src, Point &target) {
|
||||||
Matrix &paths = $map.paths();
|
Matrix &paths = $map.paths();
|
||||||
|
|
||||||
|
// BUG: limit should be a constant since it never changes
|
||||||
int limit = $map.limit();
|
int limit = $map.limit();
|
||||||
|
|
||||||
dbc::check(paths[src.y][src.x] != limit,
|
dbc::check(paths[src.y][src.x] != limit,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue