Skip to content

Commit

Permalink
Fix several Lua issues, mostly unintentional globals
Browse files Browse the repository at this point in the history
  • Loading branch information
CelticMinstrel committed Mar 5, 2021
1 parent 93398ae commit 6e0d836
Show file tree
Hide file tree
Showing 23 changed files with 72 additions and 77 deletions.
6 changes: 3 additions & 3 deletions data/ai/lua/ai_helper.lua
Expand Up @@ -1257,7 +1257,7 @@ function ai_helper.get_closest_enemy(loc, side, cfg)

local closest_distance, closest_enemy = math.huge
for _,enemy in ipairs(enemies) do
enemy_distance = M.distance_between(x, y, enemy.x, enemy.y)
local enemy_distance = M.distance_between(x, y, enemy)
if (enemy_distance < closest_distance) then
closest_enemy = enemy
closest_distance = enemy_distance
Expand Down Expand Up @@ -2298,7 +2298,7 @@ function ai_helper.get_attack_combos_full(units, enemy, cfg)
if (not attacks[1]) then return {} end

-- This recursive function does all the work:
local combos = ai_helper.add_next_attack_combo_level(combos, attacks)
local combos = ai_helper.add_next_attack_combo_level(nil, attacks)

return combos
end
Expand Down Expand Up @@ -2454,7 +2454,7 @@ function ai_helper.get_unit_time_of_day_bonus(alignment, lawful_bonus)
elseif (alignment == 'chaotic') then
multiplier = (1 - lawful_bonus / 100.)
elseif (alignment == 'liminal') then
multipler = (1 - math.abs(lawful_bonus) / 100.)
multiplier = (1 - math.abs(lawful_bonus) / 100.)
end
end
return multiplier
Expand Down
2 changes: 1 addition & 1 deletion data/ai/lua/extCAexample.lua
@@ -1,6 +1,6 @@
--! #textdomain wesnoth

example_ca = {}
local example_ca = {}

function example_ca:evaluation()
wesnoth.message("External CA evaluation says hi.")
Expand Down
75 changes: 37 additions & 38 deletions data/ai/lua/generic_recruit_engine.lua
Expand Up @@ -29,6 +29,7 @@ return {
local AH = wesnoth.require "ai/lua/ai_helper.lua"
local M = wesnoth.map
local LS = wesnoth.require "location_set"
local recruit_lib = {}

local recruit_data = {}

Expand Down Expand Up @@ -73,15 +74,15 @@ return {
local efficiency = {}
setmetatable(efficiency, { __index = get_hp_efficiency })

function poisonable(unit)
function recruit_lib.poisonable(unit)
return not unit.status.unpoisonable
end

function drainable(unit)
function recruit_lib.drainable(unit)
return not unit.status.undrainable
end

function get_best_defense(unit)
function recruit_lib.get_best_defense(unit)
local terrain_archetypes = { "Wo", "Ww", "Wwr", "Ss", "Gt", "Ds", "Ft", "Hh", "Mm", "Vi", "Ch", "Uu", "At", "Qt", "^Uf", "Xt", "Tb" }
local best_defense = 100

Expand All @@ -95,7 +96,7 @@ return {
return best_defense
end

function analyze_enemy_unit(enemy_type, ally_type)
function recruit_lib.analyze_enemy_unit(enemy_type, ally_type)
local function get_best_attack(attacker, defender, defender_defense, attacker_defense, can_poison)
-- Try to find the average damage for each possible attack and return the one that deals the most damage.
-- Would be preferable to call simulate combat, but that requires the defender to be on the map according
Expand Down Expand Up @@ -193,7 +194,7 @@ return {
local defender_attack = defender_attacks[i_d]
if (defender_attack.range == attack.range) then
for _,sp in ipairs(defender_attack.specials) do
if (sp[1] == 'drains') and drainable(attacker) then
if (sp[1] == 'drains') and recruit_lib.drainable(attacker) then
-- TODO: calculate chance to hit
-- currently assumes 50% chance to hit using supplied constant
local attacker_resistance = attacker:resistance_against(defender_attack.type)
Expand Down Expand Up @@ -257,9 +258,9 @@ return {
name = "X",
random_gender = false
}
local can_poison = poisonable(unit) and (not unit:ability('regenerate'))
local can_poison = recruit_lib.poisonable(unit) and (not unit:ability('regenerate'))
local flat_defense = 100 - unit:defense_on("Gt")
local best_defense = get_best_defense(unit)
local best_defense = recruit_lib.get_best_defense(unit)

local recruit = wesnoth.units.create {
type = ally_type,
Expand All @@ -268,12 +269,12 @@ return {
random_gender = false
}
local recruit_flat_defense = 100 - recruit:defense_on("Gt")
local recruit_best_defense = get_best_defense(recruit)
local recruit_best_defense = recruit_lib.get_best_defense(recruit)

local can_poison_retaliation = poisonable(recruit) and (not recruit:ability('regenerate'))
best_flat_attack, best_flat_damage, flat_poison = get_best_attack(recruit, unit, flat_defense, recruit_best_defense, can_poison)
best_high_defense_attack, best_high_defense_damage, high_defense_poison = get_best_attack(recruit, unit, best_defense, recruit_flat_defense, can_poison)
best_retaliation, best_retaliation_damage, retaliation_poison = get_best_attack(unit, recruit, recruit_flat_defense, best_defense, can_poison_retaliation)
local can_poison_retaliation = recruit_lib.poisonable(recruit) and (not recruit:ability('regenerate'))
local best_flat_attack, best_flat_damage, flat_poison = get_best_attack(recruit, unit, flat_defense, recruit_best_defense, can_poison)
local best_high_defense_attack, best_high_defense_damage, high_defense_poison = get_best_attack(recruit, unit, best_defense, recruit_flat_defense, can_poison)
local best_retaliation, best_retaliation_damage, retaliation_poison = get_best_attack(unit, recruit, recruit_flat_defense, best_defense, can_poison_retaliation)

local result = {
offense = { attack = best_flat_attack, damage = best_flat_damage, poison_damage = flat_poison },
Expand All @@ -287,7 +288,7 @@ return {
return analysis[ally_type]
end

function can_slow(unit)
function recruit_lib.can_slow(unit)
local attacks = unit.attacks
for i_a = 1,#attacks do
for _,sp in ipairs(attacks[i_a].specials) do
Expand All @@ -299,8 +300,8 @@ return {
return false
end

function get_hp_ratio_with_gold()
function sum_gold_for_sides(side_filter)
function recruit_lib.get_hp_ratio_with_gold()
local function sum_gold_for_sides(side_filter)
-- sum positive amounts of gold for a set of sides
-- positive only because it is used to estimate the number of enemy units that could appear
-- and negative numbers shouldn't subtract from the number of units on the map
Expand All @@ -317,10 +318,10 @@ return {

-- Hitpoint ratio of own units / enemy units
-- Also convert available gold to a hp estimate
my_units = AH.get_live_units {
local my_units = AH.get_live_units {
{ "filter_side", {{"allied_with", {side = wesnoth.current.side} }} }
}
enemies = AH.get_live_units {
local enemies = AH.get_live_units {
{ "filter_side", {{"enemy_of", {side = wesnoth.current.side} }} }
}

Expand All @@ -330,12 +331,10 @@ return {

my_hp = my_hp + sum_gold_for_sides({{"allied_with", {side = wesnoth.current.side} }})*2.3
enemy_hp = enemy_hp+sum_gold_for_sides({{"enemy_of", {side = wesnoth.current.side} }})*2.3
hp_ratio = my_hp/(enemy_hp + 1e-6)

return hp_ratio
return my_hp / enemy_hp
end

function do_recruit_eval(data)
function recruit_lib.do_recruit_eval(data)
-- Check if leader is on keep
local leader = wesnoth.units.find_on_map {
side = wesnoth.current.side,
Expand All @@ -354,7 +353,7 @@ return {
end

-- Check for space to recruit a unit
get_current_castle(leader, data)
recruit_lib.get_current_castle(leader, data)
local no_space = true
for i,c in ipairs(data.castle.locs) do
local unit = wesnoth.units.get(c[1], c[2])
Expand All @@ -369,13 +368,13 @@ return {

-- Check for minimal recruit option
if wesnoth.current.turn == 1 and params.min_turn_1_recruit and params.min_turn_1_recruit() then
if not get_village_target(leader, data)[1] then
if not recruit_lib.get_village_target(leader, data)[1] then
return 0
end
end

if not data.recruit then
data.recruit = init_data(leader)
data.recruit = recruit_lib.init_data(leader)
end
data.recruit.cheapest_unit_cost = cheapest_unit_cost

Expand All @@ -386,7 +385,7 @@ return {
return score
end

function init_data(leader)
function recruit_lib.init_data(leader)
local data = {}

-- Count enemies of each type
Expand Down Expand Up @@ -450,7 +449,7 @@ return {
local start_time, ca_name = wesnoth.get_time_stamp() / 1000., 'recruit_rushers'
if AH.print_eval() then AH.print_ts(' - Evaluating recruit_rushers CA:') end

local score = do_recruit_eval(recruit_data)
local score = recruit_lib.do_recruit_eval(recruit_data)
if score == 0 then
-- We're done for the turn, discard data
recruit_data.recruit = nil
Expand All @@ -467,7 +466,6 @@ return {
local enemy_counts = recruit_data.recruit.enemy_counts
local enemy_types = recruit_data.recruit.enemy_types
local num_enemies = recruit_data.recruit.num_enemies
local hp_ratio = get_hp_ratio_with_gold()

-- Determine effectiveness of recruitable units against each enemy unit type
local recruit_effectiveness = {}
Expand All @@ -488,7 +486,7 @@ return {
enemy_type_count = enemy_type_count + 1
local poison_vulnerable = false
for i, recruit_id in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
local analysis = analyze_enemy_unit(unit_type, recruit_id)
local analysis = recruit_lib.analyze_enemy_unit(unit_type, recruit_id)

if not recruit_effectiveness[recruit_id] then
recruit_effectiveness[recruit_id] = {damage = 0, poison_damage = 0}
Expand Down Expand Up @@ -607,7 +605,7 @@ return {
end
end

function get_current_castle(leader, data)
function recruit_lib.get_current_castle(leader, data)
if (not data.castle) or (data.castle.x ~= leader.x) or (data.castle.y ~= leader.y) then
data.castle = {
locs = AH.get_locations_no_borders {
Expand All @@ -627,9 +625,9 @@ return {
-- Find the best recruit hex
-- First choice: a hex that can reach an unowned village
-- Second choice: a hex close to the enemy
get_current_castle(leader, data)
recruit_lib.get_current_castle(leader, data)

local best_hex, village = get_village_target(leader, data)
local best_hex, village = recruit_lib.get_village_target(leader, data)
if village[1] then
table.insert(data.castle.assigned_villages_x, village[1])
table.insert(data.castle.assigned_villages_y, village[2])
Expand Down Expand Up @@ -774,7 +772,7 @@ return {
end
end

if can_slow(recruit_unit) then
if recruit_lib.can_slow(recruit_unit) then
unit_score["slows"] = true
end
if recruit_unit:matches { ability = "healing" } then
Expand All @@ -785,7 +783,8 @@ return {
end
recruitable_units[recruit_id] = recruit_unit
end
local healer_count, healable_count = get_unit_counts_for_healing()
local healer_count, healable_count = recruit_lib.get_unit_counts_for_healing()
local hp_ratio = recruit_lib.get_hp_ratio_with_gold()
local best_score = 0
local recruit_type
local offense_weight = 2.5
Expand Down Expand Up @@ -875,7 +874,7 @@ return {
return recruit_type
end

function get_unit_counts_for_healing()
function recruit_lib.get_unit_counts_for_healing()
local healers = #AH.get_live_units {
side = wesnoth.current.side,
ability = "healing",
Expand All @@ -888,7 +887,7 @@ return {
return healers, healable
end

function get_village_target(leader, data)
function recruit_lib.get_village_target(leader, data)
-- Only consider villages reachable by our fastest unit
local fastest_unit_speed = 0
for i, recruit_id in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
Expand Down Expand Up @@ -955,11 +954,11 @@ return {
end

local village_count = #villages
local test_units = get_test_units()
local test_units = recruit_lib.get_test_units()
local num_recruits = #test_units
local total_village_distance = {}
for j,c in ipairs(data.castle.locs) do
c_index = c[1] + c[2]*1000
local c_index = c[1] + c[2]*1000
total_village_distance[c_index] = 0
for i,v in ipairs(villages) do
total_village_distance[c_index] = total_village_distance[c_index] + M.distance_between(c[1], c[2], v[1], v[2])
Expand Down Expand Up @@ -1036,7 +1035,7 @@ return {
return hex, target
end

function get_test_units()
function recruit_lib.get_test_units()
local test_units, num_recruits = {}, 0
local movetypes = {}
for x,id in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
Expand Down
8 changes: 4 additions & 4 deletions data/ai/micro_ais/cas/ca_fast_combat_leader.lua
Expand Up @@ -14,9 +14,9 @@ function ca_fast_combat_leader:evaluation(cfg, data)
-- that the (more expensive) calculations for keeping the leader safe only
-- get done once, when all other Fast MAI CAs are entirely done.

leader_weight = (cfg and cfg.leader_weight) or 2
leader_attack_max_units = (cfg and cfg.leader_attack_max_units) or 3
leader_additional_threat = (cfg and cfg.leader_additional_threat) or 1
local leader_weight = (cfg and cfg.leader_weight) or 2
local leader_attack_max_units = (cfg and cfg.leader_attack_max_units) or 3
local leader_additional_threat = (cfg and cfg.leader_additional_threat) or 1

move_cache = { turn = wesnoth.current.turn }
gamedata = FAU.gamedata_setup()
Expand Down Expand Up @@ -84,7 +84,7 @@ function ca_fast_combat_leader:evaluation(cfg, data)
for _,enemy in ipairs(enemies) do
-- Only need to consider enemies that are close enough
if (wesnoth.map.distance_between(leader.x, leader.y, enemy.x, enemy.y) <= (enemy.max_moves + leader.max_moves + 1)) then
enemy_power = enemy.hitpoints
local enemy_power = enemy.hitpoints

local old_moves = enemy.moves
enemy.moves = enemy.max_moves
Expand Down
4 changes: 2 additions & 2 deletions data/ai/micro_ais/cas/ca_hunter.lua
Expand Up @@ -64,7 +64,7 @@ function ca_hunter:execution(cfg)
local rand = math.random(10)
if (not hunter_vars.goal_x) or (rand == 1) then
-- 'locs' includes border hexes, but that does not matter here
locs = AH.get_passable_locations((wml.get_child(cfg, "filter_location") or {}), hunter)
local locs = AH.get_passable_locations((wml.get_child(cfg, "filter_location") or {}), hunter)
local rand = math.random(#locs)

hunter_vars.goal_x, hunter_vars.goal_y = locs[rand][1], locs[rand][2]
Expand Down Expand Up @@ -130,7 +130,7 @@ function ca_hunter:execution(cfg)
-- If we got here, this means the hunter is either returning, or resting
if (hunter_vars.hunting_status == 'returning') then
local home_loc = AH.get_named_loc_xy('home', cfg)
goto_x, goto_y = wesnoth.find_vacant_tile(home_loc[1], home_loc[2], hunter)
local goto_x, goto_y = wesnoth.find_vacant_tile(home_loc[1], home_loc[2], hunter)

local next_hop = AH.next_hop(hunter, goto_x, goto_y)
if next_hop then
Expand Down
2 changes: 1 addition & 1 deletion data/ai/micro_ais/cas/ca_recruit_random.lua
Expand Up @@ -56,7 +56,7 @@ function ca_recruit_random:evaluation(cfg)

-- Go through all the types listed in [probability] tags (which can be comma-separated lists)
for prob in wml.child_range(cfg, "probability") do
types = AH.split(prob.type, ",")
local types = AH.split(prob.type, ",")
for _,typ in ipairs(types) do -- 'type' is a reserved keyword in Lua
-- If this type is in the recruit list, add it
for _,recruit in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
Expand Down
2 changes: 1 addition & 1 deletion data/ai/micro_ais/cas/ca_wolves_move.lua
Expand Up @@ -90,7 +90,7 @@ function ca_wolves_move:execution(cfg)
end

for i = 2,#wolves do
move = AH.find_best_move(wolves[i], function(x,y)
local move = AH.find_best_move(wolves[i], function(x,y)
local rating = 0

-- We ideally want wolves to be 2-3 hexes from each other
Expand Down
2 changes: 1 addition & 1 deletion data/ai/micro_ais/cas/ca_wolves_multipacks_functions.lua
Expand Up @@ -78,7 +78,7 @@ function wolves_multipacks_functions.assign_packs(cfg)
-- At the beginning of the scenario, this means all wolves
while (#nopack_wolves > 0) do
-- Find the first available pack number
new_pack_number = 1
local new_pack_number = 1
while packs[new_pack_number] do new_pack_number = new_pack_number + 1 end

-- If there are <=pack_size wolves left, that's the pack
Expand Down
8 changes: 4 additions & 4 deletions data/campaigns/Legend_of_Wesmere/lua/wml_tags.lua
Expand Up @@ -58,9 +58,9 @@ end

function wesnoth.wml_actions.unstore_left_behind_units(cfg)
if wml.variables["l3_store_kalenz"] ~= nil then
l3_store_kalenz = wml.array_variables["l3_store_kalenz"]
local l3_store_kalenz = wml.array_variables["l3_store_kalenz"]
for i,_ in ipairs(l3_store_kalenz) do
var_name = "l3_store_kalenz[" .. tostring(i-1) .. "]"
local var_name = "l3_store_kalenz[" .. tostring(i-1) .. "]"
wml_actions.unstore_unit {
variable = var_name,
x = "recall",
Expand All @@ -70,9 +70,9 @@ function wesnoth.wml_actions.unstore_left_behind_units(cfg)
wml.variables["l3_store_kalenz"] = nil
end
if wml.variables["l3_store_landar"] ~= nil then
l3_store_landar = wml.array_variables["l3_store_landar"]
local l3_store_landar = wml.array_variables["l3_store_landar"]
for i,_ in ipairs(l3_store_landar) do
var_name = "l3_store_landar[" .. tostring(i-1) .. "]"
local var_name = "l3_store_landar[" .. tostring(i-1) .. "]"
wml_actions.unstore_unit {
variable = var_name,
x = "recall",
Expand Down
2 changes: 1 addition & 1 deletion data/campaigns/World_Conquest/lua/campaign/enemy.lua
Expand Up @@ -6,7 +6,7 @@ local enemy = {}
local function get_advanced_units(level, list, res)
res = res or {}
-- guards against units that can advance in circles or to themselves
res_set = {}
local res_set = {}
local add_units = function(units)
for unused, typename in ipairs(units) do
local unittype = wesnoth.unit_types[typename]
Expand Down

0 comments on commit 6e0d836

Please sign in to comment.