mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
138
lua/autorun/properties/bodygroups.lua
Normal file
138
lua/autorun/properties/bodygroups.lua
Normal file
@@ -0,0 +1,138 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "bodygroups", {
|
||||
MenuLabel = "#bodygroups",
|
||||
Order = 600,
|
||||
MenuIcon = "icon16/link_edit.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "bodygroups", ent ) ) then return false end
|
||||
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to use and modify its bodygroups instead
|
||||
|
||||
--
|
||||
-- Get a list of bodygroups
|
||||
--
|
||||
local options = ent:GetBodyGroups()
|
||||
if ( !options ) then return false end
|
||||
|
||||
--
|
||||
-- If a bodygroup has more than one state - then we can configure it
|
||||
--
|
||||
for k, v in pairs( options ) do
|
||||
if ( v.num > 1 ) then return true end
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end,
|
||||
|
||||
MenuOpen = function( self, option, ent, tr )
|
||||
|
||||
local target = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
|
||||
|
||||
--
|
||||
-- Get a list of bodygroups
|
||||
--
|
||||
local options = target:GetBodyGroups()
|
||||
|
||||
--
|
||||
-- Add a submenu to our automatically created menu option
|
||||
--
|
||||
local submenu = option:AddSubMenu()
|
||||
|
||||
--
|
||||
-- For each body group - add a menu or checkbox
|
||||
--
|
||||
for k, v in pairs( options ) do
|
||||
|
||||
if ( v.num <= 1 ) then continue end
|
||||
|
||||
--
|
||||
-- If there's only 2 options, add it as a checkbox instead of a submenu
|
||||
--
|
||||
if ( v.num == 2 ) then
|
||||
|
||||
local current = target:GetBodygroup( v.id )
|
||||
local opposite = 1
|
||||
if ( current == opposite ) then opposite = 0 end
|
||||
|
||||
local opt = submenu:AddOption( string.NiceName( v.name ) )
|
||||
opt:SetChecked( current == 1 )
|
||||
opt:SetIsCheckable( true )
|
||||
opt.OnChecked = function( s, checked ) self:SetBodyGroup( ent, v.id, checked and 1 or 0 ) end
|
||||
|
||||
--
|
||||
-- More than 2 options we add our own submenu
|
||||
--
|
||||
else
|
||||
|
||||
local groups = submenu:AddSubMenu( string.NiceName( v.name ) )
|
||||
|
||||
for i = 1, v.num do
|
||||
local modelname = "Model #" .. i
|
||||
if ( v.submodels and v.submodels[ i - 1 ] != "" ) then modelname = v.submodels[ i - 1 ] end
|
||||
modelname = string.Trim( modelname, "." )
|
||||
modelname = string.Trim( modelname, "/" )
|
||||
modelname = string.Trim( modelname, "\\" )
|
||||
modelname = string.StripExtension( modelname )
|
||||
modelname = string.GetFileFromFilename( modelname )
|
||||
|
||||
local opt = groups:AddOption( string.NiceName( modelname ) )
|
||||
opt:SetRadio( true )
|
||||
opt:SetChecked( target:GetBodygroup( v.id ) == i - 1 )
|
||||
opt:SetIsCheckable( true )
|
||||
opt.OnChecked = function( s, checked ) if ( checked ) then self:SetBodyGroup( ent, v.id, i - 1 ) end end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
-- Nothing - we use SetBodyGroup below
|
||||
|
||||
end,
|
||||
|
||||
SetBodyGroup = function( self, ent, body, id )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
net.WriteUInt( body, 8 )
|
||||
net.WriteUInt( id, 8 )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
local body = net.ReadUInt( 8 )
|
||||
local id = net.ReadUInt( 8 )
|
||||
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
|
||||
|
||||
ent:SetBodygroup( body, id )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
236
lua/autorun/properties/bone_manipulate.lua
Normal file
236
lua/autorun/properties/bone_manipulate.lua
Normal file
@@ -0,0 +1,236 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "bone_manipulate", {
|
||||
MenuLabel = "#edit_bones",
|
||||
Order = 500,
|
||||
MenuIcon = "icon16/vector.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !gamemode.Call( "CanProperty", ply, "bonemanipulate", ent ) ) then return false end
|
||||
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to use and modify its bones instead
|
||||
|
||||
local bonecount = ent:GetBoneCount()
|
||||
if ( bonecount <= 1 ) then return false end
|
||||
|
||||
return ents.FindByClassAndParent( "widget_bones", ent ) == nil
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent.widget = ents.Create( "widget_bones" )
|
||||
ent.widget:Setup( ent )
|
||||
ent.widget:Spawn()
|
||||
ent.widget.LastBonePress = 0
|
||||
ent.widget.BonePressCount = 0
|
||||
|
||||
-- What happens when we click on a bone?
|
||||
ent.widget.OnBoneClick = function( w, boneid, pl )
|
||||
|
||||
-- If we have an old axis, remove it
|
||||
if ( IsValid( w.axis ) ) then w.axis:Remove() end
|
||||
|
||||
-- We clicked on the same bone
|
||||
if ( w.LastBonePress == boneid ) then
|
||||
w.BonePressCount = w.BonePressCount + 1
|
||||
if ( w.BonePressCount >= 3 ) then w.BonePressCount = 0 end
|
||||
-- We clicked on a new bone!
|
||||
else
|
||||
w.BonePressCount = 0
|
||||
w.LastBonePress = boneid
|
||||
end
|
||||
|
||||
local EntityCycle = { "widget_bonemanip_move", "widget_bonemanip_rotate", "widget_bonemanip_scale" }
|
||||
|
||||
w.axis = ents.Create( EntityCycle[ w.BonePressCount + 1 ] )
|
||||
w.axis:Setup( ent, boneid, w.BonePressCount == 1 )
|
||||
w.axis:Spawn()
|
||||
w.axis:SetPriority( 0.5 )
|
||||
w:DeleteOnRemove( w.axis )
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "bone_manipulate_end", {
|
||||
MenuLabel = "#stop_editing_bones",
|
||||
Order = 500,
|
||||
MenuIcon = "icon16/vector_delete.png",
|
||||
|
||||
Filter = function( self, ent )
|
||||
|
||||
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to use and modify its bones instead
|
||||
|
||||
return ents.FindByClassAndParent( "widget_bones", ent ) != nil
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !IsValid( ent.widget ) ) then return end
|
||||
|
||||
ent.widget:Remove()
|
||||
|
||||
end
|
||||
} )
|
||||
|
||||
local widget_bonemanip_move = {
|
||||
Base = "widget_axis",
|
||||
|
||||
OnArrowDragged = function( self, num, dist, pl, mv )
|
||||
|
||||
-- Prediction doesn't work properly yet.. because of the confusion with the bone moving, and the parenting, Agh.
|
||||
if ( CLIENT ) then return end
|
||||
|
||||
local ent = self:GetParent()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
local bone = self:GetParentAttachment()
|
||||
if ( bone <= 0 ) then return end
|
||||
|
||||
local v = Vector( 0, 0, 0 )
|
||||
|
||||
if ( num == 1 ) then v.x = dist end
|
||||
if ( num == 2 ) then v.y = dist end
|
||||
if ( num == 3 ) then v.z = dist end
|
||||
|
||||
ent:ManipulateBonePosition( bone, ent:GetManipulateBonePosition( bone ) + v )
|
||||
|
||||
end,
|
||||
|
||||
--
|
||||
-- Although we use the position from our bone, we want to use the angles from the
|
||||
-- parent bone - because that's the direction our bone goes
|
||||
--
|
||||
CalcAbsolutePosition = function( self, v, a )
|
||||
|
||||
local ent = self:GetParent()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
local bone = ent:GetBoneParent( self:GetParentAttachment() )
|
||||
if ( bone <= 0 ) then return end
|
||||
|
||||
local _, ang = ent:GetBonePosition( bone )
|
||||
local pos, _ = ent:GetBonePosition( self:GetParentAttachment() )
|
||||
return pos, ang
|
||||
|
||||
end
|
||||
}
|
||||
|
||||
scripted_ents.Register( widget_bonemanip_move, "widget_bonemanip_move" )
|
||||
|
||||
local widget_bonemanip_rotate = {
|
||||
Base = "widget_axis",
|
||||
|
||||
OnArrowDragged = function( self, num, dist, pl, mv )
|
||||
|
||||
-- Prediction doesn't work properly yet.. because of the confusion with the bone moving, and the parenting, Agh.
|
||||
if ( CLIENT ) then return end
|
||||
|
||||
local ent = self:GetParent()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
local bone = self:GetParentAttachment()
|
||||
if ( bone <= 0 ) then return end
|
||||
|
||||
local v = Angle( 0, 0, 0 )
|
||||
|
||||
if ( num == 2 ) then v.x = dist end
|
||||
if ( num == 3 ) then v.y = dist end
|
||||
if ( num == 1 ) then v.z = dist end
|
||||
|
||||
ent:ManipulateBoneAngles( bone, ent:GetManipulateBoneAngles( bone ) + v )
|
||||
|
||||
end
|
||||
}
|
||||
scripted_ents.Register( widget_bonemanip_rotate, "widget_bonemanip_rotate" )
|
||||
|
||||
local widget_bonemanip_scale = {
|
||||
Base = "widget_axis",
|
||||
IsScaleArrow = true,
|
||||
|
||||
OnArrowDragged = function( self, num, dist, pl, mv )
|
||||
|
||||
-- Prediction doesn't work properly yet.. because of the confusion with the bone moving, and the parenting, Agh.
|
||||
if ( CLIENT ) then return end
|
||||
|
||||
local ent = self:GetParent()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
local bone = self:GetParentAttachment()
|
||||
if ( bone <= 0 ) then return end
|
||||
|
||||
local v = Vector( 0, 0, 0 )
|
||||
|
||||
if ( num == 1 ) then v.x = dist end
|
||||
if ( num == 2 ) then v.y = dist end
|
||||
if ( num == 3 ) then v.z = dist end
|
||||
|
||||
ent:ManipulateBoneScale( bone, ent:GetManipulateBoneScale( bone ) + v * 0.1 )
|
||||
ent:ManipulateBoneScale( ent:GetBoneParent( bone ), ent:GetManipulateBoneScale( ent:GetBoneParent( bone ) ) + v )
|
||||
|
||||
end,
|
||||
|
||||
--
|
||||
-- Although we use the position from our bone, we want to use the angles from the
|
||||
-- parent bone - because that's the direction our bone goes
|
||||
--
|
||||
CalcAbsolutePosition = function( self, v, a )
|
||||
|
||||
local ent = self:GetParent()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
local bone = self:GetParentAttachment()
|
||||
if ( bone <= 0 ) then return end
|
||||
|
||||
local pbone = ent:GetBoneParent( bone )
|
||||
if ( pbone <= 0 ) then return end
|
||||
|
||||
local pos, ang = ent:GetBonePosition( bone )
|
||||
local pos2, _ = ent:GetBonePosition( pbone )
|
||||
|
||||
return pos + ( pos2 - pos ) * 0.5, ang
|
||||
|
||||
end
|
||||
}
|
||||
scripted_ents.Register( widget_bonemanip_scale, "widget_bonemanip_scale" )
|
||||
83
lua/autorun/properties/collisions.lua
Normal file
83
lua/autorun/properties/collisions.lua
Normal file
@@ -0,0 +1,83 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "collision_off", {
|
||||
MenuLabel = "#collision_off",
|
||||
Order = 1500,
|
||||
MenuIcon = "icon16/collision_off.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "collision", ent ) ) then return false end
|
||||
if ( ent:GetCollisionGroup() == COLLISION_GROUP_WORLD ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent:SetCollisionGroup( COLLISION_GROUP_WORLD )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "collision_on", {
|
||||
MenuLabel = "#collision_on",
|
||||
Order = 1500,
|
||||
MenuIcon = "icon16/collision_on.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "collision", ent ) ) then return false end
|
||||
|
||||
return ent:GetCollisionGroup() == COLLISION_GROUP_WORLD
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent:SetCollisionGroup( COLLISION_GROUP_NONE )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
62
lua/autorun/properties/drive.lua
Normal file
62
lua/autorun/properties/drive.lua
Normal file
@@ -0,0 +1,62 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "drive", {
|
||||
MenuLabel = "#drive",
|
||||
Order = 1100,
|
||||
MenuIcon = "icon16/joystick.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) || !IsValid( ply ) ) then return false end
|
||||
if ( ent:IsPlayer() || IsValid( ply:GetVehicle() ) ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "drive", ent ) ) then return false end
|
||||
if ( !gamemode.Call( "CanDrive", ply, ent ) ) then return false end
|
||||
|
||||
-- We cannot drive these, maybe this should have a custom GetEntityDriveMode?
|
||||
if ( ent:GetClass() == "prop_vehicle_jeep" || ent:GetClass() == "prop_vehicle_jeep_old" ) then return false end
|
||||
|
||||
-- Make sure nobody else is driving this or we can get into really invalid states
|
||||
for id, pl in ipairs( player.GetAll() ) do
|
||||
if ( pl:GetDrivingEntity() == ent ) then return false end
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
local drivemode = "drive_sandbox"
|
||||
|
||||
if ( ent.GetEntityDriveMode ) then
|
||||
drivemode = ent:GetEntityDriveMode( ply )
|
||||
end
|
||||
|
||||
drive.PlayerStartDriving( ply, ent, drivemode )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
48
lua/autorun/properties/editentity.lua
Normal file
48
lua/autorun/properties/editentity.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "editentity", {
|
||||
MenuLabel = "#entedit",
|
||||
Order = 90001,
|
||||
PrependSpacer = true,
|
||||
MenuIcon = "icon16/pencil.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( !ent.Editable ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "editentity", ent ) ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
local window = g_ContextMenu:Add( "DFrame" )
|
||||
window:SetSize( 320, 400 )
|
||||
window:SetTitle( tostring( ent ) )
|
||||
window:Center()
|
||||
window:SetSizable( true )
|
||||
|
||||
local control = window:Add( "DEntityProperties" )
|
||||
control:SetEntity( ent )
|
||||
control:Dock( FILL )
|
||||
|
||||
control.OnEntityLost = function()
|
||||
|
||||
window:Remove()
|
||||
|
||||
end
|
||||
end
|
||||
} )
|
||||
92
lua/autorun/properties/gravity.lua
Normal file
92
lua/autorun/properties/gravity.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
-- The following is for the server's eyes only
|
||||
local GravityDuplicator
|
||||
if ( SERVER ) then
|
||||
function GravityDuplicator( ply, ent, data )
|
||||
|
||||
if ( !data || !data.enabled ) then
|
||||
|
||||
duplicator.ClearEntityModifier( ent, "gravity_property" )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
-- Simply restore the value whenever we are duplicated
|
||||
-- We don't need to reapply EnableGravity because duplicator already does it for us
|
||||
ent:SetNWBool( "gravity_disabled", data.enabled )
|
||||
|
||||
duplicator.StoreEntityModifier( ent, "gravity_property", data )
|
||||
|
||||
end
|
||||
duplicator.RegisterEntityModifier( "gravity_property", GravityDuplicator )
|
||||
end
|
||||
|
||||
properties.Add( "gravity", {
|
||||
MenuLabel = "#gravity",
|
||||
Type = "toggle",
|
||||
Order = 1001,
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "gravity", ent ) ) then return false end
|
||||
|
||||
if ( ent:GetClass() == "prop_physics" ) then return true end
|
||||
if ( ent:GetClass() == "prop_ragdoll" ) then return true end
|
||||
|
||||
return false
|
||||
|
||||
end,
|
||||
|
||||
Checked = function( self, ent, ply )
|
||||
|
||||
return ent:GetNWBool( "gravity_disabled" ) == false
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
local bones = ent:GetPhysicsObjectCount()
|
||||
local b = ent:GetNWBool( "gravity_disabled" )
|
||||
|
||||
for i = 0, bones - 1 do
|
||||
|
||||
local phys = ent:GetPhysicsObjectNum( i )
|
||||
if ( IsValid( phys ) ) then
|
||||
phys:EnableGravity( b )
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ent:SetNWBool( "gravity_disabled", b == false )
|
||||
|
||||
GravityDuplicator( ply, ent, { enabled = ent:GetNWBool( "gravity_disabled" ) } )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
96
lua/autorun/properties/ignite.lua
Normal file
96
lua/autorun/properties/ignite.lua
Normal file
@@ -0,0 +1,96 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
local function CanEntityBeSetOnFire( ent )
|
||||
|
||||
-- func_pushable, func_breakable & func_physbox cannot be ignited
|
||||
if ( ent:GetClass() == "item_item_crate" ) then return true end
|
||||
if ( ent:GetClass() == "simple_physics_prop" ) then return true end
|
||||
if ( ent:GetClass():match( "prop_physics*" ) ) then return true end
|
||||
if ( ent:GetClass():match( "prop_ragdoll*" ) ) then return true end
|
||||
if ( ent:IsNPC() ) then return true end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
properties.Add( "ignite", {
|
||||
MenuLabel = "#ignite",
|
||||
Order = 999,
|
||||
MenuIcon = "icon16/fire.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( !CanEntityBeSetOnFire( ent ) ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "ignite", ent ) ) then return false end
|
||||
|
||||
return !ent:IsOnFire()
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent:Ignite( 360 )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "extinguish", {
|
||||
MenuLabel = "#extinguish",
|
||||
Order = 999,
|
||||
MenuIcon = "icon16/water.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "extinguish", ent ) ) then return false end
|
||||
|
||||
return ent:IsOnFire()
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent:Extinguish()
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
107
lua/autorun/properties/keep_upright.lua
Normal file
107
lua/autorun/properties/keep_upright.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "keepupright", {
|
||||
MenuLabel = "#keepupright",
|
||||
Order = 900,
|
||||
MenuIcon = "icon16/arrow_up.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:GetClass() != "prop_physics" ) then return false end
|
||||
if ( ent:GetNWBool( "IsUpright" ) ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "keepupright", ent ) ) then return false end
|
||||
|
||||
return true
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( ent:GetClass() != "prop_physics" ) then return end
|
||||
if ( ent:GetNWBool( "IsUpright" ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
local Phys = ent:GetPhysicsObjectNum( 0 )
|
||||
if ( !IsValid( Phys ) ) then return end
|
||||
|
||||
local constraint = constraint.Keepupright( ent, Phys:GetAngles(), 0, 999999 )
|
||||
|
||||
-- I feel like this is not stable enough
|
||||
-- This cannot be implemented without a custom constraint.Keepupright function or modification for proper duplicator support.
|
||||
--print( constraint:GetSaveTable().m_worldGoalAxis )
|
||||
--constraint:SetSaveValue( "m_localTestAxis", constraint:GetSaveTable().m_worldGoalAxis ) --ent:GetAngles():Up() )
|
||||
--constraint:SetSaveValue( "m_worldGoalAxis", Vector( 0, 0, 1 ) )
|
||||
--constraint:SetSaveValue( "m_bDampAllRotation", true )
|
||||
|
||||
if ( constraint ) then
|
||||
|
||||
ply:AddCleanup( "constraints", constraint )
|
||||
ent:SetNWBool( "IsUpright", true )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "keepupright_stop", {
|
||||
MenuLabel = "#keepupright_stop",
|
||||
Order = 900,
|
||||
MenuIcon = "icon16/arrow_rotate_clockwise.png",
|
||||
|
||||
Filter = function( self, ent )
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:GetClass() != "prop_physics" ) then return false end
|
||||
if ( !ent:GetNWBool( "IsUpright" ) ) then return false end
|
||||
return true
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( ent:GetClass() != "prop_physics" ) then return end
|
||||
if ( !ent:GetNWBool( "IsUpright" ) ) then return end
|
||||
|
||||
constraint.RemoveConstraints( ent, "Keepupright" )
|
||||
|
||||
ent:SetNWBool( "IsUpright", false )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
91
lua/autorun/properties/kinect_controller.lua
Normal file
91
lua/autorun/properties/kinect_controller.lua
Normal file
@@ -0,0 +1,91 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
CreateConVar( "sensor_debugragdoll", "0", FCVAR_NOTIFY )
|
||||
CreateConVar( "sensor_stretchragdoll", "0", FCVAR_NOTIFY )
|
||||
|
||||
end
|
||||
|
||||
local playerTimeouts = {}
|
||||
|
||||
properties.Add( "motioncontrol_ragdoll", {
|
||||
MenuLabel = "#control_with_motion_sensor",
|
||||
Order = 2500,
|
||||
MenuIcon = "icon16/controller.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( CLIENT && !motionsensor ) then return false end
|
||||
if ( CLIENT && !motionsensor.IsAvailable() ) then return false end
|
||||
if ( !ent:IsRagdoll() ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "motioncontrol_ragdoll", ent ) ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
--
|
||||
-- Start up the kinect controller. This will freeze the game for a second.
|
||||
--
|
||||
if ( !motionsensor.IsActive() ) then
|
||||
motionsensor.Start()
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, player )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !self:Filter( ent, player ) ) then return end
|
||||
|
||||
-- Do not spam please!
|
||||
local timeout = playerTimeouts[ player ]
|
||||
if ( timeout && timeout.time > CurTime() ) then
|
||||
if ( !timeout.sentMessage ) then
|
||||
ServerLog( "Player " .. tostring( player ) .. " tried to use 'motioncontrol_ragdoll' property too rapidly!\n" )
|
||||
player:PrintMessage( HUD_PRINTTALK, "Please wait at least 0.2 seconds before trying to control another ragdoll." )
|
||||
timeout.sentMessage = true
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Only 1 controller per ragdoll please!
|
||||
if ( IsValid( ent.MotionSensorController ) ) then
|
||||
ent.MotionSensorController:Remove()
|
||||
end
|
||||
|
||||
local ragdoll_motion = ents.Create( "ragdoll_motion" )
|
||||
ragdoll_motion:SetPos( player:EyePos() + player:EyeAngles():Forward() * 10 )
|
||||
ragdoll_motion:SetAngles( Angle( 0, player:EyeAngles().yaw, 0 ) )
|
||||
ragdoll_motion:SetRagdoll( ent )
|
||||
ragdoll_motion:SetController( player )
|
||||
ragdoll_motion:Spawn()
|
||||
|
||||
undo.Create( "MotionController" )
|
||||
undo.AddEntity( ragdoll_motion )
|
||||
undo.SetPlayer( player )
|
||||
undo.Finish()
|
||||
|
||||
playerTimeouts[ player ] = { time = CurTime() + 0.2, sentMessage = false }
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
82
lua/autorun/properties/npc_scale.lua
Normal file
82
lua/autorun/properties/npc_scale.lua
Normal file
@@ -0,0 +1,82 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "npc_bigger", {
|
||||
MenuLabel = "#biggify",
|
||||
Order = 1799,
|
||||
MenuIcon = "icon16/magnifier_zoom_in.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !gamemode.Call( "CanProperty", ply, "npc_bigger", ent ) ) then return false end
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( !ent:IsNPC() ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent:SetModelScale( ent:GetModelScale() * 1.25, 1 )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "npc_smaller", {
|
||||
MenuLabel = "#smallify",
|
||||
Order = 1800,
|
||||
MenuIcon = "icon16/magifier_zoom_out.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !gamemode.Call( "CanProperty", ply, "npc_smaller", ent ) ) then return false end
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( !ent:IsNPC() ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent:SetModelScale( ent:GetModelScale() * 0.8, 1 )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
89
lua/autorun/properties/persist.lua
Normal file
89
lua/autorun/properties/persist.lua
Normal file
@@ -0,0 +1,89 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "persist", {
|
||||
MenuLabel = "#makepersistent",
|
||||
Order = 400,
|
||||
MenuIcon = "icon16/link.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( GetConVarString( "sbox_persist" ):Trim() == "" ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "persist", ent ) ) then return false end
|
||||
|
||||
return !ent:GetPersistent()
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
-- TODO: Start some kind of animation, take 5 seconds to make something persistent
|
||||
|
||||
ent:SetPersistent( true )
|
||||
--ent:EnableMotion( false )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "persist_end", {
|
||||
MenuLabel = "#stoppersisting",
|
||||
Order = 400,
|
||||
MenuIcon = "icon16/link_break.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( GetConVarString( "sbox_persist" ):Trim() == "" ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "persist", ent ) ) then return false end
|
||||
|
||||
return ent:GetPersistent()
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
-- TODO: Start some kind of animation, take 5 seconds to make something persistent
|
||||
|
||||
ent:SetPersistent( false )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
67
lua/autorun/properties/remove.lua
Normal file
67
lua/autorun/properties/remove.lua
Normal file
@@ -0,0 +1,67 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "remove", {
|
||||
MenuLabel = "#remove",
|
||||
Order = 1000,
|
||||
MenuIcon = "icon16/delete.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !gamemode.Call( "CanProperty", ply, "remover", ent ) ) then return false end
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
|
||||
return true
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
-- Don't allow removal of players or objects that cannot be physically targeted by properties
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
-- Remove all constraints (this stops ropes from hanging around)
|
||||
constraint.RemoveAll( ent )
|
||||
|
||||
-- Remove it properly in 1 second
|
||||
timer.Simple( 1, function() if ( IsValid( ent ) ) then ent:Remove() end end )
|
||||
|
||||
-- Make it non solid
|
||||
ent:SetNotSolid( true )
|
||||
ent:SetMoveType( MOVETYPE_NONE )
|
||||
ent:SetNoDraw( true )
|
||||
|
||||
-- Send Effect
|
||||
local ed = EffectData()
|
||||
ed:SetEntity( ent )
|
||||
util.Effect( "entity_remove", ed, true, true )
|
||||
|
||||
ply:SendLua( "achievements.Remover()" )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
85
lua/autorun/properties/skin.lua
Normal file
85
lua/autorun/properties/skin.lua
Normal file
@@ -0,0 +1,85 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
properties.Add( "skin", {
|
||||
MenuLabel = "#skin",
|
||||
Order = 601,
|
||||
MenuIcon = "icon16/picture_edit.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:IsPlayer() ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "skin", ent ) ) then return false end
|
||||
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to modify its skin instead
|
||||
if ( !ent:SkinCount() ) then return false end
|
||||
|
||||
return ent:SkinCount() > 1
|
||||
|
||||
end,
|
||||
|
||||
MenuOpen = function( self, option, ent, tr )
|
||||
|
||||
--
|
||||
-- Add a submenu to our automatically created menu option
|
||||
--
|
||||
local submenu = option:AddSubMenu()
|
||||
|
||||
--
|
||||
-- Create a check item for each skin
|
||||
--
|
||||
local target = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
|
||||
|
||||
local num = target:SkinCount()
|
||||
|
||||
for i = 0, num - 1 do
|
||||
|
||||
local opt = submenu:AddOption( "Skin " .. i )
|
||||
opt:SetRadio( true )
|
||||
opt:SetChecked( target:GetSkin() == i )
|
||||
opt:SetIsCheckable( true )
|
||||
opt.OnChecked = function( s, checked ) if ( checked ) then self:SetSkin( ent, i ) end end
|
||||
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
-- Nothing - we use SetSkin below
|
||||
|
||||
end,
|
||||
|
||||
SetSkin = function( self, ent, id )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
net.WriteUInt( id, 8 )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
local skinid = net.ReadUInt( 8 )
|
||||
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
ent = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
|
||||
ent:SetSkin( skinid )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
202
lua/autorun/properties/statue.lua
Normal file
202
lua/autorun/properties/statue.lua
Normal file
@@ -0,0 +1,202 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
-- The following is for the server's eyes only
|
||||
local StatueDuplicator
|
||||
if ( SERVER ) then
|
||||
|
||||
function StatueDuplicator( ply, ent, data )
|
||||
|
||||
if ( !data ) then
|
||||
|
||||
duplicator.ClearEntityModifier( ent, "statue_property" )
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
-- We have been pasted from duplicator, restore the necessary variables for the unstatue to work
|
||||
if ( ent.StatueInfo == nil ) then
|
||||
|
||||
-- Ew. Have to wait a frame for the constraints to get pasted
|
||||
timer.Simple( 0, function()
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
|
||||
local bones = ent:GetPhysicsObjectCount()
|
||||
if ( bones < 2 ) then return end
|
||||
|
||||
ent:SetNWBool( "IsStatue", true )
|
||||
ent.StatueInfo = {}
|
||||
|
||||
local con = constraint.FindConstraints( ent, "Weld" )
|
||||
for id, t in pairs( con ) do
|
||||
if ( t.Ent1 != t.Ent2 || t.Ent1 != ent || t.Bone1 != 0 ) then continue end
|
||||
|
||||
ent.StatueInfo[ t.Bone2 ] = t.Constraint
|
||||
end
|
||||
|
||||
local numC = table.Count( ent.StatueInfo )
|
||||
if ( numC < 1 --[[or numC != bones - 1]] ) then duplicator.ClearEntityModifier( ent, "statue_property" ) end
|
||||
end )
|
||||
end
|
||||
|
||||
duplicator.StoreEntityModifier( ent, "statue_property", data )
|
||||
|
||||
end
|
||||
duplicator.RegisterEntityModifier( "statue_property", StatueDuplicator )
|
||||
|
||||
end
|
||||
|
||||
local playerTimeouts = {}
|
||||
|
||||
properties.Add( "statue", {
|
||||
MenuLabel = "#makestatue",
|
||||
Order = 1501,
|
||||
MenuIcon = "icon16/lock.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:GetClass() != "prop_ragdoll" ) then return false end
|
||||
if ( ent:GetNWBool( "IsStatue" ) ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "statue", ent ) ) then return false end
|
||||
return true
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( ent:GetClass() != "prop_ragdoll" ) then return end
|
||||
if ( !self:Filter( ent, ply ) ) then return end
|
||||
|
||||
-- Do not spam please!
|
||||
local timeout = playerTimeouts[ ply ]
|
||||
if ( timeout && timeout.time > CurTime() ) then
|
||||
if ( !timeout.sentMessage ) then
|
||||
ServerLog( "Player " .. tostring( ply ) .. " tried to use 'statue' property too rapidly!\n" )
|
||||
ply:PrintMessage( HUD_PRINTTALK, "Please wait at least 0.2 seconds before trying to make another ragdoll a statue." )
|
||||
timeout.sentMessage = true
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local bones = ent:GetPhysicsObjectCount()
|
||||
if ( bones < 2 ) then return end
|
||||
if ( ent.StatueInfo ) then return end
|
||||
|
||||
ent.StatueInfo = {}
|
||||
|
||||
undo.Create( "Statue" )
|
||||
|
||||
for bone = 1, bones - 1 do
|
||||
|
||||
local constr = constraint.Weld( ent, ent, 0, bone, 0 )
|
||||
|
||||
if ( constr ) then
|
||||
|
||||
ent.StatueInfo[ bone ] = constr
|
||||
ply:AddCleanup( "constraints", constr )
|
||||
undo.AddEntity( constr )
|
||||
|
||||
end
|
||||
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( ent:GetPhysicsObjectNum( bone ):GetPos() )
|
||||
effectdata:SetScale( 1 )
|
||||
effectdata:SetMagnitude( 1 )
|
||||
util.Effect( "GlassImpact", effectdata, true, true )
|
||||
|
||||
end
|
||||
|
||||
ent:SetNWBool( "IsStatue", true )
|
||||
|
||||
undo.AddFunction( function()
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
|
||||
ent:SetNWBool( "IsStatue", false )
|
||||
ent.StatueInfo = nil
|
||||
StatueDuplicator( ply, ent, nil )
|
||||
|
||||
end )
|
||||
|
||||
undo.SetPlayer( ply )
|
||||
undo.Finish()
|
||||
|
||||
StatueDuplicator( ply, ent, {} )
|
||||
|
||||
playerTimeouts[ ply ] = { time = CurTime() + 0.2, sentMessage = false }
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
|
||||
properties.Add( "statue_stop", {
|
||||
MenuLabel = "#unstatue",
|
||||
Order = 1501,
|
||||
MenuIcon = "icon16/lock_open.png",
|
||||
|
||||
Filter = function( self, ent, ply )
|
||||
if ( !IsValid( ent ) ) then return false end
|
||||
if ( ent:GetClass() != "prop_ragdoll" ) then return false end
|
||||
if ( !ent:GetNWBool( "IsStatue" ) ) then return false end
|
||||
if ( !gamemode.Call( "CanProperty", ply, "unstatue", ent ) ) then return false end
|
||||
return true
|
||||
end,
|
||||
|
||||
Action = function( self, ent )
|
||||
|
||||
self:MsgStart()
|
||||
net.WriteEntity( ent )
|
||||
self:MsgEnd()
|
||||
|
||||
end,
|
||||
|
||||
Receive = function( self, length, ply )
|
||||
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if ( !IsValid( ent ) ) then return end
|
||||
if ( !IsValid( ply ) ) then return end
|
||||
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
|
||||
if ( ent:GetClass() != "prop_ragdoll" ) then return end
|
||||
|
||||
local bones = ent:GetPhysicsObjectCount()
|
||||
if ( bones < 2 ) then return end
|
||||
if ( !ent.StatueInfo ) then return end
|
||||
|
||||
for k, v in pairs( ent.StatueInfo ) do
|
||||
|
||||
if ( IsValid( v ) ) then
|
||||
v:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ent:SetNWBool( "IsStatue", false )
|
||||
ent.StatueInfo = nil
|
||||
|
||||
StatueDuplicator( ply, ent, nil )
|
||||
|
||||
end
|
||||
|
||||
} )
|
||||
Reference in New Issue
Block a user