Synced the combat from under the dome.
This commit is contained in:
parent
110612c33a
commit
a22564bb58
8 changed files with 106 additions and 27 deletions
|
|
@ -3,14 +3,61 @@
|
|||
|
||||
namespace components {
|
||||
int Combat::attack(Combat &target) {
|
||||
int attack = Random::uniform<int>(0,1);
|
||||
float hit_prob = Random::uniform_real(0.0f, 1.0f);
|
||||
|
||||
int my_dmg = 0;
|
||||
|
||||
if(attack) {
|
||||
my_dmg = Random::uniform<int>(1, damage);
|
||||
target.hp -= my_dmg;
|
||||
if(hit_prob < attack_rating) {
|
||||
my_dmg = std::ceil(Random::uniform_real(1.0f, float(damage)) * (1.0f - toughness_rating));
|
||||
target.take_damage(my_dmg);
|
||||
}
|
||||
|
||||
INVARIANT();
|
||||
return my_dmg;
|
||||
}
|
||||
|
||||
void Combat::take_damage(int my_dmg) {
|
||||
// catch this bug
|
||||
dbc::check(hp >= 0, "HP went negative");
|
||||
|
||||
// don't hit dead parts
|
||||
if(hp == 0) return;
|
||||
|
||||
// don't go below 0
|
||||
hp = std::max(0, hp - my_dmg);
|
||||
|
||||
has_died = hp <= 0;
|
||||
INVARIANT();
|
||||
}
|
||||
|
||||
bool Combat::less_than(int level) {
|
||||
INVARIANT();
|
||||
// originally this checked main body parts like
|
||||
// head, stomach, and chest
|
||||
return hp <= level;
|
||||
}
|
||||
|
||||
bool Combat::is_dead() {
|
||||
INVARIANT();
|
||||
return has_died;
|
||||
}
|
||||
|
||||
bool Combat::almost_dead() {
|
||||
return less_than(max_hp / 4);
|
||||
}
|
||||
|
||||
bool Combat::can_heal() {
|
||||
INVARIANT();
|
||||
return hp < max_hp;
|
||||
}
|
||||
|
||||
void Combat::apply_healing(Curative& cure) {
|
||||
INVARIANT();
|
||||
hp += std::min(hp + cure.hp, max_hp);
|
||||
}
|
||||
|
||||
void Combat::INVARIANT() {
|
||||
dbc::check(!(hp <= 0 && has_died == false), "entity hp <= 0 && has_died==false, they should be dead");
|
||||
dbc::check(!(hp > 0 && has_died == true), "entity has hp > 0 but is marked dead, should be alive");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ namespace components {
|
|||
std::vector<std::string> layout;
|
||||
json actors;
|
||||
json fixtures;
|
||||
json buttons;
|
||||
};
|
||||
|
||||
struct Storyboard {
|
||||
|
|
@ -111,19 +112,28 @@ namespace components {
|
|||
};
|
||||
|
||||
struct Combat {
|
||||
int hp;
|
||||
int max_hp;
|
||||
int ap_delta;
|
||||
int max_ap;
|
||||
int damage;
|
||||
int hp=1;
|
||||
int max_hp=1;
|
||||
int ap_delta=1;
|
||||
int max_ap=1;
|
||||
int damage=1;
|
||||
float attack_rating=0.1;
|
||||
float toughness_rating=0.1;
|
||||
|
||||
// everyone starts at 0 but ap_delta is added each round
|
||||
int ap = 0;
|
||||
|
||||
/* 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 has_died = false;
|
||||
|
||||
int attack(Combat &target);
|
||||
bool less_than(int level);
|
||||
void take_damage(int my_dmg);
|
||||
bool is_dead();
|
||||
bool almost_dead();
|
||||
bool can_heal();
|
||||
void apply_healing(Curative& cure);
|
||||
void INVARIANT();
|
||||
};
|
||||
|
||||
struct LightSource {
|
||||
|
|
@ -152,7 +162,7 @@ namespace components {
|
|||
using ComponentMap = std::unordered_map<std::string, ReflFuncSignature>;
|
||||
|
||||
ENROLL_COMPONENT(Tile, display, foreground, background);
|
||||
ENROLL_COMPONENT(AnimatedScene, background, layout, actors, fixtures);
|
||||
ENROLL_COMPONENT(AnimatedScene, background, layout, actors, fixtures, buttons);
|
||||
ENROLL_COMPONENT(Sprite, name, scale);
|
||||
ENROLL_COMPONENT(Curative, hp);
|
||||
ENROLL_COMPONENT(LightSource, strength, radius);
|
||||
|
|
@ -160,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, hp, max_hp, ap_delta, max_ap, damage, dead);
|
||||
ENROLL_COMPONENT(Combat, hp, max_hp, ap_delta, max_ap, damage, attack_rating, toughness_rating);
|
||||
ENROLL_COMPONENT(Device, config, events);
|
||||
ENROLL_COMPONENT(Storyboard, image, audio, layout, beats);
|
||||
ENROLL_COMPONENT(Sound, attack, death);
|
||||
|
|
@ -184,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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -192,8 +192,7 @@ void System::death() {
|
|||
|
||||
world.query<Combat>([&](auto ent, auto &combat) {
|
||||
// bring out yer dead
|
||||
if(combat.hp <= 0 && !combat.dead) {
|
||||
combat.dead = true;
|
||||
if(combat.is_dead()) {
|
||||
if(ent != player.entity) {
|
||||
// we won't change out the player's components later
|
||||
dead_things.push_back(ent);
|
||||
|
|
@ -301,7 +300,7 @@ void System::collision() {
|
|||
for(auto entity : nearby) {
|
||||
if(world.has<Combat>(entity)) {
|
||||
auto combat = world.get<Combat>(entity);
|
||||
if(!combat.dead) {
|
||||
if(!combat.is_dead()) {
|
||||
combat_count++;
|
||||
world.send<game::Event>(game::Event::COMBAT_START, entity, entity);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue