maintenance
This commit is contained in:
parent
8c8ceaaf47
commit
d27c1fa39a
23 changed files with 1977 additions and 1564 deletions
196
scripts/libs/SquAPI_modules/smoothHead.lua
Normal file
196
scripts/libs/SquAPI_modules/smoothHead.lua
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
---SMOOTH HEAD
|
||||
---Mimics a vanilla player head, but smoother and with some extra life. Can also do smooth Torsos and Smooth Necks!
|
||||
|
||||
|
||||
---@meta _
|
||||
local squassets
|
||||
local assetPath = "./SquAssets"
|
||||
if pcall(require, assetPath) then squassets = require(assetPath) end
|
||||
assert(squassets, "§4The smoothHead module requires SquAssets, which was not found!§c")
|
||||
|
||||
---@class smoothHead
|
||||
local smoothHead = {}
|
||||
smoothHead.all = {}
|
||||
|
||||
---*CONSTRUCTOR
|
||||
---@param element ModelPart|table<ModelPart> The head element that you wish to effect. If you want a smooth neck or torso, instead of a single element, input a table of head elements(imagine it like {element1, element2, etc.}). this will apply the head rotations to each of these.
|
||||
---@param strength? number|table<number> Defaults to `1`, the target rotation is multiplied by this factor. If you want a smooth neck or torso, instead of an single number, you can put in a table(imagine it like {strength1, strength2, etc.}). this will apply each strength to each respective element.(make sure it is the same length as your element table)
|
||||
---@param tilt? number Defaults to `0.1`, for context the smooth head applies a slight tilt to the head as it's rotated toward the side, this controls the strength of that tilt.
|
||||
---@param speed? number Defaults to `1`, how fast the head will rotate toward the target rotation.
|
||||
---@param keepOriginalHeadPos? boolean|number Defaults to `true`, when true the heads position will follow the vanilla head position. For example when crouching the head will shift down to follow. If set to a number, changes which modelpart gets moved when doing actions such as crouching. this should normally be set to the neck modelpart.
|
||||
---@param fixPortrait? boolean Defaults to `true`, sets whether or not the portrait should be applied if a group named "head" is found in the elements list
|
||||
---@param animStraightenList? table<Animation> Defaults to `nil`, you can put in a list of animations that when played, will cause the head to straighten.
|
||||
---@param straightenMultiplier? number Defaults to `0.5`, how strong the head will straighten during above
|
||||
---@param straightenSpeed? number Defaults to `0.5`, how fast the head will straighten during above
|
||||
---@param blendToConsiderStopped? number Defaults to `0.1`, for above, the animation will be considered stopped when it's blend is below this value.
|
||||
---@return SquAPI.SmoothHead
|
||||
function smoothHead:new(element, strength, tilt, speed, keepOriginalHeadPos, fixPortrait, animStraightenList, straightenMultiplier, straightenSpeed, blendToConsiderStopped)
|
||||
---@class SquAPI.SmoothHead
|
||||
local self = setmetatable({}, {__index = smoothHead})
|
||||
|
||||
--if it's a single element then converts to table
|
||||
if type(element) == "ModelPart" then
|
||||
assert(element, "§4Your model path for smoothHead is incorrect.§c")
|
||||
element = { element }
|
||||
end
|
||||
|
||||
--checks each element amd updates parent type to none
|
||||
for i = 1, #element do
|
||||
assert(element[i]:getType() == "GROUP",
|
||||
"§4The head element at position " ..
|
||||
i ..
|
||||
" of the table is not a group. The head elements need to be groups that are nested inside one another to function properly.§c")
|
||||
assert(element[i], "§4The head segment at position " .. i .. " is incorrect.§c")
|
||||
element[i]:setParentType("NONE")
|
||||
end
|
||||
self.element = element
|
||||
|
||||
--if strength is a single number then converts to table by evenly dividing strength for each element
|
||||
self.strength = strength or 1
|
||||
if type(self.strength) == "number" then
|
||||
local strengthDiv = self.strength / #element
|
||||
self.strength = {}
|
||||
for i = 1, #element do
|
||||
self.strength[i] = strengthDiv
|
||||
end
|
||||
end
|
||||
|
||||
self.tilt = tilt or 0.1
|
||||
self.speed = (speed or 1)
|
||||
if keepOriginalHeadPos == nil then keepOriginalHeadPos = true end
|
||||
self.keepOriginalHeadPos = keepOriginalHeadPos
|
||||
self.animStraightenList = animStraightenList
|
||||
self.straightenMultiplier = straightenMultiplier or 0.5
|
||||
self.straightenSpeed = straightenSpeed or 0.5
|
||||
self.blendToConsiderStopped = blendToConsiderStopped or 0.1
|
||||
|
||||
self.currentStraightenMultiplier = 1
|
||||
|
||||
--portrait fix by FOX
|
||||
if fixPortrait == nil then fixPortrait = true end
|
||||
if fixPortrait then
|
||||
if type(element) == "table" then
|
||||
for _, part in ipairs(element) do
|
||||
if squassets.caseInsensitiveFind(part, "head") then
|
||||
part:copy("_squapi-portrait"):moveTo(models):setParentType("Portrait")
|
||||
:setPos(-part:getPivot())
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif type(element) == "ModelPart" and element:getType() == "GROUP" then
|
||||
if squassets.caseInsensitiveFind(element, "head") then
|
||||
element:copy("_squapi-portrait"):moveTo(models):setParentType("Portrait")
|
||||
:setPos(-element:getPivot())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
self.rot = {}
|
||||
self.rotOld = {}
|
||||
for i in ipairs(self.element) do
|
||||
self.rot[i] = vec(0,0,0)
|
||||
self.rotOld[i] = vec(0,0,0)
|
||||
end
|
||||
|
||||
self.enabled = true
|
||||
|
||||
table.insert(smoothHead.all, self)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--*CONTROL FUNCTIONS
|
||||
|
||||
---Applies an offset to the heads rotation to more easily modify it. Applies as a vector.(for multisegments it will modify the target rotation)
|
||||
---@param xRot number X rotation
|
||||
---@param yRot number Y rotation
|
||||
---@param zRot number Z rotation
|
||||
function smoothHead:setOffset(xRot, yRot, zRot)
|
||||
self.offset = vec(xRot, yRot, zRot)
|
||||
return self
|
||||
end
|
||||
|
||||
---smoothHead enable handling
|
||||
function smoothHead:disable() self.enabled = false return self end
|
||||
function smoothHead:enable() self.enabled = true return self end
|
||||
function smoothHead:toggle() self.enabled = not self.enabled return self end
|
||||
|
||||
---@param bool boolean
|
||||
function smoothHead:setEnabled(bool)
|
||||
self.enabled = bool or false
|
||||
return self
|
||||
end
|
||||
|
||||
---Resets this smooth head's position and rotation to their initial values
|
||||
function smoothHead:zero()
|
||||
for _, v in ipairs(self.element) do
|
||||
v:setPos(0, 0, 0)
|
||||
v:setOffsetRot(0, 0, 0)
|
||||
self.headRot = vec(0, 0, 0)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--*UPDATE FUNCTIONS
|
||||
|
||||
function smoothHead:tick()
|
||||
|
||||
if self.animStraightenList then
|
||||
local strengthMultiplier = 1
|
||||
for _, v in ipairs(self.animStraightenList) do
|
||||
|
||||
if v:isPlaying() and v:getBlend() > self.blendToConsiderStopped then
|
||||
strengthMultiplier = self.straightenMultiplier
|
||||
break
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.currentStraightenMultiplier = math.lerp(self.currentStraightenMultiplier, strengthMultiplier, self.straightenSpeed)
|
||||
|
||||
end
|
||||
|
||||
for i in ipairs(self.element) do
|
||||
self.rotOld[i] = self.rot[i]
|
||||
end
|
||||
|
||||
if self.enabled then
|
||||
local vanillaHeadRot = squassets.getHeadRot():add(vanilla_model.HEAD:getOffsetRot())
|
||||
|
||||
for i in ipairs(self.element) do
|
||||
self.rot[i] = math.lerp(self.rot[i], (vanillaHeadRot + vanillaHeadRot.__y * self.tilt) * self.strength[i] * self.currentStraightenMultiplier , self.speed)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
---@param dt number Tick delta
|
||||
---@param context Event.Render.context
|
||||
function smoothHead:render(dt, context)
|
||||
if self.enabled then
|
||||
for i, element in ipairs(self.element) do
|
||||
|
||||
element:setOffsetRot(
|
||||
math.lerp(self.rotOld[i], self.rot[i], dt)
|
||||
)
|
||||
-- Better Combat SquAPI Compatibility created by @jimmyhelp and @foxy2526 on Discord
|
||||
if renderer:isFirstPerson() and context == "RENDER" then
|
||||
self.element[i]:setVisible(false)
|
||||
else
|
||||
self.element[i]:setVisible(true)
|
||||
end
|
||||
end
|
||||
|
||||
if self.keepOriginalHeadPos then
|
||||
self.element
|
||||
[type(self.keepOriginalHeadPos) == "number" and self.keepOriginalHeadPos or #self.element]
|
||||
:setPos(-vanilla_model.HEAD:getOriginPos())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return smoothHead
|
||||
Loading…
Add table
Add a link
Reference in a new issue