LUA Stacker Tool stacking effects.

Hi, not a LUA expert but familiar with programming. I’m basically trying to make the stacker tool stack effects. All I get is watermelons though:

http://www.wduwant.com/index_uploads/uploads/b6e041535ebe.jpg

I presume it’s a default in Garry’s mod. So I’m wondering how to stack effects. An interesting solution seems to be to give the effect the same physics/no collision properties as the globe to the left, I’m not sure how to do that though, but that would kind of fix it.

Another way I’m thinking is to change the LUA code for the stacker tool, but I’m not sure what to modify here. I believe the newEnt or Ent variable is what’s messing with my ability to spawn the effect I’m trying to stack.

Found the github code for it here: https://github.com/Mista-Tea/improved-stacker/blob/master/lua/weapons/gmod_tool/stools/stacker.lua
I got to the point of finding the function responsible here:




function TOOL:LeftClick( trace ) 	if ( !IsValid( trace.Entity ) or trace.Entity:GetClass() ~= "prop_physics" ) then return false end 	if ( CLIENT ) then return true end  	local ply = self:GetOwner() 	 	local count = self:GetCount() 	local maxCount = self:GetMaxCount() 	 	-- check if the player's stack count is higher than the server's max allowed 	if ( maxCount >= 0 ) then 		if ( count > maxCount ) then ply:PrintMessage( HUD_PRINTTALK, "The max props that can be stacked at once is limited to " .. maxCount ) end 		count = math.Clamp( count, 0, self:GetMaxCount() ) 	end 	 	-- check if the player is trying to use stacker too quickly 	if ( ply.LastStackTime and ply.LastStackTime + self:GetDelay() > CurTime() ) then ply:PrintMessage( HUD_PRINTTALK, "You are using stacker too quickly" ) return false end 	ply.LastStackTime = CurTime() 	 	local dir    = self:GetDirection() 	local mode   = self:GetStackerMode() 	local offset = self:GetOffsetVector() 	local rotate = self:GetRotateAngle()  	local stackRelative = self:ShouldStackRelative() 	local stayInWorld   = cvarStayInWorld:GetBool()  	local ent = trace.Entity  	local entPos  = ent:GetPos() 	local entAng  = ent:GetAngles() 	local entMod  = ent:GetModel() 	local entSkin = ent:GetSkin() 	local entMat  = ent:GetMaterial()  	local colorData = { 		Color      = ent:GetColor(),  		RenderMode = ent:GetRenderMode(),  		RenderFX   = ent:GetRenderFX() 	}  	local physMat  = ent:GetPhysicsObject():GetMaterial() 	local physGrav = ent:GetPhysicsObject():IsGravityEnabled() 	local lastEnt  = ent 	local newEnts  = { ent } 	 	local newEnt 	 	undo.Create( "stacker" ) 	 	for i = 1, count, 1 do 		-- check if the player has too many active stacker props spawned out already 		if ( self:IsExceedingMax() ) then ply:PrintMessage( HUD_PRINTTALK, "Your active Stacker props exceed the 'stacker_max_total' cvar ("..cvarMaxTotal:GetInt()..")" ) break end 		-- check if the player has exceeded the sbox_maxprops cvar 		if ( !self:GetSWEP():CheckLimit( "props" ) )                         then break end 		-- check if external admin mods are blocking this entity 		if ( hook.Run( "PlayerSpawnProp", ply, entMod ) == false )           then break end 		 		if ( i == 1 or ( mode == MODE_PROP and stackRelative ) ) then 			stackdir, height, thisoffset = self:StackerCalcPos( lastEnt, mode, dir, offset ) 		end 		 		entPos = entPos + stackdir * height + thisoffset 		entAng = entAng + rotate 		 		-- check if the stacked props would be spawned outside of the world 		if ( stayInWorld and !util.IsInWorld( entPos ) ) then ply:PrintMessage( HUD_PRINTTALK, "Stacked props must be spawned within the world" ) break end 		 		newEnt = ents.Create( "prop_physics" ) 		newEnt:SetModel( entMod ) 		newEnt:SetPos( entPos ) 		newEnt:SetAngles( entAng ) 		newEnt:SetSkin( entSkin ) 		newEnt:Spawn() 		 		-- this hook is for external prop protections and anti-spam addons 		-- it is called before undo, ply:AddCount, and ply:AddCleanup to allow developers to 		-- remove or mark this entity so that those same functions (if overridden) can 		-- detect that the entity came from Stacker 		if ( !IsValid( newEnt ) or hook.Run( "StackerEntity", newEnt, ply ) ~= nil )             then break end 		if ( !IsValid( newEnt ) or hook.Run( "PlayerSpawnedProp", ply, entMod, newEnt ) ~= nil ) then break end  		-- increase the total number of active stacker props spawned by the player by 1 		self:IncrementStackerEnts() 		 		-- decrement the total number of active stacker props spawned by the player by 1 		-- when the prop gets removed in any way 		newEnt:CallOnRemove( "UpdateStackerTotal", function( ent, ply ) 			-- if the player is no longer connected, there is nothing to do 			if ( !IsValid( ply ) ) then return end 			-- don't call self:DecrementStackerEnts() here 			-- the way the gmod_tool STool was written would most likely cause using 'self' here to break 			ply.TotalStackerEnts = ( ply.TotalStackerEnts and ply.TotalStackerEnts - 1 ) or 0 		end, ply ) 		 		self:ApplyMaterial( newEnt, entMat ) 		self:ApplyColor( newEnt, colorData ) 		self:ApplyFreeze( ply, newEnt ) 		self:ApplyWeld( lastEnt, newEnt ) 		 		self:ApplyPhysicalProperties( ent, newEnt, trace.PhysicsBone, { GravityToggle = physGrav, Material = physMat } ) 		 		lastEnt = newEnt 		table.insert( newEnts, newEnt ) 		 		undo.AddEntity( newEnt ) 		ply:AddCleanup( "props", newEnt ) 	end 	 	self:ApplyNoCollide( newEnts ) 	newEnts = nil 	 	undo.SetPlayer( ply ) 	undo.Finish()  	return true end


I also realized that when I color or apply a material on the effect ring, that property is not passed onto the watermelon. I tried taking out some of the if statements to see if they’re responsible for preventing the effects from stacking but no luck.

Appreciate any help here.

You can see how effects work here: https://github.com/garrynewman/garrysmod/blob/master/garrysmod/gamemodes/base/entities/entities/prop_effect.lua

Relevant excerpt: [lua]self.AttachedEntity = ents.Create( “prop_dynamic” )
self.AttachedEntity:SetModel( self:GetModel() )
self.AttachedEntity:SetAngles( self:GetAngles() )
self.AttachedEntity:SetPos( self:GetPos() )
self.AttachedEntity:SetSkin( self:GetSkin() )
self.AttachedEntity:Spawn()
self.AttachedEntity:SetParent( self.Entity )
self.AttachedEntity:DrawShadow( false )

self:SetModel( “models/props_junk/watermelon01.mdl” )[/lua]

This might explain why the stacker makes a bunch of watermelons. Although it makes me a fair bit disappointed at the stacker tool. I’d expect it to use something reliable like, say, the duplicator library, which custom SENTs are supposed to work with.

So is there a way to transfer basically one props physics properties onto an effect? For example, the collision grid of the globe onto the effect? Does a tool like that exist?

This line on stacker tool is what seems to trigger the watermelon, right?


newEnt = ents.Create( "prop_physics" )
        newEnt:SetModel( entMod )

and in the prop_effects here


self.AttachedEntity = ents.Create( "prop_dynamic" )
 self.AttachedEntity:SetModel( self:GetModel() )
self:SetModel( "models/props_junk/watermelon01.mdl" )

So if i gather it correctly “prop_physics” means an actual prop which you can pick up with grav tool and it has collisions, while “prop_dynamic” is basically a glowing green ring effect?

Close. You’re right about prop_physics, as for prop_dynamic: https://developer.valvesoftware.com/wiki/Prop_dynamic

Prop_dynamic is the actual effect - i.e. the globe. It can’t have physics and can’t be moved with the physgun, presumably because the globe model doesn’t have a physics mesh defined.

The ring effect is unrelated and is drawn in the draw hook: https://github.com/garrynewman/garrysmod/blob/master/garrysmod/gamemodes/base/entities/entities/prop_effect.lua#L78-L79
[lua]render.SetMaterial( self.GripMaterial )
render.DrawSprite( self:GetPos(), 16, 16, color_white )[/lua]

Ah I see, so it’s the physics mesh that I could give to an effect which I could then use the stacker tool on. No clue how to do that though.

What if I inject this part from the prop_effects part



self:SetModel( "models/props_junk/watermelon01.mdl" )


and make it so



self:SetModel(trace.Entity )


and put it in the stacker lua file, would that kind of work?

Let’s stop beating around the bush, what exactly are you trying to do?

Very simple, i want to spawn the effect instead of the watermelon. So in the first pic, wherever there is the watermelon, I’m trying to figure out how to get the effect in the place.

My goal is to use that with a modified version of the stacker tool. I managed to stack things in a random manner, kind of mimicing nature. Here’s an example with breen’s desk

http://www.wduwant.com/index_uploads/uploads/c6e283f85002.jpg

I basically want to try the same thing with natural effects and not props since most effects are things like trees, rocks, grass. Objects without any gravity or physics properties.

[editline]9th April 2016[/editline]

This would allow me to easily make nature scenes with the stacker tool. So far it only works for props though.

Hi, I am the author of the Improved Stacker tool.

Just for future reference, I am on GitHub daily and have a dedicated thread for the tool here, so I am generally available to answer questions if you need firsthand help.

As to your current question, the tool’s implementation wasn’t designed for stacking anything other than prop_physics entities (e.g., the general “prop”).
I chose to stick with the original author’s intentions for the tool because it’s much easier to handle.

As Neat-Nit pointed out, I don’t use Garry’s duplicator library to handle spawning the stacked entities.
I am in the middle of a big update to the tool, but I could look into switching to or allowing a sort of “duplicator” mode.
I know there are several benefits, such as not needing to hardcode support for things like color/physical properties, but I would still need to give the users the ability to enable/disable them (it’s a really handy feature).

Unfortunately, I probably wouldn’t be able to get such an update out soon enough to suit your needs since I’m juggling classes, work, and other projects.

[editline]8th April 2016[/editline]

Could someone bump this thread so my replies stop auto-merging? I have a solution that should work for the OP.

Thank you!

I sent a PM to Crazy Knife, but for anyone else interested, I’ve hacked up a solution that allows stacking prop_effects. It even uses the correct position and angles based on the internal prop_dynamic entity rather than the watermelon crap.

Here’s an example:

Just as a warning, this really is a hacky solution and shouldn’t be used to replace your normal use of the tool. This is especially true since the official update I have coming out changes a lot of stuff around.
Just use it while you need to stack prop_effects.
Let me know if there are any errors I didn’t catch!

The code is here: http://pastebin.com/raw/ZZT7bRZp

Here is the diffchecker so you can see what I changed: https://www.diffchecker.com/kiesw0rz

Ah yes, I unpacked your addon and deleted that line. It made the watermelons spawn as a result.

[editline]9th April 2016[/editline]

Thanks! Didn’t see last post, let me test it real quick.

So, I forgot that effects don’t handle opacity the same.

If you want to make the effects in the ghost stack visible (but a little bit transparent), change line 981 to the following:


          entCol.a = isEffect and 178 or 150

Anything below 178 and they become invisible.