Can I block units from being built?

Can I block units from being built?

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
SanadaUjiosan
Conflict Terra Developer
Posts: 907
Joined: 21 Jan 2010, 06:21

Can I block units from being built?

Post by SanadaUjiosan »

What I'm essentially wanting to do is mimic the Vulture and its Scarabs from Starcraft: have a unit able to build mines, but it can only build 4 mines and then that individual unit can't build anymore mines. If you want more mines, you have to get another one of the builder units.

Could I accomplish this just in the builder unit's script? Something like "if building the mine unit then x+1. when x = 4, block being able to build the mine" ? (I'm no good at psuedo code :-) )

Or would I have to write a whole gadget to do this? :x

Note I don't want the mine unit completely unbuildable after only 4 exist (like what unitRestricted does), I just want the builder unit to not be able to build anymore after it's reach its quota.

And lastly, anyone know if there is a gadget or script floating around out there that does this (or something like this) for me to look at for examples?
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Can I block units from being built?

Post by knorke »

gadget is better. Don't panic, the simplest solution is shorter than this thread.
Something like "if building the mine unit then x+1. when x = 4, block being able to build the mine" ?
yes.

if building :arrow:
AllowUnitCreation() --> "unitDefID, builderID, builderTeam, x, y, z"

the mine unit :arrow:
check unitDefID and builderID if it is a minelayer building a mine.

x+1 :arrow:
use a table (array thing) like minesPerUnit[unitID]
if (not minesPerUnit[unitID]) then minesPerUnit[unitID] = 0 end--start counting with 0 if its the first mine from this minelayer
minesPerUnit[unitID] = minesPerUnit[unitID]+1


when x = 4 :arrow:
if (minesPerUnit[unitID] == 4)

block being able to build the mine :arrow:
return false in AllowUnitCreation
if you are feeling fancy you can also disable the buildpic button and use AllowCommand() to block the command, but leave that for later.

Don't forget to clear the table entry when a minelayer dies.

This might give you ideas:
http://springrts.com/phpbb/viewtopic.php?f=23&t=25435
User avatar
SanadaUjiosan
Conflict Terra Developer
Posts: 907
Joined: 21 Jan 2010, 06:21

Re: Can I block units from being built?

Post by SanadaUjiosan »

So I've tried to piece together your examples Knorke (thank you btw, very nice way to lay it out) but I can't get it to work.
check unitDefID and builderID if it is a minelayer building a mine.
is where I run into trouble. I don't really know how to do it (from what I've gathered there are tons of ways to do this). I currently have a custom parameter in the minelayer as is_minelayer = true and the mine is_mine = true. This clearly didn't do the trick. I'd also be okay with just a simple config section in the gadget, such as local is_mine_layer = "blahblahunitdef". Whichever is easier, honestly

Here is what I have:

Code: Select all

function gadget:GetInfo()
  return {
    name      = "Mine Limiter",
    desc      = "Limits number of mines able to be built",
    author    = "Sanada",
    date      = "March 1 2012",
    license   = "Public Domain",
    layer     = 0,
    enabled   = true  --  loaded by default	
  }
end

if (gadgetHandler:IsSyncedCode()) then
--------Config--------
local max_mines = 4
----------------------


function gadget:AllowUnitCreation(unitDefID, builderID, builderTeam, x, y, z)
	if (is_mine(unitDefID) and is_minelayer(builderID)) then
		return minesPerUnit[unitID]
	end
	if (not minesPerUnit[unitID]) then
		minesPerUnit[unitID] = 0
		else
		minesPerUnit[unitID] = minesPerUnit[unitID]+1			
	end
	if (minesPerUnit[unitID] == max_mines) then
	return false
	end

end

end


if (not gadgetHandler:IsSyncedCode()) then

end
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Can I block units from being built?

Post by gajop »

Let me try to give you a hand, this is how I would do it.
You should probably move some code to UnitCreated, f.e

Code: Select all

function gadgetHandler:UnitCreated(unitID, unitDefID, teamID, builderID)
	if (not (is_mine(unitDefID) and is_minelayer(builderID))) then
		return
	end
	if (not minesPerUnit[builderID]) then
		minesPerUnit[builderID] = 1
	else
		minesPerUnit[builderID] = minesPerUnit[builderID]+1			
	end
end

function gadget:AllowUnitCreation(unitDefID, builderID, builderTeam, x, y, z)
	if (not (is_mine(unitDefID) and is_minelayer(builderID))) then
		return true
	end
        if (not minesPerUnit[builderID]) then
                return true
        end
	return (minesPerUnit[builderID] <= max_mines)
end
Last edited by gajop on 02 Mar 2012, 12:25, edited 1 time in total.
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Can I block units from being built?

Post by gajop »

PS: Oh ye, don't forget to clear the table when the builder dies, f.e

Code: Select all

function gadgetHandler:UnitDestroyed(unitID, unitDefID, teamID, attackerID, attackerDefID, attackerTeamID)
   if (is_minelayer(unitID)) then
      minesPerUnit[unitID] = nil
   end
end
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Can I block units from being built?

Post by knorke »

what gajop said.
For the isMine(unitID/unitDefID) stuff see the "multiple buildpags" thread or the mining gadget. (such check is in quite many wudgets)
Google_Frog
Moderator
Posts: 2464
Joined: 12 Oct 2007, 09:24

Re: Can I block units from being built?

Post by Google_Frog »

If you have a unit that just places mines would it be better to lua it completely. The gadget to do so is a bit more complex but I think it looks much nicer and avoids problems with construction units. I recently made a gadget that does exactly that.

It's not really in a postable format but trust me when I say it is fairly easy (if you've been doing spring lua for years).
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Can I block units from being built?

Post by knorke »

If you have a unit that just places mines would it be better to lua it completely.
the main increase in lolfactor is that you do not have to stop to lay mines and can throw them out while on the run!
but finish the building-mines version first..
User avatar
SanadaUjiosan
Conflict Terra Developer
Posts: 907
Joined: 21 Jan 2010, 06:21

Re: Can I block units from being built?

Post by SanadaUjiosan »

I've tried all day to get this working and I'm just out of steam.

My best try was from using parts from tp_mining. I feel it was really circuitous, which makes me think I was doing it wrong, but I don't really know. If my guesses are correct, it's like a 4 step process to make a table and I just know that has to be wrong. I tried looking at other sources but everything is different and honestly the only one I could even remotely follow was tp_mining.

A table is in {} right?

What does i do?

What does pairs do?

What does _,v do?

What am I missing? Am I doing this right?

Code: Select all

if (gadgetHandler:IsSyncedCode()) then
--------Config--------
local max_mines = 4								--Maximum number of mines allowed per unit
local mines_name = {"kdronemine"}				--Mine units
local minelayers_name = {"bantitankmech"}		--Minelayer units
----------------------
--------Locals--------
local is_mine = {}
local is_minelayer = {}
----------------------


function gadget:Initialize()
	make_mine_table()
	make_minelayer_table ()
end

------Find Mines------

function make_mine_table()
	is_mines = {}
	local all_units = Spring.GetAllUnits ()
	for i in pairs(all_units) do
		local unitDefID = Spring.GetUnitDefID(all_units[i])
		if (is_mine_type (unitDefID)==true) then
			add_mine (all_units[i])
		end
	end
end

function add_mine (unitID)
	mines [unitID] = {}
	mines [unitID].alive = true
end

function is_mine (unitID)
	if (mines [unitID] ~= nil) then return true else return false end	
end

function is_mine_type (unitDefID)
	if (unitDefID == nil) then return false end
	local unitDef = UnitDefs[unitDefID]
	if (unitDef == nil) then return false end
	local unitname = unitDef.name
	for _,v in pairs(mines_name) do
		if v == unitname then return true end
	end	
	return false
end

----------------------

----Find Minelayers---

function make_minelayer_table()
	is_minelayer = {}
	local all_units = Spring.GetAllUnits ()
	for i in pairs(all_units) do
		local unitDefID = Spring.GetUnitDefID(all_units[i])
		if (is_minelayer_type (unitDefID)==true) then
			add_minelayer (all_units[i])
		end
	end
end

function add_minelayer (unitID)
	minelayers [unitID] = {}
	minelayers [unitID].alive = true	
end

function is_minelayer (unitID)
	if (minelayers [unitID] ~= nil) then return true else return false end
end

function is_minelayer_type (unitDefID)
	if (unitDefID == nil) then return false end
	local unitDef = UnitDefs[unitDefID]
	if (unitDef == nil) then return false end
	local unitname = unitDef.name
	for _,v in pairs(minelayers_name) do
		if v == unitname then return true end
	end	
	return false
end
I omitted gajop's code from the copy+paste above because I haven't touched it.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: Can I block units from being built?

Post by Niobium »

Idea sounded neat so I went ahead and made a simple version of it: http://pastebin.com/SpcSiQbb

I've made it in such a way that you should be able to drop it into any mod and see it working, though this does mean its a little weird (Every unit can drop mines, and the mines are copies of the minelayer). Shouldn't be too hard for you to change it to what you want though, I kept the gadget short (Just 96 lines) and commented the complicated lines (Most of which you can ignore).
Google_Frog
Moderator
Posts: 2464
Joined: 12 Oct 2007, 09:24

Re: Can I block units from being built?

Post by Google_Frog »

That looks like what I have (mine is integrated into a larger gadget that does other things and I couldn't be bothered gouging it out). To turn it into a really easy drag and drop gadget you could use customparams.

A unitdef could have this customparams table:

Code: Select all

customParams = {
   minedroplimit = "4",
   mineunit = "mine_unit_internal_name"
},
You access it with something like UnitDefs[unitDefID].customParams.minedroplimit

I'll copy yours and add this in a bit if noone else does.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Can I block units from being built?

Post by knorke »

give a nub your wubget and he will copy&paste for a day.
teach a nub to lua and you can copy&paste from him.
User avatar
SanadaUjiosan
Conflict Terra Developer
Posts: 907
Joined: 21 Jan 2010, 06:21

Re: Can I block units from being built?

Post by SanadaUjiosan »

This nub also can't pull understanding out of thin air... I learn from examining examples. No one's answered my earlier questions about how to call specific units either...

I would use niobium's gadget if Google_Frog, or someone else, added the custom parameter stuff. I tried last night but could not get it right. I am missing vital information...

Also, even if I could someday construct shoddy, barely working gadgets, I doubt anyone would copy+paste from me :-)
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Can I block units from being built?

Post by knorke »

Niobium:
local function GetCanUnitLayMines(uDefId)
return true
end

You did exclude excactly the part he has trouble with ;)

---

That make_minelayer_table() stuff is only needed in case of /luarules reload, which is kind of a side problem.
=forgett about it for now.

1) make gadget that says "hello" when a unit is created
2) make it say the unitname of every unit that is created
3) make that it only says "hello" to to one type of unit
4) Read http://lua-users.org/wiki/TablesTutorial it will answer
A table is in {} right?
What does i do?
What does pairs do?
What does _,v do?
5) make gadget that says hello to unittype A and unittype B, but not to others.
6) make a counter that displays the amount of units from every type
7) add the creation blocking
7) tada, you have made a unitlimit gadget

---
This is the version I made some time ago:
http://pastebin.com/JLfaZ5BE
http://pastebin.com/pZjUnVDY
It adds a "place bomb" button and when you click/hotkey the unit places a bomb behind itself.

It is 2 files, one for the minelaying and another handles "mana"/ammo/ remaining mines w/e for special abilities, which seemed like a lol idea at the time.
Also, even if I could someday construct shoddy, barely working gadgets, I doubt anyone would copy+paste from me
yes, people will. its funny because its spring.
User avatar
SanadaUjiosan
Conflict Terra Developer
Posts: 907
Joined: 21 Jan 2010, 06:21

Re: Can I block units from being built?

Post by SanadaUjiosan »

Success! I was able to get niobium's gadget to do what I want, only work for one (specified) unit and create a particular unit. Perfect! And I think I actually learned some... Thank you tons Knorke!

Now... I want to grey out the button when you're out of mines, and put a small number in a corner telling the player how many mines they have left.

I will investigate this but if anyone has any suggestions, please let them fly.

Also, I am needing a very similar gadget to fix an issue of only keeping one of a pair of units in the game at one time (cruiser and landed cruiser) so I will be trying your workflow+suggestion Knorke, don't worry :wink:

Just confirming my minor yet major success :-)
Post Reply

Return to “Lua Scripts”