SotBE S6: move unloading code into the AI

This is now possible with the new ai.synced_command Lua AI command and
means that the code does not have to be split between Lua and WML any
more.
This commit is contained in:
mattsc 2013-12-04 07:00:10 -08:00
parent 4aef27a1dd
commit 3cce3ae093
3 changed files with 27 additions and 140 deletions

View file

@ -8,12 +8,10 @@ local ca_transport = {}
-- close hex with the most unoccupied adjacent non-water hexes and move there
-- 2. If landing site is out of reach, move toward destination while
-- staying in deep water surrounded by deep water only
-- Also unload units onto best hexes adjacent to landing site
function ca_transport:evaluation(ai)
local units = wesnoth.get_units {
side = wesnoth.current.side,
formula = '$this_unit.moves > 0',
}
local units = wesnoth.get_units { side = wesnoth.current.side, formula = '$this_unit.moves > 0' }
for i,u in ipairs(units) do
local vars = H.get_child(u.__cfg, "variables")
@ -71,7 +69,7 @@ function ca_transport:execution(ai)
-- Main rating is number of unoccupied land hexes and
-- water hexes next to land hexes
-- But shouldn't be too far away (arb. set to 5 hexes here)
-- This is mostly to avoid it being across the bay in S6
-- This is mostly to avoid it being across the bay in SotBE S6
local adj_tiles = {}
if (rating >= -0.05) then
for x,y in H.adjacent_tiles(r[1], r[2]) do
@ -79,9 +77,7 @@ function ca_transport:execution(ai)
if wesnoth.match_location(x, y, { terrain = "!, W*" }) then
rating = rating + 1
table.insert(adj_tiles, { x, y, 1. } )
end
if wesnoth.match_location(x, y,
elseif wesnoth.match_location(x, y,
{
terrain = "W*",
{ "filter_adjacent_location", { terrain = "!, W*" } }
@ -90,6 +86,8 @@ function ca_transport:execution(ai)
then
rating = rating + 0.1
table.insert(adj_tiles, { x, y, 0.1 } )
else
table.insert(adj_tiles, { xa, ya, 0.0 } )
end
end
end
@ -107,22 +105,24 @@ function ca_transport:execution(ai)
end
if (max_rating > -9e99) then
-- Also find the best unloading hexes
-- TODO: this is currently not used as the AI functionality to make
-- it replay-safe does not exist; to be added later
--table.sort(best_adj_tiles, function(a, b) return a[3] > b[3] end)
--for i,tile in ipairs(best_adj_tiles) do
-- best_unit.variables['hex' .. i .. '_x'] = tile[1]
-- best_unit.variables['hex' .. i .. '_y'] = tile[2]
--end
-- For remaining hexes, simply use the center hex and let the engine decide itself
-- This also provides a safeguard against too many hexes being occupied
--for i = #best_adj_tiles + 1, 6 do
-- best_unit.variables['hex' .. i .. '_x'] = best_hex[1]
-- best_unit.variables['hex' .. i .. '_y'] = best_hex[2]
--end
ai.move_full(best_unit, best_hex[1], best_hex[2])
-- Also unload units
table.sort(best_adj_tiles, function(a, b) return a[3] > b[3] end)
for i = 1, math.min(#best_adj_tiles, 3) do
local command = "local H = wesnoth.require 'lua/helper.lua' "
.. "wesnoth.put_unit(".. best_adj_tiles[i][1] .. "," .. best_adj_tiles[i][2]
.. ", { side = " .. wesnoth.current.side
.. ", type = H.rand('Fencer,Swordsman,Mage,Cavalryman,Javelineer,Bowman,Pikeman,Bowman,Fencer')"
.. ", moves = 2 }) "
.. "local unit = wesnoth.get_unit(x1, y1) "
.. "unit.variables.landed = 'yes' "
.. "unit.variables.destination_x = 1 "
.. "unit.variables.destination_y = 30"
ai.synced_command(command, best_unit.x, best_unit.y)
end
return
end

View file

@ -1,53 +0,0 @@
local H = wesnoth.require "lua/helper.lua"
local LS = wesnoth.require "lua/location_set.lua"
local unload = {}
-- Unload units from transports preferentially onto land tiles. Second priority are
-- water hexes next to land tiles. Units are unloaded with 2 MP.
-- Unload location is around the hex given by WML variables x1, y1
-- Parameters:
-- side: the side of the unloaded units
-- unit_types: array of unit types. Units are created in the order in which types
-- are listed in this table
function unload:unload(side, unit_types)
-- Do not unload units onto hexes occupied by units of any side
local units = wesnoth.get_units {}
local unit_map = LS.create()
for i,u in ipairs(units) do unit_map:insert(u.x, u.y) end
local x1, y1 = wesnoth.get_variable('x1'), wesnoth.get_variable('y1')
local adj_tiles = {}
for xa,ya in H.adjacent_tiles(x1, y1) do
if (not unit_map:get(xa, ya)) then
if wesnoth.match_location(xa, ya, { terrain = "!, W*" }) then
table.insert(adj_tiles, { xa, ya, 1. } )
elseif wesnoth.match_location(xa, ya,
{
terrain = "W*",
{ "filter_adjacent_location", { terrain = "!, W*" } }
}
)
then
table.insert(adj_tiles, { xa, ya, 0.1 } )
else
table.insert(adj_tiles, { xa, ya, 0.0 } )
end
end
end
table.sort(adj_tiles, function(a, b) return a[3] > b[3] end)
for i,utype in ipairs(unit_types) do
if adj_tiles[i] then
wesnoth.put_unit(adj_tiles[i][1], adj_tiles[i][2], { side = side, type = utype, moves = 2 })
else -- just in case there are more units to create than available adjacent tiles
local xv, yv = wesnoth.find_vacant_tile(x1, y1)
wesnoth.put_unit(xv, yv, { side = side, type = utype })
end
end
end
return unload

View file

@ -324,77 +324,17 @@
[event]
name=moveto
first_time_only=no
[filter]
type=Transport Galleon
[filter_location]
terrain=Ww
[filter_adjacent_location]
terrain="!, W*"
[/filter_adjacent_location]
[/filter_location]
side=3
[not]
[filter_wml]
[variables]
landed=yes
[/variables]
[/filter_wml]
type=Transport Galleon
[/not]
[/filter]
[modify_unit]
[filter]
id=$unit.id
[/filter]
[variables]
landed=yes
destination_x=1
destination_y=30
[/variables]
[/modify_unit]
{RANDOM 0..2}
[switch]
variable=random
[case]
value=0
[lua]
code=<< wesnoth.require("campaigns/Son_Of_The_Black_Eye/ai/unload.lua"):unload(3, { 'Fencer', 'Swordsman', 'Mage' }) >>
[/lua]
[/case]
[case]
value=1
[lua]
code=<< wesnoth.require("campaigns/Son_Of_The_Black_Eye/ai/unload.lua"):unload(3, { 'Cavalryman', 'Javelineer', 'Bowman' }) >>
[/lua]
[/case]
[case]
value=2
[lua]
code=<< wesnoth.require("campaigns/Son_Of_The_Black_Eye/ai/unload.lua"):unload(3, { 'Pikeman', 'Bowman', 'Fencer' }) >>
[/lua]
[/case]
[/switch]
{CLEAR_VARIABLE random}
[message]
side=3
[filter_adjacent]
x,y=$x1,$y1
[/filter_adjacent]
message= _ "Pillage! Lets plunder these orcs!"
x,y=$x1,$y1
message= _ "Lets get those orcs!"
[/message]
[/event]