mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
421 lines
7.4 KiB
Lua
421 lines
7.4 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/
|
|
--]]
|
|
|
|
local BUILDER, PART = pac.PartTemplate("base")
|
|
|
|
PART.ClassName = "script"
|
|
|
|
PART.ThinkTime = 0
|
|
PART.Group = 'advanced'
|
|
PART.Icon = 'icon16/page_white_gear.png'
|
|
|
|
BUILDER:StartStorableVars()
|
|
BUILDER:GetSet("Code", "")
|
|
BUILDER:EndStorableVars()
|
|
|
|
local blacklist = {
|
|
"do",
|
|
"end",
|
|
"function",
|
|
"repeat",
|
|
"while",
|
|
}
|
|
|
|
local lib =
|
|
{
|
|
math = {
|
|
pi = math.pi,
|
|
random = math.random,
|
|
abs = math.abs,
|
|
acos = math.acos,
|
|
asin = math.asin,
|
|
atan = math.atan,
|
|
atan2 = math.atan2,
|
|
ceil = math.ceil,
|
|
cos = math.cos,
|
|
cosh = math.cosh,
|
|
deg = math.deg,
|
|
exp = math.exp,
|
|
floor = math.floor,
|
|
frexp = math.frexp,
|
|
ldexp = math.ldexp,
|
|
log = math.log,
|
|
log10 = math.log10,
|
|
max = math.max,
|
|
min = math.min,
|
|
rad = math.rad,
|
|
sin = math.sin,
|
|
sinh = math.sinh,
|
|
sqrt = math.sqrt,
|
|
tanh = math.tanh,
|
|
tan = math.tan,
|
|
|
|
clamp = math.Clamp,
|
|
randomx = math.Rand,
|
|
},
|
|
|
|
string = {
|
|
find = string.find,
|
|
}
|
|
}
|
|
|
|
|
|
local function translate_xyz(x, y, z, T, def)
|
|
if T == "Vector" then
|
|
|
|
def.x = x or def.x
|
|
def.y = y or def.y
|
|
def.z = z or def.z
|
|
|
|
return def
|
|
elseif T == "Angle" then
|
|
|
|
def.p = x or def.p
|
|
def.y = y or def.y
|
|
def.r = z or def.r
|
|
|
|
return def
|
|
elseif T == "number" then
|
|
return tonumber(x) or def -- inf protection here
|
|
elseif T == "string" then
|
|
return tostring(x)
|
|
end
|
|
end
|
|
|
|
local function translate_value(val, T)
|
|
if T == "Vector" then
|
|
return val.x, val.y, val.z
|
|
elseif T == "Angle" then
|
|
return val.p, val.y, val.r
|
|
elseif T == "number" or T == "string" then
|
|
return val
|
|
end
|
|
end
|
|
|
|
local function CreateDummies(parts)
|
|
|
|
local obj = {
|
|
SetProperty = function(_, key, x, y, z)
|
|
if not key then return end
|
|
|
|
for _, v in pairs(parts) do
|
|
if v:IsValid() and v.StorableVars[key] then
|
|
local def = v[key]
|
|
local val = translate_xyz(x ,y, z, type(def), def)
|
|
|
|
v["Set" .. key](v, val)
|
|
end
|
|
end
|
|
end,
|
|
|
|
EventHide = function(_, b)
|
|
for _, v in pairs(parts) do
|
|
if v:IsValid() then
|
|
v:SetEventTrigger(self, not not b)
|
|
end
|
|
end
|
|
end,
|
|
|
|
EventShow = function(_, b)
|
|
for _, v in pairs(parts) do
|
|
if v:IsValid() then
|
|
v:SetEventTrigger(self, not b)
|
|
end
|
|
end
|
|
end
|
|
}
|
|
|
|
return obj
|
|
end
|
|
|
|
local function CreateDummy(part, store, self)
|
|
if not part or not part:IsValid() then return end
|
|
if part.dummy_part then return part.dummy_part end
|
|
|
|
store.parts[part.UniqueID] = {}
|
|
|
|
local META =
|
|
{
|
|
SetProperty = function(_, key, x, y, z)
|
|
if key and part.StorableVars[key] then
|
|
local def = part[key]
|
|
local val = translate_xyz(x ,y, z, type(def), def)
|
|
|
|
part["Set" .. key](part, val)
|
|
end
|
|
end,
|
|
|
|
GetProperty = function(_, key)
|
|
if key and part.StorableVars[key] then
|
|
local val = part["Get" .. key](part)
|
|
|
|
if val then
|
|
local x, y, z = translate_value(val, type(val))
|
|
|
|
if x then
|
|
return x, y, z
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
|
|
EventHide = function(_, b)
|
|
part:SetEventTrigger(self, not not b)
|
|
end,
|
|
|
|
EventShow = function(_, b)
|
|
part:SetEventTrigger(self, not b)
|
|
end,
|
|
|
|
GetChildren = function()
|
|
return CreateDummies(part:GetChildren(), self)
|
|
end,
|
|
|
|
}
|
|
|
|
local obj = setmetatable(
|
|
{},
|
|
{
|
|
__index = function(_, key)
|
|
if not part:IsValid() then return end
|
|
|
|
if store.parts[part.UniqueID][key] then
|
|
return store.parts[part.UniqueID][key]
|
|
end
|
|
|
|
return META[key]
|
|
end,
|
|
|
|
__newindex = function(_, key, val)
|
|
if not part:IsValid() then return end
|
|
|
|
store.parts[part.UniqueID][key] = val
|
|
end,
|
|
}
|
|
)
|
|
|
|
part.dummy_part = obj
|
|
|
|
return obj
|
|
end
|
|
|
|
local function get_entity(part)
|
|
local ent = part:GetRootPart():GetOwner()
|
|
return ent == pac.LocalPlayer:GetViewModel() and pac.LocalPlayer or ent
|
|
end
|
|
|
|
function PART:CompileCode()
|
|
local code = self.Code
|
|
|
|
for _, word in pairs(blacklist) do
|
|
if code:find("[%p%s]" .. word) or code:find(word .. "[%p%s]") then
|
|
return false, string.format("illegal characters used %q", word)
|
|
end
|
|
end
|
|
|
|
local func = CompileString(code, "SCRIPT_ENV", false)
|
|
|
|
if isstring(func) then
|
|
return false, func
|
|
end
|
|
|
|
local store = {globals = {}, parts = {}}
|
|
|
|
local extra_lib =
|
|
{
|
|
print = function(...)
|
|
if self:GetPlayerOwner() == pac.LocalPlayer then
|
|
print(...)
|
|
|
|
local str = ""
|
|
local count = select("#", ...)
|
|
|
|
for i = 1, count do
|
|
str = str .. tostring(select(i, ...))
|
|
if i ~= count then
|
|
str = str .. ", "
|
|
end
|
|
end
|
|
|
|
self.script_printing = str
|
|
end
|
|
end,
|
|
|
|
owner = {
|
|
GetFOV = function()
|
|
local ent = get_entity(self)
|
|
|
|
if ent:IsValid() then
|
|
return ent:GetFOV()
|
|
end
|
|
end,
|
|
|
|
GetHealth = function()
|
|
local ent = get_entity(self)
|
|
|
|
if ent:IsValid() then
|
|
return ent:Health()
|
|
end
|
|
end,
|
|
},
|
|
|
|
parts = {
|
|
GetParent = function(level)
|
|
level = level or 1
|
|
local parent = self
|
|
|
|
for _ = 1, math.Clamp(level, 1, 30) do
|
|
parent = parent:GetParent()
|
|
end
|
|
|
|
return CreateDummy(parent, store, self)
|
|
end,
|
|
|
|
FindMultiple = function(str)
|
|
local parts = {}
|
|
|
|
for _, part in pairs(pac.GetParts()) do
|
|
if
|
|
part:GetPlayerOwner() == self:GetPlayerOwner() and
|
|
pac.StringFind(part:GetName(), str)
|
|
then
|
|
table.insert(parts, part)
|
|
end
|
|
end
|
|
|
|
return CreateDummies(parts, self)
|
|
end,
|
|
|
|
FindMultipleWithProperty = function()
|
|
local parts = {}
|
|
|
|
for key, part in pairs(pac.GetParts()) do
|
|
if
|
|
part:GetPlayerOwner() == self:GetPlayerOwner() and
|
|
part.StorableVars[key] and
|
|
part["Get" .. key] and part["Get" .. key]()
|
|
then
|
|
table.insert(parts, part)
|
|
end
|
|
end
|
|
|
|
return CreateDummies(parts, self)
|
|
end,
|
|
|
|
Find = function(str)
|
|
for _, part in pairs(pac.GetParts()) do
|
|
if
|
|
part:GetPlayerOwner() == self:GetPlayerOwner() and
|
|
(part.UniqueID == str or part:GetName() == str)
|
|
then
|
|
return CreateDummy(part, store, self)
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
}
|
|
|
|
local env = {}
|
|
|
|
env.__index = function(_, key)
|
|
if key == "this" or key == "self" then
|
|
return CreateDummy(self, store, self)
|
|
end
|
|
|
|
if key == "T" or key == "TIME" then
|
|
return RealTime()
|
|
end
|
|
|
|
if key == "CT" or key == "CURTIME" then
|
|
return CurTime()
|
|
end
|
|
|
|
if lib[key] then
|
|
return lib[key]
|
|
end
|
|
|
|
if extra_lib[key] then
|
|
return extra_lib[key]
|
|
end
|
|
|
|
if store[key] then
|
|
return store[key]
|
|
end
|
|
end
|
|
|
|
env.__newindex = function(_, key, val)
|
|
store[key] = val
|
|
end
|
|
|
|
self.valid_functions = {
|
|
SetProperty = "m",
|
|
GetProperty = "m",
|
|
GetChildren = "m",
|
|
EventHide = "m",
|
|
EventShow = "m",
|
|
self = "e",
|
|
this = "e",
|
|
T = "e",
|
|
TIME = "e",
|
|
CT = "e",
|
|
CURTIME = "e"
|
|
}
|
|
|
|
local function scan(tbl)
|
|
for key, val in pairs(tbl) do
|
|
self.valid_functions[key] = val
|
|
|
|
if istable(val) then
|
|
scan(val)
|
|
end
|
|
end
|
|
end
|
|
|
|
scan(lib)
|
|
scan(extra_lib)
|
|
|
|
setfenv(func, setmetatable({}, env))
|
|
|
|
return true, func
|
|
end
|
|
|
|
function PART:ShouldHighlight(str)
|
|
return self.valid_functions and self.valid_functions[str]
|
|
end
|
|
|
|
function PART:SetCode(code)
|
|
self.Code = code
|
|
local ok, func = self:CompileCode()
|
|
|
|
if ok then
|
|
self.func = func
|
|
self:SetError()
|
|
else
|
|
self:SetError(func)
|
|
self.func = nil
|
|
end
|
|
end
|
|
|
|
function PART:OnThink()
|
|
if self.func then
|
|
local ok, err = pcall(self.func)
|
|
if not ok then
|
|
self:SetError(err)
|
|
self.func = nil
|
|
else
|
|
self:SetError()
|
|
end
|
|
end
|
|
end
|
|
|
|
concommand.Add("pac_register_script_part", function()
|
|
BUILDER:Register()
|
|
end)
|