This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 8064ba84d8
commit 73479cff9e
7338 changed files with 1718883 additions and 14 deletions

View File

@@ -0,0 +1,86 @@
--[[
| 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
local PANEL = {}
PANEL.ClassName = "browser"
PANEL.Base = "DListView"
PANEL.Dir = ""
AccessorFunc(PANEL, "Dir", "Dir")
function PANEL:SetDir(str)
self.Dir = str
self:PopulateFromClient()
end
function PANEL:Init()
self:AddColumn(L"name")
self:AddColumn(L"size")
self:AddColumn(L"modified")
self:PopulateFromClient()
self:FixColumnsLayout()
end
local function OnMousePressed(self, mcode)
if mcode == MOUSE_RIGHT then
self:GetListView():OnRowRightClick(self:GetID(), self)
elseif mcode == MOUSE_LEFT then
self:GetListView():OnClickLine(self, true)
self:OnSelect()
end
end
function PANEL:AddOutfits(folder, callback)
for i, name in pairs(file.Find(folder.."*", "DATA")) do
if name:find("%.txt") then
local outfit = folder .. name
if file.Exists(outfit, "DATA") then
local filenode = self:AddLine(
name:gsub("%.txt", ""),
string.NiceSize(file.Size(outfit, "DATA")),
os.date("%m/%d/%Y %H:%M", file.Time(outfit, "DATA"))
)
filenode.FileName = name
filenode.OnSelect = callback
filenode.OnMousePressed = OnMousePressed
end
end
end
end
function PANEL:PopulateFromClient()
self:Clear()
self:AddOutfits("pac3/" .. self.Dir, function(node)
pace.LoadParts(self.Dir .. node.FileName, true)
pace.RefreshTree()
end)
end
function PANEL.OnRowRightClick(_self,id, self)
local m=DermaMenu()
m:AddOption(L"View",function()
self:GetListView():OnClickLine(self, true)
self:OnSelect()
end)
m:AddOption(L"wear on server",function()
self:GetListView():OnClickLine(self, true)
self:OnSelect()
timer.Simple(0,function()
RunConsoleCommand"pac_wear_parts"
end)
end)
m:Open()
end
pace.RegisterPanel(PANEL)

View File

@@ -0,0 +1,494 @@
--[[
| 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
local PANEL = {}
PANEL.ClassName = "editor"
PANEL.Base = "DFrame"
PANEL.menu_bar = NULL
PANEL.pac3_PanelsToRemove = {
'btnMaxim', 'btnMinim'
}
local BAR_SIZE = 17
local RENDERSCORE_SIZE = 20
local use_tabs = CreateClientConVar("pac_property_tabs", 1, true)
local zoom_persistent = CreateClientConVar("pac_zoom_persistent", 0, true, false, 'Keep zoom between sessions.')
local zoom_mousewheel = CreateClientConVar("pac_zoom_mousewheel", 0, true, false, 'Enable zooming with mouse wheel.')
local zoom_smooth = CreateClientConVar("pac_zoom_smooth", 0, true, false, 'Enable smooth zooming.')
function PANEL:Init()
self:SetTitle("")
self:SetSizable(true)
--self:DockPadding(2, 23, 2, 2)
surface.SetFont(pace.CurrentFont)
local _, h = surface.GetTextSize("|")
RENDERSCORE_SIZE = h + 1
local div = vgui.Create("DVerticalDivider", self)
div:SetDividerHeight(RENDERSCORE_SIZE)
div:Dock(FILL)
div:SetTopMin(40)
div:SetBottomMin(40)
div:SetCookieName("pac3_editor")
div:SetTopHeight(ScrH() / 1.4)
div:LoadCookies()
self.div = div
self.treePanel = pace.CreatePanel("tree")
self:SetTop(self.treePanel)
local pnl = pace.CreatePanel("properties", div)
pace.properties = pnl
self.exit_button = vgui.Create("DButton")
self.exit_button:SetText("")
self.exit_button.DoClick = function() self:Close() end
self.exit_button.Paint = function(self, w, h) derma.SkinHook("Paint", "WindowCloseButton", self, w, h) end
self.exit_button:SetSize(31, 26)
self.zoomframe = vgui.Create( "DPanel" )
self.zoomframe:SetSize( 180, 150 )
self.zoomsettings = vgui.Create("DPanel", self.zoomframe)
self.zoomsettings:Dock(TOP)
self.zoomsettings:DockPadding(4,0,4,4)
local SETTING_MARGIN_TOP = 6
self.persistcheckbox = vgui.Create("DCheckBoxLabel", self.zoomsettings)
self.persistcheckbox:SetText("Persistent camera FOV")
self.persistcheckbox:Dock(TOP)
self.persistcheckbox:SetDark(true)
self.persistcheckbox:DockMargin(0,SETTING_MARGIN_TOP,0,0)
self.persistcheckbox:SetConVar("pac_zoom_persistent")
self.persistlabel = vgui.Create("DLabel", self.zoomsettings)
self.persistlabel:Dock(TOP)
self.persistlabel:SetDark(true)
self.persistlabel:SetText("Keep the zoom when reopening the editor.")
self.persistlabel:SetWrap(true)
self.persistlabel:SetAutoStretchVertical(true)
self.mwheelcheckbox = vgui.Create("DCheckBoxLabel", self.zoomsettings)
self.mwheelcheckbox:SetText("Enable mouse wheel")
self.mwheelcheckbox:Dock(TOP)
self.mwheelcheckbox:SetDark(true)
self.mwheelcheckbox:DockMargin(0,SETTING_MARGIN_TOP,0,0)
self.mwheelcheckbox:SetConVar("pac_zoom_mousewheel")
self.mwheellabel = vgui.Create("DLabel", self.zoomsettings)
self.mwheellabel:Dock(TOP)
self.mwheellabel:SetDark(true)
self.mwheellabel:SetText("Enable zooming with mouse wheel.\n+CTRL: Precise\n+SHIFT: Fast")
self.mwheellabel:SetWrap(true)
self.mwheellabel:SetAutoStretchVertical(true)
self.smoothcheckbox = vgui.Create("DCheckBoxLabel", self.zoomsettings)
self.smoothcheckbox:SetText("Smooth zooming")
self.smoothcheckbox:Dock(TOP)
self.smoothcheckbox:SetDark(true)
self.smoothcheckbox:DockMargin(0,SETTING_MARGIN_TOP,0,0)
self.smoothcheckbox:SetConVar("pac_zoom_smooth")
self.smoothlabel = vgui.Create("DLabel", self.zoomsettings)
self.smoothlabel:Dock(TOP)
self.smoothlabel:SetDark(true)
self.smoothlabel:SetText("Enable smooth zooming.")
self.smoothlabel:SetWrap(true)
self.smoothlabel:SetAutoStretchVertical(true)
self.sliderpanel = vgui.Create("DPanel", self.zoomframe)
self.sliderpanel:SetSize(180, 20)
self.sliderpanel:Dock(TOP)
self.zoomslider = vgui.Create("DNumSlider", self.sliderpanel)
self.zoomslider:DockPadding(4,0,0,0)
self.zoomslider:SetSize(200, 20)
self.zoomslider:SetMin( 0 )
self.zoomslider:SetMax( 100 )
self.zoomslider:SetDecimals( 0 )
self.zoomslider:SetText("Camera FOV")
self.zoomslider:SetDark(true)
self.zoomslider:SetDefaultValue( 75 )
if zoom_persistent:GetInt() == 1 then
self.zoomslider:SetValue( pace.ViewFOV )
else
self.zoomslider:SetValue( 75 )
end
self.btnClose.Paint = function() end
self:SetBottom(pnl)
self:SetCookieName("pac3_editor")
self:SetPos(self:GetCookieNumber("x"), BAR_SIZE)
self:MakeBar()
self.lastTopBarHover = 0
self.rendertime_data = {}
self.okay = true
end
function PANEL:OnMousePressed()
if self.m_bSizable and gui.MouseX() > ( self.x + self:GetWide() - 20 ) then
self.Sizing = { gui.MouseX() - self:GetWide(), gui.MouseY() - self:GetTall() }
self:MouseCapture( true )
return
end
if self:GetDraggable() and gui.MouseY() < (self.y + 24) then
self.Dragging = { gui.MouseX() - self.x, gui.MouseY() - self.y }
self:MouseCapture( true )
return
end
end
function PANEL:OnMouseReleased(mc)
if mc == MOUSE_RIGHT then
self:Close()
end
self.BaseClass.OnMouseReleased(self,mc)
end
function PANEL:MakeBar()
if self.menu_bar:IsValid() then self.menu_bar:Remove() end
local bar = vgui.Create("DMenuBar", self)
bar:SetSize(self:GetWide(), BAR_SIZE)
pace.Call("MenuBarPopulate", bar)
pace.MenuBar = bar
self.menu_bar = bar
self:DockMargin(2, 2, 2, 2)
self:DockPadding(2, 2, 2, 2)
end
function PANEL:OnRemove()
if self.menu_bar:IsValid() then
self.menu_bar:Remove()
end
if self.exit_button:IsValid() then
self.exit_button:Remove()
end
if self.zoomframe:IsValid() then
self.zoomframe:Remove()
end
end
function PANEL:Think(...)
if not self.okay then return end
DFrame.Think(self, ...)
if self.Hovered and self.m_bSizable and gui.MouseX() > (self.x + self:GetWide() - 20) then
self:SetCursor("sizewe")
return
end
for k,v in pairs(pac.GetRenderTimeInfo(pac.LocalPlayer)) do
self.rendertime_data[k] = Lerp(0.03, self.rendertime_data[k] or 0, v)
end
local bar = self.menu_bar
self:SetTall(ScrH())
local w = math.max(self:GetWide(), 200)
self:SetWide(w)
self:SetPos(math.Clamp(self:GetPos(), 0, ScrW() - w), 0)
if x ~= self.last_x then
self:SetCookie("x", x)
self.last_x = x
end
if self.exit_button:IsValid() then
if self:GetPos() + self:GetWide() / 2 < ScrW() / 2 then
self.exit_button:SetPos(ScrW() - self.exit_button:GetWide() + 4, -4)
else
self.exit_button:SetPos(-4, -4)
end
end
if self.zoomframe:IsValid() then
self.zoomsettings:InvalidateLayout( true )
self.zoomsettings:SizeToChildren( false, true )
self.zoomframe:InvalidateLayout( true )
self.zoomframe:SizeToChildren( false, true )
if self:GetPos() + self:GetWide() / 2 < ScrW() / 2 then
self.zoomframe:SetPos(ScrW() - self.zoomframe:GetWide(), ScrH() - self.zoomframe:GetTall())
else
self.zoomframe:SetPos(0,ScrH() - self.zoomframe:GetTall())
end
local x, y = self.zoomframe:GetPos()
if pace.timeline.IsActive() then
self.zoomframe:SetPos(x,y-pace.timeline.frame:GetTall())
end
if pace.zoom_reset then
self.zoomslider:SetValue(75)
pace.zoom_reset = nil
end
if zoom_smooth:GetInt() == 1 then
pace.SetZoom(self.zoomslider:GetValue(),true)
else
pace.SetZoom(self.zoomslider:GetValue(),false)
end
local mx, my = input.GetCursorPos()
local x, y = self.zoomframe:GetPos()
local xs, xy = self.zoomframe:GetSize()
if mx > x and my > y and mx < x + xs and my < y + xy then
self.zoomsettings:SetVisible(true)
self.zoomsettings:RequestFocus()
else
self.zoomsettings:SetVisible(false)
end
end
end
local auto_size = CreateClientConVar("pac_auto_size_properties", 1, true)
function PANEL:PerformLayout()
if not self.okay then return end
DFrame.PerformLayout(self)
for i, val in pairs(self.pac3_PanelsToRemove) do
if IsValid(self[val]) then
self[val].SetSize(self[val], 0, 0) -- Hacky
end
end
if self.old_part ~= pace.current_part then
self.div:InvalidateLayout()
self.bottom:PerformLayout()
pace.properties:PerformLayout()
self.old_part = pace.current_part
local sz = auto_size:GetInt()
if sz > 0 then
local newh = sz > 0 and (ScrH() - math.min(pace.properties:GetHeight() + RENDERSCORE_SIZE + BAR_SIZE - 6, ScrH() / 1.5))
if sz >= 2 then
local oldh = self.div:GetTopHeight()
if newh<oldh then
self.div:SetTopHeight(newh)
end
elseif sz >= 1 then
self.div:SetTopHeight(newh)
end
end
end
end
function PANEL:SetTop(pnl)
self.top = pnl
self.div:SetTop(pnl)
end
function PANEL:SetBottom(pnl)
self.bottom = pnl
self.div:SetBottom(pnl)
end
pace.Focused = false
function pace.IsFocused()
return pace.Focused
end
local fade_time = 0.1
function pace.GainFocus(show_editor)
local self = pace.Editor
if self:IsValid() then
if self.allowclick ~= false then
self:MakePopup()
pace.Focused = true
timer.Remove("pac_editor_visibility")
self:SetVisible(true)
self.exit_button:SetVisible(true)
self.zoomframe:SetVisible(true)
self:AlphaTo(255, fade_time, 0)
self.exit_button:AlphaTo(255, fade_time, 0)
self.zoomframe:AlphaTo(255, fade_time, 0)
end
end
end
function pace.KillFocus(show_editor)
local self = pace.Editor
if self:IsValid() then
self:KillFocus()
self:SetMouseInputEnabled(false)
self:SetKeyBoardInputEnabled(false)
gui.EnableScreenClicker(false)
pace.Focused = false
if not show_editor then
self:AlphaTo(0, fade_time, 0)
self.exit_button:AlphaTo(0, fade_time, 0)
self.zoomframe:AlphaTo(0, fade_time, 0)
timer.Create("pac_editor_visibility", fade_time, 1, function()
self:SetVisible(false)
self.exit_button:SetVisible(false)
self.zoomframe:SetVisible(false)
end)
end
self.allowclick = false
timer.Simple(0.2, function()
if self:IsValid() then
self.allowclick = true
end
end)
end
end
local drawProfileInfos = 0
local textCol, drawBox
local boxW, boxH
local function drawTimeBox(text, time, x, y)
local str = string.format("%s: %.3f ms", L(text), time)
drawBox(x, y, boxW - 5, RENDERSCORE_SIZE - 1)
surface.SetTextPos(x + 5, y)
surface.DrawText(str)
return y + RENDERSCORE_SIZE
end
local function PostRenderVGUI()
end
pac.AddHook('PostRenderVGUI', 'pac_DrawProfileInfos', PostRenderVGUI)
function PANEL:PaintOver(w, h)
if not self.okay then return end
textCol = self:GetSkin().Colours.Category.Line.Text
local text = _G.PAC_VERSION and PAC_VERSION()
if text then
surface.SetFont("DermaDefault")
local x, y = self:LocalToScreen()
local w, h = surface.GetTextSize(text)
x = x + self:GetWide() + 4
y = y + self:GetTall() - 4 - h
local mx, my = gui.MousePos()
local cx, cy = self:LocalToScreen(x, y)
local hovering = false
DisableClipping(true)
if mx > x and mx < x + w and my > y and my < y + h then
hovering = true
text = "pac version: " .. text
w, h = surface.GetTextSize(text)
surface.SetDrawColor(0,0,0,255)
surface.DrawRect(x,y,w,h)
end
surface.SetTextPos(x,y)
surface.SetTextColor(255,255,255,hovering and 255 or 100)
surface.DrawText(text)
DisableClipping(false )
end
local data = self.rendertime_data
local x = 2
local y = 2
y = y + self.menu_bar:GetTall()
y = y + self.top:GetTall()
boxW, boxH = w, h
surface.SetFont(pace.CurrentFont)
textCol = self:GetSkin().Colours.Category.Line.Text
drawBox = self:GetSkin().tex.Menu_Strip
surface.SetTextColor(textCol)
cam.IgnoreZ(true)
local total = 0
for k,v in pairs(data) do
total = total + v
end
local str = string.format("%s: %.3f ms", L("average render time"), total * 1000)
drawBox(x, y, w - 5, RENDERSCORE_SIZE - 1)
local mx, my = input.GetCursorPos()
local cx, cy = self:LocalToScreen(x, y)
if cx <= mx and cy <= my and mx <= cx + w - 5 and my <= cy + RENDERSCORE_SIZE - 1 and self:IsChildHovered() then
surface.SetFont(pace.CurrentFont)
surface.SetTextColor(textCol)
local x, y = input.GetCursorPos()
x = x + 3
y = y + 3
DisableClipping(true)
for type, time in pairs(self.rendertime_data) do
y = drawTimeBox(type, time * 1000, x, y)
end
DisableClipping(false)
end
surface.SetTextPos(x + 5, y)
surface.DrawText(str)
cam.IgnoreZ(false)
end
function PANEL:Paint(w,h)
if not self.okay then return end
--surface.SetDrawColor(0, 0, 0, 255)
--surface.DrawRect(0,0,w,h)
-- there are some skins that have a transparent dframe
-- so the categories that the properties draw will be transparent
self:GetSkin().tex.Tab_Control( 0, 0, w, h )
--DFrame.Paint(self, w,h)
end
pace.RegisterPanel(PANEL)

View File

@@ -0,0 +1,767 @@
--[[
| 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
local function populate_part_menu(menu, part, func)
if part:HasChildren() then
local menu, pnl = menu:AddSubMenu(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName(), function()
func(part)
end)
pnl:SetImage(part.Icon)
for key, part in ipairs(part:GetChildren()) do
populate_part_menu(menu, part, func)
end
else
menu:AddOption(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName(), function()
func(part)
end):SetImage(part.Icon)
end
end
local function get_friendly_name(ent)
if not IsValid(ent) then return "NULL" end
local name = ent.GetName and ent:GetName()
if not name or name == "" then
name = ent:GetClass()
end
if ent:EntIndex() == -1 then
if name == "10C_BaseFlex" then
return "csentity - " .. ent:GetModel()
end
return name
end
if ent == pac.LocalPlayer then
return name
end
return ent:EntIndex() .. " - " .. name
end
do -- bone
local PANEL = {}
PANEL.ClassName = "properties_bone"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsLeftClick()
if not pace.current_part:IsValid() or not pace.current_part:GetParentOwner():IsValid() then return end
pace.SelectBone(pace.current_part:GetParentOwner(), function(data)
if not self:IsValid() then return end
self:SetValue(L(data.friendly))
self.OnValueChanged(data.friendly)
end, pace.current_part.ClassName == "bone" or pace.current_part.ClassName == "timeline_dummy_bone")
end
function PANEL:MoreOptionsRightClick()
local bones = pac.GetModelBones(pace.current_part:GetParentOwner())
local menu = DermaMenu()
menu:MakePopup()
local list = {}
for k,v in pairs(bones) do
table.insert(list, v.friendly)
end
pace.CreateSearchList(
self,
self.CurrentKey,
L"bones",
function(list)
list:AddColumn(L"name")
end,
function()
return list
end,
function()
return pace.current_part:GetBone()
end,
function(list, key, val)
return list:AddLine(val)
end
)
end
pace.RegisterPanel(PANEL)
end
do -- part
local PANEL = {}
PANEL.ClassName = "properties_part"
PANEL.Base = "pace_properties_base_type"
function PANEL:EncodeEdit(uid)
local part = pac.GetPartFromUniqueID(pac.Hash(pac.LocalPlayer), uid)
if part:IsValid() then
return part:GetName()
end
return ""
end
function PANEL:DecodeEdit(name)
if name:Trim() ~= "" then
local part = pac.FindPartByName(pac.Hash(pac.LocalPlayer), name, pace.current_part)
if part:IsValid() then
return part:GetUniqueID()
end
end
return ""
end
function PANEL:OnValueSet(val)
if not IsValid(self.part) then return end
local part = pac.GetPartFromUniqueID(pac.Hash(pac.LocalPlayer), val)
if IsValid(self.Icon) then self.Icon:Remove() end
if not part:IsValid() then
if self.CurrentKey == "TargetEntityUID" then
local owner = pace.current_part:GetOwner()
self:SetText(" " .. get_friendly_name(owner))
local pnl = vgui.Create("DImage", self)
pnl:SetImage(pace.GroupsIcons.entity)
self.Icon = pnl
end
return
end
if self.CurrentKey == "TargetEntityUID" then
if part.Owner:IsValid() then
local owner = part:GetOwner()
self:SetText(" " .. part:GetName())
else
local owner = part:GetOwner()
self:SetText(" " .. get_friendly_name(owner))
end
local pnl = vgui.Create("DImage", self)
pnl:SetImage(pace.GroupsIcons.entity)
self.Icon = pnl
return
end
self:SetText(" " .. (pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName()))
if
GetConVar("pac_editor_model_icons"):GetBool() and
part.is_model_part and
part.GetModel and
part:GetOwner():IsValid() and
part.ClassName ~= "entity2" and
part.ClassName ~= "weapon" -- todo: is_model_part is true, class inheritance issues?
then
local pnl = vgui.Create("SpawnIcon", self)
pnl:SetModel(part:GetOwner():GetModel() or "")
self.Icon = pnl
elseif isstring(part.Icon) then
local pnl = vgui.Create("DImage", self)
pnl:SetImage(part.Icon)
self.Icon = pnl
end
end
function PANEL:PerformLayout()
if not IsValid(self.Icon) then return end
self:SetTextInset(11, 0)
self.Icon:SetPos(4,0)
surface.SetFont(pace.CurrentFont)
local w,h = surface.GetTextSize(".")
h = h / 1.5
self.Icon:SetSize(h, h)
self.Icon:CenterVertical()
end
function PANEL:MoreOptionsLeftClick()
pace.SelectPart(pac.GetLocalParts(), function(part)
if not self:IsValid() then return end
self:SetValue(part:GetUniqueID())
self.OnValueChanged(part)
end)
end
function PANEL:MoreOptionsRightClick(key)
local menu = DermaMenu()
menu:MakePopup()
for _, part in pairs(pac.GetLocalParts()) do
if not part:HasParent() and part:GetShowInEditor() then
populate_part_menu(menu, part, function(part)
if not self:IsValid() then return end
self:SetValue(part:GetUniqueID())
self.OnValueChanged(part)
end)
end
end
if key ~= "ParentUID" then
menu:AddOption("none", function()
self:SetValue("")
self.OnValueChanged("")
end):SetImage(pace.MiscIcons.clear)
end
pace.FixMenu(menu)
end
pace.RegisterPanel(PANEL)
end
do -- owner
local PANEL = {}
PANEL.ClassName = "properties_ownername"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsLeftClick()
pace.SelectEntity(function(ent)
if not self:IsValid() then return end
pace.current_part:SetOwnerName(ent:EntIndex())
local name = pace.current_part:GetOwnerName()
self.OnValueChanged(name)
self:SetValue(L(name))
end)
end
function PANEL:MoreOptionsRightClick()
local menu = DermaMenu()
menu:MakePopup()
for key, name in pairs(pac.OwnerNames) do
menu:AddOption(name, function() pace.current_part:SetOwnerName(name) self.OnValueChanged(name) end)
end
local entities = menu:AddSubMenu(L"entities", function() end)
entities.GetDeleteSelf = function() return false end
for _, ent in pairs(ents.GetAll()) do
if ent:EntIndex() > 0 then
entities:AddOption(get_friendly_name(ent), function()
pace.current_part:SetOwnerName(ent:EntIndex())
self.OnValueChanged(ent:EntIndex())
end)
end
end
pace.FixMenu(menu)
end
pace.RegisterPanel(PANEL)
end
do -- sequence list
local PANEL = {}
PANEL.ClassName = "properties_sequence"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsLeftClick()
pace.CreateSearchList(
self,
self.CurrentKey,
L"animations",
function(list)
list:AddColumn(L"id"):SetFixedWidth(25)
list:AddColumn(L"name")
end,
function()
return pace.current_part:GetSequenceList()
end,
function()
return pace.current_part.SequenceName or pace.current_part.GestureName
end,
function(list, key, val)
return list:AddLine(key, val)
end
)
end
pace.RegisterPanel(PANEL)
end
do -- model
local PANEL = {}
PANEL.ClassName = "properties_model"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsRightClick()
pace.SafeRemoveSpecialPanel()
g_SpawnMenu:Open()
end
function PANEL:MoreOptionsLeftClick(key)
pace.close_spawn_menu = true
pace.SafeRemoveSpecialPanel()
local part = pace.current_part
pace.AssetBrowser(function(path)
if not part:IsValid() then return end
-- because we refresh the properties
if IsValid(self) and self.OnValueChanged then
self.OnValueChanged(path)
end
if pace.current_part.SetMaterials then
local model = pace.current_part:GetModel()
local part = pace.current_part
if part.pace_last_model and part.pace_last_model ~= model then
part:SetMaterials("")
end
part.pace_last_model = model
end
pace.PopulateProperties(pace.current_part)
for k,v in ipairs(pace.properties.List) do
if v.panel and v.panel.part == part and v.key == key then
self = v.panel
break
end
end
end, "models")
pac.AddHook("Think", "pace_close_browser", function()
if part ~= pace.current_part then
pac.RemoveHook("Think", "pace_close_browser")
pace.model_browser:SetVisible(false)
end
end)
end
pace.RegisterPanel(PANEL)
end
do -- materials and textures
local PANEL_MATERIAL = {}
PANEL_MATERIAL.ClassName = "properties_material"
PANEL_MATERIAL.Base = "pace_properties_base_type"
function PANEL_MATERIAL:MoreOptionsLeftClick(key)
pace.AssetBrowser(function(path)
if not self:IsValid() then return end
path = path:match("materials/(.+)%.vmt") or "error"
self:SetValue(path)
self.OnValueChanged(path)
end, "materials", key)
end
function PANEL_MATERIAL:MoreOptionsRightClick()
pace.SafeRemoveSpecialPanel()
local pnl = pace.CreatePanel("mat_browser")
pace.ShowSpecial(pnl, self, 300)
function pnl.MaterialSelected(_, path)
self:SetValue(path)
self.OnValueChanged(path)
end
pace.ActiveSpecialPanel = pnl
end
local PANEL = {}
local pace_material_display
PANEL.ClassName = "properties_textures"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsLeftClick()
pace.AssetBrowser(function(path)
if not self:IsValid() then return end
path = path:match("materials/(.+)%.vtf") or "error"
self:SetValue(path)
self.OnValueChanged(path)
end, "textures")
end
function PANEL:MoreOptionsRightClick()
pace.SafeRemoveSpecialPanel()
local pnl = pace.CreatePanel("mat_browser")
pace.ShowSpecial(pnl, self, 300)
function pnl.MaterialSelected(_, path)
self:SetValue(path)
self.OnValueChanged(path)
end
pace.ActiveSpecialPanel = pnl
end
function PANEL:HUDPaint()
if IsValid(self.editing) then return self:MustHideTexture() end
-- Near Button?
-- local w, h = self:GetSize()
-- local x, y = self:LocalToScreen(w, 0)
-- Near cursor
local W, H = ScrW(), ScrH()
local x, y = input.GetCursorPos()
local w, h = 256, 256
x = x + 12
y = y + 4
if x + w > W then
x = x - w - 24
end
if y + h > H then
y = y - h - 8
end
surface.SetDrawColor(255, 255, 255, 255)
surface.SetAlphaMultiplier(1)
surface.SetMaterial(pace_material_display)
surface.DrawTexturedRect(x, y, w, h)
end
PANEL_MATERIAL.HUDPaint = PANEL.HUDPaint
function PANEL:MustShowTexture()
if self.isShownTexture then return end
if not pace_material_display then
pace_material_display = CreateMaterial('pace_material_display', "UnlitGeneric", {})
end
if pace.current_part[self.CurrentKey] then
if pace.current_part[self.CurrentKey] == "" then
pace_material_display:SetTexture("$basetexture", "models/debug/debugwhite")
elseif not string.find(pace.current_part[self.CurrentKey], '^https?://') then
pace_material_display:SetTexture("$basetexture", pace.current_part[self.CurrentKey])
else
local function callback(mat, tex)
if not tex then return end
pace_material_display:SetTexture("$basetexture", tex)
end
pac.urltex.GetMaterialFromURL(pace.current_part[self.CurrentKey], callback, false, 'UnlitGeneric')
end
end
local id = tostring(self)
pac.AddHook("PostRenderVGUI", id, function()
if self:IsValid() then
self:HUDPaint()
else
pac.RemoveHook("PostRenderVGUI", id)
end
end)
self.isShownTexture = true
end
PANEL_MATERIAL.MustShowTexture = PANEL.MustShowTexture
function PANEL:MustHideTexture()
if not self.isShownTexture then return end
self.isShownTexture = false
pac.RemoveHook('PostRenderVGUI', tostring(self))
end
PANEL_MATERIAL.MustHideTexture = PANEL.MustHideTexture
function PANEL:ThinkTextureDisplay()
if self.preTextureThink then self:preTextureThink() end
if not IsValid(self.textureButton) or IsValid(self.editing) then return end
local rTime = RealTime()
self.lastHovered = self.lastHovered or rTime
if not self.textureButton:IsHovered() and not self:IsHovered() then
self.lastHovered = rTime
end
if self.lastHovered + 0.5 < rTime then
self:MustShowTexture()
else
self:MustHideTexture()
end
end
PANEL_MATERIAL.ThinkTextureDisplay = PANEL.ThinkTextureDisplay
function PANEL:OnMoreOptionsLeftClickButton(btn)
self.preTextureThink = self.Think
self.Think = self.ThinkTextureDisplay
self.textureButton = btn
end
PANEL_MATERIAL.OnMoreOptionsLeftClickButton = PANEL.OnMoreOptionsLeftClickButton
pace.RegisterPanel(PANEL)
pace.RegisterPanel(PANEL_MATERIAL)
end
do -- sound
local PANEL = {}
PANEL.ClassName = "properties_sound"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsLeftClick()
pace.AssetBrowser(function(path)
if not self:IsValid() then return end
self:SetValue(path)
self.OnValueChanged(path)
if pace.current_part:IsValid() then
pace.current_part:OnShow()
end
end, "sound")
end
pace.RegisterPanel(PANEL)
end
do -- script
local PANEL = {}
PANEL.ClassName = "properties_code"
PANEL.Base = "pace_properties_base_type"
function PANEL:MoreOptionsLeftClick()
pace.SafeRemoveSpecialPanel()
local frame = vgui.Create("DFrame")
frame:SetTitle(L"script")
pace.ShowSpecial(frame, self, 512)
frame:SetSizable(true)
local editor = vgui.Create("pace_luapad", frame)
editor:Dock(FILL)
editor:SetText(pace.current_part:GetCode())
editor.OnTextChanged = function(self)
pace.current_part:SetCode(self:GetValue())
end
editor.last_error = ""
function editor:CheckGlobal(str)
local part = pace.current_part
if not part:IsValid() then frame:Remove() return end
return part:ShouldHighlight(str)
end
function editor:Think()
local part = pace.current_part
if not part:IsValid() then frame:Remove() return end
local title = L"script editor"
if part.Error then
title = part.Error
local line = tonumber(title:match("SCRIPT_ENV:(%d-):"))
if line then
title = title:match("SCRIPT_ENV:(.+)")
if self.last_error ~= title then
editor:SetScrollPosition(line)
editor:SetErrorLine(line)
self.last_error = title
end
end
else
editor:SetErrorLine(nil)
if part.script_printing then
title = part.script_printing
part.script_printing = nil
end
end
frame:SetTitle(title)
end
pace.ActiveSpecialPanel = frame
end
pace.RegisterPanel(PANEL)
end
do -- hull
local PANEL = {}
PANEL.ClassName = "properties_hull"
PANEL.Base = "pace_properties_number"
function PANEL:OnValueSet()
local function stop()
RunConsoleCommand("-duck")
hook.Remove("PostDrawOpaqueRenderables", "pace_draw_hull")
end
local time = os.clock() + 3
hook.Add("PostDrawOpaqueRenderables", "pace_draw_hull", function()
if not pace.current_part:IsValid() then stop() return end
if pace.current_part.ClassName ~= "entity2" then stop() return end
local ent = pace.current_part:GetOwner()
if not ent.GetHull then stop() return end
if not ent.GetHullDuck then stop() return end
local min, max = ent:GetHull()
if self.udata and self.udata.crouch then
min, max = ent:GetHullDuck()
RunConsoleCommand("+duck")
end
min = min * ent:GetModelScale()
max = max * ent:GetModelScale()
render.DrawWireframeBox( ent:GetPos(), Angle(0), min, max, Color(255, 204, 51, 255), true )
if time < os.clock() then
stop()
end
end)
end
pace.RegisterPanel(PANEL)
end
do -- event ranger
local PANEL = {}
PANEL.ClassName = "properties_ranger"
PANEL.Base = "pace_properties_number"
function PANEL:OnValueSet()
local function stop()
hook.Remove("PostDrawOpaqueRenderables", "pace_draw_ranger")
end
local last_part = pace.current_part
hook.Add("PostDrawOpaqueRenderables", "pace_draw_ranger", function()
local part = pace.current_part
if not part:IsValid() then stop() return end
if part ~= last_part then stop() return end
if part.ClassName ~= "event" then stop() return end
if part:GetEvent() ~= "ranger" then stop() return end
local distance = part:GetProperty("distance")
local compare = part:GetProperty("compare")
local trigger = part.event_triggered
local parent = part:GetParent()
if not parent:IsValid() or not parent.GetWorldPosition then stop() return end
local startpos = parent:GetWorldPosition()
local endpos
local color
if self.udata then
if self.udata.ranger_property == "distance" then
endpos = startpos + parent:GetWorldAngles():Forward() * distance
color = Color(255,255,255)
elseif self.udata.ranger_property == "compare" then
endpos = startpos + parent:GetWorldAngles():Forward() * compare
color = Color(10,255,10)
end
render.DrawLine( startpos, endpos, trigger and Color(255,0,0) or color)
end
end)
end
pace.RegisterPanel(PANEL)
end
do -- event is_touching
local PANEL = {}
PANEL.ClassName = "properties_is_touching"
PANEL.Base = "pace_properties_number"
function PANEL:OnValueSet()
local function stop()
hook.Remove("PostDrawOpaqueRenderables", "pace_draw_is_touching")
end
local last_part = pace.current_part
hook.Add("PostDrawOpaqueRenderables", "pace_draw_is_touching", function()
local part = pace.current_part
if part ~= last_part then stop() return end
if not part:IsValid() then stop() return end
if part.ClassName ~= "event" then stop() return end
if part:GetEvent() ~= "is_touching" then stop() return end
local extra_radius = part:GetProperty("extra_radius") or 0
local ent
if part.RootOwner then
ent = part:GetRootPart():GetOwner()
else
ent = part:GetOwner()
end
if not IsValid(ent) then stop() return end
local radius = ent:BoundingRadius()
if radius == 0 and IsValid(ent.pac_projectile) then
radius = ent.pac_projectile:GetRadius()
end
radius = math.max(radius + extra_radius + 1, 1)
local mins = Vector(-1,-1,-1)
local maxs = Vector(1,1,1)
local startpos = ent:WorldSpaceCenter()
mins = mins * radius
maxs = maxs * radius
local tr = util.TraceHull( {
start = startpos,
endpos = startpos,
maxs = maxs,
mins = mins,
filter = ent
} )
if self.udata then
render.DrawWireframeBox( startpos, Angle( 0, 0, 0 ), mins, maxs, tr.Hit and Color(255,0,0) or Color(255,255,255), true )
end
end)
end
pace.RegisterPanel(PANEL)
end

View File

@@ -0,0 +1,110 @@
--[[
| 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 function list(mid, name, store, populate)
local list = vgui.Create("DListView", mid)
list:AddColumn(name)
function list:Refresh()
self:Clear()
self.data = populate()
for _, kv in ipairs(self.data) do
self:AddLine(kv.name)
end
end
function list:Store()
for _, line in ipairs(list:GetSelected()) do
local i = line:GetID()
local kv = self.data[i]
if kv then
store(kv)
end
end
end
function list:Populate()
self:Clear()
self.data = populate()
end
list:Refresh()
return list
end
return function(form, name, props)
local pnl = vgui.Create("Panel", form)
pnl:SetTall(200)
pnl.left = list(pnl, props.name_left, props.store_left, props.populate_left)
pnl.right = list(pnl, props.name_right, props.store_right, props.populate_right)
local button = vgui.Create("DButton", pnl)
button:SetText(props.empty_message)
local store = function() end
local selected_side = pnl.left
pnl.left.OnRowSelected = function()
pnl.right:ClearSelection()
store = function() pnl.left:Store() end
button:SetText("add to " .. name)
end
pnl.right.OnRowSelected = function()
pnl.left:ClearSelection()
store = function() pnl.right:Store() end
button:SetText("remove from " .. name)
end
local function select()
if #pnl.left:GetLines() == 0 then
selected_side = pnl.right
end
if #pnl.right:GetLines() == 0 then
selected_side = pnl.left
end
selected_side:SelectFirstItem()
end
button.DoClick = function()
store()
pnl.left:Refresh()
pnl.right:Refresh()
select()
end
select()
pnl.Think = function()
local p = 5
local w = pnl:GetWide() / 2
local h = pnl:GetTall() - button:GetTall() - p
pnl.left:SetWide(w)
pnl.left:SetTall(h)
pnl.right:SetWide(w + 1)
pnl.right:SetTall(h)
pnl.right:MoveRightOf(pnl.left, -1)
button:MoveBelow(pnl.left, p)
button:CopyWidth(pnl)
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,673 @@
--[[
| 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/
--]]
pace.Materials = {}
pace.Materials.materials =
{
"models/weapons/v_crowbar/crowbar_cyl",
"models/weapons/v_crowbar/head_uvw",
"models/weapons/v_bugbait/bugbait_sheet",
"models/combine_advisor/arm",
"models/combine_advisor/hose",
"models/combine_advisor/face5",
"models/combine_advisor/body9",
"models/barnacle/barnacle_sheet",
"models/headcrab_black/blackcrab_sheet",
"models/headcrab/allinonebacup2",
"models/headcrab_classic/headcrabsheet",
"models/stalker/stalker_sheet",
"models/zombie_poison/poisonzombie_sheet",
"models/zombie_fast/fast_zombie_sheet",
"models/gunship/gunshipsheet",
"models/shield_scanner/minelayer_sheet",
"models/roller/rollermine_sheet",
"models/dog/dog_sheet",
"models/gibs/combine_helicopter_gibs/combine_helicopter01",
"models/synth/mainbody",
"models/combine_room/combine_monitor001",
"models/items/combinerifle_ammo",
"models/shadertest/shader2",
"models/props_combine/combine_train001",
"models/props_combine/combinethumper001",
"models/props_combine/health_charger001",
"models/props_combine/masterinterface01",
"models/props_combine/introomarea_sheet",
"models/props_combine/combine_bunker01",
"models/props_combine/weaponstripper_sheet",
"models/props_combine/tpcontroller_sheet",
"models/props_combine/combine_tower01a",
"models/combine_mine/combine_mine03",
"models/magnusson_teleporter/magnusson_teleporter",
"models/combine_strider/strider_brain",
"models/combine_advisor_pod/combine_advisor_pod",
"models/magnusson_device/magnusson_device_basecolor",
"models/antlion_grub/antlion_grub",
"models/antlion/antlion_worker_wing",
"models/antlion/antlion_worker",
"models/ministrider/mini_skin_basecolor",
"models/ministrider/mini_armor_basecolor",
"models/spitball/spitball",
"models/mossman/mossman_hair",
"models/alyx/hairbits",
"models/brokenglass/glassbroken_piece1",
"models/props_halloween/flask",
"models/props_halloween/flask_liquid",
"models/props_halloween/flask_glass",
"models/props_halloween/pumpkin",
"models/props_mining/dustbowl_roof01",
"models/props_mvm/mvm_museum_coal",
"models/effects/partyhat",
"models/props_gameplay/ball001",
"models/props_gameplay/orange_cone001",
"models/player/items/soldier/dappertopper",
"models/weapons/c_items/c_candy_cane_red",
"models/props_halloween/halloween_blk",
"models/props_halloween/halloween_demoeye_glass_2",
"models/props_halloween/halloween_demoeye_glass",
"models/weapons/c_items/c_saxxy",
"models/props_halloween/scary_ghost",
"models/weapons/c_items/c_urinejar_urine",
"models/weapons/c_items/c_xms_cold_shoulder",
"models/props_wasteland/rockcliff02c",
"models/props_lakeside/flat_wall_02",
"models/props_manor/table_01b",
"models/props_manor/volume_light_01",
"models/props_medieval/stone_base001",
"models/props_medieval/fort_wall",
"models/props_mining/quarryrock02",
"models/props_nature/rock_worn001",
"models/props_swamp/tallgrass_01",
"models/props_swamp/shrub_03",
"models/props_viaduct_event/fog_plane03",
"models/weapons/v_baseball/baseball_sheet",
"hunter/myplastic",
"models/player/items/all_class/all_class_ring_diamond",
"models/effects/invulnfx_blue",
"models/effects/invulnfx_red",
"models/effects/goldenwrench",
"models/effects/cappoint_beam_neutral",
"models/effects/cappoint_beam_blue",
"models/effects/cappoint_beam_red",
"models/effects/medicyell",
"models/effects/pyro/pilotlight",
"models/effects/pyro/pilotlight_cloak",
"models/effects/pyro/pilotlight_motion",
"models/effects/invulnerability/invulnerability_red",
"models/effects/invulnerability/invulnerability_blue",
"models/effects/muzzleflash/blurmuzzle",
"models/effects/muzzleflash/brightmuzzle",
"models/lilchewchew/embers",
"models/pl_hoodoo/metaldoor001",
"models/thundermountain_fx/ibeam002_vert",
"models/thundermountain_fx/wall025_vert",
"models/thundermountain_fx/wood_beam03_vert",
"models/thundermountain_fx/wood_bridge001_vert",
"models/thundermountain_fx/wood_wall002_vert",
"models/shadertest/envball_1",
"models/shadertest/envball_2",
"models/shadertest/envball_3",
"models/shadertest/envball_4",
"models/shadertest/envball_5",
"models/shadertest/envball_6",
"models/shadertest/glassbrick",
"models/shadertest/point_camera",
"models/shadertest/shader1",
"models/shadertest/shader1_dudv",
"models/shadertest/shield",
"models/shadertest/unlitgenericmodel",
"models/shadertest/vertexlitalphatestedtexture",
"models/ihvtest/arm",
"models/ihvtest/boot",
"models/ihvtest/eyeball_l",
-- zpankr's material list
-- http://www.garrysmod.org/downloads/?a=view&id=18470
"models/wireframe",
"debug/env_cubemap_model",
"models/shadertest/shader3",
"models/shadertest/shader4",
"models/shadertest/shader5",
"models/shiny",
"models/debug/debugwhite",
"Models/effects/comball_sphere",
"Models/effects/comball_tape",
"Models/effects/splodearc_sheet",
"Models/effects/vol_light001",
"models/props_combine/stasisshield_sheet",
"models/props_combine/portalball001_sheet",
"models/props_combine/com_shield001a",
"models/props_c17/frostedglass_01a",
"models/props_lab/Tank_Glass001",
"models/props_combine/tprings_globe",
"models/rendertarget",
"models/screenspace",
"brick/brick_model",
"models/props_pipes/GutterMetal01a",
"models/props_pipes/Pipesystem01a_skin3",
"models/props_wasteland/wood_fence01a",
"models/props_c17/FurnitureFabric003a",
"models/props_c17/FurnitureMetal001a",
"models/props_c17/paper01",
"models/flesh",
"models/airboat/airboat_blur02",
"models/alyx/emptool_glow",
"models/antlion/antlion_innards",
"models/barnacle/roots",
"models/combine_advisor/body9",
"models/combine_advisor/mask",
"models/combine_scanner/scanner_eye",
"models/debug/debugwhite",
"models/dog/eyeglass",
"models/effects/comball_glow1",
"models/effects/comball_glow2",
"models/effects/portalrift_sheet",
"models/effects/slimebubble_sheet",
"models/effects/splode1_sheet",
"models/effects/splodearc_sheet",
"models/effects/splode_sheet",
"models/effects/vol_light001",
"models/gibs/woodgibs/woodgibs01",
"models/gibs/woodgibs/woodgibs02",
"models/gibs/woodgibs/woodgibs03",
"models/gibs/metalgibs/metal_gibs",
"models/items/boxsniperrounds",
"models/player/player_chrome1",
"models/props_animated_breakable/smokestack/brickwall002a",
"models/props_building_details/courtyard_template001c_bars",
"models/props_building_details/courtyard_template001c_bars",
"models/props_buildings/destroyedbuilldingwall01a",
"models/props_buildings/plasterwall021a",
"models/props_c17/frostedglass_01a",
"models/props_c17/furniturefabric001a",
"models/props_c17/furniturefabric002a",
"models/props_c17/furnituremetal001a",
"models/props_c17/gate_door02a",
"models/props_c17/metalladder001",
"models/props_c17/metalladder002",
"models/props_c17/metalladder003",
"models/props_canal/canalmap_sheet",
"models/props_canal/canal_bridge_railing_01a",
"models/props_canal/canal_bridge_railing_01b",
"models/props_canal/canal_bridge_railing_01c",
"models/props_canal/coastmap_sheet",
"models/props_canal/metalcrate001d",
"models/props_canal/metalwall005b",
"models/props_canal/rock_riverbed01a",
"models/props_combine/citadel_cable",
"models/props_combine/combine_interface_disp",
"models/props_combine/combine_monitorbay_disp",
"models/props_combine/com_shield001a",
"models/props_combine/health_charger_glass",
"models/props_combine/metal_combinebridge001",
"models/props_combine/pipes01",
"models/props_combine/pipes03",
"models/props_combine/prtl_sky_sheet",
"models/props_combine/stasisfield_beam",
"models/props_debris/building_template010a",
"models/props_debris/building_template022j",
"models/props_debris/composite_debris",
"models/props_debris/concretefloor013a",
"models/props_debris/concretefloor020a",
"models/props_debris/concretewall019a",
"models/props_debris/metalwall001a",
"models/props_debris/plasterceiling008a",
"models/props_debris/plasterwall009d",
"models/props_debris/plasterwall021a",
"models/props_debris/plasterwall034a",
"models/props_debris/plasterwall034d",
"models/props_debris/plasterwall039c",
"models/props_debris/plasterwall040c",
"models/props_debris/tilefloor001c",
"models/props_foliage/driftwood_01a",
"models/props_foliage/oak_tree01",
"models/props_interiors/metalfence007a",
"models/props_junk/plasticcrate01a",
"models/props_junk/plasticcrate01b",
"models/props_junk/plasticcrate01c",
"models/props_junk/plasticcrate01d",
"models/props_junk/plasticcrate01e",
"models/props_lab/cornerunit_cloud",
"models/props_lab/door_klab01",
"models/props_lab/security_screens",
"models/props_lab/security_screens2",
"models/props_lab/Tank_Glass001",
"models/props_lab/warp_sheet",
"models/props_lab/xencrystal_sheet",
"models/props_pipes/destroyedpipes01a",
"models/props_pipes/GutterMetal01a",
"models/props_pipes/pipeset_metal02",
"models/props_pipes/pipesystem01a_skin1",
"models/props_pipes/pipesystem01a_skin2",
"models/props_vents/borealis_vent001",
"models/props_vents/borealis_vent001b",
"models/props_vents/borealis_vent001c",
"models/props_wasteland/concretefloor010a",
"models/props_wasteland/concretewall064b",
"models/props_wasteland/concretewall066a",
"models/props_wasteland/dirtwall001a",
"models/props_wasteland/metal_tram001a",
"models/props_wasteland/quarryobjects01",
"models/props_wasteland/rockcliff02a",
"models/props_wasteland/rockcliff02b",
"models/props_wasteland/rockcliff02c",
"models/props_wasteland/rockcliff04a",
"models/props_wasteland/rockgranite02a",
"models/props_wasteland/tugboat01",
"models/props_wasteland/tugboat02",
"models/props_wasteland/wood_fence01a",
"models/props_wasteland/wood_fence01a_skin2",
"models/roller/rollermine_glow",
"models/weapons/v_crossbow/rebar_glow",
"models/weapons/v_crowbar/crowbar_cyl",
"models/weapons/v_grenade/grenade body",
"models/weapons/v_smg1/texture5",
"models/weapons/w_smg1/smg_crosshair",
"models/weapons/v_slam/new light2",
"models/weapons/v_slam/new light1",
"models/props/cs_assault/dollar",
"models/props/cs_assault/fireescapefloor",
"models/props/cs_assault/metal_stairs1",
"models/props/cs_assault/moneywrap",
"models/props/cs_assault/moneywrap02",
"models/props/cs_assault/moneytop",
"models/props/cs_assault/pylon",
"models/props/CS_militia/boulder01",
"models/props/CS_militia/milceil001",
"models/props/CS_militia/militiarock",
"models/props/CS_militia/militiarockb",
"models/props/CS_militia/milwall006",
"models/props/CS_militia/rocks01",
"models/props/CS_militia/roofbeams01",
"models/props/CS_militia/roofbeams02",
"models/props/CS_militia/roofbeams03",
"models/props/CS_militia/RoofEdges",
"models/props/cs_office/clouds",
"models/props/cs_office/file_cabinet2",
"models/props/cs_office/file_cabinet3",
"models/props/cs_office/screen",
"models/props/cs_office/snowmana",
"models/props/de_inferno/de_inferno_boulder_03",
"models/props/de_inferno/infflra",
"models/props/de_inferno/infflrd",
"models/props/de_inferno/inftowertop",
"models/props/de_inferno/offwndwb_break",
"models/props/de_inferno/roofbits",
"models/props/de_inferno/tileroof01",
"models/props/de_inferno/woodfloor008a",
"models/props/de_nuke/nukconcretewalla",
"models/props/de_nuke/nukecardboard",
"models/props/de_nuke/pipeset_metal",
"models/shadertest/predator",
}
pace.Materials.trails =
{
"trails/plasma",
"trails/tube",
"trails/electric",
"trails/smoke",
"trails/laser",
"trails/physbeam",
"trails/love",
"trails/lol",
"sprites/rollermine_shock_yellow",
"sprites/yellowlaser1",
"particle/beam_smoke_01",
"particle/beam_smoke_02",
"particle/bendibeam_nofog",
"sprites/physbeam",
"sprites/physbeama",
"sprites/rollermine_shock",
"sprites/hydraspinalcord",
"particle/Particle_Square_Gradient",
"particle/Particle_Square_Gradient_NoFog",
}
pace.Materials.sprites =
{
"sprites/glow04_noz",
"sprites/grip",
"sprites/key_0",
"sprites/key_1",
"sprites/key_10",
"sprites/key_11",
"sprites/key_12",
"sprites/key_13",
"sprites/key_14",
"sprites/key_15",
"sprites/key_2",
"sprites/key_3",
"sprites/key_4",
"sprites/key_5",
"sprites/key_6",
"sprites/key_7",
"sprites/key_8",
"sprites/key_9",
"sprites/light_ignorez",
"sprites/muzzleflash4",
"sprites/orangecore1",
"sprites/orangecore2",
"sprites/orangeflare1",
"sprites/physg_glow1",
"sprites/physg_glow2",
"sprites/physgbeamb",
"sprites/redglow1",
"sprites/animglow02",
"sprites/ar2_muzzle1",
"sprites/ar2_muzzle3",
"sprites/ar2_muzzle4",
"sprites/arrow",
"sprites/blueglow2",
"sprites/bluelaser1",
"sprites/dot",
"sprites/flamelet1",
"sprites/flamelet2",
"sprites/flamelet3",
"sprites/flamelet4",
"sprites/flamelet5",
"sprites/heatwave",
"sprites/heatwavedx70",
"sprites/hydragutbeam",
"sprites/hydragutbeamcap",
"sprites/light_glow02_add",
"sprites/light_glow02_add_noz",
"sprites/plasmaember",
"sprites/predator",
"sprites/qi_center",
"sprites/reticle",
"sprites/reticle1",
"sprites/reticle2",
"sprites/rico1",
"sprites/rico1_noz",
"sprites/scanner",
"sprites/scanner_bottom",
"sprites/scanner_dots1",
"sprites/scanner_dots2",
"sprites/strider_blackball",
"sprites/strider_bluebeam",
"sprites/tp_beam001",
"sprites/bucket_bat_blue",
"sprites/bucket_bat_red",
"sprites/bucket_bonesaw",
"sprites/bucket_bottle_blue",
"sprites/bucket_bottle_red",
"sprites/bucket_fireaxe",
"sprites/bucket_fists_blue",
"sprites/bucket_fists_red",
"sprites/bucket_flamethrower_blue",
"sprites/bucket_flamethrower_red",
"sprites/bucket_grenlaunch",
"sprites/bucket_knife",
"sprites/bucket_machete",
"sprites/bucket_medigun_blue",
"sprites/bucket_medigun_red",
"sprites/bucket_minigun",
"sprites/bucket_nailgun",
"sprites/bucket_pda",
"sprites/bucket_pda_build",
"sprites/bucket_pda_destroy",
"sprites/bucket_pipelaunch",
"sprites/bucket_pistol",
"sprites/bucket_revolver",
"sprites/bucket_rl",
"sprites/bucket_sapper",
"sprites/bucket_scatgun",
"sprites/bucket_shotgun",
"sprites/bucket_shovel",
"sprites/bucket_smg",
"sprites/bucket_sniper",
"sprites/bucket_syrgun_blue",
"sprites/bucket_syrgun_red",
"sprites/bucket_tranq",
"sprites/bucket_wrench",
"sprites/healbeam",
"sprites/healbeam_blue",
"sprites/healbeam_red",
"sprites/640_pain_down",
"sprites/640_pain_left",
"sprites/640_pain_right",
"sprites/640_pain_up",
"sprites/bomb_carried",
"sprites/bomb_carried_ring",
"sprites/bomb_carried_ring_offscreen",
"sprites/bomb_dropped",
"sprites/bomb_dropped_ring",
"sprites/bomb_planted",
"sprites/bomb_planted_ring",
"sprites/c4",
"sprites/defuser",
"sprites/hostage_following",
"sprites/hostage_following_offscreen",
"sprites/hostage_rescue",
"sprites/numbers",
"sprites/objective_rescue",
"sprites/objective_site_a",
"sprites/objective_site_b",
"sprites/player_blue_dead",
"sprites/player_blue_dead_offscreen",
"sprites/player_blue_offscreen",
"sprites/player_blue_self",
"sprites/player_blue_small",
"sprites/player_hostage_dead",
"sprites/player_hostage_dead_offscreen",
"sprites/player_hostage_offscreen",
"sprites/player_hostage_small",
"sprites/player_radio_ring",
"sprites/player_radio_ring_offscreen",
"sprites/player_red_dead",
"sprites/player_red_dead_offscreen",
"sprites/player_red_offscreen",
"sprites/player_red_self",
"sprites/player_red_small",
"sprites/player_tick",
"sprites/radar",
"sprites/radar_trans",
"sprites/radio",
"sprites/scope_arc",
"sprites/shopping_cart",
"sprites/spectator_3rdcam",
"sprites/spectator_eye",
"sprites/spectator_freecam",
"sprites/cloudglow1_nofog",
"sprites/core_beam1",
"sprites/bluelight",
"sprites/grav_flare",
"sprites/grav_light",
"sprites/orangelight",
"sprites/portalgun_effects",
"sprites/sphere_silhouette",
"sprites/redglow_mp1",
"sprites/sent_ball",
"particle/fire",
"particle/particle_composite",
"particle/Particle_Crescent",
"particle/Particle_Crescent_Additive",
"particle/Particle_Glow_02",
"particle/Particle_Glow_03",
"particle/Particle_Glow_03_Additive",
"particle/Particle_Glow_04",
"particle/Particle_Glow_04_Additive",
"particle/Particle_Glow_05",
"particle/particle_noisesphere",
"particle/Particle_Ring_Blur",
"particle/particle_ring_refract_01",
"particle/Particle_Ring_Sharp",
"particle/Particle_Ring_Sharp_Additive",
"particle/Particle_Ring_Wave_8",
"particle/Particle_Ring_Wave_8_15OB_NoFog",
"particle/Particle_Ring_Wave_Additive",
"particle/Particle_Ring_Wave_AddNoFog",
"particle/particle_smokegrenade",
"particle/particle_smokegrenade1",
"particle/particle_sphere",
"particle/rain",
"particle/smokesprites_0001",
"particle/smokesprites_0002",
"particle/smokesprites_0003",
"particle/smokesprites_0004",
"particle/smokesprites_0005",
"particle/smokesprites_0006",
"particle/smokesprites_0007",
"particle/smokesprites_0008",
"particle/smokesprites_0009",
"particle/smokesprites_0010",
"particle/smokesprites_0011",
"particle/smokesprites_0012",
"particle/smokesprites_0013",
"particle/smokesprites_0014",
"particle/smokesprites_0015",
"particle/smokesprites_0016",
"particle/SmokeStack",
"particle/snow",
"particle/sparkles",
"particle/warp1_warp",
"particle/warp2_warp",
"particle/warp3_warp_NoZ",
"particle/warp4_warp",
"particle/warp4_warp_NoZ",
"particle/warp5_warp",
"particle/warp_ripple",
"particle/glow_haze_nofog",
"particle/smoke_black_smokestack000",
"particle/smoke_black_smokestack001",
"particle/smoke_black_smokestack_all",
"particle/smokestack_nofog",
"particle/particle_rockettrail2",
"particles/balloon_bit",
"particles/fire1",
"particles/fire_glow",
"particles/flamelet1",
"particles/flamelet2",
"particles/flamelet3",
"particles/flamelet4",
"particles/flamelet5",
"particles/smokey",
}
local PANEL = {}
PANEL.ClassName = "mat_browser_sheet"
PANEL.Base = "DPanel"
AccessorFunc(PANEL, "m_Selected", "Selected")
function PANEL:Init()
local list = vgui.Create("DPanelList", self)
list:SetPadding(2)
list:SetSpacing(2)
list:EnableVerticalScrollbar(true)
list:EnableHorizontal(true)
list:Dock(FILL)
self.MatList = list
end
function PANEL:Paint(w, h)
surface.SetDrawColor(0,0,0, 255)
surface.DrawRect(0, 0, w, h)
end
local cache = {}
local function IsError(path)
if cache[path] then return true end
if Material(path):IsError() then
cache[path] = truer
return true
end
end
function PANEL:SetMaterialList(tbl)
self:SetSelected()
self.MaterialList = tbl
self.MatList:Clear(true)
for i, material in pairs(self.MaterialList) do
-- if IsError(material) then continue end
local image = vgui.Create("DImageButton")
image.m_Image.LoadMaterial = function(s) s:DoLoadMaterial() end
image:SetOnViewMaterial(material, material)
image:SetSize(64, 64)
image.Value = material
self.MatList:AddItem(image)
image.DoClick = function(image) self:SetSelected(image.Value) end
if self:GetSelected() then
image.PaintOver = HighlightedButtonPaint
self:SetSelected(material)
end
end
self:InvalidateLayout(true)
end
pace.RegisterPanel(PANEL)
local PANEL = {}
PANEL.Base = "DFrame"
PANEL.ClassName = "mat_browser"
function PANEL:Init()
self:SetTitle("materials")
local list =
{
{key = "default", val = table.Merge(list.Get("OverrideMaterials"), pace.Materials.materials)},
{key = "sprites", val = pace.Materials.sprites},
{key = "trails", val = pace.Materials.trails},
}
local sheet = vgui.Create("DPropertySheet", self)
sheet:Dock(FILL)
for _, data in pairs(list) do
local name, tbl = data.key, data.val
local pnl = pace.CreatePanel("mat_browser_sheet", self)
pnl:SetMaterialList(tbl)
pnl.SetSelected = function(_, path) self:SetSelected(path) end
sheet:AddSheet(name, pnl)
end
local entry = vgui.Create("DTextEntry", self)
entry.OnEnter = function() self:SetSelected(self.Entry:GetValue()) end
entry:Dock(BOTTOM)
entry:SetTall(20)
self.Entry = entry
self:SetDrawOnTop(true)
self:SetSize(300, 300)
self:SetSizable(true)
self:Center()
end
function PANEL:SetSelected(value)
self.Entry:SetText(value or "")
self.m_Selected = value
self:MaterialSelected(value)
end
function PANEL:MaterialSelected(path) end
pace.RegisterPanel(PANEL)

View File

@@ -0,0 +1,567 @@
--[[
| 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 PANEL = vgui.Register("pac_dtree_node_button", {}, "DButton")
pace.pac_dtree_node_button = PANEL
function PANEL:Init()
self:SetTextInset(32, 0)
self:SetContentAlignment(4)
end
function PANEL:Paint(w, h)
derma.SkinHook("Paint", "TreeNodeButton", self, w, h)
return false
end
function PANEL:UpdateColours(skin)
if self:IsSelected() then return self:SetTextStyleColor(skin.Colours.Tree.Selected) end
if self.Hovered then return self:SetTextStyleColor(skin.Colours.Tree.Hover) end
return self:SetTextStyleColor(skin.Colours.Tree.Normal)
end
local PANEL = vgui.Register("pac_dtree", {}, "DScrollPanel")
pace.pac_dtree = PANEL
AccessorFunc(PANEL, "m_bShowIcons", "ShowIcons")
AccessorFunc(PANEL, "m_iIndentSize", "IndentSize")
AccessorFunc(PANEL, "m_iLineHeight", "LineHeight")
AccessorFunc(PANEL, "m_pSelectedItem", "SelectedItem")
AccessorFunc(PANEL, "m_bClickOnDragHover", "ClickOnDragHover")
function PANEL:Init()
self:SetShowIcons(true)
self:SetIndentSize(14)
self:SetLineHeight(17)
self.RootNode = self:GetCanvas():Add("pac_dtree_node")
self.RootNode:SetRoot(self)
self.RootNode:SetParentNode(self)
self.RootNode:SetSize(5,5)
self.RootNode:Dock(TOP)
self.RootNode:SetText("")
self.RootNode:SetExpanded(true, true)
self.RootNode:DockMargin(0, 0, 0, 0)
self:SetPaintBackground(true)
end
function PANEL:Root()
return self.RootNode
end
function PANEL:AddNode(strName, strIcon)
return self.RootNode:AddNode(strName, strIcon)
end
function PANEL:ChildExpanded(bExpand)
self:InvalidateLayout()
end
function PANEL:ShowIcons()
return self.m_bShowIcons
end
function PANEL:ExpandTo(bExpand)
end
function PANEL:SetExpanded(bExpand)
end
function PANEL:Clear()
end
function PANEL:Paint(w, h)
derma.SkinHook("Paint", "Tree", self, w, h)
return true
end
function PANEL:DoClick(node)
return false
end
function PANEL:DoRightClick(node)
return false
end
function PANEL:SetSelectedItem(node)
if IsValid(self.m_pSelectedItem) then
self.m_pSelectedItem:SetSelected(false)
self:OnNodeDeselected(self.m_pSelectedItem)
end
self.m_pSelectedItem = node
if node then
node:SetSelected(true)
node:OnNodeSelected(node)
end
end
function PANEL:OnNodeSelected(node)
end
function PANEL:OnNodeDeselected(node)
end
function PANEL:MoveChildTo(child, pos)
self:InsertAtTop(child)
end
function PANEL:LayoutTree()
self:InvalidateChildren(true)
end
local PANEL = vgui.Register("pac_dtree_node", {}, "DPanel")
pace.pac_dtree_node = PANEL
AccessorFunc(PANEL, "m_pRoot", "Root")
AccessorFunc(PANEL, "m_pParentNode", "ParentNode")
AccessorFunc(PANEL, "m_strPathID", "PathID")
AccessorFunc(PANEL, "m_strWildCard", "WildCard")
AccessorFunc(PANEL, "m_bNeedsPopulating", "NeedsPopulating")
AccessorFunc(PANEL, "m_bDirty", "Dirty", FORCE_BOOL)
AccessorFunc(PANEL, "m_bNeedsChildSearch", "NeedsChildSearch", FORCE_BOOL)
AccessorFunc(PANEL, "m_bForceShowExpander", "ForceShowExpander", FORCE_BOOL)
AccessorFunc(PANEL, "m_bHideExpander", "HideExpander", FORCE_BOOL)
AccessorFunc(PANEL, "m_bDoubleClickToOpen", "DoubleClickToOpen", FORCE_BOOL)
AccessorFunc(PANEL, "m_bLastChild", "LastChild", FORCE_BOOL)
AccessorFunc(PANEL, "m_bDrawLines", "DrawLines", FORCE_BOOL)
AccessorFunc(PANEL, "m_strDraggableName", "DraggableName")
function PANEL:Init()
self:SetDoubleClickToOpen(true)
self.Label = vgui.Create("pac_dtree_node_button", self)
self.Label:SetDragParent(self)
self.Label.DoClick = function() self:InternalDoClick() end
self.Label.DoDoubleClick = function() self:InternalDoClick() end
self.Label.DoRightClick = function() self:InternalDoRightClick() end
self.Label.DragHover = function(s, t) self:DragHover(t) end
self.Expander = vgui.Create("DExpandButton", self)
self.Expander.DoClick = function() self:SetExpanded( not self.m_bExpanded) end
self.Expander:SetVisible(false)
self.Icon = vgui.Create("DImage", self)
self.Icon:SetImage("icon16/folder.png")
self.Icon:SizeToContents()
self.fLastClick = SysTime()
self:SetDrawLines(false)
self:SetLastChild(false)
end
function PANEL:SetRoot(root)
self.m_pRoot = root
root.added_nodes = root.added_nodes or {}
for i,v in ipairs(root.added_nodes) do
if v == self then return end
end
table.insert(root.added_nodes, self)
end
function PANEL:OnRemove()
local root = self:GetRoot()
if not IsValid(root) then return end
root.added_nodes = root.added_nodes or {}
for i,v in ipairs(root.added_nodes) do
if v == self then
table.remove(root.added_nodes, i)
break
end
end
end
function PANEL:IsRootNode()
return self.m_pRoot == self.m_pParentNode
end
function PANEL:InternalDoClick()
self:GetRoot():SetSelectedItem(self)
if self:DoClick() then return end
if self:GetRoot():DoClick(self) then return end
if not self.m_bDoubleClickToOpen or (SysTime() - self.fLastClick < 0.3) then
self:SetExpanded( not self.m_bExpanded)
end
self.fLastClick = SysTime()
end
function PANEL:OnNodeSelected(node)
local parent = self:GetParentNode()
if IsValid(parent) and parent.OnNodeSelected then
parent:OnNodeSelected(node)
end
end
function PANEL:InternalDoRightClick()
if self:DoRightClick() then return end
if self:GetRoot():DoRightClick(self) then return end
end
function PANEL:DoClick()
return false
end
function PANEL:DoRightClick()
return false
end
function PANEL:SetIcon(str)
if not str then return end
if str == "" then return end
self.Icon:SetImage(str)
end
function PANEL:ShowIcons()
return self:GetParentNode():ShowIcons()
end
function PANEL:GetLineHeight()
return self:GetParentNode():GetLineHeight()
end
function PANEL:GetIndentSize()
return self:GetParentNode():GetIndentSize()
end
function PANEL:SetText(strName)
self.Label:SetText(strName)
end
function PANEL:ExpandRecurse(bExpand)
self:SetExpanded(bExpand, true)
if not self.ChildNodes then return end
for k, Child in pairs(self.ChildNodes:GetItems()) do
if Child.ExpandRecurse then
Child:ExpandRecurse(bExpand)
end
end
end
function PANEL:ExpandTo(bExpand)
self:SetExpanded(bExpand, true)
self:GetParentNode():ExpandTo(bExpand)
end
function PANEL:IsExpanded()
local parent = self:GetParent():GetParent()
while IsValid(parent) and parent.m_bExpanded ~= nil do
if parent.m_bExpanded == false then
return false
end
parent = parent:GetParent():GetParent()
end
return true
end
function PANEL:SetExpanded(bExpand)
if self.m_pParentNode:IsValid() then
self:GetParentNode():ChildExpanded(bExpand)
end
self.Expander:SetExpanded(bExpand)
self.m_bExpanded = bExpand
self:InvalidateLayout(true)
if not self.ChildNodes then return end
local StartTall = self:GetTall()
if self.ChildNodes then
self.ChildNodes:SetVisible(bExpand)
if bExpand then
self.ChildNodes:InvalidateLayout(true)
end
end
self:InvalidateLayout(true)
end
function PANEL:ChildExpanded(bExpand)
self.ChildNodes:InvalidateLayout(true)
self:InvalidateLayout(true)
self:GetParentNode():ChildExpanded(bExpand)
end
function PANEL:Paint()
end
function PANEL:HasChildren()
if not IsValid(self.ChildNodes) then return false end
return self.ChildNodes:HasChildren()
end
function PANEL:DoChildrenOrder()
if not self.ChildNodes then return end
local last = table.Count(self.ChildNodes:GetChildren())
for k, Child in pairs(self.ChildNodes:GetChildren()) do
Child:SetLastChild(k == last)
end
end
function PANEL:PerformRootNodeLayout()
self.Expander:SetVisible(false)
self.Label:SetVisible(false)
self.Icon:SetVisible(false)
if IsValid(self.ChildNodes) then
self.ChildNodes:Dock(TOP)
self:SetTall(self.ChildNodes:GetTall())
end
end
function PANEL:PerformLayout()
if self:IsRootNode() then
return self:PerformRootNodeLayout()
end
local LineHeight = self:GetLineHeight()
if self.m_bHideExpander then
self.Expander:SetPos(-11, 0)
self.Expander:SetSize(15, 15)
self.Expander:SetVisible(false)
else
self.Expander:SetPos(2, 0)
self.Expander:SetSize(15, 15)
self.Expander:SetVisible(self:HasChildren() or self:GetForceShowExpander())
self.Expander:SetZPos(10)
end
self.Label:StretchToParent(0, nil, 0, nil)
self.Label:SetTall(LineHeight)
if self:ShowIcons() then
self.Icon:SetVisible(true)
self.Icon:SetPos(self.Expander.x + self.Expander:GetWide() + 4, (LineHeight - self.Icon:GetTall()) * 0.5)
self.Label:SetTextInset(self.Icon.x + self.Icon:GetWide() + 4, 0)
else
self.Icon:SetVisible(false)
self.Label:SetTextInset(self.Expander.x + self.Expander:GetWide() + 4, 0)
end
if not self.ChildNodes or not self.ChildNodes:IsVisible() then
self:SetTall(LineHeight)
return end
self.ChildNodes:SizeToContents()
self:SetTall(LineHeight + self.ChildNodes:GetTall())
self.ChildNodes:StretchToParent(LineHeight, LineHeight, 0, 0)
self:DoChildrenOrder()
end
function PANEL:CreateChildNodes()
if self.ChildNodes then return end
self.ChildNodes = vgui.Create("DListLayout", self)
self.ChildNodes:SetDropPos("852")
self.ChildNodes:SetVisible(self.m_bExpanded)
self.ChildNodes.OnChildRemoved = function()
self.ChildNodes:InvalidateLayout()
end
self.ChildNodes.OnModified = function()
self:OnModified()
end
self:InvalidateLayout()
end
function PANEL:AddPanel(pPanel)
self:CreateChildNodes()
self.ChildNodes:Add(pPanel)
self:InvalidateLayout()
end
function PANEL:AddNode(strName, strIcon)
self:CreateChildNodes()
local pNode = vgui.Create("pac_dtree_node", self)
pNode:SetText(strName)
pNode:SetParentNode(self)
pNode:SetRoot(self:GetRoot())
pNode:SetIcon(strIcon)
pNode:SetDrawLines( not self:IsRootNode())
self:InstallDraggable(pNode)
self.ChildNodes:Add(pNode)
self:InvalidateLayout()
return pNode
end
function PANEL:InsertNode(pNode)
self:CreateChildNodes()
pNode:SetParentNode(self)
pNode:SetRoot(self:GetRoot())
self:InstallDraggable(pNode)
self.ChildNodes:Add(pNode)
self:InvalidateLayout()
return pNode
end
function PANEL:InstallDraggable(pNode)
local DragName = self:GetDraggableName()
if not DragName then return end
-- Make this node draggable
pNode:SetDraggableName(DragName)
pNode:Droppable(DragName)
-- Allow item dropping onto us
self.ChildNodes:MakeDroppable(DragName, true, true)
end
function PANEL:DroppedOn(pnl)
self:InsertNode(pnl)
self:SetExpanded(true)
end
function PANEL:SetSelected(b)
self.Label:SetSelected(b)
self.Label:InvalidateLayout()
if self.OnSelected then
self:OnSelected(b)
end
end
function PANEL:DragHoverClick(HoverTime)
if not self.m_bExpanded then
self:SetExpanded(true)
end
if self:GetRoot():GetClickOnDragHover() then
self:InternalDoClick()
end
end
function PANEL:MoveToTop()
local parent = self:GetParentNode()
if not IsValid(parent) then return end
self:GetParentNode():MoveChildTo(self, 1)
end
function PANEL:MoveChildTo(child)
self.ChildNodes:InsertAtTop(child)
end
function PANEL:GetText()
return self.Label:GetText()
end
function PANEL:GetIcon()
return self.Icon:GetImage()
end
function PANEL:CleanList()
for k, panel in pairs(self.Items) do
if not IsValid(panel) or panel:GetParent() ~= self.pnlCanvas then
self.Items[k] = nil
end
end
end
function PANEL:Insert(pNode, pNodeNextTo, bBefore)
pNode:SetParentNode(self)
pNode:SetRoot(self:GetRoot())
self:CreateChildNodes()
if bBefore then
self.ChildNodes:InsertBefore(pNodeNextTo, pNode)
else
self.ChildNodes:InsertAfter(pNodeNextTo, pNode)
end
self:InvalidateLayout()
end
function PANEL:LeaveTree(pnl)
self.ChildNodes:RemoveItem(pnl, true)
self:InvalidateLayout()
end
function PANEL:OnModified()
end
function PANEL:GetChildNode(iNum)
if not IsValid(self.ChildNodes) then return end
return self.ChildNodes:GetChild(iNum)
end
function PANEL:Paint(w, h)
derma.SkinHook("Paint", "TreeNode", self, w, h)
end
function PANEL:Copy()
local copy = vgui.Create("pac_dtree_node", self:GetParent())
copy:SetText(self:GetText())
copy:SetIcon(self:GetIcon())
copy:SetRoot(self:GetRoot())
copy:SetParentNode(self:GetParentNode())
if self.ChildNodes then
for k, v in pairs(self.ChildNodes:GetChildren()) do
local childcopy = v:Copy()
copy:InsertNode(childcopy)
end
end
self:SetupCopy(copy)
return copy
end
function PANEL:SetupCopy(copy)
end
if Entity(1):IsPlayer() and not PAC_RESTART and not VLL2_FILEDEF then
pace.OpenEditor()
pace.RefreshTree(true)
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,423 @@
--[[
| 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/
--]]
do
local PANEL = vgui.Register("pac_horizontal_scrollbar", {}, "Panel")
AccessorFunc( PANEL, "m_HideButtons", "HideButtons" )
function PANEL:Init()
self.Offset = 0
self.Scroll = 0
self.CanvasSize = 1
self.BarSize = 1
self.btnLeft = vgui.Create( "DButton", self )
self.btnLeft:SetText( "" )
self.btnLeft.DoClick = function( self ) self:GetParent():AddScroll( -1 ) end
self.btnLeft.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonLeft", panel, w, h ) end
self.btnRight = vgui.Create( "DButton", self )
self.btnRight:SetText( "" )
self.btnRight.DoClick = function( self ) self:GetParent():AddScroll( 1 ) end
self.btnRight.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonRight", panel, w, h ) end
self.btnGrip = vgui.Create( "DScrollBarGrip", self )
self.btnGrip.Paint = function(panel,w,h)
local skin = panel:GetSkin()
if ( panel:GetDisabled() ) then
skin.tex.Scroller.ButtonH_Disabled( 0, 0, w, h )
elseif ( panel.Depressed ) then
return skin.tex.Scroller.ButtonH_Down( 0, 0, w, h )
elseif ( panel.Hovered ) then
return skin.tex.Scroller.ButtonH_Hover( 0, 0, w, h )
else
skin.tex.Scroller.ButtonH_Normal( 0, 0, w, h )
end
return true
end
self:SetSize( 15, 15 )
self:SetHideButtons( false )
end
function PANEL:SetEnabled( b )
if ( !b ) then
self.Offset = 0
self:SetScroll( 0 )
self.HasChanged = true
end
self:SetMouseInputEnabled( b )
self:SetVisible( b )
-- We're probably changing the width of something in our parent
-- by appearing or hiding, so tell them to re-do their layout.
if ( self.Enabled != b ) then
self:GetParent():InvalidateLayout()
if ( self:GetParent().OnScrollbarAppear ) then
self:GetParent():OnScrollbarAppear()
end
end
self.Enabled = b
end
function PANEL:Value()
return self.Pos
end
function PANEL:BarScale()
if ( self.BarSize == 0 ) then return 1 end
return self.BarSize / ( self.CanvasSize + self.BarSize )
end
function PANEL:SetUp( _barsize_, _canvassize_ )
self.BarSize = _barsize_
self.CanvasSize = math.max( _canvassize_ - _barsize_, 1 )
self:SetEnabled( _canvassize_ > _barsize_ )
self:InvalidateLayout()
end
function PANEL:OnMouseWheeled( dlta )
if ( !self:IsVisible() ) then return false end
-- We return true if the scrollbar changed.
-- If it didn't, we feed the mousehweeling to the parent panel
return self:AddScroll( dlta * -2 )
end
function PANEL:AddScroll( dlta )
local OldScroll = self:GetScroll()
dlta = dlta * 25
self:SetScroll( self:GetScroll() + dlta )
return OldScroll != self:GetScroll()
end
function PANEL:SetScroll( scrll )
if ( !self.Enabled ) then self.Scroll = 0 return end
self.Scroll = math.Clamp( scrll, 0, self.CanvasSize )
self:InvalidateLayout()
-- If our parent has a OnVScroll function use that, if
-- not then invalidate layout (which can be pretty slow)
local func = self:GetParent().OnVScroll
if ( func ) then
func( self:GetParent(), self:GetOffset() )
else
self:GetParent():InvalidateLayout()
end
end
function PANEL:AnimateTo( scrll, length, delay, ease )
local anim = self:NewAnimation( length, delay, ease )
anim.StartPos = self.Scroll
anim.TargetPos = scrll
anim.Think = function( anim, pnl, fraction )
pnl:SetScroll( Lerp( fraction, anim.StartPos, anim.TargetPos ) )
end
end
function PANEL:GetScroll()
if ( !self.Enabled ) then self.Scroll = 0 end
return self.Scroll
end
function PANEL:GetOffset()
if ( !self.Enabled ) then return 0 end
return self.Scroll * -1
end
function PANEL:Think()
end
function PANEL:Paint( w, h )
self:GetSkin().tex.Scroller.TrackH(0,0,w,h)
return true
end
function PANEL:OnMousePressed()
local x, y = self:CursorPos()
local PageSize = self.BarSize
if ( x > self.btnGrip.x ) then
self:SetScroll( self:GetScroll() + PageSize )
else
self:SetScroll( self:GetScroll() - PageSize )
end
end
function PANEL:OnMouseReleased()
self.Dragging = false
self.DraggingCanvas = nil
self:MouseCapture( false )
self.btnGrip.Depressed = false
end
function PANEL:OnCursorMoved( x, y )
if ( !self.Enabled ) then return end
if ( !self.Dragging ) then return end
local x, y = self:ScreenToLocal( gui.MouseX(), 0 )
-- Uck.
x = x - self.btnLeft:GetWide()
x = x - self.HoldPos
local BtnHeight = self:GetTall()
if ( self:GetHideButtons() ) then BtnHeight = 0 end
local TrackSize = self:GetWide() - BtnHeight * 2 - self.btnGrip:GetWide()
x = x / TrackSize
self:SetScroll( x * self.CanvasSize )
end
function PANEL:Grip()
if ( !self.Enabled ) then return end
if ( self.BarSize == 0 ) then return end
self:MouseCapture( true )
self.Dragging = true
local x, y = self.btnGrip:ScreenToLocal( gui.MouseX(), 0 )
self.HoldPos = x
self.btnGrip.Depressed = true
end
function PANEL:PerformLayout()
local Wide = self:GetTall()
local BtnHeight = Wide
if ( self:GetHideButtons() ) then BtnHeight = 0 end
local Scroll = self:GetScroll() / self.CanvasSize
local BarSize = math.max( self:BarScale() * ( self:GetWide() - ( BtnHeight * 2 ) ), 10 )
local Track = self:GetWide() - ( BtnHeight * 2 ) - BarSize
Track = Track + 1
Scroll = Scroll * Track
self.btnGrip:SetPos( BtnHeight + Scroll, 0 )
self.btnGrip:SetSize( BarSize, Wide )
if ( BtnHeight > 0 ) then
self.btnLeft:SetPos( 0, 0, Wide, Wide )
self.btnLeft:SetSize( BtnHeight, Wide )
self.btnRight:SetPos( self:GetWide() - BtnHeight, 0 )
self.btnRight:SetSize(BtnHeight, Wide )
self.btnLeft:SetVisible( true )
self.btnRight:SetVisible( true )
else
self.btnLeft:SetVisible( false )
self.btnRight:SetVisible( false )
self.btnRight:SetSize( BtnHeight, Wide )
self.btnLeft:SetSize( BtnHeight, Wide )
end
end
end
do
local PANEL = vgui.Register("pac_scrollpanel_horizontal", {}, "DPanel")
AccessorFunc( PANEL, "Padding", "Padding" )
AccessorFunc( PANEL, "pnlCanvas", "Canvas" )
function PANEL:Init()
self.pnlCanvas = vgui.Create( "Panel", self )
self.pnlCanvas.OnMousePressed = function( self, code ) self:GetParent():OnMousePressed( code ) end
self.pnlCanvas:SetMouseInputEnabled( true )
self.pnlCanvas.PerformLayout = function( pnl )
self:PerformLayout()
self:InvalidateParent()
end
-- Create the scroll bar
self.VBar = vgui.Create( "pac_horizontal_scrollbar", self )
self.VBar:Dock( BOTTOM )
self:SetPadding( 0 )
self:SetMouseInputEnabled( true )
-- This turns off the engine drawing
self:SetPaintBackgroundEnabled( false )
self:SetPaintBorderEnabled( false )
self:SetPaintBackground( false )
end
function PANEL:AddItem( pnl )
pnl:SetParent( self:GetCanvas() )
end
function PANEL:OnChildAdded( child )
self:AddItem( child )
end
function PANEL:SizeToContents()
self:SetSize( self.pnlCanvas:GetSize() )
end
function PANEL:GetVBar()
return self.VBar
end
function PANEL:GetCanvas()
return self.pnlCanvas
end
function PANEL:InnerWidth()
return self:GetCanvas():GetTall()
end
function PANEL:Rebuild()
self:GetCanvas():SizeToChildren( true, false )
-- Although this behaviour isn't exactly implied, center vertically too
if ( self.m_bNoSizing && self:GetCanvas():GetWide() < self:GetWide() ) then
self:GetCanvas():SetPos( ( self:GetWide() - self:GetCanvas():GetWide() ) * 0.5, 0 )
end
end
function PANEL:OnMouseWheeled( dlta )
return self.VBar:OnMouseWheeled( dlta )
end
function PANEL:OnVScroll( iOffset )
self.pnlCanvas:SetPos( iOffset, 0 )
end
function PANEL:ScrollToChild( panel )
self:PerformLayout()
local x, y = self.pnlCanvas:GetChildPosition( panel )
local w, h = panel:GetSize()
x = x + w * 0.5
x = x - self:GetWide() * 0.5
self.VBar:AnimateTo( x, 0.5, 0, 0.5 )
end
function PANEL:PerformLayout()
local Tall = self.pnlCanvas:GetWide()
local Wide = self:GetWide()
local YPos = 0
self:Rebuild()
self.VBar:SetUp( self:GetWide(), self.pnlCanvas:GetWide() )
YPos = self.VBar:GetOffset()
if ( self.VBar.Enabled ) then Wide = Wide - self.VBar:GetWide() end
self.pnlCanvas:SetPos( YPos, 0 )
self.pnlCanvas:SetWide( Wide )
self:Rebuild()
if ( Tall != self.pnlCanvas:GetWide() ) then
self.VBar:SetScroll( self.VBar:GetScroll() ) -- Make sure we are not too far down!
end
end
function PANEL:Clear()
return self.pnlCanvas:Clear()
end
end

View File

@@ -0,0 +1,593 @@
--[[
| 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
local PANEL = {}
PANEL.ClassName = "tree"
PANEL.Base = "pac_dtree"
function PANEL:Init()
pace.pac_dtree.Init(self)
self:SetLineHeight(18)
self:SetIndentSize(10)
self.parts = {}
self:Populate()
pace.tree = self
end
do
local function get_added_nodes(self)
local added_nodes = {}
for i,v in ipairs(self.added_nodes) do
if v.part and v:IsVisible() and v:IsExpanded() then
table.insert(added_nodes, v)
end
end
table.sort(added_nodes, function(a, b) return select(2, a:LocalToScreen()) < select(2, b:LocalToScreen()) end)
return added_nodes
end
local function scroll_to_node(self, node)
timer.Simple(0.1, function()
if not self:IsValid() then return end
if not node:IsValid() then return end
local _, y = self:LocalToScreen()
local h = self:GetTall()
local _, node_y = node:LocalToScreen()
if node_y > y + h or node_y < y then
self:ScrollToChild(node)
end
end)
end
local info_image = {
pace.MiscIcons.info,
pace.MiscIcons.warning,
pace.MiscIcons.error,
}
function PANEL:Think(...)
if not pace.current_part:IsValid() then return end
if
pace.current_part.pace_tree_node and
pace.current_part.pace_tree_node:IsValid() and not
(
pace.BusyWithProperties:IsValid() or
pace.ActiveSpecialPanel:IsValid() or
pace.editing_viewmodel or
pace.editing_hands or
pace.properties.search:HasFocus()
) and
not gui.IsConsoleVisible()
then
if input.IsKeyDown(KEY_LEFT) then
pace.Call("VariableChanged", pace.current_part, "EditorExpand", false)
elseif input.IsKeyDown(KEY_RIGHT) then
pace.Call("VariableChanged", pace.current_part, "EditorExpand", true)
end
if input.IsKeyDown(KEY_UP) or input.IsKeyDown(KEY_PAGEUP) then
local added_nodes = get_added_nodes(self)
local offset = input.IsKeyDown(KEY_PAGEUP) and 10 or 1
if not self.scrolled_up or self.scrolled_up < os.clock() then
for i,v in ipairs(added_nodes) do
if v == pace.current_part.pace_tree_node then
local node = added_nodes[i - offset] or added_nodes[1]
if node then
node:DoClick()
scroll_to_node(self, node)
break
end
end
end
self.scrolled_up = self.scrolled_up or os.clock() + 0.4
end
else
self.scrolled_up = nil
end
if input.IsKeyDown(KEY_DOWN) or input.IsKeyDown(KEY_PAGEDOWN) then
local added_nodes = get_added_nodes(self)
local offset = input.IsKeyDown(KEY_PAGEDOWN) and 10 or 1
if not self.scrolled_down or self.scrolled_down < os.clock() then
for i,v in ipairs(added_nodes) do
if v == pace.current_part.pace_tree_node then
local node = added_nodes[i + offset] or added_nodes[#added_nodes]
if node then
node:DoClick()
--scroll_to_node(self, node)
break
end
end
end
self.scrolled_down = self.scrolled_down or os.clock() + 0.4
end
else
self.scrolled_down = nil
end
end
for _, part in pairs(pac.GetLocalParts()) do
local node = part.pace_tree_node
if not node or not node:IsValid() then continue end
if node.add_button then
node.add_button:SetVisible(false)
end
if part.Info then
local info = part.Info
node.info:SetTooltip(info.message)
node.info:SetImage(info_image[info.type])
node.info:SetVisible(true)
else
node.info:SetVisible(false)
end
if part.ClassName == "event" then
if part.is_active then
node.Icon:SetImage("icon16/clock_red.png")
else
node.Icon:SetImage(part.Icon)
end
end
if part.ClassName == "custom_animation" then
local anim = part:GetLuaAnimation()
if anim then
node:SetText(part:GetName() .. " [" .. string.format("%.2f", anim.Frame + anim.FrameDelta) .. "]")
end
end
if (part.ClassName == "proxy" or part.ClassName == "event") and part.Name == "" then
node:SetText(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName())
end
if part:IsHiddenCached() then
if not node.Icon.event_icon then
local pnl = vgui.Create("DImage", node.Icon)
pnl:SetImage("icon16/clock_red.png")
pnl:SetSize(8, 8)
pnl:SetPos(8, 8)
pnl:SetVisible(false)
node.Icon.event_icon = pnl
end
node.Icon.event_icon:SetVisible(true)
else
if node.Icon.event_icon then
node.Icon.event_icon:SetVisible(false)
end
end
end
local pnl = vgui.GetHoveredPanel() or NULL
if pnl:IsValid() then
local pnl = pnl:GetParent()
if IsValid(pnl) and IsValid(pnl.part) then
pace.Call("HoverPart", pnl.part)
if pnl.add_button then
pnl.add_button:SetVisible(true)
end
end
end
end
end
function PANEL:OnMouseReleased(mc)
if mc == MOUSE_RIGHT then
pace.Call("PartMenu")
end
end
function PANEL:SetModel(path)
if not file.Exists(path, "GAME") then
path = player_manager.TranslatePlayerModel(path)
if not file.Exists(path, "GAME") then
print(path, "is invalid")
return
end
end
local pnl = vgui.Create("SpawnIcon", self)
pnl:SetModel(path or "")
pnl:SetSize(16, 16)
self.Icon:Remove()
self.Icon = pnl
self.ModelPath = path
end
function PANEL:GetModel()
return self.ModelPath
end
local function install_drag(node)
node:SetDraggableName("pac3")
local old = node.OnDrop
function node:OnDrop(child, ...)
-- we're hovering on the label, not the actual node
-- so get the parent node instead
if not child.part then
child = child:GetParent()
end
if child.part and child.part:IsValid() then
if self.part and self.part:IsValid() and self.part:GetParent() ~= child.part then
pace.RecordUndoHistory()
self.part:SetParent(child.part)
pace.RecordUndoHistory()
end
elseif self.part and self.part:IsValid() then
if self.part.ClassName ~= "group" then
pace.RecordUndoHistory()
local group = pac.CreatePart("group", self.part:GetPlayerOwner())
group:SetEditorExpand(true)
self.part:SetParent(group)
pace.RecordUndoHistory()
pace.TrySelectPart()
else
pace.RecordUndoHistory()
self.part:SetParent()
pace.RecordUndoHistory()
pace.RefreshTree(true)
end
end
return old(self, child, ...)
end
function node:DroppedOn(child)
if not child.part then
child = child:GetParent()
end
self:InsertNode(child)
self:SetExpanded(true)
if child.part and child.part:IsValid() then
if self.part and self.part:IsValid() and child.part:GetParent() ~= self.part then
pace.RecordUndoHistory()
child.part:SetParent(self.part)
pace.RecordUndoHistory()
end
end
end
end
local function install_expand(node)
local old = node.SetExpanded
node.SetExpanded = function(self, b, ...)
if self.part and self.part:IsValid() then
self.part:SetEditorExpand(b)
return old(self, b, ...)
end
end
local old = node.Expander.OnMousePressed
node.Expander.OnMousePressed = function(pnl, code, ...)
old(pnl, code, ...)
if code == MOUSE_RIGHT then
local menu = DermaMenu()
menu:SetPos(input.GetCursorPos())
menu:MakePopup()
menu:AddOption(L"collapse all", function()
node.part:CallRecursive('SetEditorExpand', false)
pace.RefreshTree(true)
end):SetImage('icon16/arrow_in.png')
menu:AddOption(L"expand all", function()
node.part:CallRecursive('SetEditorExpand', true)
pace.RefreshTree(true)
end):SetImage('icon16/arrow_down.png')
end
end
end
local fix_folder_funcs = function(tbl)
tbl.MakeFolder = function() end
tbl.FilePopulateCallback = function() end
tbl.FilePopulate = function() end
tbl.PopulateChildren = function() end
tbl.ChildExpanded = function() end
tbl.PopulateChildrenAndSelf = function() end
return tbl
end
local function node_layout(self, ...)
pace.pac_dtree_node.PerformLayout(self, ...)
if self.Label then
self.Label:SetFont(pace.CurrentFont)
--self.Label:SetTextColor(derma.Color("text_dark", self, color_black))
end
if self.add_button then
local x = self.Label:GetPos() + self.Label:GetTextInset() + 4
surface.SetFont(pace.CurrentFont)
local w = surface.GetTextSize(self.Label:GetText())
self.add_button:SetPos(x + w, (self.Label:GetTall() - self.add_button:GetTall()) / 2)
end
if self.info then
local is_adding = self.add_button:IsVisible()
local x = self.Label:GetPos() + self.Label:GetTextInset() + (is_adding and self.add_button:GetWide() + 4 or 4)
surface.SetFont(pace.CurrentFont)
local w = surface.GetTextSize(self.Label:GetText())
self.info:SetPos(x + w, (self.Label:GetTall() - self.info:GetTall()) / 2)
end
end
local function add_parts_menu(node)
pace.Call("AddPartMenu", node.part)
end
-- a hack, because creating a new node button will mess up the layout
function PANEL:AddNode(...)
if self.RootNode then
install_drag(self.RootNode)
end
local node = fix_folder_funcs((self.RootNode and pace.pac_dtree.AddNode or pace.pac_dtree_node.AddNode)(self, ...))
install_expand(node)
install_drag(node)
local add_button = node:Add("DImageButton")
add_button:SetImage(pace.MiscIcons.new)
add_button:SetSize(16, 16)
add_button:SetVisible(false)
add_button.DoClick = function() add_parts_menu(node) pace.Call("PartSelected", node.part) end
add_button.DoRightClick = function() node:DoRightClick() end
node.add_button = add_button
node.SetModel = self.SetModel
node.GetModel = self.GetModel
node.AddNode = PANEL.AddNode
node.PerformLayout = node_layout
local info = node:Add("DImageButton")
info:SetImage(pace.MiscIcons.info)
info:SetSize(16, 16)
info:SetVisible(false)
info.DoClick = function() pace.MessagePrompt(info:GetTooltip()) end
node.info = info
return node
end
local enable_model_icons = CreateClientConVar("pac_editor_model_icons", "1")
function PANEL:PopulateParts(node, parts, children)
fix_folder_funcs(node)
local temp = {}
for k,v in pairs(parts) do
table.insert(temp, v)
end
parts = temp
local tbl = {}
table.sort(parts, function(a,b)
return a and b and a:GetName() < b:GetName()
end)
for key, val in pairs(parts) do
if not val:HasChildren() then
table.insert(tbl, val)
end
end
for key, val in pairs(parts) do
if val:HasChildren() then
table.insert(tbl, val)
end
end
for key, part in pairs(tbl) do
key = part.Id
if not part:GetShowInEditor() then goto CONTINUE end
if not part:HasParent() or children then
local part_node
if IsValid(part.pace_tree_node) then
part_node = part.pace_tree_node
elseif IsValid(self.parts[key]) then
part_node = self.parts[key]
else
part_node = node:AddNode(pace.pac_show_uniqueid:GetBool() and string.format("%s (%s)", part:GetName(), part:GetPrintUniqueID()) or part:GetName())
end
fix_folder_funcs(part_node)
if part.Description then part_node:SetTooltip(L(part.Description)) end
part.pace_tree_node = part_node
part_node.part = part
self.parts[key] = part_node
part_node.DoClick = function()
if not part:IsValid() then return end
pace.Call("PartSelected", part)
--part_node.add_button:SetVisible(true)
return true
end
part_node.DoRightClick = function()
if not part:IsValid() then return end
pace.Call("PartMenu", part)
pace.Call("PartSelected", part)
part_node:InternalDoClick()
return true
end
if
enable_model_icons:GetBool() and
part.is_model_part and
part.GetModel and
part:GetOwner():IsValid()
then
part_node:SetModel(part:GetOwner():GetModel(), part.Icon)
elseif isstring(part.Icon) then
part_node.Icon:SetImage(part.Icon)
end
self:PopulateParts(part_node, part:GetChildren(), true)
if part.newly_created then
part_node:SetSelected(true)
local function expand(part)
if part:HasParent() and part.Parent.pace_tree_node then
part.Parent.pace_tree_node:SetExpanded(true)
expand(part.Parent)
end
end
expand(part)
part_node:SetSelected(true)
part.newly_created = nil
else
part_node:SetSelected(false)
part_node:SetExpanded(part:GetEditorExpand())
end
end
::CONTINUE::
end
end
function PANEL:SelectPart(part)
for key, node in pairs(self.parts) do
if not node.part or not node.part:IsValid() then
node:Remove()
self.parts[key] = nil
else
if node.part == part then
node:SetSelected(true)
else
node:SetSelected(false)
end
end
end
self:InvalidateLayout()
end
function PANEL:Populate(reset)
self:SetLineHeight(18)
self:SetIndentSize(2)
for key, node in pairs(self.parts) do
if reset or (not node.part or not node.part:IsValid()) then
node:Remove()
self.parts[key] = nil
end
end
--[[self.m_pSelectedItem = nil
for key, node in pairs(self:GetItems()) do
node:Remove()
end]]
self:PopulateParts(self, pac.GetLocalParts())
self:InvalidateLayout()
end
pace.RegisterPanel(PANEL)
local function remove_node(part)
if not part:GetShowInEditor() then return end
if (part.pace_tree_node or NULL):IsValid() then
part.pace_tree_node:SetForceShowExpander()
part.pace_tree_node:GetRoot().m_pSelectedItem = nil
part.pace_tree_node:Remove()
pace.RefreshTree()
end
end
pac.AddHook("pac_OnPartRemove", "pace_remove_tree_nodes", remove_node)
local last_refresh = 0
local function refresh(part)
if last_refresh > SysTime() then return end
if not part:GetShowInEditor() then return end
last_refresh = SysTime() + 0.1
timer.Simple(0, function()
if not part:IsValid() then return end
if not part:GetShowInEditor() then return end
pace.RefreshTree(true)
end)
end
pac.AddHook("pac_OnWoreOutfit", "pace_refresh_tree_nodes", refresh)
pac.AddHook("pac_OnPartParent", "pace_refresh_tree_nodes", refresh)
pac.AddHook("pac_OnPartCreated", "pace_refresh_tree_nodes", refresh)
pac.AddHook("pace_OnVariableChanged", "pace_create_tree_nodes", function(part, key, val)
if key == "EditorExpand" then
local node = part.pace_tree_node
if IsValid(node) then
node:SetExpanded(val)
end
end
end)
function pace.RefreshTree(reset)
if pace.tree:IsValid() then
timer.Create("pace_refresh_tree", 0.01, 1, function()
if pace.tree:IsValid() then
pace.tree:Populate(reset)
pace.tree.RootNode:SetExpanded(true, true) -- why do I have to do this?
pace.TrySelectPart()
end
end)
end
end
if Entity(1):IsPlayer() and not PAC_RESTART and not VLL2_FILEDEF then
pace.OpenEditor()
pace.RefreshTree(true)
end

View File

@@ -0,0 +1,209 @@
--[[
| 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 PANEL = {}
PANEL.Base = "DFrame"
PANEL.ClassName = "web_browser"
function PANEL:Init()
self:SetTitle("Web Browser")
self:SetDeleteOnClose(false)
self:ShowCloseButton(true)
self:SetDraggable(true)
self:SetSizable(true)
local top = vgui.Create("EditablePanel", self)
top:Dock(TOP)
top:SetTall(24)
self.top = top
local btn = vgui.Create("DButton", top)
btn:SetText("Back")
btn:SizeToContents()
btn:SetWide(btn:GetWide()+8)
btn:Dock(LEFT)
btn.DoClick = function()
self.browser:RunJavascript("history.back();")
end
local btn = vgui.Create("DButton", top)
btn:SetText("Forward")
btn:SizeToContents()
btn:SetWide(btn:GetWide()+8)
btn:Dock(LEFT)
btn.DoClick = function()
self.browser:RunJavascript("history.forward();")
end
local btn = vgui.Create("DButton", top)
btn:SetText("Refresh")
btn:SizeToContents()
btn:SetWide(btn:GetWide() + 8)
btn:Dock(LEFT)
btn.DoClick = function()
self.browser:RunJavascript("location.reload(true);")
end
btn.Paint = function(btn,w,h)
DButton.Paint(btn,w,h)
if self.loaded then
if self.browser:IsLoading() then
self.loaded = false
end
surface.SetDrawColor(100, 240, 50, 200)
surface.DrawRect(1, 1, w-2, h-2)
end
if self.browser:IsLoading() then
surface.SetDrawColor(240 + math.sin(RealTime()*10)*15, 100, 50, 200)
surface.DrawRect(1, 1, w-2, h-2)
end
end
local entry = vgui.Create("DTextEntry", top)
self.entry = entry
entry:Dock(FILL)
entry:SetTall( 24)
entry.OnEnter = function(entry)
local val = entry:GetText()
local js,txt = val:match("javascript:(.+)")
if js and txt then
self.browser:QueueJavascript(txt)
return
end
self:OpenURL(val)
end
local browser = vgui.Create("DHTML", self)
self.browser = browser
browser:Dock(FILL)
browser.Paint = function() end
browser.OpeningURL = pac.Message
browser.FinishedURL = pac.Message
browser:AddFunction("gmod", "LoadedURL", function(url, title)
self:LoadedURL(url,title)
end)
browser:AddFunction("gmod", "dbg", function(...)
pac.Message('[Browser] ', ...)
end)
browser:AddFunction("gmod", "status", function(txt)
self:StatusChanged(txt)
end)
browser.ActionSignal = function(...)
pac.Message('[BrowserACT] ', ...)
end
browser.OnKeyCodePressed = function(browser,code)
if code == 96 then
self.browser:RunJavascript[[location.reload(true);]]
return
end
end
local status = vgui.Create("DLabel", self)
self.status = status
status:SetText""
status:Dock(BOTTOM)
end
function PANEL:StatusChanged(txt)
if self.statustxt ~= txt then
self.statustxt = txt
self.status:SetText(txt or "")
end
end
function PANEL:LoadedURL(url,title)
if self.entry:HasFocus() then return end
self.entry:SetText(url)
self.loaded = true
self:SetTitle(title and title ~= "" and title or "Web browser")
end
function PANEL:OpenURL(url)
self.browser:OpenURL(url)
self.entry:SetText(url)
end
function PANEL:Think(w,h)
self.BaseClass.Think(self,w,h)
if input.IsKeyDown(KEY_ESCAPE) then
self:Close()
end
if not self.wasloading and self.browser:IsLoading() then
self.wasloading = true
end
if self.wasloading and not self.browser:IsLoading() then
self.wasloading = false
self.browser:QueueJavascript[[gmod.LoadedURL(document.location.href,document.title); gmod.status(""); ]]
self.browser:QueueJavascript[[function alert(str) { console.log("Alert: "+str); }]]
self.browser:QueueJavascript[[if (!document.body.style.background) { document.body.style.background = 'white'; }; void 0;]]
self.browser:QueueJavascript[[
function getLink() {
gmod.status(this.href || "-");
}
function clickLink() {
if (this.href) {
gmod.LoadedURL(this.href,"Loading...");
}
gmod.status("Loading...");
}
var links = document.getElementsByTagName("a");
for (i = 0; i < links.length; i++) {
links[i].addEventListener('mouseover',getLink,false)
links[i].addEventListener('click',clickLink,false)
}
]]
end
end
function PANEL:Show()
if not self:IsVisible() then
self:SetVisible(true)
self:MakePopup()
self:SetKeyboardInputEnabled(true)
self:SetMouseInputEnabled(true)
end
if ValidPanel(self.browser) then
self.browser:RequestFocus()
end
end
function PANEL:Close()
self:SetVisible(false)
end
pace.wiki_panel = NULL
function pace.ShowWiki(url)
if pace.wiki_panel:IsValid() then
pace.wiki_panel:Remove()
end
local pnl = pace.CreatePanel("web_browser")
pnl:OpenURL(url or pace.WikiURL)
pnl:SetSize(ScrW()*0.9, ScrH()*0.8)
pnl:Center()
pnl:MakePopup()
pace.wiki_panel = pnl
end
pace.RegisterPanel(PANEL)