Skip to content

Commit 9ecdd96

Browse files
committed
proxy graphing
add a graph mode for proxies with a few features and some navigation buttons, the x value can be any expression but it might not make sense with many functions, especially since it's not smart in knowing whether there's limits to the real outputs of certain variables like eye angles because calculating every point in real time is hell due to huge numbers of compiles, it caches for performance, but the sampling method isn't perfect with keeping up with navigation but it tries to be flexible. the reset button can try to fix issues tweak some functions related to part reference error checking make some functions compatible for the grapher added non-flat dot_forward and dot_right add the Functions list in the source for GetActiveFunctions
1 parent dcbf4db commit 9ecdd96

File tree

4 files changed

+1584
-4
lines changed

4 files changed

+1584
-4
lines changed

lua/pac3/core/client/parts/proxy.lua

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ function PART:GetOrFindCachedPart(uid_or_name)
107107
self.erroring_cached_parts = {}
108108
self.found_cached_parts = self.found_cached_parts or {}
109109
if self.found_cached_parts[uid_or_name] then self.erroring_cached_parts[uid_or_name] = nil return self.found_cached_parts[uid_or_name] end
110-
if self.erroring_cached_parts[uid_or_name] then return end
111-
if self.bad_uid_search and self.bad_uid_search > 250 then return end
110+
if self.bad_uid_search and self.bad_uid_search > 250 then
111+
return
112+
end
112113

113114
local owner = self:GetPlayerOwner()
114115
part = pac.GetPartFromUniqueID(pac.Hash(owner), uid_or_name) or pac.FindPartByPartialUniqueID(pac.Hash(owner), uid_or_name)
@@ -122,10 +123,11 @@ function PART:GetOrFindCachedPart(uid_or_name)
122123
self.erroring_cached_parts[uid_or_name] = true
123124
self.bad_uid_search = self.bad_uid_search or 0
124125
self.bad_uid_search = self.bad_uid_search + 1
125-
if self:GetPlayerOwner() == LocalPlayer() and not pace.still_loading_wearing then
126+
if self:GetPlayerOwner() == LocalPlayer() and not pace.still_loading_wearing and self.bad_uid_search > 2 then
126127
pace.FlashNotification("performance warning! " .. tostring(self) .. " keeps searching for parts not finding anything! " .. tostring(uid_or_name) .. " may be unused!")
127128
end
128129
else
130+
self.bad_uid_search = nil
129131
self.found_cached_parts[uid_or_name] = part
130132
return part
131133
end
@@ -457,7 +459,7 @@ PART.Inputs.sample_and_hold = function(self, seed, duration, min, max, ease)
457459
self.samplehold = self.samplehold or {}
458460
self.samplehold_prev = self.samplehold_prev or {}
459461
self.samplehold_duration = self.samplehold_duration or {}
460-
self.samplehold_prev[seed] = self.samplehold_prev[seed] or {value = min, refresh = CurTime()}
462+
self.samplehold_prev[seed] = self.samplehold_prev[seed] or {value = min + math.random()*(max-min), refresh = CurTime()}
461463
self.samplehold[seed] = self.samplehold[seed] or {value = min + math.random()*(max-min), refresh = CurTime() + duration}
462464

463465
self.samplehold_duration[seed] = self.samplehold_duration[seed] or CurTime()
@@ -745,6 +747,7 @@ PART.Inputs.ezfade = function(self, speed, starttime, endtime)
745747
starttime = starttime or 0
746748
self.time = self.time or pac.RealTime
747749
local timeex = pac.RealTime - self.time
750+
if self.timeex_override then timeex = self.timeex_override end
748751
local start_offset_constant = -starttime * speed
749752
local result = 0
750753

@@ -777,6 +780,7 @@ PART.Inputs.ezfade_4pt = function(self, in_starttime, in_endtime, out_starttime,
777780

778781
self.time = self.time or pac.RealTime
779782
local timeex = pac.RealTime - self.time
783+
if self.timeex_override then timeex = self.timeex_override end
780784

781785
if in_starttime == in_endtime then
782786
if timeex < in_starttime then
@@ -1143,6 +1147,7 @@ PART.Inputs.pose_parameter_true = function(self, name)
11431147
local owner = get_owner(self)
11441148
if owner:IsValid() then
11451149
local min, max = owner:GetPoseParameterRange(owner:LookupPoseParameter(name))
1150+
if not min or not max then return 0 end
11461151
return min + (max - min)*(owner:GetPoseParameter(name))
11471152
end
11481153
return 0
@@ -1467,6 +1472,32 @@ do
14671472
end
14681473
end
14691474

1475+
PART.Inputs.dot_forward = function(self)
1476+
local part = get_owner(self)
1477+
1478+
if part:IsValid() then
1479+
local ang = part:IsPlayer() and part:EyeAngles() or part:GetAngles()
1480+
local dir = pac.EyePos - part:EyePos()
1481+
dir:Normalize()
1482+
return dir:Dot(ang:Forward())
1483+
end
1484+
1485+
return 0
1486+
end
1487+
1488+
PART.Inputs.dot_right = function(self)
1489+
local part = get_owner(self)
1490+
1491+
if part:IsValid() then
1492+
local ang = part:IsPlayer() and part:EyeAngles() or part:GetAngles()
1493+
local dir = pac.EyePos - part:EyePos()
1494+
dir:Normalize()
1495+
return dir:Dot(ang:Right())
1496+
end
1497+
1498+
return 0
1499+
end
1500+
14701501
PART.Inputs.flat_dot_forward = function(self)
14711502
local part = get_owner(self)
14721503

@@ -1687,31 +1718,43 @@ function PART:SetExpression(str, slot)
16871718
end
16881719

16891720
function PART:SetExpressionOnHide(str)
1721+
if not self.errors_override then self:SetWarning() else timer.Simple(10, function() self:SetWarning() end) end
1722+
self.error = false
16901723
self.ExpressionOnHide = str
16911724
self:SetExpression(str, 0)
16921725
end
16931726

16941727
function PART:SetExtra1(str)
1728+
if not self.errors_override then self:SetWarning() else timer.Simple(10, function() self:SetWarning() end) end
1729+
self.error = false
16951730
self.Extra1 = str
16961731
self:SetExpression(str, 1)
16971732
end
16981733

16991734
function PART:SetExtra2(str)
1735+
if not self.errors_override then self:SetWarning() else timer.Simple(10, function() self:SetWarning() end) end
1736+
self.error = false
17001737
self.Extra2 = str
17011738
self:SetExpression(str, 2)
17021739
end
17031740

17041741
function PART:SetExtra3(str)
1742+
if not self.errors_override then self:SetWarning() else timer.Simple(10, function() self:SetWarning() end) end
1743+
self.error = false
17051744
self.Extra3 = str
17061745
self:SetExpression(str, 3)
17071746
end
17081747

17091748
function PART:SetExtra4(str)
1749+
if not self.errors_override then self:SetWarning() else timer.Simple(10, function() self:SetWarning() end) end
1750+
self.error = false
17101751
self.Extra4 = str
17111752
self:SetExpression(str, 4)
17121753
end
17131754

17141755
function PART:SetExtra5(str)
1756+
if not self.errors_override then self:SetWarning() else timer.Simple(10, function() self:SetWarning() end) end
1757+
self.error = false
17151758
self.Extra5 = str
17161759
self:SetExpression(str, 5)
17171760
end
@@ -2182,6 +2225,12 @@ function PART:GetActiveFunctions()
21822225
table.insert(possible_funcs, kw)
21832226
end
21842227
end
2228+
for kw,_ in pairs(PART.Functions) do
2229+
local kw2 = kw .. "("
2230+
if string.find(self.Expression, kw2, 0, true) ~= nil then
2231+
table.insert(possible_funcs, kw)
2232+
end
2233+
end
21852234

21862235
return possible_funcs
21872236
end

lua/pac3/editor/client/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ include("about.lua")
3232
include("animation_timeline.lua")
3333
include("render_scores.lua")
3434
include("wires.lua")
35+
include("proxy_graphing.lua")
3536

3637
include("wear_filter.lua")
3738
include("show_outfit_on_use.lua")

lua/pac3/editor/client/parts.lua

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4004,6 +4004,77 @@ function pace.AddClassSpecificPartMenuComponents(menu, obj)
40044004
end):SetIcon("icon16/star.png")
40054005
end
40064006
end
4007+
4008+
local menu2, pnl = menu:AddSubMenu("Show graph", function()
4009+
pace.OpenProxyGrapher(obj)
4010+
end) pnl:SetImage("icon16/chart_line.png")
4011+
if pace.request_proxy_stats == "graph" then
4012+
local menu3, pnl2 = menu:AddSubMenu("Close graph", function()
4013+
pace.CloseProxyGrapher()
4014+
end) pnl2:SetImage("icon16/chart_line_delete.png")
4015+
end
4016+
4017+
menu2:AddOption("Small bounds (+): x:{0,10}, y:{0,2}", function()
4018+
pace.OpenProxyGrapher(obj)
4019+
timer.Simple(0, function()
4020+
pace.proxygraph_properties.panels["step"]:SetValue(0.02)
4021+
pace.proxygraph_properties.panels["min_x"]:SetValue(0)
4022+
pace.proxygraph_properties.panels["max_x"]:SetValue(10)
4023+
pace.proxygraph_properties.panels["min_y"]:SetValue(0)
4024+
pace.proxygraph_properties.panels["max_y"]:SetValue(2)
4025+
end)
4026+
end)
4027+
menu2:AddOption("Small bounds (+/-): x:{0,10}, y:{-2,2}", function()
4028+
pace.OpenProxyGrapher(obj)
4029+
timer.Simple(0, function()
4030+
pace.proxygraph_properties.panels["step"]:SetValue(0.02)
4031+
pace.proxygraph_properties.panels["min_x"]:SetValue(0)
4032+
pace.proxygraph_properties.panels["max_x"]:SetValue(10)
4033+
pace.proxygraph_properties.panels["min_y"]:SetValue(-2)
4034+
pace.proxygraph_properties.panels["max_y"]:SetValue(2)
4035+
end)
4036+
end)
4037+
menu2:AddOption("Mid bounds: x:{-100,100}, y:{-50,50}", function()
4038+
pace.OpenProxyGrapher(obj)
4039+
timer.Simple(0, function()
4040+
pace.proxygraph_properties.panels["step"]:SetValue(1)
4041+
pace.proxygraph_properties.panels["min_x"]:SetValue(-100)
4042+
pace.proxygraph_properties.panels["max_x"]:SetValue(100)
4043+
pace.proxygraph_properties.panels["min_y"]:SetValue(-50)
4044+
pace.proxygraph_properties.panels["max_y"]:SetValue(50)
4045+
end)
4046+
end)
4047+
menu2:AddOption("Large bounds: x:{-100,100}, y:{-1000,1000}", function()
4048+
pace.OpenProxyGrapher(obj)
4049+
timer.Simple(0, function()
4050+
pace.proxygraph_properties.panels["step"]:SetValue(1)
4051+
pace.proxygraph_properties.panels["min_x"]:SetValue(-100)
4052+
pace.proxygraph_properties.panels["max_x"]:SetValue(100)
4053+
pace.proxygraph_properties.panels["min_y"]:SetValue(-1000)
4054+
pace.proxygraph_properties.panels["max_y"]:SetValue(1000)
4055+
end)
4056+
end)
4057+
menu2:AddOption("Mega bounds: x:{-1000,1000}, y:{-10000,10000}", function()
4058+
pace.OpenProxyGrapher(obj)
4059+
timer.Simple(0, function()
4060+
pace.proxygraph_properties.panels["step"]:SetValue(100)
4061+
pace.proxygraph_properties.panels["min_x"]:SetValue(-1000)
4062+
pace.proxygraph_properties.panels["max_x"]:SetValue(1000)
4063+
pace.proxygraph_properties.panels["min_y"]:SetValue(-10000)
4064+
pace.proxygraph_properties.panels["max_y"]:SetValue(10000)
4065+
end)
4066+
end)
4067+
menu2:AddOption("Astronomical bounds: x:{-1000000,1000000}, y:{-1000000,1000000}", function()
4068+
pace.OpenProxyGrapher(obj)
4069+
timer.Simple(0, function()
4070+
pace.proxygraph_properties.panels["step"]:SetValue(50000)
4071+
pace.proxygraph_properties.panels["min_x"]:SetValue(-1000000)
4072+
pace.proxygraph_properties.panels["max_x"]:SetValue(1000000)
4073+
pace.proxygraph_properties.panels["min_y"]:SetValue(-1000000)
4074+
pace.proxygraph_properties.panels["max_y"]:SetValue(1000000)
4075+
end)
4076+
end)
4077+
40074078
elseif obj.ClassName == "beam" then
40084079
if not IsValid(obj.TargetPart) and obj.MultipleEndPoints == "" then
40094080
menu:AddOption("Link parent as end point", function()

0 commit comments

Comments
 (0)