From fb5a98b72ab79949d1da7f75a3d6150c2906ef40 Mon Sep 17 00:00:00 2001 From: jacopograndi Date: Mon, 30 Aug 2021 14:48:06 +0200 Subject: gui: tech representation, menu, tile & unit info, attack info --- game/gst.cpp | 142 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 39 deletions(-) (limited to 'game/gst.cpp') diff --git a/game/gst.cpp b/game/gst.cpp index f6d5aa1..0a524fc 100644 --- a/game/gst.cpp +++ b/game/gst.cpp @@ -28,25 +28,25 @@ Entity& Gst::get_at (int x, int y) { } float Gst::get_type_bonus (Entity &atk, Entity &def) { - float b = 1; + float b = 0; switch(atk.info->ent_class) { case EntityInfo::Class::inf: - if (def.info->ent_class == EntityInfo::Class::bld) b += 1.0/3; - if (def.info->ent_class == EntityInfo::Class::sie) b += 1.0/3; + if (def.info->ent_class == EntityInfo::Class::bld) b += 1.0f/3.0f; + if (def.info->ent_class == EntityInfo::Class::sie) b += 1.0f/3.0f; break; case EntityInfo::Class::cav: if (def.info->ent_class == EntityInfo::Class::bld) b += -0.5; - if (def.info->ent_class == EntityInfo::Class::inf) b += 1.0/3; - if (def.info->ent_class == EntityInfo::Class::ran) b += 1.0/3; + if (def.info->ent_class == EntityInfo::Class::inf) b += 1.0f/3.0f; + if (def.info->ent_class == EntityInfo::Class::ran) b += 1.0f/3.0f; break; case EntityInfo::Class::ran: - if (def.info->ent_class == EntityInfo::Class::bld) b += -0.5; + if (def.info->ent_class == EntityInfo::Class::bld) b += -0.5f; break; case EntityInfo::Class::sie: - if (def.info->ent_class == EntityInfo::Class::bld) b += +0.5; + if (def.info->ent_class == EntityInfo::Class::bld) b += +0.5f; break; } return b; @@ -54,15 +54,24 @@ float Gst::get_type_bonus (Entity &atk, Entity &def) { std::vector Gst::get_bonuses (Entity &atk, Entity &def) { std::vector bs; - bs.emplace_back( - tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus, - Bonus::Id::ground, true); - bs.emplace_back( - tiles[ground.tiles[ground.at(def.x, def.y)]].defence_bonus, - Bonus::Id::ground, false); + if (tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus != 0) { - bs.emplace_back(get_type_bonus(atk, def), Bonus::Id::type, true); - bs.emplace_back(get_type_bonus(def, atk), Bonus::Id::type, false); + bs.emplace_back( + tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus, + Bonus::Id::ground, true); + } + if (tiles[ground.tiles[ground.at(def.x, def.y)]].defence_bonus != 0) { + bs.emplace_back( + tiles[ground.tiles[ground.at(def.x, def.y)]].defence_bonus, + Bonus::Id::ground, false); + } + + if (get_type_bonus(atk, def) != 0) { + bs.emplace_back(get_type_bonus(atk, def), Bonus::Id::type, true); + } + if (get_type_bonus(def, atk) != 0) { + bs.emplace_back(get_type_bonus(def, atk), Bonus::Id::type, false); + } if (info_has_ability(atk.info, "Causes Fear")) bs.emplace_back(-1.0f/3, Bonus::Id::ability, false); @@ -95,11 +104,10 @@ std::vector Gst::get_bonuses (Entity &atk, Entity &def) { if (info_has_ability(atk.info, "Frenzy")) bs.emplace_back(1/atk.hp, Bonus::Id::ability, true); - return bs; } -float Gst::get_damage (Entity &atk, Entity &def) { +float Gst::get_damage (Entity &atk, Entity &def, float atk_hp) { float atkmul = 1; float defmul = 1; @@ -109,24 +117,30 @@ float Gst::get_damage (Entity &atk, Entity &def) { else { defmul += bonus.amt; } } - float dam = (atk.info->attack * atk.hp * atkmul) + float dam = (atk.info->attack * atk_hp * atkmul) / (2.0f*def.info->defence * defmul); return dam; } +float Gst::get_damage (Entity &atk, Entity &def) { + return get_damage(atk, def, atk.hp); +} + bool Gst::get_first_strike (Entity &atk, Entity &def) { bool fs { false }; fs = info_has_ability(atk.info, "First Strike"); return fs; } -float clamp (float hp) { if (hp > 100) hp = 100; return hp; } +float clamp (float hp) { + if (hp > 100) hp = 100; + if (hp < 0) hp = 0; + return hp; +} -void Gst::battle (Entity &atk, Entity &def) { - std::cout << "! attack " << atk.info->name << "(hp:" << atk.hp << "), " - << def.info->name << "(hp:" << def.hp << ") \n"; - +BattleResult Gst::battle_res (Entity &atk, Entity &def) { + BattleResult result { atk.hp, def.hp }; bool first_strike_atk = info_has_ability(atk.info, "First Strike"); bool first_strike_def = info_has_ability(def.info, "First Strike"); bool skirmish_atk = info_has_ability(atk.info, "Skirmish"); @@ -142,30 +156,54 @@ void Gst::battle (Entity &atk, Entity &def) { first_strike_def = first_strike_def || (anticav_def && atk.info->ent_class == EntityInfo::Class::cav); + int dist = abs(atk.x-def.x) + abs(atk.y-def.y); + bool def_inrange = (dist <= get_range(def)) ? true : false; + bool swap = false; if (first_strike_def && !first_strike_atk) swap = true; if (swap) { - atk.hp = clamp(atk.hp - get_damage(def, atk)); + if (def_inrange) { + result.atk_hp = clamp( + result.atk_hp - get_damage(def, atk, result.def_hp)); + } if (!info_has_ability(atk.info, "No Counter")) - if (atk.hp > 0) def.hp -= get_damage(atk, def); + if (result.atk_hp > 0) + result.def_hp = clamp( + result.def_hp - get_damage(atk, def, result.atk_hp)); } else { - def.hp = clamp(def.hp - get_damage(atk, def)); - if (!info_has_ability(def.info, "No Counter")) - if (def.hp > 0) atk.hp -= get_damage(def, atk); + result.def_hp = clamp( + result.def_hp - get_damage(atk, def, result.atk_hp)); + if (!info_has_ability(def.info, "No Counter") && def_inrange) + if (result.def_hp > 0) + result.atk_hp = clamp( + result.atk_hp - get_damage(def, atk, result.def_hp)); } if (info_has_ability(atk.info, "Rapid Fire")) - if (def.hp > 0) - def.hp = clamp(def.hp - get_damage(atk, def)); + if (result.def_hp > 0) + result.def_hp = clamp( + result.def_hp - get_damage(atk, def, result.def_hp)); + + if (info_has_ability(def.info, "Rapid Fire") && def_inrange) + if (result.atk_hp > 0) + result.atk_hp = clamp( + result.atk_hp - get_damage(def, atk, result.def_hp)); - if (info_has_ability(def.info, "Rapid Fire")) - if (atk.hp > 0) - atk.hp = clamp(atk.hp - get_damage(def, atk)); + if (result.atk_hp > 0 && info_has_ability(atk.info, "Zeal")) + result.atk_hp = clamp(result.atk_hp + 20); + if (result.def_hp > 0 && info_has_ability(def.info, "Zeal")) + result.def_hp = clamp(result.def_hp + 20); + + return result; +} + +void Gst::battle (Entity &atk, Entity &def) { + std::cout << "! attack " << atk.info->name << "(hp:" << atk.hp << "), " + << def.info->name << "(hp:" << def.hp << ") \n"; - if (atk.hp > 0 && info_has_ability(atk.info, "Zeal")) - atk.hp = clamp(atk.hp + 20); - if (def.hp > 0 && info_has_ability(def.info, "Zeal")) - def.hp = clamp(def.hp + 20); + auto result = battle_res(atk, def); + atk.hp = result.atk_hp; + def.hp = result.def_hp; std::cout << "! result " << atk.info->name << "(hp:" << atk.hp << "), " << def.info->name << "(hp:" << def.hp << ") \n"; @@ -182,6 +220,15 @@ void Gst::clear_dead() { } } +int Gst::get_range (Entity &ent) { + int range = ent.info->range; + if (range > 1) { + range += tiles[ground.tiles[ground.at(ent.x, ent.y)]].range_bonus; + } + if (range < 1) range = 1; + return range; +} + std::vector Gst::get_possible_builds (Entity &ent) { std::vector builds; for (int id : ent.info->build) { @@ -196,7 +243,7 @@ bool Gst::check_req_build(Entity &ent, EntityInfo *info) { for (int id : info->adjacent) { bool adj = false; for (Entity &e : entities) { - if (e.info->id == id) { + if (e.info->id == id && ent.owner == e.owner) { int dist = abs(e.x-ent.x) + abs(e.y-ent.y); if (dist == 1) { adj = true; @@ -213,7 +260,7 @@ bool Gst::check_req_build(Entity &ent, EntityInfo *info) { } int mindist = 9999; for (Entity &e : entities) { - if (e.info->id == 100) { + if (e.info->id == 100 && ent.owner == e.owner) { int dist = abs(e.x-ent.x) + abs(ent.y-e.y); if (dist < mindist) { mindist = dist; @@ -260,4 +307,21 @@ void Gst::end_day () { turn = 0; day++; } + for (Entity &e : entities) { + e.done = false; + e.moved = 0; + if (e.owner == turn) { + Player &player = players[e.owner]; + for (int i=0; iprod[i]; + } + // todo heal when on top of building + if (e.building < 0) { + e.building++; + if (e.building == 0) { + e.hp += 50; if (e.hp > 100) e.hp = 100; + } + } + } + } } \ No newline at end of file -- cgit v1.2.3-54-g00ecf