maintenance
This commit is contained in:
parent
8c8ceaaf47
commit
d27c1fa39a
23 changed files with 1977 additions and 1564 deletions
145
scripts/libs/SquAPI_modules/ear.lua
Normal file
145
scripts/libs/SquAPI_modules/ear.lua
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
---@meta _
|
||||
local squassets
|
||||
local assetPath = "./SquAssets"
|
||||
if pcall(require, assetPath) then squassets = require(assetPath) end
|
||||
assert(squassets, "§4The ear module requires SquAssets, which was not found!§c")
|
||||
|
||||
|
||||
---@class ear
|
||||
local ear = {}
|
||||
ear.all = {}
|
||||
|
||||
---*CONSTRUCTOR
|
||||
---@param leftEar ModelPart The left ear's model path.
|
||||
---@param rightEar? ModelPart The right ear's model path, if you don't have a right ear, just leave this blank or set to nil.
|
||||
---@param rangeMultiplier? number Defaults to `1`, how far the ears should rotate with your head.
|
||||
---@param horizontalEars? boolean Defaults to `false`, if you have elf-like ears(ears that stick out horizontally), set this to true.
|
||||
---@param bendStrength? number Defaults to `2`, how much the ears should move when you move.
|
||||
---@param doEarFlick? boolean Defaults to `true`, whether or not the ears should randomly flick.
|
||||
---@param earFlickChance? number Defaults to `400`, how often the ears should flick in ticks, timer is random between 0 to n ticks.
|
||||
---@param earStiffness? number Defaults to `0.1`, how stiff the ears should be.
|
||||
---@param earBounce? number Defaults to `0.8`, how bouncy the ears should be.
|
||||
---@return SquAPI.Ear
|
||||
function ear:new(leftEar, rightEar, rangeMultiplier, horizontalEars, bendStrength, doEarFlick,
|
||||
earFlickChance, earStiffness, earBounce)
|
||||
---@class SquAPI.ear
|
||||
local self = {}
|
||||
|
||||
assert(leftEar, "§4The first ear's model path is incorrect.§c")
|
||||
self.leftEar = leftEar
|
||||
self.rightEar = rightEar
|
||||
self.horizontalEars = horizontalEars
|
||||
self.rangeMultiplier = rangeMultiplier or 1
|
||||
if self.horizontalEars then self.rangeMultiplier = self.rangeMultiplier / 2 end
|
||||
self.bendStrength = bendStrength or 2
|
||||
earStiffness = earStiffness or 0.1
|
||||
earBounce = earBounce or 0.8
|
||||
|
||||
if doEarFlick == nil then doEarFlick = true end
|
||||
self.doEarFlick = doEarFlick
|
||||
self.earFlickChance = earFlickChance or 400
|
||||
|
||||
self.eary = squassets.BERP:new(earStiffness, earBounce)
|
||||
self.earx = squassets.BERP:new(earStiffness, earBounce)
|
||||
self.earz = squassets.BERP:new(earStiffness, earBounce)
|
||||
self.targets = { 0, 0, 0 }
|
||||
self.oldpose = "STANDING"
|
||||
|
||||
self.enabled = true
|
||||
|
||||
self = setmetatable(self, {__index = ear})
|
||||
table.insert(ear.all, self)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--*CONTROL FUNCTIONS
|
||||
|
||||
---ear enable handling
|
||||
function ear:disable() self.enabled = false return self end
|
||||
function ear:enable() self.enabled = true return self end
|
||||
function ear:toggle() self.enabled = not self.enabled return self end
|
||||
|
||||
---@param bool boolean
|
||||
function ear:setEnabled(bool)
|
||||
self.enabled = bool or false
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--*UPDATE FUNCTIONS
|
||||
|
||||
function ear:tick()
|
||||
if self.enabled then
|
||||
local vel = math.min(math.max(-0.75, squassets.forwardVel()), 0.75)
|
||||
local yvel = math.min(math.max(-1.5, squassets.verticalVel()), 1.5) * 5
|
||||
local svel = math.min(math.max(-0.5, squassets.sideVel()), 0.5)
|
||||
local headrot = squassets.getHeadRot()
|
||||
local bend = self.bendStrength
|
||||
if headrot[1] < -22.5 then bend = -bend end
|
||||
|
||||
--gives the ears a short push when crouching/uncrouching
|
||||
local pose = player:getPose()
|
||||
if pose == "CROUCHING" and self.oldpose == "STANDING" then
|
||||
self.eary.vel = self.eary.vel + 5 * self.bendStrength
|
||||
elseif pose == "STANDING" and self.oldpose == "CROUCHING" then
|
||||
self.eary.vel = self.eary.vel - 5 * self.bendStrength
|
||||
end
|
||||
self.oldpose = pose
|
||||
|
||||
--main physics
|
||||
if self.horizontalEars then
|
||||
local rot = 10 * bend * (yvel + vel * 10) + headrot[1] * self.rangeMultiplier
|
||||
local addrot = headrot[2] * self.rangeMultiplier
|
||||
self.targets[2] = rot + addrot
|
||||
self.targets[3] = -rot + addrot
|
||||
else
|
||||
self.targets[1] = headrot[1] * self.rangeMultiplier + 2 * bend * (yvel + vel * 15)
|
||||
self.targets[2] = headrot[2] * self.rangeMultiplier - svel * 100 * self.bendStrength
|
||||
self.targets[3] = self.targets[2]
|
||||
end
|
||||
|
||||
--ear flicking
|
||||
if self.doEarFlick then
|
||||
if math.random(0, self.earFlickChance) == 1 then
|
||||
if math.random(0, 1) == 1 then
|
||||
self.earx.vel = self.earx.vel + 50
|
||||
else
|
||||
self.earz.vel = self.earz.vel - 50
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
self.leftEar:setOffsetRot(0, 0, 0)
|
||||
self.rightEar:setOffsetRot(0, 0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---@param dt number Tick delta
|
||||
function ear:render(dt, _)
|
||||
if self.enabled then
|
||||
self.eary:berp(self.targets[1], dt)
|
||||
self.earx:berp(self.targets[2], dt)
|
||||
self.earz:berp(self.targets[3], dt)
|
||||
|
||||
local rot3 = self.earx.pos / 4
|
||||
local rot3b = self.earz.pos / 4
|
||||
|
||||
if self.horizontalEars then
|
||||
local y = self.eary.pos / 4
|
||||
self.leftEar:setOffsetRot(y, self.earx.pos / 3, rot3)
|
||||
if self.rightEar then
|
||||
self.rightEar:setOffsetRot(y, self.earz.pos / 3, rot3b)
|
||||
end
|
||||
else
|
||||
self.leftEar:setOffsetRot(self.eary.pos, rot3, rot3)
|
||||
if self.rightEar then
|
||||
self.rightEar:setOffsetRot(self.eary.pos, rot3b, rot3b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ear
|
||||
Loading…
Add table
Add a link
Reference in a new issue