AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include('shared.lua') ENT.WireDebugName = "WIRE_FieldGen" local MODEL = Model( "models/props_lab/binderblue.mdl" ) local EMP_IGNORE_INPUTS = { Kill=true , Pod=true , Eject=true , Lock=true , Terminate = true }; EMP_IGNORE_INPUTS["Damage Armor"]=true; EMP_IGNORE_INPUTS["Strip weapons"]=true; EMP_IGNORE_INPUTS["Damage Health"]=true; function ENT:Initialize() self:PhysicsInit( SOLID_VPHYSICS ) self:SetMoveType( MOVETYPE_VPHYSICS ) self:SetSolid( SOLID_VPHYSICS ) self.multiplier=1; self.active=0; self.objects={}; self.prox=100; self.direction=Vector(0,1,0); self.ignore={} self.props=1; self.npcs=1; self.player=0; if ( self.Type == "Wind" ) then self.direction=Vector(1,0,0); end self:ConfigInOuts(); self:SetOverlayText( self:GetDisplayText() ) end function ENT:SetType( v ) self.Type=v; end function ENT:Setworkonplayers( v ) self.workonplayers=v; end function ENT:Setignoreself( v ) self.ignoreself=v; end function ENT:Setarc( v ) self.arc=v; end function ENT:BuildIgnoreList() local queue={self} self.ignore={} self.ignore[ self:EntIndex() ] = self while ( # queue > 0 ) do local CEnt = constraint.GetTable( table.remove( queue ) ) if type(CEnt) == "table" then for _, mc in pairs( CEnt ) do if mc.Constraint.Type != "Rope" then for _, my in pairs( mc.Entity ) do if self.ignore[ my.Index ] != my.Entity then self.ignore[ my.Index ] = my.Entity table.insert( queue , my.Entity ); end end end end end end end function ENT:GetTypes() return { "Gravity" , "Pull" , "Push" , "Hold" , "Wind" , "Vortex" , "Flame" , "Crush" , "EMP" , "Death" , "Heal" , "Battery" , "NoCollide" , "Speed" }; end function ENT:GetTypeName( Type ) local Text=""; if Type == "Gravity" then Text = "Zero Gravity"; elseif Type == "Pull" then Text = "Attraction"; elseif Type == "Push" then Text = "Repulsion"; elseif Type == "Hold" then Text = "Stasis"; elseif Type == "Wind" then Text = "Wind"; elseif Type == "Vortex" then Text = "Vortex"; elseif Type == "Flame" then Text = "Flame"; elseif Type == "Crush" then Text = "Pressure"; elseif Type == "EMP" then Text = "Electromagnetic"; elseif Type == "Death" then Text = "Radiation"; elseif Type == "Heal" then Text = "Recovery"; elseif Type == "Battery" then Text = "Battery"; elseif Type == "NoCollide" then Text = "Phase"; elseif Type == "Speed" then Text = "Accelerator"; end return Text; end function ENT:GetDisplayText() local Text = self:GetTypeName( self.Type ) .. " Field Generator ( "; if self.active == 0 then Text = Text .. "Off )" else Text = Text .. "On )" end return Text; end function ENT:ConfigInOuts() if ( self.Type == "Gravity" ) then self.Inputs = Wire_CreateInputs(self, { "Active" , "Distance" } ) elseif ( self.Type == "Wind" || self.Type == "Vortex" ) then self.Inputs = Wire_CreateInputs(self, { "Active" , "Distance","Multiplier", "Direction.X" , "Direction.Y", "Direction.Z", "Direction" } ) WireLib.AdjustSpecialInputs(self, { "Active", "Distance","Multiplier", "Direction.X" , "Direction.Y", "Direction.Z", "Direction"}, { "NORMAL","NORMAL", "NORMAL", "NORMAL", "NORMAL","NORMAL", "VECTOR"}) else self.Inputs = Wire_CreateInputs(self, { "Active" , "Distance" , "Multiplier" } ) end self.Outputs = Wire_CreateOutputs(self, { } ) end function ENT:TriggerInput(iname, value) if ( value != nil && iname == "Distance" ) then self.prox=value; end if ( value != nil && iname == "Direction.X" ) then self.direction.x=value; end if ( value != nil && iname == "Direction.Y" ) then self.direction.y=value; end if ( value != nil && iname == "Direction.Z" ) then self.direction.z=value; end if ( value != nil && iname == "Direction" ) then if (type(value) != "Vector") then Msg("non vector passed!\n") return end self.direction=value; end if ( value != nil && iname == "Multiplier" ) then if value > 0 then self.multiplier=value; else self.multiplier=1.0; end end if ( value != nil && iname == "Active" ) then self.active=value; end if self.active == 0 then self:Disable(); end self:SetOverlayText( self:GetDisplayText() ) end function ENT:is_true( value ) if type(value) == "number" and math.abs(value) < 0.0001 then return false; end if type(value) == "string" and value == "0" then return false; end return value; end function ENT:Toogle_Prop_Gravity( prop , yes_no ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetMoveType() == MOVETYPE_NONE then return false; end if prop:GetMoveType() == MOVETYPE_NOCLIP then return false; end //do this to prevent -uncliping- if prop:GetClass() != "player" && !gamemode.Call("PhysgunPickup",self.pl,prop) then return false; end if prop:GetMoveType() != MOVETYPE_VPHYSICS then if yes_no == false then if prop:IsNPC() || prop:IsPlayer() then prop:SetMoveType(MOVETYPE_FLY); prop:SetMoveCollide(MOVECOLLIDE_FLY_BOUNCE); else prop:SetGravity(0); end else if prop:IsPlayer() then prop:SetMoveType(MOVETYPE_WALK); prop:SetMoveCollide(MOVECOLLIDE_DEFAULT); elseif prop:IsNPC() then prop:SetMoveType(MOVETYPE_STEP); prop:SetMoveCollide(MOVECOLLIDE_DEFAULT); else prop:SetGravity(1); end end end if prop:GetPhysicsObjectCount() > 1 then for x=0,prop:GetPhysicsObjectCount()-1 do local part=prop:GetPhysicsObjectNum(x) part:EnableGravity( yes_no ); end return false; end local phys=prop:GetPhysicsObject(); if ( !phys:IsValid() ) then return end phys:EnableGravity( yes_no ); end function ENT:Gravity_Logic() local NewObjs={}; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do self:Toogle_Prop_Gravity( contact , false ); NewObjs[ contact:EntIndex() ] = contact; end for idx,contact in pairs( self.objects ) do if ( NewObjs[ idx ] != contact ) then self:Toogle_Prop_Gravity( contact , true ) end end self.objects = NewObjs; end function ENT:Gravity_Disable() for _,contact in pairs( self.objects ) do self:Toogle_Prop_Gravity( contact , true ) end end function ENT:Slow_Prop( prop , yes_no ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetMoveType() == MOVETYPE_NONE then return false; end if prop:GetMoveType() == MOVETYPE_NOCLIP then return false; end //do this to prevent -uncliping- if prop:GetClass() != "player" && !gamemode.Call("PhysgunPickup",self.pl,prop) then return false; end local MulU=self.multiplier+15.1; if MulU < 15.1 then MulU=15.1; end if prop:GetMoveType() != MOVETYPE_VPHYSICS then if yes_no == false then if prop:IsNPC() || prop:IsPlayer() then if !prop:Alive() && prop:GetRagdollEntity() then local RagDoll=prop:GetRagdollEntity() for x=1,RagDoll:GetPhysicsObjectCount() do local part=RagDoll:GetPhysicsObjectNum(x) part:EnableGravity( yes_no ); part:SetDragCoefficient( 100 * self.multiplier ); end end prop:SetMoveType(MOVETYPE_FLY); prop:SetMoveCollide(MOVECOLLIDE_FLY_BOUNCE); else prop:SetGravity(0); end local Mul = -( 1 - 1 / ( MulU / 15 ) ); local vel = prop:GetVelocity(); if prop.AddVelocity then prop:AddVelocity( vel * Mul ); else prop:SetVelocity( vel * Mul ); end else if prop:IsNPC() || prop:IsPlayer() then if !prop:Alive() && prop:GetRagdollEntity() then local RagDoll=prop:GetRagdollEntity() for x=1,RagDoll:GetPhysicsObjectCount() do local part=RagDoll:GetPhysicsObjectNum(x) part:EnableGravity( yes_no ); part:SetDragCoefficient( 1 ); end end end if prop:IsPlayer() then prop:SetMoveCollide(MOVETYPE_WALK); prop:SetMoveCollide(MOVECOLLIDE_DEFAULT); elseif prop:IsNPC() then prop:SetMoveCollide(MOVETYPE_STEP); prop:SetMoveCollide(MOVECOLLIDE_DEFAULT); else prop:SetGravity(1); end end end if prop:GetPhysicsObjectCount() > 1 then for x=0,prop:GetPhysicsObjectCount()-1 do local part=prop:GetPhysicsObjectNum(x) part:EnableGravity( yes_no ); if ! yes_no then part:SetDragCoefficient( 100 * self.multiplier ); else part:SetDragCoefficient( 1 ); end end return false; end local phys=prop:GetPhysicsObject(); if ( !phys:IsValid() ) then return end phys:EnableGravity( yes_no ); if ! yes_no then phys:SetDragCoefficient( 100 * self.multiplier ); else phys:SetDragCoefficient( 1 ); end end function ENT:Static_Logic() local NewObjs={}; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do self:Slow_Prop( contact , false ); NewObjs[ contact:EntIndex() ] = contact; end for idx,contact in pairs( self.objects ) do if ( NewObjs[ idx ] != contact ) then self:Slow_Prop( contact , true ) end end self.objects = NewObjs; end function ENT:Static_Disable() for _,contact in pairs( self.objects ) do self:Slow_Prop( contact , true ) end end function ENT:PullPushProp( prop , vec ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetMoveType() == MOVETYPE_NONE then return false; end if prop:GetClass() != "player" && !gamemode.Call("PhysgunPickup",self.pl,prop) then return false; end if prop:GetMoveType() != MOVETYPE_VPHYSICS then if prop.AddVelocity then prop:AddVelocity( vec ); else prop:SetVelocity( vec ); end end if prop:GetPhysicsObjectCount() > 1 then for x=0,prop:GetPhysicsObjectCount()-1 do local part=prop:GetPhysicsObjectNum(x) part:AddVelocity( vec ); end return false; end local phys=prop:GetPhysicsObject(); if ( !phys:IsValid() ) then return end phys:AddVelocity( vec ); end function ENT:VelModProp( prop , mul ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetMoveType() == MOVETYPE_NONE then return false; end if prop:GetClass() != "player" && !gamemode.Call("PhysgunPickup",self.pl,prop) then return false; end if prop:GetMoveType() != MOVETYPE_VPHYSICS then if prop.AddVelocity then prop:AddVelocity( prop:GetVelocity():Normalize() * mul ); else prop:SetVelocity( prop:GetVelocity():Normalize() * mul); end end if prop:GetPhysicsObjectCount() > 1 then for x=0,prop:GetPhysicsObjectCount()-1 do local part=prop:GetPhysicsObjectNum(x) part:AddVelocity( part:GetVelocity():Normalize() * mul ); end return false; end local phys=prop:GetPhysicsObject(); if ( !phys:IsValid() ) then return end phys:AddVelocity( phys:GetVelocity():Normalize() * mul ); end function ENT:Pull_Logic() local Center=self:GetPos(); for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do local Path = Center-contact:GetPos(); local Length = Path:Length(); Path = Path * ( 1.0 / Length ) * math.sqrt(1-Length/self.prox) self:PullPushProp( contact , Path * self.multiplier ); end end function ENT:Pull_Disable() end function ENT:Push_Logic() local Center=self:GetPos(); local HalfProx=self.prox / 2; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do local Path = contact:GetPos()-Center; local Length = Path:Length(); Path = Path * ( 1.0 / Length ) self:PullPushProp( contact , Path * self.multiplier ); end end function ENT:Push_Logic() local Center=self:GetPos(); local HalfProx=self.prox / 2; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do local Path = contact:GetPos()-Center; local Length = Path:Length(); Path = Path * ( 1.0 / Length ) self:PullPushProp( contact , Path * self.multiplier ); end end function ENT:Push_Logic() local Center=self:GetPos(); local HalfProx=self.prox / 2; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do local Path = contact:GetPos()-Center; local Length = Path:Length(); Path = Path * ( 1.0 / Length ) self:PullPushProp( contact , Path * self.multiplier ); end end function ENT:Push_Disable() end function ENT:Wind_Logic() local Up = self.direction:Normalize(); for _,contact in pairs( self:GetEverythingInSphere( self:GetPos(), self.prox || 10 ) ) do self:PullPushProp( contact , Up * self.multiplier ); end end function ENT:Wind_Disable() end function ENT:GetEverythingInSphere( center , range ) local Objs=ents.FindInSphere( self:GetPos(), range ) if self.arc >= 0 && self.arc < 360 then local rgc=math.cos( (self.arc/360) * math.pi ); //decrease arc by half, 0-360 isntead of 0-180 local Tmp={} local upvec=self:GetUp(); local pos = self:GetPos(); for _,obj in pairs( Objs ) do if obj:GetMoveType() != MOVETYPE_NOCLIP then local dir = ( obj:GetPos() - pos ):Normalize(); if dir:Dot( upvec ) > rgc then table.insert( Tmp , obj ); end end end Objs=Tmp; else local Tmp={} local upvec=self:GetUp(); local pos = self:GetPos(); for _,obj in pairs( Objs ) do if obj:GetMoveType() != MOVETYPE_NOCLIP then table.insert( Tmp , obj ); end end Objs=Tmp; end return Objs; end function ENT:Vortex_Logic() local Up = self.direction:Normalize(); local Center=self:GetPos(); local HalfProx=self.prox / 2; for _,contact in pairs( self:GetEverythingInSphere( Center , self.prox || 10 ) ) do local Path = ( contact:GetPos()+contact:GetVelocity() )-Center; self:PullPushProp( contact , Path:Normalize():Cross( Up ) * self.multiplier ); end end function ENT:Vortex_Disable() end function ENT:Flame_Apply( prop , yes_no ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if prop:GetMoveType() == MOVETYPE_NONE then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetClass() != "player" && !gamemode.Call("PhysgunPickup",self.pl,prop) then return false; end if yes_no == true then prop:Ignite( self.multiplier , 0.0 ); else prop:Extinguish(); end end function ENT:Flame_Logic() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do self:Flame_Apply( contact , true ); end end function ENT:Flame_Disable() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do self:Flame_Apply( contact , false ); end end function ENT:Crush_Apply( prop , yes_no ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetClass() != "player" && !gamemode.Call( "PhysgunPickup", self.pl , prop ) then return false; end if yes_no == true then prop:TakeDamage( self.multiplier , self.pl ); end end function ENT:Battery_Apply( prop , yes_no ) local x,maxx; if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetClass() != "player" && !gamemode.Call( "PhysgunPickup", self.pl , prop ) then return false; end if prop.Armor then x=prop:Armor()+self.multiplier; maxx=100; // prop:GetMaxHealth(); if ( x > maxx ) then x=maxx; end prop:SetArmor( x ) end end function ENT:Health_Apply( prop , yes_no ) local x,maxx; if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetClass() != "player" && !gamemode.Call( "PhysgunPickup", self.pl , prop ) then return false; end if yes_no == true then x=prop:Health()+self.multiplier; maxx=prop:GetMaxHealth(); if ( x > maxx ) then x=maxx; end prop:SetHealth( x ) end end function ENT:Heal_Logic() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do if contact:IsNPC() || contact:IsPlayer() then self:Health_Apply( contact , true ); end end end function ENT:Heal_Disable() end function ENT:Death_Logic() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do if contact:IsNPC() || contact:IsPlayer() then self:Crush_Apply( contact , true )//cheat and use crushing effect, just do it on npcs/players tho. end end end function ENT:Death_Disable() end function ENT:Crush_Logic() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do self:Crush_Apply( contact , true ) end end function ENT:Crush_Disable() end function ENT:EMP_Apply( prop , yes_no ) if ( !prop:IsValid() ) then return end if ( self.ignore[ prop:EntIndex() ] == prop ) then return false; end if ( !self:is_true(self.workonplayers) && prop:GetClass() == "player" ) then return false; end if prop:GetClass() != "player" && !gamemode.Call( "PhysgunPickup", self.pl , prop ) then return false; end if (prop) and (prop.Inputs) and type(prop.Inputs) == 'table' then for k,v in pairs(prop.Inputs) do if EMP_IGNORE_INPUTS[ k ] != true then //Msg( k .. "\n" ); use to find out what inputs are bad to override. =D if v.Type == "NORMAL" then if (prop.TriggerInput) then if yes_no then prop:TriggerInput( k , prop.Inputs[ k ].Value + math.random() * ( self.multiplier * 2 ) - self.multiplier ) else prop:TriggerInput( k , prop.Inputs[ k ].Value ) end end elseif v.Type == "VECTOR" then if (prop.TriggerInput) then if yes_no then prop:TriggerInput( k , prop.Inputs[ k ].Value + Vector(math.random() * ( self.multiplier * 2 ) - self.multiplier,math.random() * ( self.multiplier * 2 ) - self.multiplier ,math.random() * ( self.multiplier * 2 ) - self.multiplier) ) else prop:TriggerInput( k , prop.Inputs[ k ].Value ) end end end end end end end function ENT:EMP_Logic() local NewObjs={}; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do self:EMP_Apply( contact , true ); NewObjs[ contact:EntIndex() ] = contact; end for idx,contact in pairs( self.objects ) do if ( NewObjs[ idx ] != contact ) then self:EMP_Apply( contact , false ) end end self.objects = NewObjs; end function ENT:EMP_Disable() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do self:EMP_Apply( contact , false ); end end function ENT:WakeUp( prop ) if prop != nil then if prop:GetMoveType() == MOVETYPE_VPHYSICS then if prop:GetPhysicsObjectCount() > 1 then for x=0,prop:GetPhysicsObjectCount()-1 do local part=prop:GetPhysicsObjectNum(x) part:Wake(); end return false; end local phys=prop:GetPhysicsObject(); if ( phys:IsValid() ) then phys:Wake(); end end end end function ENT:NoCollide_Logic() local myid; local obj; local Valid={}; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do myid=contact:EntIndex(); if ( self.ignore[ myid ] != contact ) then Valid[ myid ]=true; if self.objects[ myid ] == nil && contact.SetCollisionGroup && contact.GetCollisionGroup then self.objects[ myid ] = {}; self.objects[ myid ].old_group=contact:GetCollisionGroup(); self.objects[ myid ].obj=contact; contact:SetCollisionGroup( COLLISION_GROUP_WORLD ); self:WakeUp(contact); end end end for Idx,contact in pairs( self.objects ) do if true != Valid[ Idx ] && type(contact) == "table" then if ( contact.obj:IsValid() ) then contact.obj:SetCollisionGroup( contact.old_group ); self:WakeUp(contact.obj); end self.objects[Idx]=nil; end end end function ENT:NoCollide_Disable() for Idx,contact in pairs( self.objects ) do if type(contact) == "table" then if ( contact.obj:IsValid() ) then contact.obj:SetCollisionGroup( contact.old_group ); self:WakeUp(contact.obj); end end end self.objects={}; end function ENT:Battery_Logic() for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do if contact:IsNPC() || contact:IsPlayer() then self:Battery_Apply( contact , true ); end end end function ENT:Speed_Logic() local NewObjs={}; local doo=nil; for _,contact in pairs( self:GetEverythingInSphere( self:GetPos() , self.prox || 10 ) ) do if ( self.multiplier > 0 ) then self:VelModProp( contact , 1+self.multiplier ); elseif ( self.multiplier < 0 ) then self:VelModProp( contact , -1+self.multiplier ); end end end function ENT:Think() if self:is_true( self.ignoreself ) then self:BuildIgnoreList(); // ignore these guys... else self.ignore={} end if self.active != 0 then if self.Type == "Gravity" then self:Gravity_Logic(); elseif self.Type == "Hold" then self:Static_Logic(); elseif self.Type == "Pull" then self:Pull_Logic(); elseif self.Type == "Push" then self:Push_Logic(); elseif self.Type == "Wind" then self:Wind_Logic(); elseif self.Type == "Vortex" then self:Vortex_Logic(); elseif self.Type == "Flame" then self:Flame_Logic(); elseif self.Type == "Crush" then self:Crush_Logic(); elseif self.Type == "Death" then self:Death_Logic(); elseif self.Type == "Heal" then self:Heal_Logic(); elseif self.Type == "NoCollide" then self:NoCollide_Logic(); elseif self.Type == "Battery" then self:Battery_Logic(); elseif self.Type == "Speed" then self:Speed_Logic(); elseif self.Type == "EMP" then self:EMP_Logic(); end end self.BaseClass.Think(self) end function ENT:Disable() if self.Type == "Gravity" then self:Gravity_Disable(); elseif self.Type == "NoCollide" then self:NoCollide_Disable(); elseif self.Type == "Hold" then self:Static_Disable(); elseif self.Type == "Pull" then self:Pull_Disable(); elseif self.Type == "Push" then self:Push_Disable(); elseif self.Type == "Wind" then self:Wind_Disable(); elseif self.Type == "Vortex" then self:Vortex_Disable(); elseif self.Type == "Flame" then self:Flame_Disable(); elseif self.Type == "Crush" then self:Crush_Disable(); elseif self.Type == "Death" then self:Death_Disable(); elseif self.Type == "Heal" then self:Heal_Disable(); elseif self.Type == "EMP" then self:EMP_Disable(); end self.BaseClass.Think(self) end function ENT:OnRemove() self:Disable(); end