Unlocked combat finally but the robots won't chase you.

This commit is contained in:
Zed A. Shaw 2026-03-31 23:12:04 -04:00
parent 2b69f388e5
commit e9365e0d87
6 changed files with 34 additions and 79 deletions

View file

@ -6,7 +6,7 @@
"foreground": "enemies/fg:player", "foreground": "enemies/fg:player",
"background": "color:transparent" "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": { "body_parts": {
"head": 200, "head": 200,
"chest": 200, "chest": 200,
@ -30,7 +30,7 @@
"foreground": "enemies/fg:rat_giant", "foreground": "enemies/fg:rat_giant",
"background": "color:transparent" "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": { "body_parts": {
"head": 50, "head": 50,
"chest": 50, "chest": 50,

View file

@ -1,29 +1,35 @@
#include "game/components.hpp" #include "game/components.hpp"
#include "algos/rand.hpp" #include "algos/rand.hpp"
#include <algorithm>
namespace components { namespace components {
int Combat::attack(Combat &target) { int Combat::attack(Combat &target) {
int attack = Random::uniform<int>(0,1); int attack = 1;
int my_dmg = 0; int my_dmg = 0;
if(attack) { my_dmg = Random::uniform<int>(1, damage);
my_dmg = Random::uniform<int>(1, damage); target.take_damage(my_dmg);
target.take_damage(my_dmg);
}
return my_dmg; return my_dmg;
} }
void Combat::take_damage(int my_dmg) { void Combat::take_damage(int my_dmg) {
for(auto& [key, hp] : body_parts) { int count = Random::uniform(1, int(body_parts.size() - 1));
if(Random::uniform(0, 1) == 0) {
body_parts[key] = hp - my_dmg; 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) { 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() { bool Combat::is_dead() {
@ -35,7 +41,11 @@ namespace components {
} }
bool Combat::can_heal() { 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) { void Combat::apply_healing(Curative& cure) {

View file

@ -122,6 +122,11 @@ namespace components {
{"left_leg", 10}, {"left_leg", 10},
}; };
std::array<std::string, 7> part_names{
"head", "chest", "stomach",
"right_arm", "left_arm",
"right_leg", "left_leg"};
// everyone starts at 0 but ap_delta is added each round // everyone starts at 0 but ap_delta is added each round
int ap = 0; int ap = 0;

View file

@ -1,3 +1,4 @@
#define FSM_DEBUG 1
#include "gui/fsm.hpp" #include "gui/fsm.hpp"
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
@ -34,8 +35,6 @@ namespace gui {
FSM_STATE(State, ATTACKING, ev, data); FSM_STATE(State, ATTACKING, ev, data);
FSM_STATE(State, ROTATING, ev); FSM_STATE(State, ROTATING, ev);
FSM_STATE(State, IDLE, ev, data); 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, LOOTING, ev, data);
FSM_STATE(State, END, ev); FSM_STATE(State, END, ev);
} }
@ -72,11 +71,8 @@ namespace gui {
dbc::log("!!!!!! FIX System::combat(0) doesn't use any weapons, only first"); dbc::log("!!!!!! FIX System::combat(0) doesn't use any weapons, only first");
$systems.runCombat(0); $systems.runCombat(0);
run_systems(); run_systems();
state(State::IN_COMBAT);
} break;
case COMBAT_STOP:
state(State::IDLE); state(State::IDLE);
break; } break;
case ATTACK: { case ATTACK: {
int attack_id = std::any_cast<int>(data); int attack_id = std::any_cast<int>(data);
$systems.runCombat(attack_id); $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) { void FSM::LOOTING(Event ev, std::any data) {
using enum Event; using enum Event;
@ -151,11 +139,12 @@ namespace gui {
state(State::ROTATING); state(State::ROTATING);
break; break;
case ATTACK: case ATTACK:
$main_ui.play_hands();
$main_ui.dirty();
sound::play("Sword_Hit_1");
$status_ui.update();
state(State::ATTACKING); state(State::ATTACKING);
break; break;
case COMBAT_START:
state(State::IN_COMBAT);
break;
case CLOSE: case CLOSE:
dbc::log("Nothing to close."); dbc::log("Nothing to close.");
break; 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) { void FSM::try_move(int dir, bool strafe) {
auto& level = GameDB::current_level(); auto& level = GameDB::current_level();
using enum State; using enum State;
@ -387,9 +335,6 @@ namespace gui {
auto &damage = std::any_cast<components::CombatResult&>(data); auto &damage = std::any_cast<components::CombatResult&>(data);
} }
break; break;
case eGUI::COMBAT_START:
event(Event::COMBAT_START);
break;
case eGUI::ENTITY_SPAWN: { case eGUI::ENTITY_SPAWN: {
auto& sprite = world->get<components::Sprite>(entity); auto& sprite = world->get<components::Sprite>(entity);
$main_ui.$rayview->update_sprite(entity, sprite); $main_ui.$rayview->update_sprite(entity, sprite);

View file

@ -16,8 +16,6 @@ namespace gui {
enum class State { enum class State {
START=__LINE__, START=__LINE__,
MOVING=__LINE__, MOVING=__LINE__,
IN_COMBAT=__LINE__,
COMBAT_ROTATE=__LINE__,
ATTACKING=__LINE__, ATTACKING=__LINE__,
ROTATING=__LINE__, ROTATING=__LINE__,
LOOTING=__LINE__, LOOTING=__LINE__,
@ -48,8 +46,6 @@ namespace gui {
void MAPPING(game::Event ev); void MAPPING(game::Event ev);
void ROTATING(game::Event ev); void ROTATING(game::Event ev);
void IDLE(game::Event ev, std::any data); 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 LOOTING(game::Event ev, std::any data);
void END(game::Event ev); void END(game::Event ev);

View file

@ -33,8 +33,7 @@ int main(int argc, char* argv[]) {
// BUG: need to sort out how to deal with this in the FSM // BUG: need to sort out how to deal with this in the FSM
if(main.in_state(gui::State::IDLE) if(main.in_state(gui::State::IDLE)
|| main.in_state(gui::State::LOOTING) || main.in_state(gui::State::LOOTING))
|| main.in_state(gui::State::IN_COMBAT))
{ {
main.handle_keyboard_mouse(); main.handle_keyboard_mouse();
} else{ } else{