Module: Natural20::Navigation

Includes:
Weapons
Included in:
AiController::Standard
Defined in:
lib/natural_20/concerns/navigation.rb

Instance Method Summary collapse

Methods included from Weapons

#compute_advantages_and_disadvantages, #damage_modifier, #target_advantage_condition

Instance Method Details

#candidate_squares(map, battle, entity) ⇒ Object

Parameters:



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 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) ⇒ Object

Parameters:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 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