mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
include( "duplicator/transport.lua" )
|
||||
include( "duplicator/arming.lua" )
|
||||
|
||||
if ( CLIENT ) then
|
||||
|
||||
include( "duplicator/icon.lua" )
|
||||
|
||||
else
|
||||
|
||||
AddCSLuaFile( "duplicator/arming.lua" )
|
||||
AddCSLuaFile( "duplicator/transport.lua" )
|
||||
AddCSLuaFile( "duplicator/icon.lua" )
|
||||
util.AddNetworkString( "CopiedDupe" )
|
||||
|
||||
end
|
||||
|
||||
TOOL.Category = "Construction"
|
||||
TOOL.Name = "#tool.duplicator.name"
|
||||
|
||||
TOOL.Information = {
|
||||
{ name = "left" },
|
||||
{ name = "right" }
|
||||
}
|
||||
|
||||
cleanup.Register( "duplicates" )
|
||||
|
||||
--
|
||||
-- PASTE
|
||||
--
|
||||
function TOOL:LeftClick( trace )
|
||||
|
||||
if ( CLIENT ) then return true end
|
||||
|
||||
--
|
||||
-- Get the copied dupe. We store it on the player so it will still exist if they die and respawn.
|
||||
--
|
||||
local dupe = self:GetOwner().CurrentDupe
|
||||
if ( !dupe ) then return false end
|
||||
|
||||
--
|
||||
-- We want to spawn it flush on thr ground. So get the point that we hit
|
||||
-- and take away the mins.z of the bounding box of the dupe.
|
||||
--
|
||||
local SpawnCenter = trace.HitPos
|
||||
SpawnCenter.z = SpawnCenter.z - dupe.Mins.z
|
||||
|
||||
--
|
||||
-- Spawn it rotated with the player - but not pitch.
|
||||
--
|
||||
local SpawnAngle = self:GetOwner():EyeAngles()
|
||||
SpawnAngle.pitch = 0
|
||||
SpawnAngle.roll = 0
|
||||
|
||||
--
|
||||
-- Spawn them all at our chosen positions
|
||||
--
|
||||
duplicator.SetLocalPos( SpawnCenter )
|
||||
duplicator.SetLocalAng( SpawnAngle )
|
||||
|
||||
DisablePropCreateEffect = true
|
||||
|
||||
local Ents = duplicator.Paste( self:GetOwner(), dupe.Entities, dupe.Constraints )
|
||||
|
||||
DisablePropCreateEffect = nil
|
||||
|
||||
duplicator.SetLocalPos( vector_origin )
|
||||
duplicator.SetLocalAng( angle_zero )
|
||||
|
||||
--
|
||||
-- Create one undo for the whole creation
|
||||
--
|
||||
undo.Create( "Duplicator" )
|
||||
|
||||
for k, ent in pairs( Ents ) do
|
||||
undo.AddEntity( ent )
|
||||
end
|
||||
|
||||
for k, ent in pairs( Ents ) do
|
||||
self:GetOwner():AddCleanup( "duplicates", ent )
|
||||
end
|
||||
|
||||
undo.SetPlayer( self:GetOwner() )
|
||||
|
||||
undo.Finish()
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Copy
|
||||
--
|
||||
function TOOL:RightClick( trace )
|
||||
|
||||
if ( !IsValid( trace.Entity ) ) then return false end
|
||||
if ( CLIENT ) then return true end
|
||||
|
||||
--
|
||||
-- Set the position to our local position (so we can paste relative to our `hold`)
|
||||
--
|
||||
duplicator.SetLocalPos( trace.HitPos )
|
||||
duplicator.SetLocalAng( Angle( 0, self:GetOwner():EyeAngles().yaw, 0 ) )
|
||||
|
||||
local Dupe = duplicator.Copy( trace.Entity )
|
||||
|
||||
duplicator.SetLocalPos( vector_origin )
|
||||
duplicator.SetLocalAng( angle_zero )
|
||||
|
||||
if ( !Dupe ) then return false end
|
||||
|
||||
--
|
||||
-- Tell the clientside that they're holding something new
|
||||
--
|
||||
net.Start( "CopiedDupe" )
|
||||
net.WriteUInt( 1, 1 )
|
||||
net.WriteVector( Dupe.Mins )
|
||||
net.WriteVector( Dupe.Maxs )
|
||||
net.WriteString( "Unsaved dupe" )
|
||||
net.WriteUInt( table.Count( Dupe.Entities ), 24 )
|
||||
net.WriteUInt( 0, 16 )
|
||||
net.Send( self:GetOwner() )
|
||||
|
||||
--
|
||||
-- Store the dupe on the player
|
||||
--
|
||||
self:GetOwner().CurrentDupeArmed = false
|
||||
self:GetOwner().CurrentDupe = Dupe
|
||||
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
|
||||
if ( CLIENT ) then
|
||||
|
||||
--
|
||||
-- Builds the context menu
|
||||
--
|
||||
function TOOL.BuildCPanel( CPanel, tool )
|
||||
|
||||
CPanel:ClearControls()
|
||||
|
||||
CPanel:AddControl( "Header", { Description = "#tool.duplicator.desc" } )
|
||||
|
||||
CPanel:AddControl( "Button", { Text = "#tool.duplicator.showsaves", Command = "dupe_show" } )
|
||||
|
||||
if ( !tool && IsValid( LocalPlayer() ) ) then tool = LocalPlayer():GetTool( "duplicator" ) end
|
||||
if ( !tool || !tool.CurrentDupeName ) then return end
|
||||
|
||||
local info = "Name: " .. tool.CurrentDupeName
|
||||
info = info .. "\nEntities: " .. tool.CurrentDupeEntCount
|
||||
|
||||
CPanel:AddControl( "Label", { Text = info } )
|
||||
|
||||
if ( tool.CurrentDupeWSIDs && #tool.CurrentDupeWSIDs > 0 ) then
|
||||
CPanel:AddControl( "Label", { Text = "Required workshop content:" } )
|
||||
for _, wsid in pairs( tool.CurrentDupeWSIDs ) do
|
||||
local subbed = ""
|
||||
if ( steamworks.IsSubscribed( wsid ) ) then subbed = " (Subscribed)" end
|
||||
local b = CPanel:AddControl( "Button", { Text = wsid .. subbed } )
|
||||
b.DoClick = function( s, ... ) steamworks.ViewFile( wsid ) end
|
||||
steamworks.FileInfo( wsid, function( result )
|
||||
if ( !IsValid( b ) ) then return end
|
||||
b:SetText( result.title .. subbed )
|
||||
end )
|
||||
end
|
||||
end
|
||||
|
||||
if ( tool.CurrentDupeCanSave ) then
|
||||
local b = CPanel:AddControl( "Button", { Text = "#dupes.savedupe", Command = "dupe_save" } )
|
||||
hook.Add( "DupeSaveUnavailable", b, function() b:Remove() end )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function TOOL:RefreshCPanel()
|
||||
local CPanel = controlpanel.Get( "duplicator" )
|
||||
if ( !CPanel ) then return end
|
||||
|
||||
self.BuildCPanel( CPanel, self )
|
||||
end
|
||||
|
||||
--
|
||||
-- Received by the client to alert us that we have something copied
|
||||
-- This allows us to enable the save button in the spawn menu
|
||||
--
|
||||
net.Receive( "CopiedDupe", function( len, client )
|
||||
|
||||
local canSave = net.ReadUInt( 1 )
|
||||
if ( canSave == 1 ) then
|
||||
hook.Run( "DupeSaveAvailable" )
|
||||
else
|
||||
hook.Run( "DupeSaveUnavailable" )
|
||||
end
|
||||
|
||||
local ply = LocalPlayer()
|
||||
if ( !IsValid( ply ) || !ply.GetTool ) then return end
|
||||
|
||||
local tool = ply:GetTool( "duplicator" )
|
||||
if ( !tool ) then return end
|
||||
|
||||
tool.CurrentDupeCanSave = canSave == 1
|
||||
tool.CurrentDupeMins = net.ReadVector()
|
||||
tool.CurrentDupeMaxs = net.ReadVector()
|
||||
|
||||
tool.CurrentDupeName = net.ReadString()
|
||||
tool.CurrentDupeEntCount = net.ReadUInt( 24 )
|
||||
|
||||
local workshopCount = net.ReadUInt( 16 )
|
||||
local addons = {}
|
||||
for i = 1, workshopCount do
|
||||
table.insert( addons, net.ReadString() )
|
||||
end
|
||||
tool.CurrentDupeWSIDs = addons
|
||||
|
||||
tool:RefreshCPanel()
|
||||
|
||||
end )
|
||||
|
||||
-- This is not perfect, but let the player see roughly the outline of what they are about to paste
|
||||
function TOOL:DrawHUD()
|
||||
|
||||
local ply = LocalPlayer()
|
||||
if ( !IsValid( ply ) || !self.CurrentDupeMins || !self.CurrentDupeMaxs ) then return end
|
||||
|
||||
local tr = LocalPlayer():GetEyeTrace()
|
||||
|
||||
local pos = tr.HitPos
|
||||
pos.z = pos.z - self.CurrentDupeMins.z
|
||||
|
||||
local ang = LocalPlayer():GetAngles()
|
||||
ang.p = 0
|
||||
ang.r = 0
|
||||
|
||||
cam.Start3D()
|
||||
render.DrawWireframeBox( pos, ang, self.CurrentDupeMins, self.CurrentDupeMaxs )
|
||||
cam.End3D()
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user