Levels are now expanded out as you travel down and the stairs are only placed at the end of the level instead of randomly.

main
Zed A. Shaw 11 months ago
parent 82216b8307
commit 59a6882b70
  1. 17
      assets/devices.json
  2. 2
      constants.hpp
  3. 2
      devices.cpp
  4. 2
      events.hpp
  5. 3
      gui.cpp
  6. 11
      levelmanager.cpp
  7. 6
      levelmanager.hpp
  8. 2
      point.hpp
  9. 2
      render.hpp
  10. 3
      spatialmap.hpp
  11. 17
      worldbuilder.cpp

@ -2,10 +2,12 @@
"STAIRS_DOWN": { "STAIRS_DOWN": {
"id": "STAIRS_DOWN", "id": "STAIRS_DOWN",
"name": "Stairs Down", "name": "Stairs Down",
"placement": "fixed",
"foreground": [24, 205, 189], "foreground": [24, 205, 189],
"background": [24, 205, 189], "background": [24, 205, 189],
"description": "Stairs that go down further into the dungeon.", "description": "Stairs that go down further into the dungeon.",
"inventory_count": 0, "inventory_count": 0,
"randomized": false,
"components": [ "components": [
{"type": "Tile", "config": {"chr": "\u2ac5"}}, {"type": "Tile", "config": {"chr": "\u2ac5"}},
{"type": "Device", {"type": "Device",
@ -20,11 +22,26 @@
"background": [24, 205, 189], "background": [24, 205, 189],
"description": "Stairs that go up, for the weak.", "description": "Stairs that go up, for the weak.",
"inventory_count": 0, "inventory_count": 0,
"placement": "fixed",
"components": [ "components": [
{"type": "Tile", "config": {"chr": "\u2259"}}, {"type": "Tile", "config": {"chr": "\u2259"}},
{"type": "Device", {"type": "Device",
"config": {"test": true}, "events": ["Events::GUI::STAIRS_UP"] "config": {"test": true}, "events": ["Events::GUI::STAIRS_UP"]
} }
] ]
},
"SPIKE_TRAP": {
"id": "SPIKE_TRAP",
"name": "Spike trap",
"foreground": [24, 205, 189],
"background": [24, 205, 189],
"description": "Spikes stab you from the floor.",
"inventory_count": 0,
"components": [
{"type": "Tile", "config": {"chr": "\u1ac7"}},
{"type": "Device",
"config": {"test": true}, "events": ["Events::GUI::TRAP"]
}
]
} }
} }

@ -27,8 +27,6 @@ constexpr wchar_t UI_BASE_CHAR = L'█';
constexpr int BG_BOX_OFFSET=5; constexpr int BG_BOX_OFFSET=5;
// NOTE: max seems to be about x=240, y=120 // NOTE: max seems to be about x=240, y=120
constexpr int GAME_MAP_X=80;
constexpr int GAME_MAP_Y=40;
constexpr int INVENTORY_PIXEL_X=50; constexpr int INVENTORY_PIXEL_X=50;
constexpr int INVENTORY_PIXEL_Y=50; constexpr int INVENTORY_PIXEL_Y=50;
constexpr int INVENTORY_WIDTH=99; constexpr int INVENTORY_WIDTH=99;

@ -14,6 +14,8 @@ namespace components {
events.push_back(Events::GUI::STAIRS_DOWN); events.push_back(Events::GUI::STAIRS_DOWN);
} else if(name == "Events::GUI::STAIRS_UP") { } else if(name == "Events::GUI::STAIRS_UP") {
events.push_back(Events::GUI::STAIRS_UP); events.push_back(Events::GUI::STAIRS_UP);
} else if(name == "Events::GUI::TRAP") {
events.push_back(Events::GUI::TRAP);
} else { } else {
dbc::sentinel(fmt::format("Unknown device event {}", name)); dbc::sentinel(fmt::format("Unknown device event {}", name));
} }

@ -2,7 +2,7 @@
namespace Events { namespace Events {
enum GUI { enum GUI {
START, COMBAT, LOOT, DEATH, STAIRS_UP, STAIRS_DOWN START, COMBAT, LOOT, DEATH, STAIRS_UP, STAIRS_DOWN, TRAP
}; };
struct Combat { struct Combat {

@ -297,6 +297,9 @@ void GUI::handle_world_events() {
(bool)device.config["test"])); (bool)device.config["test"]));
// toggle_modal(&$next_level_ui, $next_level); // toggle_modal(&$next_level_ui, $next_level);
} break; } break;
case eGUI::TRAP: {
$status_ui.log("You stepped on a TRAP!");
} break;
default: default:
$status_ui.log(format("INVALID EVENT! {},{}", evt, entity)); $status_ui.log(format("INVALID EVENT! {},{}", evt, entity));
} }

@ -13,6 +13,13 @@ LevelManager::LevelManager() {
create_level(); create_level();
} }
LevelScaling LevelManager::scale_level() {
return {
30 + (5 * int($current_level)),
20 + (5 * int($current_level))
};
}
size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) { size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
auto world = make_shared<DinkyECS::World>(); auto world = make_shared<DinkyECS::World>();
@ -22,7 +29,9 @@ size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
save::load_configs(*world); save::load_configs(*world);
} }
auto map = make_shared<Map>(GAME_MAP_X, GAME_MAP_Y); auto scaling = scale_level();
auto map = make_shared<Map>(scaling.map_width, scaling.map_height);
WorldBuilder builder(*map); WorldBuilder builder(*map);
builder.generate(*world); builder.generate(*world);

@ -17,6 +17,11 @@ struct GameLevel {
shared_ptr<SpatialMap> collision; shared_ptr<SpatialMap> collision;
}; };
struct LevelScaling {
int map_width=40;
int map_height=50;
};
class LevelManager { class LevelManager {
public: public:
std::vector<GameLevel> $levels; std::vector<GameLevel> $levels;
@ -30,4 +35,5 @@ class LevelManager {
GameLevel &current(); GameLevel &current();
size_t current_index() { return $current_level; } size_t current_index() { return $current_level; }
GameLevel &get(size_t index); GameLevel &get(size_t index);
LevelScaling scale_level();
}; };

@ -15,7 +15,7 @@ struct Point {
typedef std::vector<Point> PointList; typedef std::vector<Point> PointList;
struct PointHash { template<> struct std::hash<Point> {
size_t operator()(const Point& p) const { size_t operator()(const Point& p) const {
return std::hash<int>()(p.x) ^ std::hash<int>()(p.y); return std::hash<int>()(p.x) ^ std::hash<int>()(p.y);
} }

@ -25,8 +25,6 @@ struct RenderConfig {
wchar_t bg_tile = BG_TILE; wchar_t bg_tile = BG_TILE;
wchar_t ui_base_char = UI_BASE_CHAR; wchar_t ui_base_char = UI_BASE_CHAR;
int bg_box_offset=BG_BOX_OFFSET; int bg_box_offset=BG_BOX_OFFSET;
int game_map_x=GAME_MAP_X;
int game_map_y=GAME_MAP_Y;
}; };
struct SFMLRender { struct SFMLRender {

@ -7,7 +7,8 @@
typedef std::vector<DinkyECS::Entity> EntityList; typedef std::vector<DinkyECS::Entity> EntityList;
typedef std::unordered_map<Point, DinkyECS::Entity, PointHash> PointEntityMap; // Point's has is in point.hpp
typedef std::unordered_map<Point, DinkyECS::Entity> PointEntityMap;
struct FoundEntities { struct FoundEntities {
bool found; bool found;

@ -216,8 +216,12 @@ void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config
json& entity_db = select_entity_type(config, gen_config); json& entity_db = select_entity_type(config, gen_config);
std::vector<std::string> keys; std::vector<std::string> keys;
for(auto &el : entity_db.items()) { for(auto& el : entity_db.items()) {
keys.push_back(el.key()); auto& data = el.value();
if(data["placement"] == nullptr) {
keys.push_back(el.key());
}
} }
int rand_entity = Random::uniform<int>(0, keys.size() - 1); int rand_entity = Random::uniform<int>(0, keys.size() - 1);
@ -230,6 +234,14 @@ void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config
} }
} }
inline void place_stairs(DinkyECS::World& world, GameConfig& config, Map& map) {
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, map, entity_data, last_room);
check_player(world, entity);
}
void WorldBuilder::place_entities(DinkyECS::World &world) { void WorldBuilder::place_entities(DinkyECS::World &world) {
auto &config = world.get_the<GameConfig>(); auto &config = world.get_the<GameConfig>();
// configure a player as a fact of the world // configure a player as a fact of the world
@ -251,6 +263,7 @@ void WorldBuilder::place_entities(DinkyECS::World &world) {
} }
randomize_entities(world, config); randomize_entities(world, config);
place_stairs(world, config, $map);
} }
void WorldBuilder::generate(DinkyECS::World &world) { void WorldBuilder::generate(DinkyECS::World &world) {