Files
wnsrc/lua/pac3/editor/client/init.lua
lifestorm 73479cff9e Upload
2024-08-04 22:55:00 +03:00

420 lines
9.8 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
include("autorun/pac_core_init.lua")
pace = pace or {}
pace.luadata = include("pac3/libraries/luadata.lua")
include("language.lua")
include("icons.lua")
include("util.lua")
include("wear.lua")
include("select.lua")
include("view.lua")
include("parts.lua")
include("saved_parts.lua")
include("logic.lua")
include("undo.lua")
include("fonts.lua")
include("settings.lua")
include("shortcuts.lua")
include("asset_browser.lua")
include("menu_bar.lua")
include("mctrl.lua")
include("panels.lua")
include("tools.lua")
include("spawnmenu.lua")
include("wiki.lua")
include("examples.lua")
include("about.lua")
include("animation_timeline.lua")
include("render_scores.lua")
include("wires.lua")
include("wear_filter.lua")
include("show_outfit_on_use.lua")
do
local hue =
{
"red",
"orange",
"yellow",
"green",
"turquoise",
"blue",
"purple",
"magenta",
}
local sat =
{
"pale",
"",
"strong",
}
local val =
{
"dark",
"",
"bright"
}
function pace.HSVToNames(h,s,v)
return
hue[math.Round((1+(h/360)*#hue))] or hue[1],
sat[math.ceil(s*#sat)] or sat[1],
val[math.ceil(v*#val)] or val[1]
end
function pace.ColorToNames(c)
if c.r == 255 and c.g == 255 and c.b == 255 then return "white", "", "bright" end
if c.r == 0 and c.g == 0 and c.b == 0 then return "black", "", "bright" end
return pace.HSVToNames(ColorToHSV(Color(c.r, c.g, c.b)))
end
end
function pace.CallHook(str, ...)
return hook.Call("pace_" .. str, GAMEMODE, ...)
end
pace.ActivePanels = pace.ActivePanels or {}
pace.Editor = NULL
local remember = CreateConVar("pac_editor_remember_position", "1", {FCVAR_ARCHIVE}, "Remember PAC3 editor position on screen")
local positionMode = CreateConVar("pac_editor_position_mode", "0", {FCVAR_ARCHIVE}, "Editor position mode. 0 - Left, 1 - middle, 2 - Right. Has no effect if pac_editor_remember_position is true")
local showCameras = CreateConVar("pac_show_cameras", "1", {FCVAR_ARCHIVE}, "Show the PAC cameras of players using the editor")
local showInEditor = CreateConVar("pac_show_in_editor", "1", {FCVAR_ARCHIVE}, "Show the 'In PAC3 Editor' text above players using the editor")
pace.pac_show_uniqueid = CreateConVar("pac_show_uniqueid", "0", {FCVAR_ARCHIVE}, "Show uniqueids of parts inside editor")
function pace.OpenEditor()
pace.CloseEditor()
if hook.Run("PrePACEditorOpen", pac.LocalPlayer) == false then return end
pac.Enable()
pace.RefreshFiles()
pace.SetLanguage()
local editor = pace.CreatePanel("editor")
editor:SetSize(240, ScrH())
editor:MakePopup()
--editor:SetPos(0, 0)
editor.Close = function()
--editor:OnRemove() -- ??? This is called by the engine
--editor.__OnClosed = true
pace.CloseEditor()
end
pace.Editor = editor
pace.Active = true
if remember:GetBool() then
local x = cookie.GetNumber("pac_editor_x", 0)
if x < 0 or x + 240 > ScrW() then
x = 0
end
editor:SetPos(x, 0)
cookie.Set("pac_editor_x", tostring(x))
else
local mode = positionMode:GetInt()
if mode == 1 then
editor:SetPos(ScrW() / 2 - 120, 0)
elseif mode == 2 then
editor:SetPos(ScrW() - 240, 0)
else
editor:SetPos(0, 0)
end
end
if ctp and ctp.Disable then
ctp:Disable()
end
RunConsoleCommand("pac_enable", "1")
RunConsoleCommand("pac_in_editor", "1")
pace.SetInPAC3Editor(true)
pace.DisableExternalHooks()
vgui.GetWorldPanel():SetWorldClicker(false)
pace.Call("OpenEditor")
end
function pace.CloseEditor()
pace.RestoreExternalHooks()
if pace.Editor:IsValid() then
local x = pace.Editor:GetPos()
cookie.Set("pac_editor_x", tostring(x))
--if not editor.__OnClosed then
--pace.Editor:OnRemove() -- ??? This is called by the engine
--end
pace.Editor:Remove()
pace.Active = false
pace.Focused = false
pace.Call("CloseEditor")
if pace.timeline.IsActive() then
pace.timeline.Close()
end
end
RunConsoleCommand("pac_in_editor", "0")
pace.SetInPAC3Editor(false)
end
function pace.HasFocus()
return pace.Editor:IsValid() and pace.Editor:HasFocus()
end
pac.AddHook("pac_Disable", "pac_editor_disable", function()
pace.CloseEditor()
end)
function pace.RefreshFiles()
pace.CachedFiles = nil
if pace.Editor:IsValid() then
pace.Editor:MakeBar()
end
if pace.SpawnlistBrowser:IsValid() then
pace.SpawnlistBrowser:PopulateFromClient()
end
end
function pace.Panic()
pace.CloseEditor()
for key, pnl in pairs(pace.ActivePanels) do
if pnl:IsValid() then
pnl:Remove()
table.remove(pace.ActivePanels, key)
end
end
pace.SafeRemoveSpecialPanel()
for i, ent in ipairs(ents.GetAll()) do
if ent:IsValid() then
ent.pac_onuse_only = nil
ent.pac_onuse_only_check = nil
hook.Remove('pace_OnUseOnlyUpdates', ent)
end
end
end
do -- forcing hooks
pace.ExternalHooks =
{
"CalcView",
"ShouldDrawLocalPlayer",
}
function pace.DisableExternalHooks()
if DLib or ULib then return end -- hook with priority
for _, event in pairs(pace.ExternalHooks) do
local hooks = hook.GetTable()[event]
if hooks then
pace.OldHooks = pace.OldHooks or {}
pace.OldHooks[event] = pace.OldHooks[event] or {}
pace.OldHooks[event] = table.Copy(hooks)
for name in pairs(hooks) do
if isstring(name) and name:sub(1, 4) ~= "pace_" then
hook.Remove(event, name)
end
end
end
end
end
function pace.RestoreExternalHooks()
if DLib or ULib then return end -- hook with priority
if pace.OldHooks then
for event, hooks in pairs(pace.OldHooks) do
for name, func in pairs(hooks) do
if isstring(name) and name:sub(1, 4) ~= "pace_" then
hook.Add(event, name, func)
end
end
end
end
pace.OldHooks = nil
end
end
function pace.IsActive()
return pace.Active == true
end
concommand.Add("pac_editor_panic", function()
pace.Panic()
timer.Simple(0.1, function() pace.OpenEditor() end)
end)
concommand.Add("pac_editor", function(_, _, args)
if args[1] == "toggle" then
if pace.IsActive() then
pace.CloseEditor()
else
pace.OpenEditor()
end
else
pace.OpenEditor()
end
end)
concommand.Add("pac_reset_eye_angles", function() pace.ResetEyeAngles() end)
concommand.Add("pac_toggle_tpose", function() pace.SetTPose(not pace.GetTPose()) end)
function pace.Call(str, ...)
if pace["On" .. str] then
if hook.Run("pace_On" .. str, ...) ~= false then
return pace["On" .. str](...)
end
else
ErrorNoHalt("missing function pace.On" .. str .. "!\n")
end
end
do
function pace.SetInPAC3Editor(b)
net.Start("pac_in_editor")
net.WriteBit(b)
net.SendToServer()
end
local up = Vector(0,0,10000)
hook.Add("HUDPaint", "pac_in_editor", function()
for _, ply in ipairs(player.GetAll()) do
if ply ~= pac.LocalPlayer and ply:GetNW2Bool("pac_in_editor") then
if showCameras:GetInt() == 1 then
if ply.pac_editor_cam_pos then
if not IsValid(ply.pac_editor_camera) then
ply.pac_editor_camera = ClientsideModel("models/tools/camera/camera.mdl")
ply.pac_editor_camera:SetModelScale(0.25,0)
local ent = ply.pac_editor_camera
ply:CallOnRemove("pac_editor_camera", function()
SafeRemoveEntity(ent)
end)
end
local ent = ply.pac_editor_camera
local dt = math.Clamp(FrameTime() * 5, 0.0001, 0.5)
ent:SetPos(LerpVector(dt, ent:GetPos(), ply.pac_editor_cam_pos))
ent:SetAngles(LerpAngle(dt, ent:GetAngles(), ply.pac_editor_cam_ang))
local pos_3d = ent:GetPos()
local dist = pos_3d:Distance(EyePos())
if dist > 10 then
local pos_2d = pos_3d:ToScreen()
if pos_2d.visible then
local alpha = math.Clamp(pos_3d:Distance(EyePos()) * -1 + 500, 0, 500)/500
if alpha > 0 then
draw.DrawText(ply:Nick() .. "'s PAC3 camera", "ChatFont", pos_2d.x, pos_2d.y, Color(255,255,255,alpha*255), 1)
if not ply.pac_editor_part_pos:IsZero() then
surface.SetDrawColor(255, 255, 255, alpha*100)
local endpos = ply.pac_editor_part_pos:ToScreen()
if endpos.visible then
surface.DrawLine(pos_2d.x, pos_2d.y, endpos.x, endpos.y)
end
end
end
end
end
end
else
if ply.pac_editor_camera then
SafeRemoveEntity(ply.pac_editor_camera)
ply.pac_editor_camera = nil
end
end
if showInEditor:GetInt() == 1 then
local pos_3d = ply:NearestPoint(ply:EyePos() + up) + Vector(0,0,5)
local alpha = math.Clamp(pos_3d:Distance(EyePos()) * -1 + 500, 0, 500)/500
if alpha > 0 then
local pos_2d = pos_3d:ToScreen()
draw.DrawText("In PAC3 Editor", "ChatFont", pos_2d.x, pos_2d.y, Color(255,255,255,alpha*255), 1)
end
end
else
if ply.pac_editor_camera then
SafeRemoveEntity(ply.pac_editor_camera)
ply.pac_editor_camera = nil
end
end
end
end)
do
local lastViewPos, lastViewAngle, lastTargetPos
timer.Create("pac_in_editor", 0.25, 0, function()
if not pace.Active then return end
if not pace.current_part:IsValid() then return end
local pos, ang = pace.GetViewPos(), pace.GetViewAngles()
local target_pos = pace.mctrl.GetWorldPosition()
if not target_pos then return end
if lastViewPos == pos and lastViewAngle == ang and lastTargetPos == target_pos then return end
lastViewPos, lastViewAngle, lastTargetPos = pos, ang, target_pos
net.Start("pac_in_editor_posang", true)
net.WriteVector(pos)
net.WriteAngle(ang)
net.WriteVector(target_pos)
net.SendToServer()
end)
end
net.Receive("pac_in_editor_posang", function()
local ply = net.ReadEntity()
if not IsValid( ply ) then return end
local pos = net.ReadVector()
local ang = net.ReadAngle()
local part_pos = net.ReadVector()
ply.pac_editor_cam_pos = pos
ply.pac_editor_cam_ang = ang
ply.pac_editor_part_pos = part_pos
end)
end
pace.RegisterPanels()