-- UNIT TRANSPORTER
-- [[ By Sorfox]]
state.loadedTrucks = {} -- we have a nested table that holds following data: loadedTrucks[truck_ID] = {loadedUnit_ID1, loadedUnit_ID2, ...}
activeTruck = nil -- a global variable is defined
function firstTimeFakeLoadingOnTruck()
print("Within the function: firstTimeFakeLoadingOnTruck.")
local activeUnit = activeTruck -- update the local variable (ID of the truck) with the data of the gloal variable, which was "filled" in the triggering functions (below) and which reference this function
local unitsOnTruck = state.loadedTrucks[activeUnit.id] -- initialize local variable 'unitsOnTruck' [always first action in order to be able to use it] and connect it with exactly this truck; KEY for the state.table = activeUnit/currentUnit.id
if unitsOnTruck == nil then
print("This truck (ID: " .. activeUnit.id .. ") has never been loaded before, so we do it by means of Lua artificially.")
unitsOnTruck = {[1] = "firstUnitFakeLoading", [2] = "secondUnitFakeLoading"}
state.loadedTrucks[activeUnit.id] = unitsOnTruck
print("Case ZERO - state.table successfully updated!") -- just for checking if formula worked
end
end -- 'end' of function firstTimeFakeLoadingOnTruck()
-----------------------------------------------------------------------------------------------------------------------
function loadUnitsOnTruck()
print("Within the function: loadUnitsOnTruck.")
local unitTypeAllowedToBeLoaded = civ.getUnitType(21) -- defines which unit(s) can be loaded on the truck -> modifiable (!) -> references the position of '@UNITS' in 'rules.txt' file
local supplyTruckType1 = civ.getUnitType(26) -- defines which unit(s) count as 'truck' (= land transporter / carrying vehicle) -> modifiable (!) -> references the position of '@UNITS' in 'rules.txt' file
local supplyTruckType2 = civ.getUnitType(118)
local transportVehicleType = {}
transportVehicleType[21]=true
transportVehicleType[118]=true
local cargoUnitType = {}
cargoUnitType[21]=true
cargoUnitType[27]=true
cargoUnitType[37]=true
cargoUnitType[24]=true
local successfullFakeLoading = 0 -- helper local variable (0 = false / 1 = true)
local activeUnit = civ.getActiveUnit()
local activeTile = nil
if activeUnit then -- check that there is an active unit
activeTile = civ.getActiveUnit().location -- gets the active unit and selects the tile
else -- if there is no active unit, then
print("No active unit.") -- 1) show this info in the console
return -- 2) and end the function, since there is no point in doing any further calculation
end
if not(cargoUnitType[activeUnit.type.id]) then -- if there is no unitTypeAllowedToBeLoaded /cagoUnitType on the tile then there is no point to continue the code -> Therefore: return
print("Active unit is NOT a unitTypeAllowedToBeLoaded.")
return
end
print("Active unit is a unitTypeAllowedToBeLoaded.") -- if this line is reached (not broken up before) there must be an active unit which is a unitTypeAllowedToBeLoaded
for currentUnit in activeTile.units do -- do a 'for loop' over every unit on the active tile, where (we already know) units of unitTypes allowed to be loaded exist
--if currentUnit.type == supplyTruckType then
if (currentUnit.type == supplyTruckType1 or currentUnit.type == supplyTruckType2) then
print("loadFunction - checking the truck ID " .. currentUnit.id) -- if this line is reached (not broken up before) there must be an active unit equal to supplyTruckType
local unitsOnTruck = state.loadedTrucks[currentUnit.id] -- "fill" the local variable 'unitsOnTruck' with data about the loaded units (IDs) on exactly this truck; KEY for the state.table = currentUnit.id
activeTruck = currentUnit -- update the global variable, i.e. ID of the truck used right at this moment; since this funtion - in one case - jump to the funtion 'firstTimeFakeLoadingOnTruck()', where the ID is needed
if unitsOnTruck == nil then -- if this line is reached (not broken up before) there must be an active unit equal to supplyTruckType (=2nd condition) BUT it still can be a "virgin" truck, which will always result in code errors
print("unitsOnTruck == nil | This truck (ID: " .. currentUnit.id .. ") has never been loaded before, so we do it by means of Lua artificially.")
firstTimeFakeLoadingOnTruck() -- jump to and then execute this function
successfullFakeLoading = 1 -- toggle local variable "on" = proof that each place of the truck is at least "fake loaded", since the line before 'function firstTimeFakeLoadingOnTruck()' did run
end
if unitsOnTruck ~= nil or successfullFakeLoading == 1 then -- only now we can introduce the variables ('firstUnit'+'secondUnit') in the code, earlier there would be an error "attempt to index a nil value (global 'unitsOnTruck')" -> covered by 'firstTimeFakeLoadingOnTruck()'
unitsOnTruck = state.loadedTrucks[currentUnit.id]
activeTruck = nil -- delete content of the global variable
local firstUnit = unitsOnTruck[1] -- data of the first unit will be stored by means of their ID -> 'local' = initialize the variable within this function
local secondUnit = unitsOnTruck[2]
if firstUnit == nil or firstUnit == "firstUnitFakeLoading" then -- if there is NO first - or only a "firstUnitFakeLoading" (which is also NO) - unit on the truck => LOAD IT!
civ.ui.text("Loading first unit on the truck.")
unitsOnTruck = {[1] = activeUnit.id, [2] = secondUnit} -- 1st step of "table magic": update the locale variable 'unitsOnTruck' with the newest info about the activeUnit.id, which is now loaded in the table
civ.teleportUnit(activeUnit, civ.getTile(2, 184, 2)) -- code to teleport the currently loaded unit to a certain square on night map
activeUnit.order = 3 -- after teleportation to 2. map -> unit is set to 'sleep'
state.loadedTrucks[currentUnit.id] = unitsOnTruck -- 2nd step of "table magic": update the state.table with the newest info -> which was stored in the locale variable table 'unitsOnTruck' - done during the 1st step
currentUnit:activate() -- activates the truck, after loading the 1st unit, clearing its orders, and, if it has a human owner and movement points left, selects it on the map
break
elseif secondUnit == nil or secondUnit == "secondUnitFakeLoading" then -- checking if there is still space on the selected truck (secondUnit == nil, or "secondUnitFakeLoading"), if yes => LOAD IT!
civ.ui.text("Loading second unit on the truck.")
unitsOnTruck = {[1] = firstUnit, [2] = activeUnit.id} -- same procedure + code as with firstUnit, but of course here the 2nd unit must be stored in the table differently => [2] = activeUnit.id
civ.teleportUnit(activeUnit, civ.getTile(2, 184, 2))
activeUnit.order = 3
state.loadedTrucks[currentUnit.id] = unitsOnTruck
currentUnit:activate() -- activates the truck, after loading the 2nd unit, clearing its orders, and, if it has a human owner and movement points left, selects it on the map
break
elseif (firstUnit ~= nil and firstUnit ~= "firstUnitFakeLoading") and (secondUnit ~= nil and secondUnit ~= "secondUnitFakeLoading") then
civ.ui.text("The truck is full, due to the fact that it is only possible to load two units on it.")
end
end
end
end
end -- 'end' of function loadUnitsOnTruck()
-----------------------------------------------------------------------------------------------------------------------
function unloadUnitsOffTruck()
print("Within the function: unloadUnitsOffTruck.")
local supplyTruckType1 = civ.getUnitType(26)
local supplyTruckType2 = civ.getUnitType(118)
local successfullFakeLoading = 0
local activeUnit = civ.getActiveUnit()
local activeTile = nil
if activeUnit then -- check that there is an active unit
activeTile = civ.getActiveUnit().location -- gets the acive unit and selects the tile
else -- if there is no active unit, then
print("No active unit.") -- 1) show this info in the console
return -- 2) and end the function, since there is no point in doing any further calculation
end
if (activeUnit.type ~= supplyTruckType1 and activeUnit.type ~= supplyTruckType2) then -- if there is no truck on the tile then there is no point to continue the code -> Therefore: return
print("Active unit is NOT the supplyTruckType.")
return
else
print("UN-loadFunction - checking the truck ID " .. activeUnit.id) -- if this line is reached (not broken up before) there must be an active unit equal to supplyTruckType
local unitsOnTruck = state.loadedTrucks[activeUnit.id] -- "fill" the local variable 'unitsOnTruck' with data about the loaded units (IDs) on exactly this truck; KEY for the state.table = currentUnit.id
activeTruck = activeUnit -- update the global variable, i.e. ID of the truck used right at this moment; since this funtion - in one case - jump to the funtion 'firstTimeFakeLoadingOnTruck()', where the ID is needed
if unitsOnTruck == nil then -- if this line is reached (not broken up before) there must be an active unit equal to supplyTruckType (=2nd condition) BUT it still can be a "virgin" truck, which will always result in code errors
print("unitsOnTruck == nil | This truck (ID: " .. activeUnit.id .. ") has never been loaded before, so we do it by means of Lua artificially.")
firstTimeFakeLoadingOnTruck() -- from that code line on -> each place of the truck is at least "fake loaded"
successfullFakeLoading = 1
end
if unitsOnTruck ~= nil or successfullFakeLoading == 1 then -- only now we can introduce the variables ('firstUnit'+'secondUnit') in the code, earlier there would be an error "attempt to index a nil value (global 'unitsOnTruck')" -> covered by 'firstTimeFakeLoadingOnTruck()'
unitsOnTruck = state.loadedTrucks[activeUnit.id]
activeTruck = nil -- delete content of the global variable
local firstUnit = unitsOnTruck[1] -- data of the first unit will be stored by means of their ID -> 'local' = initialize the variable within this function
local secondUnit = unitsOnTruck[2]
if (firstUnit == nil or firstUnit == "firstUnitFakeLoading") and (secondUnit == nil or secondUnit == "secondUnitFakeLoading") then -- Case ONE: the respective truck is empty
civ.ui.text("There are NO units to unload from this (ID: " .. activeUnit.id .. ") empty truck.")
return
elseif firstUnit ~= nil and firstUnit ~= "firstUnitFakeLoading" then
local firstUnitComplete = civ.getUnit(firstUnit)
civ.teleportUnit(firstUnitComplete, activeTile) -- code to teleport the currently loaded unit to exactly the same tile as where the truck stands (first map)
firstUnitComplete:activate() -- activates the unloaded unit, clearing its orders, and, if it has a human owner and movement points left, selects it on the map
unitsOnTruck[1] = "firstUnitFakeLoading" -- removes the value (ID of the firstUnit) from the table; Be aware: We do the procedure NOT on variable 'firstUnit' since it's just used for easier reading the code - i.e. a representation of 'unitsOnTruck[1]' => the direct table entry, which we have to change here
state.loadedTrucks[activeUnit.id] = unitsOnTruck -- update the state.table
elseif secondUnit ~= nil and secondUnit ~= "secondUnitFakeLoading" then
local secondUnitComplete = civ.getUnit(secondUnit)
civ.teleportUnit(secondUnitComplete, activeTile) -- code to teleport the currently loaded unit to exactly the same tile as where the truck stands (first map)
secondUnitComplete:activate() -- activates the unloaded unit, clearing its orders, and, if it has a human owner and movement points left, selects it on the map
unitsOnTruck[2] = "secondUnitFakeLoading" -- removes the value (ID of the secondUnit) from the table; Be aware: We do the procedure NOT on variable 'secondUnit' since it's just used for easier reading the code - i.e. a representation of 'unitsOnTruck[2]' => the direct table entry, which we have to change here
state.loadedTrucks[activeUnit.id] = unitsOnTruck -- update the state.table
end
end
end
end -- 'end' of function unloadUnitsOffTruck()
-----------------------------------------------------------------------------------------------------------------------
function onActivateEveryUnit(activeUnit, source)
print("Within the function: onActivateEveryUnit.")
local supplyTruckType1 = civ.getUnitType(26)
local supplyTruckType2 = civ.getUnitType(118)
local successfullFakeLoading = 0
if (activeUnit.type ~= supplyTruckType1 and activeUnit.type ~= supplyTruckType2) then -- if the currently activeUnit is no truck then there is no point to continue the code -> Therefore:
print("Active unit is NOT the supplyTruckType.") -- 1) show this info in the console
return -- 2) and end the function
else
print("Active unit (ID: " .. activeUnit.id .. ") is supplyTruckType.") -- if this line is reached (not broken up before), the currently activeUnit must be a truck
local unitsOnTruck = state.loadedTrucks[activeUnit.id] -- "fill" the local variable 'unitsOnTruck' with data about the loaded units (IDs) on exactly this truck; KEY for the state.table = activeUnit/currentUnit.id
activeTruck = activeUnit -- update the global variable, i.e. ID of the truck used right at this moment; since this funtion - in one case - jump to the funtion 'firstTimeFakeLoadingOnTruck()', where the ID is needed
if unitsOnTruck == nil then -- if this line is reached (not broken up before) there must be an active unit equal to supplyTruckType (=2nd condition) BUT it still can be a "virgin" truck, which will always result in code errors
print("unitsOnTruck == nil | Therefore: Execute funtion: firstTimeFakeLoadingOnTruck.")
firstTimeFakeLoadingOnTruck() -- from that code line on -> each place of the truck is at least "fake loaded"
successfullFakeLoading = 1
end
if unitsOnTruck ~= nil or successfullFakeLoading == 1 then -- only now we can introduce the variables ('firstUnit'+'secondUnit') in the code, earlier there would be an error "attempt to index a nil value (global 'unitsOnTruck')" -> covered by 'firstTimeFakeLoadingOnTruck()'
unitsOnTruck = state.loadedTrucks[activeUnit.id]
activeTruck = nil -- delete content of the global variable
local firstUnit = unitsOnTruck[1] -- data of the first unit will be stored by means of their ID -> 'local' = initialize the variable within this function
local secondUnit = unitsOnTruck[2]
if (firstUnit == nil or firstUnit == "firstUnitFakeLoading") and (secondUnit == nil or secondUnit == "secondUnitFakeLoading") then -- Case ONE: the respective truck is empty
civ.ui.text("Empty truck (ID: " .. activeUnit.id .. ").")
return
elseif (firstUnit ~= nil and firstUnit ~= "firstUnitFakeLoading") and (secondUnit == nil or secondUnit == "secondUnitFakeLoading") then -- Case TWO: if there is ONLY the firstUnit on the truck
civ.ui.text("Currently only unit " .. firstUnit .. " is on the truck " .. activeUnit.id .. ".")
return
elseif (firstUnit == nil or firstUnit == "firstUnitFakeLoading") and (secondUnit ~= nil and secondUnit ~= "secondUnitFakeLoading") then -- Case THREE: if there is ONLY the secondUnit on the truck
civ.ui.text("Currently only unit " .. secondUnit .. " is on the truck " .. activeUnit.id .. ".")
return
elseif (firstUnit ~= nil and firstUnit ~= "firstUnitFakeLoading") and (secondUnit ~= nil and secondUnit ~= "secondUnitFakeLoading") then -- Case FOUR: truck is full / loaded with "real" units
civ.ui.text("Currently the units: " .. firstUnit .. ", " .. secondUnit .. " are on the truck " .. activeUnit.id .. ".")
end
end
end
end