Entity modifiers

I made this tool that switches one screen to another prop/entity.
Now I’m trying to make it behave nice with (Advanced) Duplicator.
local function switchscreen(screen, ent)
screen.GPUEntity = ent

	duplicator.StoreEntityModifier(screen, "wire_gpulib_switcher", { ent })

duplicator.RegisterEntityModifier("wire_gpulib_switcher", function(ply, screen, data)
	print(ply, screen, data)
	local ent = data[1]
	switchscreen(screen, ent)


Now the problem is that the “PrintTable(data)” line always prints the old entity, not the newly created one.

Is there a solution that gives me the newly created entity somehow?
Support for the regular duplicator is kind of optional, but would still be nice :slight_smile:

Support for the Regular duplicator comes free with the advanced duplicator in my experience.
To get the newly created entity the only method I’ve seen that works is through the PostEntityPaste entity hook as it gives the table of newly created entities where the key is the entity ID of the old entity. You’d end up having to put the following in the screen’s PostEntityPaste hook:
[lua]function ENT:PostEntityPaste(ply, ent, createdEnts)
– so we don’t break wire duping
self.BaseClass.PostEntityPaste(self, ply, ent, createdEnts)
switchscreen(self, createdEnts[ ent.EntMods.wire_gpulib_switcher[1] ])
Also you’d have to change this
[lua]-- old function
– duplicator.StoreEntityModifier(screen, “wire_gpulib_switcher”, { ent })
– new function
duplicator.StoreEntityModifier(screen, “wire_gpulib_switcher”, { ent:EntIndex() })[/lua]


I’ve been trying to understand the complexities of the duplication system myself.
RegisterEntityClass allows you to define a function for creating the specific entity class, it fails to work if you’re defining for a base class as all subclasses will have to redefine it.
The EntityModifiers are handy for if you want to alter an entity but can’t alter its definition. A useful example is the Mass STool, which stores a change in mass which gets applied when it’s duped. This is a generic method of duplicator alteration, which unfortunately still has the drawback of not being aware of other entities that have been pasted.
The PreEntityCopy hook is called before it copies the entity, this can be useful for storing your entity modifiers if there wasn’t a better moment to do it beforehand. PostEntityPaste gets passed the CreatedEntities list, which contains references to the new entities with indexes of the entity index of the original entity. The PostEntityPaste method does have the shortcomings of it not knowing about the created Constraints, which could be fixed by calling PostEntityPaste after the constraints have been created.
In short, there are problems with the system which ought to be addressed.

Does anyone else find the new submission form keeps stripping out their lua tags?


Redefining the following would allow you to have the CreatedEnts and CreatedConstraints as parameters for the entity modifier and PostEntityPaste.
[lua]function duplicator.Paste( Player, EntityList, ConstraintList )

local CreatedEntities = {}

// Create the Entities
for k, v in pairs( EntityList ) do

    CreatedEntities[ k ] = duplicator.CreateEntityFromTable( Player, v )
    if ( CreatedEntities[ k ] ) then
        CreatedEntities[ k ].BoneMods = table.Copy( v.BoneMods )
        CreatedEntities[ k ].EntityMods = table.Copy( v.EntityMods )
        CreatedEntities[ k ].PhysicsObjects = table.Copy( v.PhysicsObjects )
        CreatedEntities[ k ] = nil

local CreatedConstraints = {}

// Create constraints
for k, Constraint in pairs( ConstraintList ) do

    local Entity = duplicator.CreateConstraintFromTable( Constraint, CreatedEntities )
    if ( Entity && Entity:IsValid() ) then
        table.insert( CreatedConstraints, Entity )


// Apply modifiers to the created entities
for EntID, Ent in pairs( CreatedEntities ) do    

    ApplyEntityModifiers ( Player, Ent, CreatedEntities, CreatedConstraints )
    ApplyBoneModifiers ( Player, Ent, CreatedEntities, CreatedConstraints )

    if ( Ent.PostEntityPaste ) then
        Ent:PostEntityPaste( Player, Ent, CreatedEntities, CreatedConstraints )


return CreatedEntities, CreatedConstraints


Applies entity modifiers
function duplicator.ApplyEntityModifiers( Player, Ent, CreatedEnts, CreatedConstraints )

if ( !Ent ) then return end
if ( !Ent.EntityMods ) then return end

for Type, ModFunction in pairs( EntityModifiers ) do

    if ( Ent.EntityMods[ Type ] ) then

        ModFunction( Player, Ent, Ent.EntityMods[ Type ], CreatedEnts, CreatedConstraints )


oh damnit, I just found out that advdupe applies entity modifiers immediately after creating the entity, as opposed to after all entities…

hmm, I could register a constraint…
the main disadvantage would be that it wastes an edict slot for no good reason


my solution:
[lua]-- Calls func once (Advanced) Duplicator has finished spawning the entity that previously had the entity id entid.
– Usage: WireLib.PostDupe(entid, function(ent) … end)
function WireLib.PostDupe(entid, func)
local CreatedEntities

local paste_functions = {
	[duplicator.Paste] = true,
	[AdvDupe.Paste] = true,
	[AdvDupe.OverTimePasteProcess] = true,

-- Go through the call stack to find someone who has a CreatedEntities table for us.
local i,info = 1,debug.getinfo(1)
while info do
	if paste_functions[info.func] then
		for j = 1,20 do
			local name, value = debug.getlocal(i, j)
			if name == "CreatedEntities" then
				CreatedEntities = value
	i = i+1
	info = debug.getinfo(i)

-- Nothing found? Too bad...
if not CreatedEntities then return end

-- Wait until the selected entity has been spawned...
local unique = {}
timer.Create(unique, 1, 240, function(CreatedEntities, entid, unique, func)
	local ent = CreatedEntities[entid]
	if ent then
		-- and call the callback
end, CreatedEntities, entid, unique, func)


works with both duplicator and advanced duplicator and will be in wiremod r2001 :slight_smile:
can be used out of an entity modifier handler and should also be usable from an entity creation hook, like duplicator.RegisterEntityClass