From c52ce11e493b8127983a5999b9d21e4b26047f24 Mon Sep 17 00:00:00 2001 From: mattsc Date: Sun, 2 Sep 2018 15:08:24 -0700 Subject: [PATCH] Lua AIs: replace tabs with spaces (cherry-picked from commit 45a3bf93636fb7b34b27a3411784d0484eeb18d6) --- data/ai/lua/ca_castle_switch.lua | 368 +++++++++--------- .../micro_ais/cas/ca_forest_animals_move.lua | 2 +- .../cas/ca_forest_animals_new_rabbit.lua | 2 +- .../ai/ca_transport_S6.lua | 10 +- 4 files changed, 191 insertions(+), 191 deletions(-) diff --git a/data/ai/lua/ca_castle_switch.lua b/data/ai/lua/ca_castle_switch.lua index 56aa829e7c2b..fda8b4953531 100644 --- a/data/ai/lua/ca_castle_switch.lua +++ b/data/ai/lua/ca_castle_switch.lua @@ -7,200 +7,200 @@ local CS_leader_score -- Note that leader_target is also needed by the recruiting CA, so it must be stored in 'data' local function get_reachable_enemy_leaders(unit) - -- We're cheating a little here and also find hidden enemy leaders. That's - -- because a human player could make a pretty good educated guess as to where - -- the enemy leaders are likely to be while the AI does not know how to do that. - local potential_enemy_leaders = AH.get_live_units { canrecruit = 'yes', - { "filter_side", { { "enemy_of", {side = wesnoth.current.side} } } } - } - local enemy_leaders = {} - for j,e in ipairs(potential_enemy_leaders) do - local path, cost = wesnoth.find_path(unit, e.x, e.y, { ignore_units = true, viewing_side = 0 }) - if cost < AH.no_path then - table.insert(enemy_leaders, e) - end - end - - return enemy_leaders + -- We're cheating a little here and also find hidden enemy leaders. That's + -- because a human player could make a pretty good educated guess as to where + -- the enemy leaders are likely to be while the AI does not know how to do that. + local potential_enemy_leaders = AH.get_live_units { canrecruit = 'yes', + { "filter_side", { { "enemy_of", {side = wesnoth.current.side} } } } + } + local enemy_leaders = {} + for j,e in ipairs(potential_enemy_leaders) do + local path, cost = wesnoth.find_path(unit, e.x, e.y, { ignore_units = true, viewing_side = 0 }) + if cost < AH.no_path then + table.insert(enemy_leaders, e) + end + end + + return enemy_leaders end local ca_castle_switch = {} function ca_castle_switch:evaluation(cfg, data) - local start_time, ca_name = wesnoth.get_time_stamp() / 1000., 'castle_switch' - if AH.print_eval() then AH.print_ts(' - Evaluating castle_switch CA:') end - - if ai.aspects.passive_leader then - -- Turn off this CA if the leader is passive - return 0 - end - - local leader = wesnoth.get_units { - side = wesnoth.current.side, - canrecruit = 'yes', - formula = '(movement_left = total_movement) and (hitpoints = max_hitpoints)' - }[1] - if not leader then - -- CA is irrelevant if no leader or the leader may have moved from another CA - data.leader_target = nil - if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end - return 0 - end - - local cheapest_unit_cost = AH.get_cheapest_recruit_cost() - - if data.leader_target and wesnoth.sides[wesnoth.current.side].gold >= cheapest_unit_cost then - -- make sure move is still valid - local next_hop = AH.next_hop(leader, data.leader_target[1], data.leader_target[2]) - if next_hop and next_hop[1] == data.leader_target[1] - and next_hop[2] == data.leader_target[2] then - return CS_leader_score - end - end - - local width,height,border = wesnoth.get_map_size() - local keeps = wesnoth.get_locations { - terrain = 'K*,K*^*,*^K*', -- Keeps - x = '1-'..width, - y = '1-'..height, - { "not", { {"filter", {}} }}, -- That have no unit - { "not", { radius = 6, {"filter", { canrecruit = 'yes', - { "filter_side", { { "enemy_of", {side = wesnoth.current.side} } } } - }} }}, -- That are not too close to an enemy leader - { "not", { - x = leader.x, y = leader.y, terrain = 'K*,K*^*,*^K*', - radius = 3, - { "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } } - }}, -- That are not close and connected to a keep the leader is on - { "filter_adjacent_location", { - terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' - }} -- That are not one-hex keeps - } - if #keeps < 1 then - -- Skip if there aren't extra keeps to evaluate - -- In this situation we'd only switch keeps if we were running away - if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end - return 0 - end - - local enemy_leaders = get_reachable_enemy_leaders(leader) - - -- Look for the best keep - local best_score, best_loc, best_turns = 0, {}, 3 - for i,loc in ipairs(keeps) do - -- Only consider keeps within 2 turns movement - local path, cost = wesnoth.find_path(leader, loc[1], loc[2]) - local score = 0 - -- Prefer closer keeps to enemy - local turns = math.ceil(cost/leader.max_moves) - if turns <= 2 then - score = 1/turns - for j,e in ipairs(enemy_leaders) do - score = score + 1 / M.distance_between(loc[1], loc[2], e.x, e.y) - end - - if score > best_score then - best_score = score - best_loc = loc - best_turns = turns - end - end - end - - -- If we're on a keep, - -- don't move to another keep unless it's much better when uncaptured villages are present - if best_score > 0 and wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then - local close_unowned_village = (wesnoth.get_villages { - { "and", { - x = leader.x, - y = leader.y, - radius = leader.max_moves - }}, - owner_side = 0 - })[1] - if close_unowned_village then - local score = 1/best_turns - for j,e in ipairs(enemy_leaders) do - -- count all distances as three less than they actually are - score = score + 1 / (M.distance_between(leader.x, leader.y, e.x, e.y) - 3) - end - - if score > best_score then - best_score = 0 - end - end - end - - if best_score > 0 then - local next_hop = AH.next_hop(leader, best_loc[1], best_loc[2]) - - if next_hop and ((next_hop[1] ~= leader.x) or (next_hop[2] ~= leader.y)) then - -- See if there is a nearby village that can be captured without delaying progress - local close_villages = wesnoth.get_villages( { - { "and", { x = next_hop[1], y = next_hop[2], radius = leader.max_moves }}, - owner_side = 0 }) - for i,loc in ipairs(close_villages) do - local path_village, cost_village = wesnoth.find_path(leader, loc[1], loc[2]) - if cost_village <= leader.moves then - local dummy_leader = leader:clone() - dummy_leader.x = loc[1] - dummy_leader.y = loc[2] - local path_keep, cost_keep = wesnoth.find_path(dummy_leader, best_loc[1], best_loc[2]) - local turns_from_keep = math.ceil(cost_keep/leader.max_moves) - if turns_from_keep < best_turns - or (turns_from_keep == 1 and wesnoth.sides[wesnoth.current.side].gold < cheapest_unit_cost) - then - -- There is, go there instead - next_hop = loc - break - end - end - end - end - - data.leader_target = next_hop - - -- if we're on a keep, wait until there are no movable units on the castle before moving off - CS_leader_score = 290000 - if wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then - local castle = wesnoth.get_locations { - x = "1-"..width, y = "1-"..height, - { "and", { - x = leader.x, y = leader.y, radius = 200, - { "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } } - }} - } - local should_wait = false - for i,loc in ipairs(castle) do - local unit = wesnoth.get_unit(loc[1], loc[2]) - if (not AH.is_visible_unit(wesnoth.current.side, unit)) then - should_wait = false - break - elseif unit.moves > 0 then - should_wait = true - end - end - if should_wait then - CS_leader_score = 15000 - end - end - - if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end - return CS_leader_score - end - - if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end - return 0 + local start_time, ca_name = wesnoth.get_time_stamp() / 1000., 'castle_switch' + if AH.print_eval() then AH.print_ts(' - Evaluating castle_switch CA:') end + + if ai.aspects.passive_leader then + -- Turn off this CA if the leader is passive + return 0 + end + + local leader = wesnoth.get_units { + side = wesnoth.current.side, + canrecruit = 'yes', + formula = '(movement_left = total_movement) and (hitpoints = max_hitpoints)' + }[1] + if not leader then + -- CA is irrelevant if no leader or the leader may have moved from another CA + data.leader_target = nil + if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end + return 0 + end + + local cheapest_unit_cost = AH.get_cheapest_recruit_cost() + + if data.leader_target and wesnoth.sides[wesnoth.current.side].gold >= cheapest_unit_cost then + -- make sure move is still valid + local next_hop = AH.next_hop(leader, data.leader_target[1], data.leader_target[2]) + if next_hop and next_hop[1] == data.leader_target[1] + and next_hop[2] == data.leader_target[2] then + return CS_leader_score + end + end + + local width,height,border = wesnoth.get_map_size() + local keeps = wesnoth.get_locations { + terrain = 'K*,K*^*,*^K*', -- Keeps + x = '1-'..width, + y = '1-'..height, + { "not", { {"filter", {}} }}, -- That have no unit + { "not", { radius = 6, {"filter", { canrecruit = 'yes', + { "filter_side", { { "enemy_of", {side = wesnoth.current.side} } } } + }} }}, -- That are not too close to an enemy leader + { "not", { + x = leader.x, y = leader.y, terrain = 'K*,K*^*,*^K*', + radius = 3, + { "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } } + }}, -- That are not close and connected to a keep the leader is on + { "filter_adjacent_location", { + terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' + }} -- That are not one-hex keeps + } + if #keeps < 1 then + -- Skip if there aren't extra keeps to evaluate + -- In this situation we'd only switch keeps if we were running away + if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end + return 0 + end + + local enemy_leaders = get_reachable_enemy_leaders(leader) + + -- Look for the best keep + local best_score, best_loc, best_turns = 0, {}, 3 + for i,loc in ipairs(keeps) do + -- Only consider keeps within 2 turns movement + local path, cost = wesnoth.find_path(leader, loc[1], loc[2]) + local score = 0 + -- Prefer closer keeps to enemy + local turns = math.ceil(cost/leader.max_moves) + if turns <= 2 then + score = 1/turns + for j,e in ipairs(enemy_leaders) do + score = score + 1 / M.distance_between(loc[1], loc[2], e.x, e.y) + end + + if score > best_score then + best_score = score + best_loc = loc + best_turns = turns + end + end + end + + -- If we're on a keep, + -- don't move to another keep unless it's much better when uncaptured villages are present + if best_score > 0 and wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then + local close_unowned_village = (wesnoth.get_villages { + { "and", { + x = leader.x, + y = leader.y, + radius = leader.max_moves + }}, + owner_side = 0 + })[1] + if close_unowned_village then + local score = 1/best_turns + for j,e in ipairs(enemy_leaders) do + -- count all distances as three less than they actually are + score = score + 1 / (M.distance_between(leader.x, leader.y, e.x, e.y) - 3) + end + + if score > best_score then + best_score = 0 + end + end + end + + if best_score > 0 then + local next_hop = AH.next_hop(leader, best_loc[1], best_loc[2]) + + if next_hop and ((next_hop[1] ~= leader.x) or (next_hop[2] ~= leader.y)) then + -- See if there is a nearby village that can be captured without delaying progress + local close_villages = wesnoth.get_villages( { + { "and", { x = next_hop[1], y = next_hop[2], radius = leader.max_moves }}, + owner_side = 0 }) + for i,loc in ipairs(close_villages) do + local path_village, cost_village = wesnoth.find_path(leader, loc[1], loc[2]) + if cost_village <= leader.moves then + local dummy_leader = leader:clone() + dummy_leader.x = loc[1] + dummy_leader.y = loc[2] + local path_keep, cost_keep = wesnoth.find_path(dummy_leader, best_loc[1], best_loc[2]) + local turns_from_keep = math.ceil(cost_keep/leader.max_moves) + if turns_from_keep < best_turns + or (turns_from_keep == 1 and wesnoth.sides[wesnoth.current.side].gold < cheapest_unit_cost) + then + -- There is, go there instead + next_hop = loc + break + end + end + end + end + + data.leader_target = next_hop + + -- if we're on a keep, wait until there are no movable units on the castle before moving off + CS_leader_score = 290000 + if wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then + local castle = wesnoth.get_locations { + x = "1-"..width, y = "1-"..height, + { "and", { + x = leader.x, y = leader.y, radius = 200, + { "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } } + }} + } + local should_wait = false + for i,loc in ipairs(castle) do + local unit = wesnoth.get_unit(loc[1], loc[2]) + if (not AH.is_visible_unit(wesnoth.current.side, unit)) then + should_wait = false + break + elseif unit.moves > 0 then + should_wait = true + end + end + if should_wait then + CS_leader_score = 15000 + end + end + + if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end + return CS_leader_score + end + + if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end + return 0 end function ca_castle_switch:execution(cfg, data) - local leader = wesnoth.get_units { side = wesnoth.current.side, canrecruit = 'yes' }[1] + local leader = wesnoth.get_units { side = wesnoth.current.side, canrecruit = 'yes' }[1] - if AH.print_exec() then AH.print_ts(' Executing castle_switch CA') end - if AH.show_messages() then wesnoth.wml_actions.message { speaker = leader.id, message = 'Switching castles' } end + if AH.print_exec() then AH.print_ts(' Executing castle_switch CA') end + if AH.show_messages() then wesnoth.wml_actions.message { speaker = leader.id, message = 'Switching castles' } end - AH.checked_move(ai, leader, data.leader_target[1], data.leader_target[2]) - data.leader_target = nil + AH.checked_move(ai, leader, data.leader_target[1], data.leader_target[2]) + data.leader_target = nil end return ca_castle_switch diff --git a/data/ai/micro_ais/cas/ca_forest_animals_move.lua b/data/ai/micro_ais/cas/ca_forest_animals_move.lua index 49385224a4c3..c94ec89f2c61 100644 --- a/data/ai/micro_ais/cas/ca_forest_animals_move.lua +++ b/data/ai/micro_ais/cas/ca_forest_animals_move.lua @@ -155,7 +155,7 @@ function ca_forest_animals_move:execution(cfg) -- If this is a rabbit ending on a hole -> disappears if (unit.type == rabbit_type) and hole_map:get(farthest_hex[1], farthest_hex[2]) then - wesnoth.invoke_synced_command("rabbit_despawn", { x = farthest_hex[1], y = farthest_hex[2]}) + wesnoth.invoke_synced_command("rabbit_despawn", { x = farthest_hex[1], y = farthest_hex[2]}) end end diff --git a/data/ai/micro_ais/cas/ca_forest_animals_new_rabbit.lua b/data/ai/micro_ais/cas/ca_forest_animals_new_rabbit.lua index 1673bf958e84..9374aa3d0e38 100644 --- a/data/ai/micro_ais/cas/ca_forest_animals_new_rabbit.lua +++ b/data/ai/micro_ais/cas/ca_forest_animals_new_rabbit.lua @@ -56,7 +56,7 @@ function ca_forest_animals_new_rabbit:execution(cfg) x, y = wesnoth.find_vacant_tile(holes[i].x, holes[i].y) end - wesnoth.invoke_synced_command("rabbit_spawn", { rabbit_type = cfg.rabbit_type, x = x, y = y}) + wesnoth.invoke_synced_command("rabbit_spawn", { rabbit_type = cfg.rabbit_type, x = x, y = y}) end if wesnoth.sides[wesnoth.current.side].shroud then diff --git a/data/campaigns/Son_Of_The_Black_Eye/ai/ca_transport_S6.lua b/data/campaigns/Son_Of_The_Black_Eye/ai/ca_transport_S6.lua index dceadbcd763e..0568861d2522 100644 --- a/data/campaigns/Son_Of_The_Black_Eye/ai/ca_transport_S6.lua +++ b/data/campaigns/Son_Of_The_Black_Eye/ai/ca_transport_S6.lua @@ -110,12 +110,12 @@ function ca_transport:execution() -- Also unload units table.sort(best_adj_tiles, function(a, b) return a[3] > b[3] end) - local command_data = { x = best_unit.x, y = best_unit.y } - for i = 1, math.min(#best_adj_tiles, 3) do - table.insert(command_data, T.dst { x = best_adj_tiles[i][1], y = best_adj_tiles[i][2]} ) - end + local command_data = { x = best_unit.x, y = best_unit.y } + for i = 1, math.min(#best_adj_tiles, 3) do + table.insert(command_data, T.dst { x = best_adj_tiles[i][1], y = best_adj_tiles[i][2]} ) + end - wesnoth.invoke_synced_command("ship_unload", command_data) + wesnoth.invoke_synced_command("ship_unload", command_data) return end