Lua sync to unsync
synced and unsynced lua
When making a gadget you will sometimes want to combine synced and unsynced code.
For example if you do some things with units, that will need to be synced code.
The UnitDestroyed, UnitFinished etc. callins only exist in synced code.
But if you also want to draw on the screen (for example to mark units) then the drawing will have to happen in unsynced code.
Here is a choatic gadget that makes "miners" fill their "cargo bay" if they kill ressources.
Notice the _G.miners = miners; it makes a copy (?) of the synced miners table acessable to the unsynced code.
In the the unsynced code, the miners table can now be acessed with SYNCED.miners
_G is a table that can be read in both synced and unsynced.
GG (not used here) is a table that can be acessed by all (synced) gadgets
function gadget:GetInfo()
return {
name = "mining blabla2",
desc = "some broken stuff less broken",
author = "knorke",
date = "4 Okt 2010",
license = "rcdraco's draco license",
layer = 0,
enabled = true -- loaded by default
}
end
if (gadgetHandler:IsSyncedCode()) then
local miners = {} -- [unitID] alive: true oder false cargo: wieviel er trägt status: was er gerade macht: "loading" "unloading" "mining" "to_res" "to_hq"
local miner_name = "arm_flash";
local ressource_name = "arm_solar_collector"
function gadget:UnitFinished(unitID, unitDefID, teamID)
if (is_miner_type (unitDefID) == true) then add_miner (unitID) end
end
function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)
--remove destroyed miners:
if is_miner (unitID) then remove_miner (unitID) end
--wenn etwas geerntet wurde:
if (is_ressource_type (unitDefID)) then Spring.Echo ("ressource mined") end
if (is_miner(attackerID)) then Spring.Echo ("miner mined") end
if (is_ressource_type (unitDefID) and is_miner(attackerID)) then
miners[attackerID].cargo = miners[attackerID].cargo + 25
Spring.Echo ("finished mining! cargo:" .. miners[attackerID].cargo)
end
end
function gadget:GameFrame(frameNum)
_G.miners = miners;
end
function gadget:Initialize()
make_miner_table()
_G.miners = miners;
end
function marker_on_unit (_uID, _text)
if (markers == false) then return end
if (_uID == nil) then return end
if (_text == nil) then return end
local x,y,z=Spring.GetUnitPosition (_uID)
if (x == nil or y == nil or z == nil) then return end
Spring.MarkerAddPoint (x,y,z, _text .. "id:" .. _uID)
end
function make_miner_table()
miners = {}
local all_units = Spring.GetAllUnits ()
for i in pairs(all_units) do
local unitDefID = Spring.GetUnitDefID(all_units[i])
if (is_miner_type (unitDefID)==true) then
add_miner (all_units[i])
end
end
end
function is_miner_type (unitDefID)
if (unitDefID == nil) then return false end
local unitDef = UnitDefs[unitDefID]
if (unitDef == nil) then return false end
if (unitDef.name == miner_name) then return true end
return false
end
function is_ressource_type (unitDefID)
if (unitDefID == nil) then return false end
local unitDef = UnitDefs[unitDefID]
if (unitDef == nil) then return false end
if (unitDef.name == ressource_name) then return true end
return false
end
function is_miner (unitID)
if (miners [unitID] ~= nil) then return true else return false end
end
function add_miner (unitID)
miners [unitID] = {}
miners [unitID].alive = true
miners [unitID].cargo = 0
marker_on_unit (unitID, "added")
end
--------------------------------------------------------
--Border between SYNC and UNSYNC
--when i wear my frilly dress im a real touhou
end
if (not gadgetHandler:IsSyncedCode()) then
--------------------------------------------------------
--Length of table, for synced (using spairs)
function sxlen(tbl)
local qq = 0;
for v in spairs(tbl) do
qq = qq + 1;
end
return qq;
end
function gadget:DrawScreen()
gl.Color(0.5, 0.5, 0.5, 1)
local ty = 0
for i in spairs(SYNCED.miners) do
ty = ty + 1
gl.Text (ty .."| [" .. i .. "]".. "cargo:" .. SYNCED.miners[i].cargo, 100,300-ty*25 , 25, 'o')
end
gl.Text ("miners counted="..ty .. "#miners:" .. sxlen(SYNCED.miners), 100,300 , 25, 'o')
end
function gadget:DrawWorldPreUnit()
gl.LineWidth(5.0)
for i in spairs(SYNCED.miners) do
if (SYNCED.miners[i].alive == true and i ~= nil and SYNCED.miners[i] ~=nil) then
local x,y,z=Spring.GetUnitPosition (i)
if (x ~= nil and y ~= nil and z ~= nil) then
gl.Color(0, 1, 0, 1)
gl.DrawGroundCircle (x,y,z, 50, 4) --all miners marked with a diamond shape
--cargo status
gl.Color(1, 0, 0, 1)
gl.DrawGroundCircle (x+60,y,z, 90, 3)
gl.Color(1, 1, 0, 1)
gl.DrawGroundCircle (x+60,y,z, SYNCED.miners[i].cargo, 3) --growing triangle shows cargo status
end
end
end
end
end
The thread to this gadget: http://springrts.com/phpbb/viewtopic.php?f=23&t=24230
Another way is to use SendToUnsynced
Here is an example by quantum:
http://pastebin.com/hMHv3Lrf
[LCC]quantum[0K] every time there is a new target, i send "addTarget" and its number to unsynced
[LCC]quantum[0K] when a target is removed from the list, i send "removeTarget" and its number
[LCC]quantum[0K] this wierd stuff:
[LCC]quantum[0K] _G.laserEventArgs = eventArgs
[LCC]quantum[0K] SendToUnsynced("LaserEvent")
[LCC]quantum[0K] _G.laserEventArgs = nil
[LCC]quantum[0K] puts the eventArgs table somewhere were unsynced can find it
[LCC]quantum[0K] sends a signal to unsynced called "LaserEvent"
[LCC]quantum[0K] and removes the table
[LCC]quantum[0K] on the unsynced side, _G.laserEventArgs becomes SYNCED.laserEventArgs
[LCC]quantum[0K] this copies it to another table, ready for reuse: for k, v in spairs(SYNCED.laserEventArgs) do
[LCC]quantum[0K] eventArgs[k] = v
[LCC]quantum[0K] end
[LCC]quantum[0K] also, this: gadgetHandler:AddSyncAction("LaserEvent", HandleLaserEvent)
LCC]quantum[0K] means that i want the HandleLaserEvent function to be called every time i do SendToUnsynced("LaserEvent")