|
|
| Line 1: |
Line 1: |
| == synced and unsynced lua == | | == synced and unsynced lua == |
| | | <br /> |
| When making a gadget you will sometimes want to combine synced and unsynced code.<br> | | <br /> |
| For example if you do some things with units, that will need to be synced code. <br> | | <center><b>Using globals</b></center> |
| The UnitDestroyed, UnitFinished etc. callins only exist in synced code.<br> | | <br /> |
| 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.<br>
| | When making a gadget you will sometimes want to combine synced and unsynced code.<br /> |
| | | For example if you do some things with units, that code will need to be synced. <br /> |
| Here is a choatic gadget that makes "miners" fill their "cargo bay" if they kill ressources.<br>
| | The UnitDestroyed, UnitFinished etc. callins can only be called in synced code. Using them inside unsynced code is not going to work.<br> |
| Notice the _G.miners = miners; it makes a copy (?) of the synced miners table acessable to the unsynced code.<br>
| | If you want to draw on the screen (for example to mark units) then the drawing will have to happen in unsynced code. |
| In the the unsynced code, the miners table can now be acessed with SYNCED.miners<br>
| | <br /> |
| _G is a table that can be read in both synced and unsynced.<br>
| | <br /> |
| GG (not used here) is a table that can be acessed by all (synced) gadgets<br>
| | The following example demonstrates how to change the value inside the synced block of code and read the value in the unsynced block of code: |
| | | <br /> |
| <pre>function gadget:GetInfo() | | <code> |
| 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 | | 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 number = 10 -- declaring variable 'number' |
| 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() | | function gadget:SomeSyncedCallin(...) |
| make_miner_table()
| | number=number+1 -- increment variable's value by one |
| _G.miners = miners;
| | _G.number=number -- save the new value into a global variable |
| end | | end |
|
| |
|
| function marker_on_unit (_uID, _text)
| | else |
| 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() | | function gadget:SomeUnsyncedCallin(...) |
| miners = {}
| | Spring.Echo(SYNCED.number) -- print the global variable's value on screen |
| local all_units = Spring.GetAllUnits ()
| | end |
| 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 | | end |
| | </code> |
| | <br /> |
| | <br /> |
| | <br /> |
| | <br /> |
|
| |
|
| function is_ressource_type (unitDefID)
| | <center><b>Using special functions</b></center> |
| if (unitDefID == nil) then return false end
| | <br /> |
| 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</pre><br>
| |
| The thread to this gadget: http://springrts.com/phpbb/viewtopic.php?f=23&t=24230
| |
| | |
| <br> | |
| Another way is to use SendToUnsynced<br> | | Another way is to use SendToUnsynced<br> |
| Here is an example by quantum:<br> | | Here is an example by quantum:<br> |
synced and unsynced lua
Using globals
When making a gadget you will sometimes want to combine synced and unsynced code.
For example if you do some things with units, that code will need to be synced.
The UnitDestroyed, UnitFinished etc. callins can only be called in synced code. Using them inside unsynced code is not going to work.
If you want to draw on the screen (for example to mark units) then the drawing will have to happen in unsynced code.
The following example demonstrates how to change the value inside the synced block of code and read the value in the unsynced block of code:
if (gadgetHandler:IsSyncedCode()) then
local number = 10 -- declaring variable 'number'
function gadget:SomeSyncedCallin(...)
number=number+1 -- increment variable's value by one
_G.number=number -- save the new value into a global variable
end
else
function gadget:SomeUnsyncedCallin(...)
Spring.Echo(SYNCED.number) -- print the global variable's value on screen
end
end
Using special functions
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")