From e9365e0d875f532ef688b7421685afe0ec75e234 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Tue, 31 Mar 2026 23:12:04 -0400 Subject: [PATCH] Unlocked combat finally but the robots won't chase you. --- assets/enemies.json | 4 +-- src/combat/combat.cpp | 30 ++++++++++++------ src/game/components.hpp | 5 +++ src/gui/fsm.cpp | 67 ++++------------------------------------- src/gui/fsm.hpp | 4 --- src/main.cpp | 3 +- 6 files changed, 34 insertions(+), 79 deletions(-) diff --git a/assets/enemies.json b/assets/enemies.json index 0577aae..a81cf47 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -6,7 +6,7 @@ "foreground": "enemies/fg:player", "background": "color:transparent" }, - {"_type": "Combat", "max_hp": 50, "max_ap": 12, "ap_delta": 6, "damage": 100, "dead": false, + {"_type": "Combat", "max_hp": 50, "max_ap": 12, "ap_delta": 6, "damage": 20, "dead": false, "body_parts": { "head": 200, "chest": 200, @@ -30,7 +30,7 @@ "foreground": "enemies/fg:rat_giant", "background": "color:transparent" }, - {"_type": "Combat", "max_hp": 50, "max_ap": 12, "ap_delta": 6,"damage": 10, "dead": false, + {"_type": "Combat", "max_hp": 50, "max_ap": 12, "ap_delta": 6,"damage": 30, "dead": false, "body_parts": { "head": 50, "chest": 50, diff --git a/src/combat/combat.cpp b/src/combat/combat.cpp index e72739a..34c6807 100644 --- a/src/combat/combat.cpp +++ b/src/combat/combat.cpp @@ -1,29 +1,35 @@ #include "game/components.hpp" #include "algos/rand.hpp" +#include namespace components { int Combat::attack(Combat &target) { - int attack = Random::uniform(0,1); + int attack = 1; int my_dmg = 0; - if(attack) { - my_dmg = Random::uniform(1, damage); - target.take_damage(my_dmg); - } + my_dmg = Random::uniform(1, damage); + target.take_damage(my_dmg); return my_dmg; } void Combat::take_damage(int my_dmg) { - for(auto& [key, hp] : body_parts) { - if(Random::uniform(0, 1) == 0) { - body_parts[key] = hp - my_dmg; + int count = Random::uniform(1, int(body_parts.size() - 1)); + + while(count > 0) { + fmt::println("COUNT: {}", count); + for(auto& [key, hp] : body_parts) { + if(count > 0 && Random::uniform(0, 1) == 0) { + fmt::println("HIT! name={} count={} dmg={} hp={}", key, count, my_dmg, hp); + body_parts[key] = std::max(0, hp - my_dmg); + count--; + } } } } bool Combat::less_than(int level) { - return body_parts["head"] < level || body_parts["stomach"] < level || body_parts["chest"] < level; + return body_parts["head"] <= level || body_parts["stomach"] <= level || body_parts["chest"] <= level; } bool Combat::is_dead() { @@ -35,7 +41,11 @@ namespace components { } bool Combat::can_heal() { - return less_than(max_hp / 2); + for(auto& [key, hp] : body_parts) { + if(hp < max_hp) return true; + } + + return false; } void Combat::apply_healing(Curative& cure) { diff --git a/src/game/components.hpp b/src/game/components.hpp index d81b67d..fcd9d95 100644 --- a/src/game/components.hpp +++ b/src/game/components.hpp @@ -122,6 +122,11 @@ namespace components { {"left_leg", 10}, }; + std::array part_names{ + "head", "chest", "stomach", + "right_arm", "left_arm", + "right_leg", "left_leg"}; + // everyone starts at 0 but ap_delta is added each round int ap = 0; diff --git a/src/gui/fsm.cpp b/src/gui/fsm.cpp index 298b091..fb420c4 100644 --- a/src/gui/fsm.cpp +++ b/src/gui/fsm.cpp @@ -1,3 +1,4 @@ +#define FSM_DEBUG 1 #include "gui/fsm.hpp" #include #include @@ -34,8 +35,6 @@ namespace gui { FSM_STATE(State, ATTACKING, ev, data); FSM_STATE(State, ROTATING, ev); FSM_STATE(State, IDLE, ev, data); - FSM_STATE(State, IN_COMBAT, ev); - FSM_STATE(State, COMBAT_ROTATE, ev); FSM_STATE(State, LOOTING, ev, data); FSM_STATE(State, END, ev); } @@ -72,11 +71,8 @@ namespace gui { dbc::log("!!!!!! FIX System::combat(0) doesn't use any weapons, only first"); $systems.runCombat(0); run_systems(); - state(State::IN_COMBAT); - } break; - case COMBAT_STOP: state(State::IDLE); - break; + } break; case ATTACK: { int attack_id = std::any_cast(data); $systems.runCombat(attack_id); @@ -96,14 +92,6 @@ namespace gui { } } - void FSM::COMBAT_ROTATE(Event) { - if(auto aim = $main_ui.play_rotate()) { - auto& player_pos = GameDB::player_position(); - player_pos.aiming_at = *aim; - state(State::IN_COMBAT); - } - } - void FSM::LOOTING(Event ev, std::any data) { using enum Event; @@ -151,11 +139,12 @@ namespace gui { state(State::ROTATING); break; case ATTACK: + $main_ui.play_hands(); + $main_ui.dirty(); + sound::play("Sword_Hit_1"); + $status_ui.update(); state(State::ATTACKING); break; - case COMBAT_START: - state(State::IN_COMBAT); - break; case CLOSE: dbc::log("Nothing to close."); break; @@ -191,47 +180,6 @@ namespace gui { } } - void FSM::IN_COMBAT(Event ev) { - using enum Event; - - switch(ev) { - case MOUSE_CLICK: - mouse_action(guecs::NO_MODS); - break; - case MOUSE_MOVE: { - mouse_action({1 << guecs::ModBit::hover}); - } break; - case TICK: - run_systems(); - break; - case ATTACK: - $main_ui.play_hands(); - $main_ui.dirty(); - sound::play("Sword_Hit_1"); - $status_ui.update(); - state(State::ATTACKING); - break; - case ROTATE_LEFT: - $main_ui.plan_rotate(-1, DEFAULT_ROTATE); - state(State::COMBAT_ROTATE); - break; - case ROTATE_RIGHT: - $main_ui.plan_rotate(1, DEFAULT_ROTATE); - state(State::COMBAT_ROTATE); - break; - case COMBAT_STOP: - $main_ui.$overlay_ui.close_sprite("top_right"); - state(State::IDLE); - break; - case QUIT: - $window.close(); - state(State::END); - return; - default: - break; - } - } - void FSM::try_move(int dir, bool strafe) { auto& level = GameDB::current_level(); using enum State; @@ -387,9 +335,6 @@ namespace gui { auto &damage = std::any_cast(data); } break; - case eGUI::COMBAT_START: - event(Event::COMBAT_START); - break; case eGUI::ENTITY_SPAWN: { auto& sprite = world->get(entity); $main_ui.$rayview->update_sprite(entity, sprite); diff --git a/src/gui/fsm.hpp b/src/gui/fsm.hpp index 36aed03..7d2ff44 100644 --- a/src/gui/fsm.hpp +++ b/src/gui/fsm.hpp @@ -16,8 +16,6 @@ namespace gui { enum class State { START=__LINE__, MOVING=__LINE__, - IN_COMBAT=__LINE__, - COMBAT_ROTATE=__LINE__, ATTACKING=__LINE__, ROTATING=__LINE__, LOOTING=__LINE__, @@ -48,8 +46,6 @@ namespace gui { void MAPPING(game::Event ev); void ROTATING(game::Event ev); void IDLE(game::Event ev, std::any data); - void IN_COMBAT(game::Event ev); - void COMBAT_ROTATE(game::Event ev); void LOOTING(game::Event ev, std::any data); void END(game::Event ev); diff --git a/src/main.cpp b/src/main.cpp index 28a5f35..164a7b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,8 +33,7 @@ int main(int argc, char* argv[]) { // BUG: need to sort out how to deal with this in the FSM if(main.in_state(gui::State::IDLE) - || main.in_state(gui::State::LOOTING) - || main.in_state(gui::State::IN_COMBAT)) + || main.in_state(gui::State::LOOTING)) { main.handle_keyboard_mouse(); } else{