module Natural20::Navigation
Public Instance Methods
candidate_squares(map, battle, entity)
click to toggle source
@param map [natural20::BattleMap] @param battle [Natural20::Battle] @param entity [Natural20::Entity]
# File lib/natural_20/concerns/navigation.rb, line 7 def candidate_squares(map, battle, entity) compute = AiController::PathCompute.new(battle, map, entity) cur_pos_x, cur_pos_y = map.entity_or_object_pos(entity) compute.build_structures(cur_pos_x, cur_pos_y) compute.path candidate_squares = [[[cur_pos_x, cur_pos_y], 0]] map.size[0].times.each do |pos_x| map.size[1].times.each do |pos_y| next unless map.line_of_sight_for?(entity, pos_x, pos_y) next unless map.placeable?(entity, pos_x, pos_y, battle) path, cost = compute.incremental_path(cur_pos_x, cur_pos_y, pos_x, pos_y) next if path.nil? candidate_squares << [[pos_x, pos_y], cost.floor] end end candidate_squares.uniq.to_h end
evaluate_square(map, battle, entity, opponents)
click to toggle source
@param map [Natural20::BattleMap] @param battle [Natural20::Battle] @param entity [Natural20::Entity] @param opponents [Array<Natural20::Entity>]
# File lib/natural_20/concerns/navigation.rb, line 33 def evaluate_square(map, battle, entity, opponents) melee_attack_squares = {} opponents.each do |opp| opp.melee_squares(map).each do |pos| melee_attack_squares[pos] ||= 0 melee_attack_squares[pos] += 1 end end attack_options = if entity.npc? entity.npc_actions.map do |npc_action| next if npc_action[:ammo] && entity.item_count(npc_action[:ammo]) <= 0 next if npc_action[:if] && !entity.eval_if(npc_action[:if]) next unless npc_action[:type] == 'melee_attack' npc_action end.first end destinations = candidate_squares(map, battle, entity) destinations.map do |d, _cost| # evaluate defense melee_offence = 0.0 ranged_offence = 0.0 defense = 0.0 mobility = 0.0 support = 0.0 if melee_attack_squares.key?(d) melee_offence += 0.2 defense -= 0.05 * melee_attack_squares[d] if attack_options opponents.each do |opp| adv, _adv_info = target_advantage_condition(battle, entity, opp, attack_options, source_pos: d) melee_offence += adv end end else ranged_offence += 0.1 opponents.each do |opp| defense += map.cover_calculation(map, opp, entity, entity_2_pos: d, naturally_stealthy: entity.class_feature?('naturally_stealthy')).to_f end end if map.requires_squeeze?(entity, *d, map, battle) mobility -= 1.0 melee_offence -= 0.5 ranged_offence -= 0.5 end mobility -= 0.001 * map.line_distance(entity, *d) [d, [melee_offence, ranged_offence, defense, mobility, support]] end.to_h end