diff --git a/data/campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua b/data/campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua new file mode 100644 index 00000000000..758f0a2b7c2 --- /dev/null +++ b/data/campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua @@ -0,0 +1,67 @@ +local AH = wesnoth.require "ai/lua/ai_helper.lua" + +local ca_aggressive_attack_no_suicide = {} + +function ca_aggressive_attack_no_suicide:evaluation(ai, cfg, self) + + local units = wesnoth.get_units { + side = wesnoth.current.side, + formula = '$this_unit.attacks_left > 0' + } + --print('#units', #units) + if (not units[1]) then return 0 end + + -- Get all possible attacks + local attacks = AH.get_attacks(units, { include_occupied = true }) + --print('#attacks', #attacks) + if (not attacks[1]) then return 0 end + + -- Now find the best of the possible attacks + local max_rating, best_attack = -9e99, {} + for i, att in ipairs(attacks) do + local attacker = wesnoth.get_unit(att.src.x, att.src.y) + local defender = wesnoth.get_unit(att.target.x, att.target.y) + + local attacker_dst = wesnoth.copy_unit(attacker) + attacker_dst.x, attacker_dst.y = att.dst.x, att.dst.y + + local att_stats, def_stats = wesnoth.simulate_combat(attacker_dst, defender) + + if (att_stats.hp_chance[0] == 0) then + local rating = def_stats.hp_chance[0] * 100 + + local attacker_damage = attacker.hitpoints - att_stats.average_hp + local defender_damage = defender.hitpoints - def_stats.average_hp + + rating = rating + defender_damage + rating = rating - attacker_damage / 10. + + -- Also, take strongest unit first + rating = rating + attacker.hitpoints / 10. + --print('rating:', rating, attacker.id, defender.id) + + if (rating > max_rating) then + max_rating = rating + best_attack = att + end + end + end + + if (max_rating > -9e99) then + self.data.attack = best_attack + return 100000 + end + + return 0 +end + +function ca_aggressive_attack_no_suicide:execution(ai, cfg, self) + local attacker = wesnoth.get_unit(self.data.attack.src.x, self.data.attack.src.y) + local defender = wesnoth.get_unit(self.data.attack.target.x, self.data.attack.target.y) + + AH.movefull_outofway_stopunit(ai, attacker, self.data.attack.dst.x, self.data.attack.dst.y) + ai.attack(attacker, defender) + self.data.attack = nil +end + +return ca_aggressive_attack_no_suicide diff --git a/data/campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua b/data/campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua new file mode 100644 index 00000000000..51a71772630 --- /dev/null +++ b/data/campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua @@ -0,0 +1,31 @@ +local R = wesnoth.require "ai/lua/retreat.lua" +local AH = wesnoth.require "ai/lua/ai_helper.lua" + +local retreat = {} + +function retreat:evaluation(ai, cfg, self) + + local units = wesnoth.get_units { + side = wesnoth.current.side, + formula = '$this_unit.moves > 0' + } + --print('#units', #units) + if (not units[1]) then return 0 end + + local unit, dst, enemy_threat = R.retreat_injured_units(units) + + if unit then + self.data.retreat_unit = unit + self.data.retreat_dst = dst + return 101000 + end + + return 0 +end + +function retreat:execution(ai, cfg, self) + AH.movefull_outofway_stopunit(ai, self.data.retreat_unit, self.data.retreat_dst[1], self.data.retreat_dst[2]) + self.data.retreat_unit, self.data.retreat_dst = nil, nil +end + +return retreat diff --git a/data/campaigns/The_Rise_Of_Wesnoth/scenarios/15_A_New_Land.cfg b/data/campaigns/The_Rise_Of_Wesnoth/scenarios/15_A_New_Land.cfg index 7d9413e4e75..8f9519aad6a 100644 --- a/data/campaigns/The_Rise_Of_Wesnoth/scenarios/15_A_New_Land.cfg +++ b/data/campaigns/The_Rise_Of_Wesnoth/scenarios/15_A_New_Land.cfg @@ -52,10 +52,27 @@ recruit=Elvish Archer, Elvish Fighter, Elvish Scout, Elvish Shaman, Elvish Hero, Elvish Marksman, Elvish Druid [ai] {NO_SCOUTS} - recruitment_ignore_bad_movement=yes - recruitment_pattern=scout,fighter,archer,fighter, archer, healer - aggression=1.0 - caution=0.0 + recruitment_pattern=fighter,archer,fighter,archer,healer + + {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop ( + [candidate_action] + engine=lua + name=retreat + id=retreat + max_score=101000 + location="campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua" + [/candidate_action] + )} + {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop ( + [candidate_action] + engine=lua + name=aggressive_attack_no_suicide + id=aggressive_attack_no_suicide + max_score=100000 + location="campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua" + [/candidate_action] + )} + {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop combat} [/ai] {FLAG_VARIANT wood-elvish} [/side] @@ -79,10 +96,27 @@ recruit=Dwarvish Fighter, Dwarvish Thunderer, Dwarvish Guardsman, Dwarvish Steelclad, Dwarvish Thunderguard [ai] {NO_SCOUTS} - recruitment_ignore_bad_movement=yes - recruitment_pattern=fighter,fighter,fighter,mixed fighter - aggression=1.0 - caution=0.0 + recruitment_pattern=fighter,archer,fighter,archer,healer + + {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop ( + [candidate_action] + engine=lua + name=retreat + id=retreat + max_score=101000 + location="campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua" + [/candidate_action] + )} + {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop ( + [candidate_action] + engine=lua + name=aggressive_attack_no_suicide + id=aggressive_attack_no_suicide + max_score=100000 + location="campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua" + [/candidate_action] + )} + {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop combat} [/ai] {FLAG_VARIANT knalgan} [/side] @@ -105,10 +139,27 @@ recruit=Elvish Archer, Elvish Fighter, Elvish Scout, Elvish Shaman [ai] {NO_SCOUTS} - recruitment_ignore_bad_movement=yes - recruitment_pattern=scout,fighter,archer,fighter, archer, healer - aggression=1.0 - caution=0.0 + recruitment_pattern=fighter,archer,fighter,archer,healer + + {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop ( + [candidate_action] + engine=lua + name=retreat + id=retreat + max_score=101000 + location="campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua" + [/candidate_action] + )} + {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop ( + [candidate_action] + engine=lua + name=aggressive_attack_no_suicide + id=aggressive_attack_no_suicide + max_score=100000 + location="campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua" + [/candidate_action] + )} + {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop combat} [/ai] {FLAG_VARIANT long} [/side] @@ -465,7 +516,7 @@ _"Notes:"+"" {NEW_GOLD_CARRYOVER $anl_carryover} next_scenario=16_The_Kalian [/endlevel] - + {CLEAR_VARIABLE anl_carryover} [/event] [/scenario]