This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 0e770b2b49
commit 94063e4369
7342 changed files with 1718932 additions and 14 deletions

View File

@@ -0,0 +1,622 @@
--[[
| 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/
--]]
local L = pace.LanguageString
-- load only when hovered above
local function add_expensive_submenu_load(pnl, callback)
local old = pnl.OnCursorEntered
pnl.OnCursorEntered = function(...)
callback()
pnl.OnCursorEntered = old
return old(...)
end
end
function pace.WearParts(temp_wear_filter)
local allowed, reason = pac.CallHook("CanWearParts", pac.LocalPlayer)
if allowed == false then
pac.Message(reason or "the server doesn't want you to wear parts for some reason")
return
end
return pace.WearOnServer(temp_wear_filter)
end
function pace.OnCreatePart(class_name, name, mdl, no_parent)
local part
local parent = NULL
if no_parent then
if class_name ~= "group" then
local group
local parts = pac.GetLocalParts()
if table.Count(parts) == 1 then
local test = select(2, next(parts))
if test.ClassName == "group" then
group = test
end
else
group = pac.CreatePart("group")
end
part = pac.CreatePart(class_name)
part:SetParent(group)
parent = group
else
part = pac.CreatePart(class_name)
end
else
if class_name ~= "group" and not next(pac.GetLocalParts()) then
pace.Call("CreatePart", "group")
end
part = pac.CreatePart(class_name)
parent = pace.current_part
if parent:IsValid() then
part:SetParent(parent)
elseif class_name ~= "group" then
for _, v in pairs(pac.GetLocalParts()) do
if v.ClassName == "group" then
part:SetParent(v)
parent = v
break
end
end
end
end
if name then part:SetName(name) end
if part.SetModel then
if mdl then
part:SetModel(mdl)
elseif class_name == "model" or class_name == "model2" then
part:SetModel("models/pac/default.mdl")
end
end
local ply = pac.LocalPlayer
if part:GetPlayerOwner() == ply then
pace.SetViewPart(part)
end
if not input.IsControlDown() then
pace.Call("PartSelected", part)
end
part.newly_created = true
if parent.GetDrawPosition and parent:IsValid() and not parent:HasParent() and parent.OwnerName == "world" and part:GetPlayerOwner() == ply then
local data = ply:GetEyeTrace()
if data.HitPos:Distance(ply:GetPos()) < 1000 then
part:SetPosition(data.HitPos)
else
part:SetPosition(ply:GetPos())
end
end
pace.RefreshTree()
return part
end
function pace.OnPartSelected(part, is_selecting)
local parent = part:GetRootPart()
if parent:IsValid() and (parent.OwnerName == "viewmodel" or parent.OwnerName == "hands") then
pace.editing_viewmodel = parent.OwnerName == "viewmodel"
pace.editing_hands = parent.OwnerName == "hands"
elseif pace.editing_viewmodel or pace.editing_hands then
pace.editing_viewmodel = false
pace.editing_hands = false
end
pace.current_part = part
pace.PopulateProperties(part)
pace.mctrl.SetTarget(part)
pace.SetViewPart(part)
if pace.Editor:IsValid() then
pace.Editor:InvalidateLayout()
end
pace.SafeRemoveSpecialPanel()
if pace.tree:IsValid() then
pace.tree:SelectPart(part)
end
pace.current_part_uid = part.UniqueID
if not is_selecting then
pace.StopSelect()
end
end
function pace.OnVariableChanged(obj, key, val, not_from_editor)
local valType = type(val)
if valType == 'Vector' then
val = Vector(val)
elseif valType == 'Angle' then
val = Angle(val)
end
if not not_from_editor then
timer.Create("pace_backup", 1, 1, pace.Backup)
if not pace.undo_release_varchange then
pace.RecordUndoHistory()
pace.undo_release_varchange = true
end
timer.Create("pace_undo", 0.25, 1, function()
pace.undo_release_varchange = false
pace.RecordUndoHistory()
end)
end
if key == "OwnerName" then
local owner_name = obj:GetProperty(key)
if val == "viewmodel" then
pace.editing_viewmodel = true
elseif val == "hands" then
pace.editing_hands = true
elseif owner_name == "hands" then
pace.editing_hands = false
elseif owner_name == "viewmodel" then
pace.editing_viewmodel = false
end
end
obj:SetProperty(key, val)
local node = obj.pace_tree_node
if IsValid(node) then
if key == "Event" then
pace.PopulateProperties(obj)
elseif key == "Name" then
if not obj:HasParent() then
pace.RemovePartOnServer(obj:GetUniqueID(), true, true)
end
node:SetText(val)
elseif key == "Model" and val and val ~= "" and isstring(val) then
node:SetModel(val)
elseif key == "Parent" then
local tree = obj.pace_tree_node
if IsValid(tree) then
node:Remove()
tree = tree:GetRoot()
if tree:IsValid() then
tree:SetSelectedItem(nil)
pace.RefreshTree(true)
end
end
end
if obj.Name == "" then
node:SetText(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", obj:GetName(), obj:GetPrintUniqueID()) or obj:GetName())
end
end
if obj.ClassName:StartWith("sound", nil, true) then
timer.Create("pace_preview_sound", 0.25, 1, function()
obj:OnShow()
end)
end
timer.Simple(0, function()
if not IsValid(obj) then return end
local prop_panel = obj.pace_properties and obj.pace_properties[key]
if IsValid(prop_panel) then
local old = prop_panel.OnValueChanged
prop_panel.OnValueChanged = function() end
prop_panel:SetValue(val)
prop_panel.OnValueChanged = old
end
end)
end
pac.AddHook("pac_OnPartParent", "pace_parent", function(parent, child)
pace.Call("VariableChanged", parent, "Parent", child, true)
end)
function pace.GetRegisteredParts()
local out = {}
for class_name, PART in pairs(pac.GetRegisteredParts()) do
local cond = not PART.ClassName:StartWith("base") and
PART.show_in_editor ~= false and
PART.is_deprecated ~= false
if cond then
table.insert(out, PART)
end
end
return out
end
do -- menu
local trap
function pace.AddRegisteredPartsToMenu(menu, parent)
local partsToShow = {}
local clicked = false
hook.Add('Think', menu, function()
local ctrl = input.IsControlDown()
if clicked and not ctrl then
menu:SetDeleteSelf(true)
RegisterDermaMenuForClose(menu)
CloseDermaMenus()
return
end
menu:SetDeleteSelf(not ctrl)
end)
hook.Add('CloseDermaMenus', menu, function()
clicked = true
if input.IsControlDown() then
menu:SetVisible(true)
RegisterDermaMenuForClose(menu)
end
end)
local function add_part(menu, part)
local newMenuEntry = menu:AddOption(L(part.FriendlyName or part.ClassName:Replace('_', ' ')), function()
pace.RecordUndoHistory()
pace.Call("CreatePart", part.ClassName, nil, nil, parent)
pace.RecordUndoHistory()
trap = true
end)
if part.Icon then
newMenuEntry:SetImage(part.Icon)
if part.Group == "legacy" then
local mat = Material(pace.GroupsIcons.experimental)
newMenuEntry.m_Image.PaintOver = function(_, w,h)
surface.SetMaterial(mat)
surface.DrawTexturedRect(2,6,13,13)
end
end
end
end
local sortedTree = {}
for _, part in pairs(pace.GetRegisteredParts()) do
local group = part.Group or part.Groups or "other"
if isstring(group) then
group = {group}
end
for i, name in ipairs(group) do
if not sortedTree[name] then
sortedTree[name] = {}
sortedTree[name].parts = {}
sortedTree[name].icon = pace.GroupsIcons[name]
sortedTree[name].name = L(name)
end
partsToShow[part.ClassName] = nil
if name == part.ClassName or name == part.FriendlyName then
sortedTree[name].group_class_name = part.ClassName
else
table.insert(sortedTree[name].parts, part)
end
end
end
local other = sortedTree.other
sortedTree.other = nil
for group, groupData in pairs(sortedTree) do
local sub, pnl = menu:AddSubMenu(groupData.name, function()
if groupData.group_class_name then
pace.RecordUndoHistory()
pace.Call("CreatePart", groupData.group_class_name, nil, nil, parent)
pace.RecordUndoHistory()
end
end)
sub.GetDeleteSelf = function() return false end
if groupData.icon then
pnl:SetImage(groupData.icon)
end
trap = false
table.sort(groupData.parts, function(a, b) return a.ClassName < b.ClassName end)
for i, part in ipairs(groupData.parts) do
add_part(sub, part)
end
hook.Add('Think', sub, function()
local ctrl = input.IsControlDown()
if clicked and not ctrl then
sub:SetDeleteSelf(true)
RegisterDermaMenuForClose(sub)
CloseDermaMenus()
return
end
sub:SetDeleteSelf(not ctrl)
end)
hook.Add('CloseDermaMenus', sub, function()
if input.IsControlDown() and trap then
trap = false
sub:SetVisible(true)
end
RegisterDermaMenuForClose(sub)
end)
end
for i,v in ipairs(other.parts) do
add_part(menu, v)
end
for class_name, part in pairs(partsToShow) do
local newMenuEntry = menu:AddOption(L((part.FriendlyName or part.ClassName):Replace('_', ' ')), function()
pace.RecordUndoHistory()
pace.Call("CreatePart", class_name, nil, nil, parent)
pace.RecordUndoHistory()
end)
if part.Icon then
newMenuEntry:SetImage(part.Icon)
end
end
end
function pace.OnAddPartMenu(obj)
local base = vgui.Create("EditablePanel")
base:SetPos(input.GetCursorPos())
base:SetSize(200, 300)
base:MakePopup()
function base:OnRemove()
pac.RemoveHook("VGUIMousePressed", "search_part_menu")
end
local edit = base:Add("DTextEntry")
edit:SetTall(20)
edit:Dock(TOP)
edit:RequestFocus()
edit:SetUpdateOnType(true)
local result = base:Add("DPanel")
result:Dock(FILL)
function edit:OnEnter()
if result.found[1] then
pace.RecordUndoHistory()
pace.Call("CreatePart", result.found[1].ClassName)
pace.RecordUndoHistory()
end
base:Remove()
end
edit.OnValueChange = function(_, str)
result:Clear()
result.found = {}
for _, part in ipairs(pace.GetRegisteredParts()) do
if (part.FriendlyName or part.ClassName):find(str, nil, true) then
table.insert(result.found, part)
end
end
table.sort(result.found, function(a, b) return #a.ClassName < #b.ClassName end)
for _, part in ipairs(result.found) do
local line = result:Add("DButton")
line:SetText("")
line:SetTall(20)
line.DoClick = function()
pace.RecordUndoHistory()
pace.Call("CreatePart", part.ClassName)
base:Remove()
pace.RecordUndoHistory()
end
local btn = line:Add("DImageButton")
btn:SetSize(16, 16)
btn:SetPos(4,0)
btn:CenterVertical()
btn:SetMouseInputEnabled(false)
if part.Icon then
btn:SetImage(part.Icon)
if part.Group == "legacy" then
local mat = Material(pace.GroupsIcons.experimental)
btn.m_Image.PaintOver = function(_, w,h)
surface.SetMaterial(mat)
surface.DrawTexturedRect(2,6,13,13)
end
end
end
local label = line:Add("DLabel")
label:SetTextColor(label:GetSkin().Colours.Category.Line.Text)
label:SetText(L((part.FriendlyName or part.ClassName):Replace('_', ' ')))
label:SizeToContents()
label:MoveRightOf(btn, 4)
label:SetMouseInputEnabled(false)
label:CenterVertical()
line:Dock(TOP)
end
base:SetHeight(20 * #result.found + edit:GetTall())
end
edit:OnValueChange("")
pac.AddHook("VGUIMousePressed", "search_part_menu", function(pnl, code)
if code == MOUSE_LEFT or code == MOUSE_RIGHT then
if not base:IsOurChild(pnl) then
base:Remove()
end
end
end)
end
function pace.Copy(obj)
pace.Clipboard = obj:ToTable()
end
function pace.Cut(obj)
pace.RecordUndoHistory()
pace.Copy(obj)
obj:Remove()
pace.RecordUndoHistory()
end
function pace.Paste(obj)
if not pace.Clipboard then return end
pace.RecordUndoHistory()
local newObj = pac.CreatePart(pace.Clipboard.self.ClassName)
newObj:SetTable(pace.Clipboard, true)
newObj:SetParent(obj)
pace.RecordUndoHistory()
end
function pace.PasteProperties(obj)
if not pace.Clipboard then return end
pace.RecordUndoHistory()
local tbl = pace.Clipboard
tbl.self.Name = nil
tbl.self.ParentUID = nil
tbl.self.UniqueID = nil
tbl.children = {}
obj:SetTable(tbl)
pace.RecordUndoHistory()
end
function pace.Clone(obj)
pace.RecordUndoHistory()
obj:Clone()
pace.RecordUndoHistory()
end
function pace.RemovePart(obj)
pace.RecordUndoHistory()
obj:Remove()
pace.RecordUndoHistory()
pace.RefreshTree()
if not obj:HasParent() and obj.ClassName == "group" then
pace.RemovePartOnServer(obj:GetUniqueID(), false, true)
end
end
function pace.OnPartMenu(obj)
local menu = DermaMenu()
menu:SetPos(input.GetCursorPos())
if obj then
if not obj:HasParent() then
menu:AddOption(L"wear", function() pace.SendPartToServer(obj) end):SetImage(pace.MiscIcons.wear)
end
menu:AddOption(L"copy", function() pace.Copy(obj) end):SetImage(pace.MiscIcons.copy)
menu:AddOption(L"paste", function() pace.Paste(obj) end):SetImage(pace.MiscIcons.paste)
menu:AddOption(L"cut", function() pace.Cut(obj) end):SetImage('icon16/cut.png')
menu:AddOption(L"paste properties", function() pace.PasteProperties(obj) end):SetImage(pace.MiscIcons.replace)
menu:AddOption(L"clone", function() pace.Clone(obj) end):SetImage(pace.MiscIcons.clone)
menu:AddSpacer()
end
pace.AddRegisteredPartsToMenu(menu, not obj)
menu:AddSpacer()
if obj then
local save, pnl = menu:AddSubMenu(L"save", function() pace.SaveParts() end)
pnl:SetImage(pace.MiscIcons.save)
add_expensive_submenu_load(pnl, function() pace.AddSaveMenuToMenu(save, obj) end)
end
local load, pnl = menu:AddSubMenu(L"load", function() pace.LoadParts() end)
add_expensive_submenu_load(pnl, function() pace.AddSavedPartsToMenu(load, false, obj) end)
pnl:SetImage(pace.MiscIcons.load)
if obj then
menu:AddSpacer()
menu:AddOption(L"remove", function() pace.RemovePart(obj) end):SetImage(pace.MiscIcons.clear)
end
menu:Open()
menu:MakePopup()
end
function pace.OnNewPartMenu()
pace.current_part = NULL
local menu = DermaMenu()
menu:MakePopup()
menu:SetPos(input.GetCursorPos())
pace.AddRegisteredPartsToMenu(menu)
menu:AddSpacer()
local load, pnl = menu:AddSubMenu(L"load", function() pace.LoadParts() end)
pnl:SetImage(pace.MiscIcons.load)
add_expensive_submenu_load(pnl, function() pace.AddSavedPartsToMenu(load, false, obj) end)
menu:AddOption(L"clear", function()
pace.ClearParts()
end):SetImage(pace.MiscIcons.clear)
end
end
do
pac.haloex = include("pac3/libraries/haloex.lua")
function pace.OnHoverPart(self)
local tbl = {}
local ent = self:GetOwner()
if ent:IsValid() then
table.insert(tbl, ent)
end
for _, child in ipairs(self:GetChildrenList()) do
local ent = self:GetOwner()
if ent:IsValid() then
table.insert(tbl, ent)
end
end
if #tbl > 0 then
local pulse = math.sin(pac.RealTime * 20) * 0.5 + 0.5
pulse = pulse * 255
pac.haloex.Add(tbl, Color(pulse, pulse, pulse, 255), 1, 1, 1, true, true, 5, 1, 1)
end
end
end