



--[[---------------------------------------------------------

   Duplicator module,

   to add new constraints or entity classes use...



   duplicator.RegisterConstraint( "name", funct, ... )

   duplicator.RegisterEntityClass( "class", funct, ... )



-----------------------------------------------------------]]



module( "duplicator", package.seeall )



--

-- When saving or loading all coordinates are saved relative to these

--

local LocalPos = Vector( 0, 0, 0 )

local LocalAng = Angle( 0, 0, 0 )



--

-- Should be set to the player that is creating/copying stuff. Can be nil.

--

local ActionPlayer = nil



--

-- The physics object Saver/Loader

--

local PhysicsObject =

{

	Save = function( data, phys )



		data.Pos = phys:GetPos()

		data.Angle = phys:GetAngles()

		data.Frozen = !phys:IsMoveable()

		if ( !phys:IsGravityEnabled() ) then data.NoGrav = true end

		if ( phys:IsAsleep() ) then data.Sleep = true end



		data.Pos, data.Angle = WorldToLocal( data.Pos, data.Angle, LocalPos, LocalAng )



	end,



	Load = function( data, phys )



		if ( isvector( data.Pos ) && isangle( data.Angle ) ) then



			local pos, ang = LocalToWorld( data.Pos, data.Angle, LocalPos, LocalAng )

			phys:SetPos( pos )

			phys:SetAngles( ang )



		end



		if ( data.Sleep ) then

			-- Make it sleep in the next frame so the entity has time to set up the bones

			timer.Simple( 0, function()

				if ( IsValid( phys ) ) then phys:Sleep() end

			end )

		else

			phys:Wake()

		end



		if ( data.Frozen ) then



			phys:EnableMotion( false )



			-- If we're being created by a player then add these to their frozen list so they can unfreeze them all

			if ( IsValid( ActionPlayer ) ) then

				ActionPlayer:AddFrozenPhysicsObject( Entity, phys )

			end



		end



		if ( data.NoGrav ) then phys:EnableGravity( false ) end



	end,

}



--

-- Entity physics saver

--

local EntityPhysics =

{

	--

	-- Loop each bone, calling PhysicsObject.Save

	--

	Save = function( data, Entity )



		local num = Entity:GetPhysicsObjectCount()



		for objectid = 0, num-1 do

	

			local obj = Entity:GetPhysicsObjectNum( objectid )

			if ( !obj:IsValid() ) then continue end



			data[ objectid ] = {}

			PhysicsObject.Save( data[ objectid ], obj )

	

		end



	end,



	--

	-- Loop each bone, calling PhysicsObject.Load

	--

	Load = function( data, Entity )



		if ( !istable( data ) ) then return end

	

		for objectid, objectdata in pairs( data ) do

	

			local Phys = Entity:GetPhysicsObjectNum( objectid )

			if ( !IsValid( Phys ) ) then continue end

		

			PhysicsObject.Load( objectdata, Phys )

		

		end



	end,

}



--

-- Entity saver

--

local EntitySaver =

{

	--

	-- Called on each entity when saving

	--

	Save = function( data, ent )



		--

		-- Merge the entities actual table with the table we're saving

		-- this is terrible behaviour - but it's what we've always done.

		--

		if ( ent.PreEntityCopy ) then ent:PreEntityCopy() end

		table.Merge( data, ent:GetTable() )

		if ( ent.PostEntityCopy ) then ent:PostEntityCopy() end



		--

		-- Set so me generic variables that pretty much all entities

		-- would like to save.

		--

		data.Pos				= ent:GetPos()

		data.Angle				= ent:GetAngles()

		data.Class				= ent:GetClass()

		data.Model				= ent:GetModel()

		data.Skin				= ent:GetSkin()

		data.Mins, data.Maxs	= ent:GetCollisionBounds()

		data.ColGroup			= ent:GetCollisionGroup()

		data.Name				= ent:GetName()

		data.WorkshopID			= ent:GetWorkshopID()



		data.Pos, data.Angle	= WorldToLocal( data.Pos, data.Angle, LocalPos, LocalAng )



		data.ModelScale			= ent:GetModelScale()

		if ( data.ModelScale == 1 ) then data.ModelScale = nil end



		-- We have no reason to keep the creation ID anymore - but we will

		if ( ent:CreatedByMap() ) then

			data.MapCreationID = ent:MapCreationID()

		end



		-- Allow the entity to override the class

		-- (this is a hack for the jeep, since it's real class is different from the one it reports as)

		if ( ent.ClassOverride ) then data.Class = ent.ClassOverride end



		-- Save the physics

		data.PhysicsObjects = data.PhysicsObjects or {}

		EntityPhysics.Save( data.PhysicsObjects, ent )



	

		-- Flexes

		data.FlexScale = ent:GetFlexScale()

		for i = 0, ent:GetFlexNum() do

	

			local w = ent:GetFlexWeight( i )

			if ( w != 0 ) then

				data.Flex = data.Flex or {}

				data.Flex[ i ] = w

			end

	

		end



		-- Body Groups

		local bg = ent:GetBodyGroups()

		if ( bg ) then



			for k, v in pairs( bg ) do

		

				--

				-- If it has a non default setting, save it.

				--

				if ( ent:GetBodygroup( v.id ) > 0 ) then

	

					data.BodyG = data.BodyG or {}

					data.BodyG[ v.id ] = ent:GetBodygroup( v.id )

	

				end

		

			end



		end

		

		-- Bone Manipulator

		if ( ent:HasBoneManipulations() ) then

	

			data.BoneManip = {}

	

			for i=0, ent:GetBoneCount() do

		

				local t = {}

			

				local s = ent:GetManipulateBoneScale( i )

				local a = ent:GetManipulateBoneAngles( i )

				local p = ent:GetManipulateBonePosition( i )

			

				if ( s != Vector( 1, 1, 1 ) ) then	t[ 's' ] = s end -- scale

				if ( a != Angle( 0, 0, 0 ) ) then	t[ 'a' ] = a end -- angle

				if ( p != Vector( 0, 0, 0 ) ) then	t[ 'p' ] = p end -- position

		

				if ( table.Count( t ) > 0 ) then

					data.BoneManip[ i ] = t

				end

		

			end

	

		end



		--

		-- Store networks vars/DT vars (assigned using SetupDataTables)

		--

		if ( ent.GetNetworkVars ) then

			data.DT = ent:GetNetworkVars()

		end

		

	

		-- Make this function on your SENT if you want to modify the

		--  returned table specifically for your entity.

		if ( ent.OnEntityCopyTableFinish ) then

			ent:OnEntityCopyTableFinish( data )

		end



		--

		-- Exclude this crap

		--

		for k, v in pairs( data ) do



			if ( isfunction(v) ) then

				data[k] = nil

			end



		end



		data.OnDieFunctions			= nil

		data.AutomaticFrameAdvance	= nil

		data.BaseClass				= nil



	end,



	--

	-- Fill in the data!

	--

	Load = function( data, ent )



		if ( !data ) then return end

		if ( data.Model ) then ent:SetModel( data.Model ) end

		if ( data.Angle ) then ent:SetAngles( data.Angle ) end

		if ( data.Pos ) then ent:SetPos( data.Pos ) end

		if ( data.Skin ) then ent:SetSkin( data.Skin ) end

		if ( data.Flex ) then DoFlex( ent, data.Flex, data.FlexScale ) end

		if ( data.BoneManip ) then DoBoneManipulator( ent, data.BoneManip ) end

		if ( data.ModelScale ) then ent:SetModelScale( data.ModelScale, 0 ) end

		if ( data.ColGroup ) then ent:SetCollisionGroup( data.ColGroup ) end

		if ( data.Name ) then ent:SetName( data.Name ) end



		-- Body Groups

		if ( data.BodyG ) then

			for k, v in pairs( data.BodyG ) do

				ent:SetBodygroup( k, v )

			end

		end



		--

		-- Restore NetworkVars/DataTable variables (the SetupDataTables values)

		--

		if ( ent.RestoreNetworkVars ) then

			ent:RestoreNetworkVars( data.DT )

		end



	end,

}





local DuplicateAllowed = {}



--

-- Allow this entity to be duplicated

--

function Allow( classname )

	

	DuplicateAllowed[ classname ] = true



end



--

-- Returns true if we can copy/paste this entity

--

function IsAllowed( classname )

	

	return DuplicateAllowed[ classname ]



end





ConstraintType 	= ConstraintType or {}



--

-- When a copy is copied it will be translated according to these

-- If you set them - make sure to set them back to 0 0 0!

--

function SetLocalPos( v ) LocalPos = v * 1 end

function SetLocalAng( v ) LocalAng = v * 1 end

	

--[[---------------------------------------------------------

   Register a constraint to be duplicated

-----------------------------------------------------------]]

function RegisterConstraint( _name_ , _function_, ... )	



	ConstraintType[ _name_ ] 	= {}

	

	ConstraintType[ _name_ ].Func = _function_

	ConstraintType[ _name_ ].Args = {...}

	

end





EntityClasses	= EntityClasses or {}



--[[---------------------------------------------------------

   Register an entity's class, to allow it to be duplicated

-----------------------------------------------------------]]

function RegisterEntityClass( _name_ , _function_, ... )



	EntityClasses[ _name_ ] 		= {}

	

	EntityClasses[ _name_ ].Func 	= _function_

	EntityClasses[ _name_ ].Args 	= {...}



	Allow( _name_ )

	

end



--[[---------------------------------------------------------

   Returns an entity class factory

-----------------------------------------------------------]]

function FindEntityClass( _name_ )



	if ( !_name_ ) then return end

	return EntityClasses[ _name_ ]



end



--[[---------------------------------------------------------



-----------------------------------------------------------]]

BoneModifiers 				= BoneModifiers or {}

EntityModifiers				= EntityModifiers or {}



function RegisterBoneModifier( _name_, _function_ )		BoneModifiers[ _name_ ] 			= _function_ end

function RegisterEntityModifier( _name_, _function_ )	EntityModifiers[ _name_ ] 			= _function_ end



if ( !SERVER ) then return end



--[[---------------------------------------------------------

   Restore's the flex data

-----------------------------------------------------------]]

function DoFlex( ent, Flex, Scale )



	if ( !Flex ) then return end

	if ( !IsValid(ent) ) then return end



	for k, v in pairs( Flex ) do

		ent:SetFlexWeight( k, v )

	end

	

	if ( Scale ) then

		ent:SetFlexScale( Scale )

	end



end



--[[---------------------------------------------------------

   Restore's the bone's data

-----------------------------------------------------------]]

function DoBoneManipulator( ent, Bones )



	if ( !Bones ) then return end

	if ( !IsValid(ent) ) then return end

	

	for k, v in pairs( Bones ) do

	

		if ( v.s ) then ent:ManipulateBoneScale( k, v.s ) end

		if ( v.a ) then ent:ManipulateBoneAngles( k, v.a ) end

		if ( v.p ) then ent:ManipulateBonePosition( k, v.p ) end

		

	end



end



--[[---------------------------------------------------------

   Generic function for duplicating stuff

-----------------------------------------------------------]]

function GenericDuplicatorFunction( Player, data )



	if ( !IsAllowed( data.Class ) ) then

		-- MsgN( "duplicator: ", data.Class, " isn't allowed to be duplicated!" )

		return

	end



	--

	-- Is this entity 'admin only'?

	--

	if ( IsValid( Player ) && !Player:IsAdmin() ) then



		if ( !scripted_ents.GetMember( data.Class, "Spawnable" ) ) then return end

		if ( scripted_ents.GetMember( data.Class, "AdminOnly" ) ) then return end



	end



	local Entity = ents.Create( data.Class )

	if ( !IsValid( Entity ) ) then return end

	

	-- TODO: Entity not found - maybe spawn a prop_physics with their model?

	

	DoGeneric( Entity, data )



	Entity:Spawn()

	Entity:Activate()

	

	EntityPhysics.Load( data.PhysicsObjects, Entity )

	

	table.Merge( Entity:GetTable(), data )

	

	return Entity

	

end



--[[---------------------------------------------------------

	Automates the process of adding crap the EntityMods table

-----------------------------------------------------------]]

function StoreEntityModifier( Entity, Type, Data )



	if (!Entity) then return end

	if (!Entity:IsValid()) then return end



	Entity.EntityMods = Entity.EntityMods or {}

	

	-- Copy the data

	local NewData = Entity.EntityMods[ Type ] or {}

	table.Merge( NewData, Data )

	

	Entity.EntityMods[ Type ] = NewData



end



--[[---------------------------------------------------------

	Clear entity modification

-----------------------------------------------------------]]

function ClearEntityModifier( Entity, Type )



	if (!Entity) then return end

	if (!Entity:IsValid()) then return end

	

	Entity.EntityMods = Entity.EntityMods or {}

	Entity.EntityMods[ Type ] = nil



end



--[[---------------------------------------------------------

	Automates the process of adding crap the BoneMods table

-----------------------------------------------------------]]

function StoreBoneModifier( Entity, BoneID, Type, Data )



	if (!Entity) then return end

	if (!Entity:IsValid()) then return end



	-- Copy the data

	NewData = {}

	table.Merge( NewData , Data )

	

	-- Add it to the entity

	Entity.BoneMods = Entity.BoneMods or {}

	Entity.BoneMods[ BoneID ] = Entity.BoneMods[ BoneID ] or {}

	

	Entity.BoneMods[ BoneID ][ Type ] = NewData



end



--[[---------------------------------------------------------

	Returns a copy of the passed entity's table

-----------------------------------------------------------]]

function CopyEntTable( Ent )



	local output = {}

	EntitySaver.Save( output, Ent )

	return output



end



--

-- Work out the AABB size

--

function WorkoutSize( Ents )



	local mins = Vector( -1, -1, -1 )

	local maxs = Vector( 1, 1, 1 )





	for k, v in pairs( Ents ) do

	

		if ( !v.Mins || !v.Maxs ) then continue end

		if ( !v.Angle || !v.Pos ) then continue end



		--

		-- Rotate according to the entity!

		--

		local RotMins = v.Mins * 1

		local RotMaxs = v.Maxs * 1

		RotMins:Rotate( v.Angle )

		RotMaxs:Rotate( v.Angle )



		--

		-- This is dumb and the logic is wrong, but it works for now.

		--

		mins.x = math.min( mins.x, v.Pos.x + RotMins.x )

		mins.y = math.min( mins.y, v.Pos.y + RotMins.y )

		mins.z = math.min( mins.z, v.Pos.z + RotMins.z )

		mins.x = math.min( mins.x, v.Pos.x + RotMaxs.x )

		mins.y = math.min( mins.y, v.Pos.y + RotMaxs.y )

		mins.z = math.min( mins.z, v.Pos.z + RotMaxs.z )



		maxs.x = math.max( maxs.x, v.Pos.x + RotMins.x )

		maxs.y = math.max( maxs.y, v.Pos.y + RotMins.y )

		maxs.z = math.max( maxs.z, v.Pos.z + RotMins.z )

		maxs.x = math.max( maxs.x, v.Pos.x + RotMaxs.x )

		maxs.y = math.max( maxs.y, v.Pos.y + RotMaxs.y )

		maxs.z = math.max( maxs.z, v.Pos.z + RotMaxs.z )



	end



	return mins, maxs



end



--[[---------------------------------------------------------

   Copy this entity, and all of its constraints and entities

   and put them in a table.

-----------------------------------------------------------]]

function Copy( Ent, AddToTable )



	local Ents = {}

	local Constraints = {}

	

	GetAllConstrainedEntitiesAndConstraints( Ent, Ents, Constraints )

	

	local EntTables = {}

	if ( AddToTable != nil ) then EntTables = AddToTable.Entities or {} end



	for k, v in pairs(Ents) do

		EntTables[ k ] = CopyEntTable( v )

	end

	

	local ConstraintTables = {}

	if ( AddToTable != nil ) then ConstraintTables = AddToTable.Constraints or {} end



	for k, v in pairs(Constraints) do

		ConstraintTables[ k ] = v

	end



	local mins, maxs = WorkoutSize( EntTables )



	return {



		Entities		=	EntTables,

		Constraints		=	ConstraintTables,

		Mins			=	mins,

		Maxs			=	maxs



	}



end



--[[---------------------------------------------------------

-----------------------------------------------------------]]

function CopyEnts( Ents )



	local Ret = { Entities = {}, Constraints = {} }

	

	for k, v in pairs( Ents ) do

	

		Ret = Copy( v, Ret )



	end



	

	return Ret



end



--[[---------------------------------------------------------

   Create an entity from a table.

-----------------------------------------------------------]]

function CreateEntityFromTable( Player, EntTable )



	--

	-- Convert position/angle to `local`

	--

	if ( EntTable.Pos && EntTable.Angle ) then



		EntTable.Pos, EntTable.Angle = LocalToWorld( EntTable.Pos, EntTable.Angle, LocalPos, LocalAng )



	end



	local EntityClass = FindEntityClass( EntTable.Class )

	

	-- This class is unregistered. Instead of failing try using a generic

	-- Duplication function to make a new copy..

	if ( !EntityClass ) then

	

		return GenericDuplicatorFunction( Player, EntTable )

	

	end

	

	-- Build the argument list

	local ArgList = {}

	

	for iNumber, Key in pairs( EntityClass.Args ) do



		local Arg = nil

	

		-- Translate keys from old system

		if ( Key == "pos" || Key == "position" ) then Key = "Pos" end

		if ( Key == "ang" || Key == "Ang" || Key == "angle" ) then Key = "Angle" end

		if ( Key == "model" ) then Key = "Model" end

		

		Arg = EntTable[ Key ]

		

		-- Special keys

		if ( Key == "Data" ) then Arg = EntTable end

		

		-- If there's a missing argument then unpack will stop sending at that argument so send it as `false`

		if ( Arg == nil ) then Arg = false end

		

		ArgList[ iNumber ] = Arg

		

	end

	

	-- Create and return the entity

	return EntityClass.Func( Player, unpack(ArgList) )

	

end





--[[---------------------------------------------------------

  Make a constraint from a constraint table

-----------------------------------------------------------]]

function CreateConstraintFromTable( Constraint, EntityList )



	local Factory = ConstraintType[ Constraint.Type ]

	if ( !Factory ) then return end



	local Args = {}

	for k, Key in pairs( Factory.Args ) do

	

		local Val = Constraint[ Key ]

		

		for i=1, 6 do



			if ( Constraint.Entity[ i ] ) then



				if ( Key == "Ent"..i ) then

					Val = EntityList[ Constraint.Entity[ i ].Index ]

					if ( Constraint.Entity[ i ].World ) then

						Val = game.GetWorld()

					end

				end



				if ( Key == "Bone"..i ) then Val = Constraint.Entity[ i ].Bone or 0 end

				if ( Key == "LPos"..i ) then Val = Constraint.Entity[ i ].LPos end

				if ( Key == "WPos"..i ) then Val = Constraint.Entity[ i ].WPos end

				if ( Key == "Length"..i ) then Val = Constraint.Entity[ i ].Length or 0 end



			end

		end

		

		-- If there's a missing argument then unpack will stop sending at that argument

		if ( Val == nil ) then Val = false end

		

		table.insert( Args, Val )

	

	end



	local Entity = Factory.Func( unpack(Args) )

	

	return Entity



end



--[[---------------------------------------------------------

   Given entity list and constranit list, create all entities

   and return their tables

-----------------------------------------------------------]]

function Paste( Player, EntityList, ConstraintList )



	--

	-- Store the player

	--

	local oldplayer = ActionPlayer

	ActionPlayer = Player



	--

	-- Copy the table - because we're gonna be changing some stuff on it.	

	--

	local EntityList = table.Copy( EntityList )

	local ConstraintList = table.Copy( ConstraintList )



	local CreatedEntities = {}

	

	--

	-- Create the Entities

	--

	for k, v in pairs( EntityList ) do

	

		local e = nil

		local b = ProtectedCall( function() e = CreateEntityFromTable( Player, v ) end )

		if  ( !b ) then continue end



		if ( IsValid( e ) ) then



			--

			-- Call this here ( as well as before :Spawn) because Spawn/Init might have stomped the values

			--

			if ( e.RestoreNetworkVars ) then

				e:RestoreNetworkVars( v.DT )

			end



			if ( e.OnDuplicated ) then

				e:OnDuplicated( v )

			end



		end



		CreatedEntities[ k ] = e

		

		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 )

			

		else

		

			CreatedEntities[ k ] = nil

		

		end

		

	end

	

	--

	-- Apply modifiers to the created entities

	--

	for EntID, Ent in pairs( CreatedEntities ) do

	

		ApplyEntityModifiers ( Player, Ent )

		ApplyBoneModifiers ( Player, Ent )

	

		if ( Ent.PostEntityPaste ) then

			Ent:PostEntityPaste( Player, Ent, CreatedEntities )

		end

	

	end

	

	

	local CreatedConstraints = {}

	

	--

	-- Create constraints

	--

	for k, Constraint in pairs( ConstraintList ) do

	

		local Entity = CreateConstraintFromTable( Constraint, CreatedEntities )

		

		if ( Entity && Entity:IsValid() ) then

			table.insert( CreatedConstraints, Entity )

		end

	

	end



	ActionPlayer = oldplayer



	return CreatedEntities, CreatedConstraints

	

end





--[[---------------------------------------------------------

  Applies entity modifiers

-----------------------------------------------------------]]

function ApplyEntityModifiers( Player, Ent )



	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 ] )

			

		end

	end



end





--[[---------------------------------------------------------

  Applies Bone Modifiers

-----------------------------------------------------------]]

function ApplyBoneModifiers( Player, Ent )



	if ( !Ent ) then return end

	if ( !Ent.PhysicsObjects ) then return end

	if ( !Ent.BoneMods ) then return end



	--

	-- Loop every Bone on the entity

	--

    for Bone, Types in pairs( Ent.BoneMods ) do



		-- The physics object isn't valid, skip it.

        if ( !Ent.PhysicsObjects[Bone] ) then continue end



		-- Loop through each modifier on this bone

        for Type, Data in pairs(Types) do



			-- Find and all the function

            local ModFunction = BoneModifiers[Type]

            if ( ModFunction ) then

                ModFunction( Player, Ent, Bone, Ent:GetPhysicsObjectNum( Bone ), Data )

            end



        end



    end



end





--[[---------------------------------------------------------

  Returns all constrained Entities and constraints

  This is kind of in the wrong place. No not call this

  from outside of this code. It will probably get moved to

  constraint.lua soon.

-----------------------------------------------------------]]

function GetAllConstrainedEntitiesAndConstraints( ent, EntTable, ConstraintTable )



	if ( !IsValid( ent ) ) then return end



	-- Translate the class name

	local classname = ent:GetClass()

	if ( ent.ClassOverride ) then classname = ent.ClassOverride end

	

	-- Is the entity in the dupe whitelist?

	if ( !IsAllowed( classname ) ) then

		-- MsgN( "duplicator: ", classname, " isn't allowed to be duplicated!" )

		return

	end



	-- Entity doesn't want to be duplicated.

	if ( ent.DoNotDuplicate ) then return end



	EntTable[ ent:EntIndex() ] = ent

	

	if ( !constraint.HasConstraints( ent ) ) then return end

	

	local ConTable = constraint.GetTable( ent )

	

	for key, constraint in pairs( ConTable ) do



		local index = constraint.Constraint:GetCreationID()

		

		if ( !ConstraintTable[ index ] ) then



			-- Add constraint to the constraints table

			ConstraintTable[ index ] = constraint



			-- Run the Function for any ents attached to this constraint

			for key, ConstrainedEnt in pairs( constraint.Entity ) do



				GetAllConstrainedEntitiesAndConstraints( ConstrainedEnt.Entity, EntTable, ConstraintTable )

				

			end

			

		end

	end



	return EntTable, ConstraintTable

	

end





--

-- Return true if this entity should be removed when RemoveMapCreatedEntities is called

-- We don't want to remove all entities.

--

local function ShouldMapEntityBeRemoved( ent, classname )



	if ( classname == "prop_physics" ) then return true end

	if ( classname == "prop_physics_multiplayer" ) then return true end

	if ( classname == "prop_ragdoll" ) then return true end

	if ( ent:IsNPC() ) then return true end



	return false



end



--

-- Help to remove certain map created entities before creating the saved entities

-- This is obviously so we don't get duplicate props everywhere. It should be called

-- before calling Paste.

--

function RemoveMapCreatedEntities()



	local list = ents.GetAll()



	for k, v in pairs( list ) do



		if ( ShouldMapEntityBeRemoved( v, v:GetClass() ) ) then

			v:Remove()

		end



	end



end



--

-- BACKWARDS COMPATIBILITY - PHASE OUT, RENAME?

--

function DoGenericPhysics( Entity, Player, data )



	if ( !data || !data.PhysicsObjects ) then return end



	EntityPhysics.Load( data.PhysicsObjects, Entity )



end



--

--

--

function DoGeneric( ent, data )



	EntitySaver.Load( data, ent )



end

