mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
206 lines
4.4 KiB
Lua
206 lines
4.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 = "faceposer"
|
||
|
|
|
||
|
|
PART.FriendlyName = "face poser"
|
||
|
|
PART.Icon = 'icon16/monkey.png'
|
||
|
|
PART.Group = 'entity'
|
||
|
|
|
||
|
|
|
||
|
|
BUILDER:StartStorableVars()
|
||
|
|
:GetSet("Preset", "", {enums = function(part)
|
||
|
|
local ent = part:GetOwner()
|
||
|
|
if not ent:IsValid() then return end
|
||
|
|
|
||
|
|
local maps = {}
|
||
|
|
|
||
|
|
local toolgun = {}
|
||
|
|
for i = 0, 255 do
|
||
|
|
local name = ent:GetFlexName(i)
|
||
|
|
if name then
|
||
|
|
toolgun[name] = GetConVar("faceposer_flex" .. i):GetFloat()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
maps.toolgun = util.TableToJSON({
|
||
|
|
scale = GetConVar("faceposer_scale"):GetFloat(),
|
||
|
|
weight_map = util.TableToJSON(toolgun),
|
||
|
|
})
|
||
|
|
|
||
|
|
for preset_name, map in pairs(presets.GetTable( "face" )) do
|
||
|
|
local preset = {}
|
||
|
|
for key, weight in pairs(map) do
|
||
|
|
local i = tonumber(key:match("faceposer_flex(%d+)"))
|
||
|
|
if i then
|
||
|
|
local name = ent:GetFlexName(i)
|
||
|
|
if name then
|
||
|
|
preset[name] = tonumber(weight)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
maps[preset_name] = util.TableToJSON({
|
||
|
|
scale = tonumber(map.faceposer_scale),
|
||
|
|
weight_map = util.TableToJSON(preset),
|
||
|
|
})
|
||
|
|
end
|
||
|
|
|
||
|
|
return maps
|
||
|
|
end})
|
||
|
|
:GetSet("FlexWeights", "", {hidden = true})
|
||
|
|
:GetSet("Scale", 1)
|
||
|
|
:GetSet("Additive", false)
|
||
|
|
:EndStorableVars()
|
||
|
|
|
||
|
|
|
||
|
|
-- Make the internal flex names be more presentable, TODO: handle numbers
|
||
|
|
local function PrettifyName( name )
|
||
|
|
name = name:Replace( "_", " " )
|
||
|
|
|
||
|
|
-- Try to split text into words, where words would start with single uppercase character
|
||
|
|
local newParts = {}
|
||
|
|
for id, str in pairs( string.Explode( " ", name ) ) do
|
||
|
|
local wordStart = 1
|
||
|
|
for i = 2, str:len() do
|
||
|
|
local c = str[ i ]
|
||
|
|
if ( c:upper() == c ) then
|
||
|
|
local toAdd = str:sub(wordStart, i - 1)
|
||
|
|
if ( toAdd:upper() == toAdd ) then continue end
|
||
|
|
table.insert( newParts, toAdd )
|
||
|
|
wordStart = i
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
table.insert( newParts, str:sub(wordStart, str:len()))
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Uppercase all first characters
|
||
|
|
for id, str in pairs( newParts ) do
|
||
|
|
if ( str:len() < 2 ) then continue end
|
||
|
|
newParts[ id ] = str:Left( 1 ):upper() .. str:sub( 2 )
|
||
|
|
end
|
||
|
|
|
||
|
|
return table.concat( newParts, " " )
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
function PART:GetDynamicProperties()
|
||
|
|
local ent = self:GetOwner()
|
||
|
|
if not ent:IsValid() then return end
|
||
|
|
if ent.GetFlexNum and ent:GetFlexNum() and ent:GetFlexNum() == 0 then return end
|
||
|
|
|
||
|
|
local tbl = {}
|
||
|
|
|
||
|
|
for i = 0, ent:GetFlexNum() - 1 do
|
||
|
|
local name = ent:GetFlexName(i)
|
||
|
|
|
||
|
|
tbl[name] = {
|
||
|
|
key = name,
|
||
|
|
sort_key = -i,
|
||
|
|
get = function()
|
||
|
|
local weight_map = util.JSONToTable(self:GetFlexWeights()) or {}
|
||
|
|
|
||
|
|
return weight_map[name] or 0
|
||
|
|
end,
|
||
|
|
set = function(val)
|
||
|
|
local weight_map = util.JSONToTable(self:GetFlexWeights()) or {}
|
||
|
|
|
||
|
|
weight_map[name] = tonumber(val) or 0
|
||
|
|
|
||
|
|
self:SetFlexWeights(util.TableToJSON(weight_map))
|
||
|
|
end,
|
||
|
|
udata = {
|
||
|
|
editor_friendly = PrettifyName(name),
|
||
|
|
group = "flexes",
|
||
|
|
editor_sensitivity = 0.1,
|
||
|
|
editor_onchange = function(self, num)
|
||
|
|
local min, max = ent:GetFlexBounds(i)
|
||
|
|
|
||
|
|
return math.Clamp(num, min, max)
|
||
|
|
end,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
return tbl
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:SetPreset(json)
|
||
|
|
local preset = util.JSONToTable(json)
|
||
|
|
if preset then
|
||
|
|
self:SetFlexWeights(preset.weight_map)
|
||
|
|
self:SetScale(preset.scale)
|
||
|
|
end
|
||
|
|
self.Preset = ""
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:GetNiceName()
|
||
|
|
return "face pose"
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:GetWeightMap()
|
||
|
|
local data = self:GetFlexWeights()
|
||
|
|
|
||
|
|
if data ~= self.last_data then
|
||
|
|
self.weight_map = util.JSONToTable(data) or {}
|
||
|
|
self.last_data = data
|
||
|
|
end
|
||
|
|
|
||
|
|
return self.weight_map
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:UpdateFlex()
|
||
|
|
local ent = self:GetOwner()
|
||
|
|
if not ent:IsValid() then return end
|
||
|
|
|
||
|
|
ent:SetFlexScale(self.Scale)
|
||
|
|
ent.pac_touching_flexes = ent.pac_touching_flexes or {}
|
||
|
|
|
||
|
|
for name, weight in pairs(self:GetWeightMap()) do
|
||
|
|
local id = ent:GetFlexIDByName(name)
|
||
|
|
if id then
|
||
|
|
if self.Additive then
|
||
|
|
weight = ent:GetFlexWeight(id) + weight
|
||
|
|
end
|
||
|
|
ent:SetFlexWeight(id, weight)
|
||
|
|
ent.pac_touching_flexes[id] = pac.RealTime + 0.1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnThink()
|
||
|
|
local ent = self:GetOwner()
|
||
|
|
if not ent:IsPlayer() then
|
||
|
|
self:UpdateFlex()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnBuildBonePositions()
|
||
|
|
self:UpdateFlex()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnShow(from_rendering)
|
||
|
|
self:UpdateFlex()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnHide()
|
||
|
|
self:UpdateFlex()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PART:OnRemove()
|
||
|
|
self:UpdateFlex()
|
||
|
|
end
|
||
|
|
|
||
|
|
BUILDER:Register()
|