Enemies now turn into a lootable device witha grave_stone sprite so you know they died. Need to implement noclipping on items with collision.
This commit is contained in:
parent
0199248354
commit
3b9525cca4
8 changed files with 92 additions and 74 deletions
|
@ -30,7 +30,7 @@
|
||||||
"player": {
|
"player": {
|
||||||
},
|
},
|
||||||
"worldgen": {
|
"worldgen": {
|
||||||
"enemy_probability": 40,
|
"enemy_probability": 90,
|
||||||
"empty_room_probability": 10,
|
"empty_room_probability": 10,
|
||||||
"device_probability": 20
|
"device_probability": 20
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,9 +60,8 @@
|
||||||
"foreground": [32, 123, 164],
|
"foreground": [32, 123, 164],
|
||||||
"background": [24, 205, 189]
|
"background": [24, 205, 189]
|
||||||
},
|
},
|
||||||
{"_type": "Device",
|
{"_type": "LightSource", "strength": 50, "radius": 0.5},
|
||||||
"config": {"test": true},
|
{"_type": "Device", "config": {"test": true}, "events": []},
|
||||||
"events": []},
|
|
||||||
{"_type": "Sprite", "name": "grave_stone"}
|
{"_type": "Sprite", "name": "grave_stone"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace Events {
|
namespace Events {
|
||||||
enum GUI {
|
enum GUI {
|
||||||
START, COMBAT, LOOT, DEATH, STAIRS_UP, STAIRS_DOWN, TRAP,
|
START, COMBAT, LOOT, DEATH, STAIRS_UP, STAIRS_DOWN, TRAP,
|
||||||
COMBAT_START, NO_NEIGHBORS, ATTACK, NOOP
|
COMBAT_START, NO_NEIGHBORS, ATTACK, UPDATE_SPRITE, NOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Combat {
|
struct Combat {
|
||||||
|
|
12
gui.cpp
12
gui.cpp
|
@ -372,7 +372,7 @@ namespace gui {
|
||||||
System::collision($level);
|
System::collision($level);
|
||||||
System::motion($level);
|
System::motion($level);
|
||||||
System::lighting($level);
|
System::lighting($level);
|
||||||
System::death($level);
|
System::death($level, $levels.$components);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSM::active() {
|
bool FSM::active() {
|
||||||
|
@ -385,16 +385,14 @@ namespace gui {
|
||||||
|
|
||||||
while(world.has_event<eGUI>()) {
|
while(world.has_event<eGUI>()) {
|
||||||
auto [evt, entity, data] = world.recv<eGUI>();
|
auto [evt, entity, data] = world.recv<eGUI>();
|
||||||
|
auto player = world.get_the<Player>();
|
||||||
|
|
||||||
switch(evt) {
|
switch(evt) {
|
||||||
case eGUI::COMBAT: {
|
case eGUI::COMBAT: {
|
||||||
auto &damage = std::any_cast<Events::Combat&>(data);
|
auto &damage = std::any_cast<Events::Combat&>(data);
|
||||||
auto enemy_combat = world.get<Combat>(entity);
|
|
||||||
|
|
||||||
if(damage.enemy_did > 0) {
|
if(damage.enemy_did > 0) {
|
||||||
$status_view.log(fmt::format("Enemy HIT YOU for {} damage!", damage.enemy_did));
|
$status_view.log(fmt::format("Enemy HIT YOU for {} damage!", damage.enemy_did));
|
||||||
$status_view.log(fmt::format("-- Enemy has {} HP left.", enemy_combat.hp));
|
|
||||||
auto player = world.get_the<Player>();
|
|
||||||
auto player_combat = world.get<Combat>(player.entity);
|
auto player_combat = world.get<Combat>(player.entity);
|
||||||
$combat_view.set_damage(float(player_combat.hp) / float(player_combat.max_hp));
|
$combat_view.set_damage(float(player_combat.hp) / float(player_combat.max_hp));
|
||||||
} else {
|
} else {
|
||||||
|
@ -425,6 +423,12 @@ namespace gui {
|
||||||
$rotation = 0;
|
$rotation = 0;
|
||||||
event(Event::ATTACK);
|
event(Event::ATTACK);
|
||||||
break;
|
break;
|
||||||
|
case eGUI::DEATH: {
|
||||||
|
if(entity != player.entity) {
|
||||||
|
auto &sprite = $level.world->get<Sprite>(entity);
|
||||||
|
$rayview.update_sprite(entity, sprite);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case eGUI::NOOP:
|
case eGUI::NOOP:
|
||||||
$status_view.log(fmt::format("NOOP EVENT! {},{}", evt, entity));
|
$status_view.log(fmt::format("NOOP EVENT! {},{}", evt, entity));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -342,6 +342,12 @@ void Raycaster::draw(sf::RenderTarget& target) {
|
||||||
sprite_casting(target);
|
sprite_casting(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Raycaster::update_sprite(DinkyECS::Entity ent, components::Sprite& sprite) {
|
||||||
|
fmt::println("entity UPDATE SPRITE {} will have sprite named {}", ent, sprite.name);
|
||||||
|
auto sprite_txt = $textures.get(sprite.name);
|
||||||
|
$sprites.insert_or_assign(ent, sprite_txt);
|
||||||
|
}
|
||||||
|
|
||||||
void Raycaster::set_level(GameLevel level) {
|
void Raycaster::set_level(GameLevel level) {
|
||||||
$level = level;
|
$level = level;
|
||||||
auto& tiles = $level.map->tiles();
|
auto& tiles = $level.map->tiles();
|
||||||
|
|
|
@ -58,5 +58,6 @@ struct Raycaster {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_level(GameLevel level);
|
void set_level(GameLevel level);
|
||||||
|
void update_sprite(DinkyECS::Entity ent, components::Sprite& sprite);
|
||||||
void init_shaders();
|
void init_shaders();
|
||||||
};
|
};
|
||||||
|
|
136
systems.cpp
136
systems.cpp
|
@ -104,35 +104,37 @@ void System::motion(GameLevel &level) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::death(GameLevel &level) {
|
void System::death(GameLevel &level, components::ComponentMap& components) {
|
||||||
auto &world = *level.world;
|
auto &world = *level.world;
|
||||||
auto &collider = *level.collision;
|
|
||||||
auto player = world.get_the<Player>();
|
auto player = world.get_the<Player>();
|
||||||
|
auto& config = world.get_the<GameConfig>();
|
||||||
|
std::vector<DinkyECS::Entity> dead_things;
|
||||||
|
|
||||||
// BUG: this is where entities can die on top of
|
world.query<Combat>([&](auto ent, auto &combat) {
|
||||||
// BUG: eachother and overlap their corpse
|
|
||||||
// BUG: maybe that can be allowed and looting just shows
|
|
||||||
// BUG: all dead things there?
|
|
||||||
world.query<Position, Combat>([&](auto ent, auto &position, auto &combat) {
|
|
||||||
// bring out yer dead
|
// bring out yer dead
|
||||||
if(combat.hp <= 0 && !combat.dead) {
|
if(combat.hp <= 0 && !combat.dead) {
|
||||||
fmt::println("DIE! entity {} died", ent);
|
|
||||||
combat.dead = true;
|
combat.dead = true;
|
||||||
// take them out of collision map
|
if(ent != player.entity) {
|
||||||
collider.remove(position.location);
|
// we won't change out the player's components later
|
||||||
|
dead_things.push_back(ent);
|
||||||
if(ent == player.entity) {
|
|
||||||
world.send<Events::GUI>(Events::GUI::DEATH, ent, {});
|
|
||||||
} else {
|
|
||||||
// remove their motion so they're dead
|
|
||||||
// CHANGE: this needs to remove the enemies that are
|
|
||||||
// dead and then replace them at that position with
|
|
||||||
// a gave_stone device. And then that makes it so you
|
|
||||||
// can loot their dead bodies.
|
|
||||||
world.remove<Motion>(ent);
|
|
||||||
}
|
}
|
||||||
|
// we need to send this event for everything that dies
|
||||||
|
world.send<Events::GUI>(Events::GUI::DEATH, ent, {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// this goes through everything that died and changes them to a gravestone
|
||||||
|
// NOTE: this could be a separate system but also could be a function in
|
||||||
|
// components::
|
||||||
|
for(auto ent : dead_things) {
|
||||||
|
// remove their enemy setting
|
||||||
|
world.remove<Motion>(ent);
|
||||||
|
world.remove<Combat>(ent);
|
||||||
|
world.remove<EnemyConfig>(ent);
|
||||||
|
|
||||||
|
auto entity_data = config.devices["GRAVE_STONE"];
|
||||||
|
components::configure_entity(components, world, ent, entity_data["components"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::combat(GameLevel &level) {
|
void System::combat(GameLevel &level) {
|
||||||
|
@ -173,54 +175,60 @@ void System::collision(GameLevel &level) {
|
||||||
|
|
||||||
// this is guaranteed to not return the given position
|
// this is guaranteed to not return the given position
|
||||||
auto [found, nearby] = collider.neighbors(player_position.location);
|
auto [found, nearby] = collider.neighbors(player_position.location);
|
||||||
|
int combat_count = 0;
|
||||||
|
|
||||||
if(found) {
|
// BUG: this logic is garbage, needs a refactor
|
||||||
for(auto entity : nearby) {
|
for(auto entity : nearby) {
|
||||||
if(world.has<Combat>(entity)) {
|
if(world.has<Combat>(entity)) {
|
||||||
|
auto combat = world.get<Combat>(entity);
|
||||||
|
if(!combat.dead) {
|
||||||
|
combat_count++;
|
||||||
world.send<Events::GUI>(Events::GUI::COMBAT_START, entity, entity);
|
world.send<Events::GUI>(Events::GUI::COMBAT_START, entity, entity);
|
||||||
} else if(world.has<InventoryItem>(entity)) {
|
|
||||||
auto item = world.get<InventoryItem>(entity);
|
|
||||||
auto& item_pos = world.get<Position>(entity);
|
|
||||||
auto& inventory = world.get<Inventory>(player.entity);
|
|
||||||
|
|
||||||
if(world.has<LightSource>(entity)) {
|
|
||||||
inventory.add(item);
|
|
||||||
auto &new_light = world.get<LightSource>(entity);
|
|
||||||
world.set<LightSource>(player.entity, new_light);
|
|
||||||
inventory.light = new_light;
|
|
||||||
world.remove<LightSource>(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(world.has<Weapon>(entity)) {
|
|
||||||
inventory.add(item);
|
|
||||||
auto &weapon = world.get<Weapon>(entity);
|
|
||||||
player_combat.damage = weapon.damage;
|
|
||||||
world.remove<Weapon>(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(world.has<Loot>(entity)) {
|
|
||||||
auto &loot = world.get<Loot>(entity);
|
|
||||||
inventory.gold += loot.amount;
|
|
||||||
world.remove<Loot>(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(world.has<Curative>(entity)) {
|
|
||||||
auto& cure = world.get<Curative>(entity);
|
|
||||||
player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp);
|
|
||||||
world.remove<Curative>(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
collider.remove(item_pos.location);
|
|
||||||
world.remove<Tile>(entity);
|
|
||||||
world.remove<InventoryItem>(entity);
|
|
||||||
world.send<Events::GUI>(Events::GUI::LOOT, entity, item);
|
|
||||||
} else if(world.has<Device>(entity)) {
|
|
||||||
System::device(world, player.entity, entity);
|
|
||||||
} else {
|
|
||||||
println("UNKNOWN COLLISION TYPE {}", entity);
|
|
||||||
}
|
}
|
||||||
|
} else if(world.has<InventoryItem>(entity)) {
|
||||||
|
auto item = world.get<InventoryItem>(entity);
|
||||||
|
auto& item_pos = world.get<Position>(entity);
|
||||||
|
auto& inventory = world.get<Inventory>(player.entity);
|
||||||
|
|
||||||
|
if(world.has<LightSource>(entity)) {
|
||||||
|
inventory.add(item);
|
||||||
|
auto &new_light = world.get<LightSource>(entity);
|
||||||
|
world.set<LightSource>(player.entity, new_light);
|
||||||
|
inventory.light = new_light;
|
||||||
|
world.remove<LightSource>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(world.has<Weapon>(entity)) {
|
||||||
|
inventory.add(item);
|
||||||
|
auto &weapon = world.get<Weapon>(entity);
|
||||||
|
player_combat.damage = weapon.damage;
|
||||||
|
world.remove<Weapon>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(world.has<Loot>(entity)) {
|
||||||
|
auto &loot = world.get<Loot>(entity);
|
||||||
|
inventory.gold += loot.amount;
|
||||||
|
world.remove<Loot>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(world.has<Curative>(entity)) {
|
||||||
|
auto& cure = world.get<Curative>(entity);
|
||||||
|
player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp);
|
||||||
|
world.remove<Curative>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
collider.remove(item_pos.location);
|
||||||
|
world.remove<Tile>(entity);
|
||||||
|
world.remove<InventoryItem>(entity);
|
||||||
|
world.send<Events::GUI>(Events::GUI::LOOT, entity, item);
|
||||||
|
} else if(world.has<Device>(entity)) {
|
||||||
|
System::device(world, player.entity, entity);
|
||||||
|
} else {
|
||||||
|
println("UNKNOWN COLLISION TYPE {}", entity);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if(combat_count == 0) {
|
||||||
world.send<Events::GUI>(Events::GUI::NO_NEIGHBORS, player.entity, player.entity);
|
world.send<Events::GUI>(Events::GUI::NO_NEIGHBORS, player.entity, player.entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace System {
|
||||||
void lighting(GameLevel &level);
|
void lighting(GameLevel &level);
|
||||||
void motion(GameLevel &level);
|
void motion(GameLevel &level);
|
||||||
void collision(GameLevel &level);
|
void collision(GameLevel &level);
|
||||||
void death(GameLevel &level);
|
void death(GameLevel &level, components::ComponentMap& components);
|
||||||
void enemy_pathing(GameLevel &level);
|
void enemy_pathing(GameLevel &level);
|
||||||
|
|
||||||
void init_positions(DinkyECS::World &world, SpatialMap &collider);
|
void init_positions(DinkyECS::World &world, SpatialMap &collider);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue