Embark allows land units to embark for sea travel. Position a land unit next to an Ocean or Deep Ocean tile, disband the unit, and a temporary boat will be created with a new land unit in the boat (the replacement of the disbanded unit.) After the replacement unit leaves the boat, the empty boat will be disbanded at the beginning of the next turn. The boat is an unhomed unit, and the replacement Horseman keeps the same homecity as the original. Veteran status and current hit points of the original Horseman are lost since Freeciv 2.6.4 Lua has no way of determining those values from the original unit. Movement points are deliberately reduced to zero so that the "Embark" action uses one turn without further movement being possible in the same turn.
Code: Select all
--##############################################################################
function Lua_EmbarkBoatsCleanup(turn, year)
if ( Embark == nil ) then Embark=true end
-- If this routine is disabled, just return without doing anything else
if not ( Embark ) then return end
if ( debugLuaScripts ) then log.error("%s","EmbarkBoatsCleanup BEGIN") end
-- Declare local variables
local i, owner, killBoat
-- Declare global vars if needed
if ( _G.EmbarkBoats == nil ) then _G.EmbarkBoats={} end
-- If Embark boat is empty, destroy it
for i=1,#_G.EmbarkBoats,1 do
if ( _G.EmbarkBoats[i] ~= nil ) then
owner=(_G.EmbarkBoats[i]).owner
killBoat=true
for cargo in (_G.EmbarkBoats[i]):cargo_iterate() do
-- If there are units in the boat, don't kill the boat
killBoat=false
end
if ( killBoat == true) then
-- Killing the unit will trigger unit_lost ?
edit.unit_kill(_G.EmbarkBoats[i],"disbanded",owner)
_G.EmbarkBoats[i]=nil
end
end
end
if ( debugLuaScripts ) then log.error("%s","EmbarkBoatsCleanup END") end
end
signal.connect("turn_started", "Lua_EmbarkBoatsCleanup")
--##############################################################################
function Lua_Embark(unit, player, reason)
-- Flaky behavior in Freeciv 2.6.4, the disbanded unit is sometimes left viisble on the map, and in the city units list, but not addressable
-- That persists across turns, and it is even possible for the unit to disappear after fog-of-war, but still be visible in city unit list
-- switch to Editing mode > Global Observer, and then back to your tribe and -poof- the disbanded unit is gone completely
-- If needed global vars are not set, set them, part 1 of 2
if ( Embark == nil ) then Embark=true end
if ( debugLuaScripts == nil ) then debugLuaScripts=false end
-- If this routine is disabled, just return without doing anything else
if not ( Embark ) then return end
if ( debugLuaScripts ) then log.error("%s","Embark BEGIN") end
-- This prevents processing of disbanded/killed temp unit from ExtendVision
if ( extendVisionInProgress ) then return end
-- If needed global vars aren't set, set them
if ( topology == nil ) or ( _G.wrapX == nil ) or ( _G.wrapY == nil )
or ( _G.xSize == nil ) or ( _G.ySize == nil ) or ( _G.topo == nil ) then
topology=(server.setting.get("topology"))
_G.xSize=tonumber(server.setting.get("xsize"))
_G.ySize=tonumber(server.setting.get("ysize"))
_G.topo="classic"
_G.wrapX=false
_G.wrapY=false
topoFields={}
-- Split topology field (from scenario settings) to a table
count=1
for field in string.gmatch(topology, "[^|]+") do
topoFields[count]=field
count=(count+1)
end
-- Evaluate topology settings
if ( #topoFields > 0 ) then
for i=1,#topoFields,1 do
if ( topoFields[i] == "WRAPX" ) then _G.wrapX=true
elseif ( topoFields[i] == "WRAPY" ) then _G.wrapY=true
elseif ( topoFields[i] == "ISO" ) then _G.topo="ISO"
elseif ( topoFields[i] == "HEX" ) then _G.topo="HEX" end
end
end
end
-- Declare global function
function _G.is_XY_map_location_valid(x,y)
if ( _G.wrapX and _G.wrapY )
or ( _G.wrapX and ( y >= 0 ) and ( y < _G.ySize ) )
or ( _G.wrapY and ( x >= 0 ) and ( x < _G.xSize ) )
or ( y >= 0 and y < _G.ySize and x >= 0 and x < _G.xSize ) then
return true
else
return false
end
end
-- To Embark, the unit must be disbanded
if not ( reason == "disbanded" ) then
if ( debugLuaScripts ) then log.error("%s","Embark: not a disbanded unit") end
return
end
-- Declare local variables
local tile, x, y, i, h, v, homecity, unitVet, unitMovesLeft, unitHPLeft, unitType, randomNum, embarkTile, checkTile
-- Gather info about the original unit being disbanded
tile=(unit).tile
x=(tile).x
y=(tile).y
homecity=(unit).homecity
unitType=(unit).utype
-- Declare global vars if needed
if ( _G.EmbarkBoats == nil ) then _G.EmbarkBoats={} end
-- Unit must NOT be in a city, or on water or "Inaccessible" tiles
if ( tile.terrain.id == find.terrain("Lake").id )
or ( tile.terrain.id == find.terrain("Ocean").id )
or ( tile.terrain.id == find.terrain("Deep Ocean").id )
or ( tile.terrain.id == find.terrain("Inaccessible").id )
or ( (tile):city() ) then
return
end
-- Check 1st ring of tiles around unit for adjacent water tile, get tile ID
h={-1,-1,-1, 0, 0, 1, 1, 1}
v={-1, 0, 1,-1, 1,-1, 0, 1}
for i=1,#h,1 do
if _G.is_XY_map_location_valid( (h[i]+x),(v[i]+y) ) then
checkTile=find.tile((h[i]+x),(v[i]+y))
if ( checkTile.terrain.id == find.terrain("Ocean").id )
or ( checkTile.terrain.id == find.terrain("Deep Ocean").id )
and ( checkTile:num_untis() == 0 ) then
embarkTile=checkTile
goto continue
end
end
end
-- ToDo: check 2nd ring of tiles if no embarkTile was found in 1st ring?
::continue::
-- if a valid embarkTile was found, then create the boat on that tile
transportUnitType=find.unit_type("Trireme")
unitVet=0
unitMovesLeft=0
unitHPLeft=-1
homecity=nil
edit.create_unit_full(player, embarkTile, transportUnitType, unitVet, homecity, unitMovesLeft, unitHPLeft, nil)
-- Get the new transport unit's id and record in global array
if ( (embarkTile):num_units() == 1 ) then
for tileUnit in ( (embarkTile):units_iterate() ) do
if ( (tileUnit).homecity == 0 ) then embarkBoatID=tileUnit end
end
end
_G.EmbarkBoats[#_G.EmbarkBoats+1]=(embarkBoatID)
-- Finally, create the replacement for the disbanded unit
-- Replacement unit is created -in- the transport unit, and presumably -on- the same tile as the transport unit
homecity=(unit):get_homecity()
edit.create_unit_full(player, embarkTile, unitType, unitVet, homecity, unitMovesLeft, unitHPLeft, embarkBoatID)
-- Uncomment the next line (remove the two hyphens) to receive a messgae list entry every time a unit Embarks
--notify.event_msg(player,tile,0,"\tEmbark: A unit has embarked on a sea voyage." )
if ( debugLuaScripts ) then log.error("%s","Embark END") end
end
signal.connect("unit_lost", "Lua_Embark")
^ Horseman next to Ocean tile is ready to Embark
^ Horseman next to an Ocean tile is disbanded, and replaced by a Horseman in a boat.
^ Horseman exits the boat which will then be disbanded at the start of the next turn.
^ Boat has been disbanded now that the Horseman is again on land.
I haven't yet added this into the FairTEST scenario file with all the other Lua scripts, and it is likely to interact poorly with the Military-to-Work Program Lua script since both are triggered by disbanding units.