You now receive damage to multiple body parts and can heal them all too.

This commit is contained in:
Zed A. Shaw 2026-03-30 23:53:38 -04:00
parent 1777a6bbf2
commit 360402cb3c
6 changed files with 61 additions and 23 deletions

View file

@ -8,30 +8,39 @@ namespace components {
if(attack) {
my_dmg = Random::uniform<int>(1, damage);
target.hit_limb(my_dmg);
target.take_damage(my_dmg);
}
return my_dmg;
}
void Combat::hit_limb(int my_dmg) {
body_parts["head"] -= 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;
}
}
}
bool Combat::less_than(int level) {
return body_parts["head"] < level || body_parts["stomach"] < level || body_parts["chest"] < level;
}
bool Combat::is_dead() {
return body_parts["head"] < 0;
return less_than(0);
}
bool Combat::almost_dead() {
return body_parts["head"] < 20;
return less_than(max_hp / 4);
}
bool Combat::can_heal() {
return body_parts["head"] < 50;
return less_than(max_hp / 2);
}
void Combat::apply_healing(Curative& cure) {
int new_hp = body_parts["head"] + cure.hp;
body_parts["head"] = std::min(new_hp, 50);
for(auto& [key, hp] : body_parts) {
body_parts[key] = std::min(hp + cure.hp, max_hp);
}
}
}

View file

@ -107,11 +107,18 @@ namespace components {
};
struct Combat {
int ap_delta;
int max_ap;
int damage;
int max_hp=1;
int ap_delta=1;
int max_ap=1;
int damage=1;
std::unordered_map<std::string, int> body_parts{
{"head", 50},
{"head", 10},
{"chest", 10},
{"stomach", 10},
{"right_arm", 10},
{"left_arm", 10},
{"right_leg", 10},
{"left_leg", 10},
};
// everyone starts at 0 but ap_delta is added each round
@ -120,8 +127,9 @@ namespace components {
/* NOTE: This is used to _mark_ entities as dead, to detect ones that have just died. Don't make attack automatically set it.*/
bool dead = false;
bool less_than(int level);
int attack(Combat &target);
void hit_limb(int my_dmg);
void take_damage(int my_dmg);
bool is_dead();
bool almost_dead();
bool can_heal();
@ -162,7 +170,7 @@ namespace components {
ENROLL_COMPONENT(EnemyConfig, ai_script, ai_start_name, ai_goal_name);
ENROLL_COMPONENT(Personality, hearing_distance, tough);
ENROLL_COMPONENT(Motion, dx, dy, random);
ENROLL_COMPONENT(Combat, ap_delta, max_ap, damage, dead);
ENROLL_COMPONENT(Combat, max_hp, ap_delta, max_ap, damage, body_parts);
ENROLL_COMPONENT(Device, config, events);
ENROLL_COMPONENT(Storyboard, image, audio, layout, beats);
ENROLL_COMPONENT(Sound, attack, death);
@ -186,7 +194,7 @@ namespace components {
template <typename COMPONENT> void enroll(ComponentMap &m) {
m[NameOf<COMPONENT>::name] = [](DinkyECS::World& world, DinkyECS::Entity ent, nlohmann::json &j) {
COMPONENT c;
COMPONENT c{};
from_json(j, c);
world.set<COMPONENT>(ent, c);
};

View file

@ -17,11 +17,11 @@ namespace gui {
$gui.layout(
"[head]"
"[chest]"
"[stomach]"
"[right_arm]"
"[left_arm]"
"[stomach]"
"[left_leg]"
"[right_leg]");
"[right_leg]"
"[left_leg]");
$gui.set<Background>($gui.MAIN, {$gui.$parser, });

View file

@ -208,6 +208,7 @@ namespace gui {
$main_ui.play_hands();
$main_ui.dirty();
sound::play("Sword_Hit_1");
$status_ui.update();
state(State::ATTACKING);
break;
case ROTATE_LEFT: