Quantcast
Channel: The Battle for Wesnoth Forums
Viewing all articles
Browse latest Browse all 1798

Lua Labs • Re: Another basic lua query: hopefully brief syntax check

$
0
0
Hi,
Found time to do a bit more on this recently and am making progress, albeit slooowly... :x

I'm not sure of some syntax and am just checking to see if I've got it right?

I'm stealing the "protective parents" ca logic from forest animals (ca_forest_animals_tusker_attack.lua).
Specifically it's this snippet I'm unsure of how to rewrite:

Code:

    -- The tusker moves as close to enemy as possible    -- Closeness to tusklets is secondary criterion    local adj_tusklets = wesnoth.units.find_on_map {        side = wesnoth.current.side,        type = cfg.tusklet_type,        { "filter_adjacent", { id = target.id } }    }
Instead of cfg.tusklet_type, the method used to identify the tusklet equivalent ("follower") in my version is a unit filter:

Code:

      [filter_follower]        type=Icemonax        [filter_wml]          [variables]            wmai=1          [/variables]        [/filter_wml]      [/filter_follower]
I also want to honour [avoid] whilst moving the protecting unit ("wanderer").

So I have this code for the protect action (it's not finished, I just want to minimise syntax errors here :) ).

Code:

-- ca_wanderers_protect.lualocal AH = wesnoth.require "ai/lua/ai_helper.lua"local M = wesnoth.maplocal function get_wanderers(cfg)  local wanderers = AH.get_units_with_moves { side = wesnoth.current.side, { "and", filter_wanderer } }  return wanderersend-- Returns enemies adjacent to follower units-- function ai_helper.get_attackable_enemies(filter, side, cfg)-- ****************************************************-- *** REFERENCED BY QUESTION 1 BELOW ***-- ****************************************************  local function get_adjacent_enemies(cfg)  local adjacent_enemies = AH.get_attackable_enemies( { "filter_adjacent", { side = wesnoth.current.side, { "and", filter_follower } } }      side = wesnoth.current.side      avoid_map = avoid_locs )  return adjacent_enemiesendlocal ca_wanderers_protect = {}-- Check whether there is an enemy next to a follower and attack it (if disable_protect=false)function ca_wanderers_protect:evaluation(cfg)  if cfg.disable_protectthen return 0 end  -- Protect followers disabled (not default)  if (not filter_wanderer)then return 0 end  -- No filter_wanderer tag  if (not filter_follower)then return 0 end  -- No filter_follower tag  if (not get_wanderers(cfg)[1])then return 0 end  -- No wanderers with moves, so nothing to move  if (not get_adjacent_enemies(cfg)[1])then return 0 end  -- No adjacent enemies  return cfg.ca_scoreendfunction ca_wanderers_protect:execution(cfg)  local wanderers = get_wanderers(cfg)  local adjacent_enemies = get_adjacent_enemies(cfg)  local avoid_locs = AH.get_avoid_map(ai, nil, true)  -- [avoid]ed locations, if any  -- Find the closest enemy to any wanderer  ---@type number, unit?,  unit?  local min_dist, attacker, target = math.huge, nil, nil  for _,wanderer in ipairs(wanderers) do    for _,enemy in ipairs(adjacent_enemies) do      local dist = M.distance_between(wanderer.x, wanderer.y, enemy.x, enemy.y)      if (dist < min_dist) then min_dist, attacker, target = dist, wanderer, enemy end    end  end-- ****************************************************-- *** REFERENCED BY QUESTION 2 BELOW ***-- ****************************************************  -- The wanderer moves as close to enemy as possible  -- Closeness to followers is secondary criterion  -- wesnoth.units.find_on_map(filter) → array of units  local adj_followers = wesnoth.units.find_on_map { side = wesnoth.current.side, { "and", filter_follower } { "and", "filter_adjacent", { id = target.id } } }  local best_hex = AH.find_best_move(attacker, function(x, y), { avoid_map = avoid_locs }  local rating = -M.distance_between(x, y, target.x, target.y)  for _,follower in ipairs(adj_followers) do    if (M.distance_between(x, y, follower.x, follower.y) == 1) then rating = rating + 0.1 end  end  return rating  end)  AH.robust_move_and_attack(ai, attacker, best_hex, target)endreturn ca_wanderers_protect

Questions:
  1. Follower filter is stored thus: local filter_follower = wml.get_child(cfg,"filter_follower")

    Code:

      local adjacent_enemies = AH.get_attackable_enemies( { "filter_adjacent", { side = wesnoth.current.side, { "and", filter_follower } } }      side = wesnoth.current.side      avoid_map = avoid_locs ) 
    I'd like this to honour [avoid] when moving attacking wanderers (more for consistency than anything else, if it's complicated I can omit it :) ).
    Is the best place to add that here (presumably removing some otherwise attackable enemies due to [avoid]) or process avoided locations later?

    Presently I specify side= so the function knows that avoid_map is indeed that and not a garbled side - is there a more elegant way to do this?

    Is enclosing parameters with "(...)" correct or should I use "{...}"?

    Finally: any other syntax errors?
  2. When using the existing logic I need to identify enemies adjacent to followers.
    Original reference code uses type = cfg.tusklet_type whereas I have filter_follower.

    Code:

      local adj_followers = wesnoth.units.find_on_map { side = wesnoth.current.side, { "and", filter_follower } { "and", "filter_adjacent", { id = target.id } } }  
    Can I simply append filter_adjacent and if so have I done it correctly?
    Alternatively, is there a better way given what I have to work with?
    E.g. maybe working with the enemy units adjacent to followers rather than vice-versa?

I've kept my questions to a minimun (I have loads more but those I'll work on) but these would be quick wins if anyone could point out the more glaring errors! :)

Thanks in advance for your time and trouble, much appreciated as always.

Cheers!
-- Spannerbag

Statistics: Posted by Spannerbag — Yesterday, 12:00 pm



Viewing all articles
Browse latest Browse all 1798

Trending Articles