Ok, now... it's time to create a Unit (the NewbieDevice) and place it in the gameworld! Hurrah!
This gives a value to NEWBIE_COMMAND, when activated.
Code: Select all
OurCmd = {}
for _, id in pairs(Cmds) do
OurCmd[id] = true
end
This is, so far as I can see, asking, "hey, what command is currently being issued?" This means, among other things, you could assign multiple commands to a single button- i.e., "Do A & B, if both share same numeric value from Table Cmds". Then you could have, for example, "combo attacks", with "powerup times", where some of it charges back up faster than others, or where you can only use "powerup level C", if A and B are already charged. I can see a lot of uses for that little section right there.
Code: Select all
NEWBIE_DEVICE_RANGE = 200
NEWBIE_DEVICE_RANGE_SQ = NEWBIE_DEVICE_RANGE * NEWBIE_DEVICE_RANGE
Here is, for about the only time in this whole script, what looks like some very ordinary variable assignments. I should probably ask... are these local? Or global? But, tbh, they're invoked in only one place, under very specific circumstances, so it's not a major worry.
Here, we're creating a Table, which we will assign variables to within the main body of the script. Basically, all I'm using it for is to halt the script, if invoked more than once.
Ok, so now we have a command assignment, LUA knows when this thing is being invoked, we've set up some basic commands and a table, for storing variables specific to the executing Unit. Time to actually do something.
Code: Select all
function CmdNewbieCommand(unitID, unitDefID, teamID, cmdID, params, options)
-- defines the Newbie Command, so that it doesn't try to check a nil value
if _NewbieCommandUsed[unitID] == nil then
_NewbieCommandUsed[unitID] = 0
end
-- if we've invoked the Newbie Command before, do nothing
if _NewbieCommandUsed[unitID] > 0 then
return true;
end
-- XXX need unsafe changes, we're doing something potentially nasty
AllowUnsafeChanges("USE AT YOUR OWN PERIL")
-- try to create in map
local z, facing
-- name, X, Y, Z, facing, team (optional) -> unitid
local newID = Spring.CreateUnit('NewbieDevice', params[1], params[2], z, facing)
-- This will create the Unit, and put it on the ground.
Spring.SetUnitPosition(newID, params[1], params[2], params[3])
-- start a cob script, which will animate our Unit "planting" the Newbie Device
Spring.CallCOBScript(unitID, "PlantNewbieDevice")
-- XXX unsafe changes not needed anymore
AllowUnsafeChanges("thanks")
-- We're informing LUA that this Unit has built a Newbie Device
_NewbieCommandUsed[unitID] = 1
return true
end
In the Function above, we're setting up the basics of creating the Unit. I have not figured out how to make sure that the Unit that's created is assigned to my Team yet, so for now, it's just being created, and I haven't even given it to Gaia.
Note that this just *tries* to create the Unit. It doesn't necessarily succeed, and it doesn't give the user any feedback.
Now, for some code to check whether our spawning Unit is in range, or has already fired:
Code: Select all
-- check range
-- if you want to disable a command, always check that here, merely removing
-- a button won't be sufficient
function AllowNewbieCommand(unitID, unitDefID, teamID, cmdID, params, options)
local x, z
x, _, z = Spring.GetUnitPosition(unitID)
local dx = params[1]-x
local dz = params[3]-z
if dx*dx + dz*dz > NEWBIE_DEVICE_RANGE_SQ then
-- XXX don't know if this echoes to all players
Spring.Echo("Not in range to plant Newbie Device, select somewhere closer")
return false
end
if _NewbieCommandUsed[unitID] = 1 then
Spring.Echo("Newbie Devices have been used up!")
return false
return true
end
This code basically provides the user with helpful feedback, instead of the dreaded, "WTF ARfGFH, IT BORKEN, IT SAY IT WURK". Give users feedback! They appreciate it, and it makes your game feel 100% more professional!
Now, if the Newbie Device was actually planted successfully... we want to change the command description, so users aren't confused:
Code: Select all
function UpdateNewbieCommandDescription(unitID, unitDefID, teamdID)
local cmds = Spring.GetUnitCmdDescs(unitID)
local i = 0
local thecmd
for k, cmd in ipairs(cmds) do
if cmd.id == Cmds.NEWBIE_COMMAND then
i = k
thecmd = cmd
break
end
end
if _NewbieCommandUsed[unitID] = 1 then
thecmd.name = string.format("Empty!")
else
thecmd.name = "Newbie Command!"
end
Spring.EditUnitCmdDesc(unitID, i, thecmd)
return 1
end
Which, when ya boil it down, says, "If Unit can perform NEWBIE_COMMAND, then change the Icon's text based on whether or not it ever executed successfully."
*************************************************************
*************************************************************
*************************************************************
That is, more or less, it. There are two major features missing from this code, besides whatever smallish bugs I find (or, ack, files that show up missing) and I would like some help with these, so that this sort of command, when it has a range, looks professional, and acts right:
1. I dunno how to assign the Newbie Device (in my case, a minefield I've developed) to my Team properly. Should be easy, I just don't know what to put there. In the Orbital Barrage script, the object spawned is assigned to Gaia... obviously, I don't want that to happen, in this case.
2. I need to draw a range square, since this uses a square range. I really don't have any idea how to do that yet. Any help would be appreciated, I know that's probably a lot harder, because it'd have to be contextual (i.e., "if user presses button, and _NewbieCommandUsed[unitID] = 0, show range square, until either the Unit command context changes (hard, I'm sure) or _NewbieCommandUsed[unitID] = 1, otherwise do nothing".
Feel more than free to find, and hopefully share, any other major screwups with me. Just be nice about it, I did a lot of typing here
Assume, for now, that this would go in main.lua- I know how includes work. The only thing that bugs me, frankly, is that the Orbital Barrage main.lua refers to "print_r.lua", but it's unclear where those Functions are being called within this example script.