mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-18 06:03:47 +03:00
Upload
This commit is contained in:
205
lua/pac3/core/client/parts/faceposer.lua
Normal file
205
lua/pac3/core/client/parts/faceposer.lua
Normal file
@@ -0,0 +1,205 @@
|
||||
--[[
|
||||
| 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()
|
||||
Reference in New Issue
Block a user