This commit is contained in:
lifestorm
2024-08-05 18:40:29 +03:00
parent 9f505a0646
commit c6d9b6f580
8044 changed files with 1853472 additions and 21 deletions

View File

@@ -0,0 +1,123 @@
--[[
| 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 PLUGIN = PLUGIN
PLUGIN.cameraWheelOffset = 1
PLUGIN.cameraWheelDelta = PLUGIN.cameraWheelOffset
PLUGIN.cameraInOutOffset = 0
PLUGIN.cameraInOutDelta = PLUGIN.cameraInOutOffset
local function GetHeadBone(client)
local head
for i = 1, client:GetBoneCount() do
if (string.find(client:GetBoneName(i):lower(), "head")) then
head = i
break
end
end
return head
end
function PLUGIN:PlayerBindPress(client, bind, bPressed)
if (!client:GetNetVar("actEnterAngle")) then
return
end
if (bind:find("+jump") and bPressed) then
ix.command.Send("ExitAct")
PLUGIN.cameraInOutOffset = ix.option.Get("thirdpersonEnabled") and 1 or 0
return true
end
end
function PLUGIN:InputMouseApply(cmd)
if !LocalPlayer():GetNetVar("actEnterAngle") then
return
end
local mouseWheel = cmd:GetMouseWheel()
if mouseWheel != 0 then
self.cameraWheelOffset = math.Clamp(self.cameraWheelOffset + (-mouseWheel * 0.5), 1.0, 1.5)
end
end
local traceMin = Vector(-4, -4, -4)
local traceMax = Vector(4, 4, 4)
function PLUGIN:CalcView(client, origin)
if !client:GetNetVar("actEnterAngle") then
return
end
local frameTime = FrameTime()
self.cameraWheelDelta = math.Approach(self.cameraWheelDelta, self.cameraWheelOffset, frameTime * 6)
self.cameraInOutDelta = math.Approach(self.cameraInOutDelta, self.cameraInOutOffset, frameTime * 4)
local view = {}
view.drawviewer = self.cameraInOutDelta >= 0.225 * (self.cameraWheelOffset * 0.1)
local head = GetHeadBone(client)
local headOffset = Vector(0, 0, 64)
if head then
headOffset = client:GetBonePosition(head)
end
local currentAngle = client.camAng or angle_zero
local tracePosition = {}
tracePosition.start = headOffset + client:GetNetVar("actEnterAngle"):Forward() * 10
tracePosition.endpos = tracePosition.start - currentAngle:Forward() * (70 * self.cameraInOutDelta) * self.cameraWheelDelta
tracePosition.filter = client
tracePosition.ignoreworld = false
tracePosition.mins = traceMin
tracePosition.maxs = traceMax
view.origin = util.TraceHull(tracePosition).HitPos
view.angles = currentAngle + client:GetViewPunchAngles()
local aimOrigin = view.origin
local traceAngle = {}
traceAngle.start = aimOrigin
traceAngle.endpos = aimOrigin + currentAngle:Forward() * 65535
traceAngle.filter = client
traceAngle.ignoreworld = (client:GetMoveType() == MOVETYPE_NOCLIP)
client:SetEyeAngles((util.TraceLine(traceAngle).HitPos - client:GetShootPos()):Angle())
return view
end
net.Receive("ixActEnter", function()
if ix.option.Get("thirdpersonEnabled") then
PLUGIN.cameraInOutOffset = 1
PLUGIN.cameraInOutDelta = PLUGIN.cameraInOutOffset
end
PLUGIN.cameraInOutOffset = 1
end)
net.Receive("ixActLeave", function()
PLUGIN.cameraWheelOffset = 1
PLUGIN.cameraWheelDelta = PLUGIN.cameraWheelOffset
PLUGIN.cameraInOutOffset = 0
PLUGIN.cameraInOutDelta = PLUGIN.cameraInOutOffset
end)

View File

@@ -0,0 +1,377 @@
--[[
| 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 function FacingWall(client)
local data = {}
data.start = client:EyePos()
data.endpos = data.start + client:GetForward() * 20
data.filter = client
if (!util.TraceLine(data).Hit) then
return "@faceWall"
end
end
local function FacingWallBack(client)
local data = {}
data.start = client:LocalToWorld(client:OBBCenter())
data.endpos = data.start - client:GetForward() * 20
data.filter = client
if (!util.TraceLine(data).Hit) then
return "@faceWallBack"
end
end
function PLUGIN:SetupActs()
-- sit
ix.act.Register("Sit", "metrocop", {
sequence = {"n7_male_sit_ground", "n7_male_sit01", "n7_male_sit02", "n7_male_sit03", "n7_male_sit04", "n7_male_sit05", "n7_male_sit06", "n7_male_sit07"},
untimed = true
})
ix.act.Register("Sit", "citizen_male", {
sequence = {"willard_male_male_sit_ground", "willard_male_male_sit01", "willard_male_male_sit02", "willard_male_male_sit03", "willard_male_male_sit04", "willard_male_male_sit05", "willard_male_male_sit06", "willard_male_male_sit07"},
untimed = true
})
ix.act.Register("Sit", "citizen_female", {
sequence = {"willard_female_sit_ground", "willard_female_sit01", "willard_female_sit02", "willard_female_sit03", "willard_female_sit04", "willard_female_sit05", "willard_female_sit06", "willard_female_sit07"},
untimed = true
})
ix.act.Register("Sit", "metrocop_female", {
sequence = {"n7_female_sit_ground", "n7_female_sit01", "n7_female_sit02", "n7_female_sit03", "n7_female_sit04", "n7_female_sit05", "n7_female_sit06", "n7_female_sit07"},
untimed = true
})
-- sitwall
ix.act.Register("SitWall", "metrocop", {
sequence = {
{"n7_male_sitwall", check = FacingWallBack},
},
untimed = true,
idle = true
})
ix.act.Register("SitWall", "citizen_male", {
sequence = {
{"willard_male_male_sitwall", check = FacingWallBack},
},
untimed = true,
idle = true
})
ix.act.Register("SitWall", "metrocop_female", {
sequence = {
{"n7_female_sitwall", check = FacingWallBack},
},
untimed = true,
idle = true
})
ix.act.Register("SitWall", "citizen_female", {
sequence = {
{"willard_female_sitwall", check = FacingWallBack},
},
untimed = true,
idle = true
})
--sitlean
ix.act.Register("SitLean", {"citizen_male", "citizen_female"}, {
sequence = {"sitccouchtv1", "sitchair1", "sitchairtable1", "sitcouch1", "sitcouchknees1"},
untimed = true,
idle = true
})
ix.act.Register("SitChair", "citizen_male", {
start = {"idle_to_sit_chair"},
sequence = "sit_chair",
finish = {"sit_chair_to_idle", duration = 2.1},
untimed = true,
idle = true
})
-- Idle
ix.act.Register("Idle", "vortigaunt", {
sequence = "idle_nectar",
untimed = true,
idle = true
})
-- Kneel
ix.act.Register("Kneel", "vortigaunt", {
sequence = "rescue_idle",
untimed = true,
idle = true
})
-- Sit
ix.act.Register("Sit", "vortigaunt", {
sequence = {"chess_wait", {"sit_rollercoaster", offset = function(client)
return client:GetUp() * 25 + client:GetForward() * -30
end}
},
untimed = true,
idle = true
})
-- stand
ix.act.Register("Stand","metrocop", {
sequence = {"n7_male_stand01", "n7_male_stand02", "n7_male_stand03", "n7_male_stand04", "n7_male_stand05"},
untimed = true
})
ix.act.Register("Stand", "citizen_male", {
sequence = {"willard_male_male_stand01", "willard_male_male_stand02", "willard_male_male_stand03", "willard_male_male_stand04", "willard_male_male_stand05"},
untimed = true
})
ix.act.Register("Stand", "metrocop_female", {
sequence = {"n7_female_stand01", "n7_female_stand02", "n7_female_stand03", "n7_female_stand04", "n7_female_stand05"},
untimed = true
})
ix.act.Register("Stand", "citizen_female", {
sequence = {"willard_female_stand01", "willard_female_stand02", "willard_female_stand03", "willard_female_stand04", "willard_female_stand05"},
untimed = true
})
-- type
ix.act.Register("Type", "overwatch", {
sequence = "console_type_loop",
untimed = true,
idle = true
})
-- cheer
ix.act.Register("Cheer", {"citizen_male", "metrocop"}, {
sequence = {{"cheer1", duration = 1.6}, "cheer2", "wave_smg1"}
})
ix.act.Register("Cheer", {"citizen_female", "metrocop_female"}, {
sequence = {"cheer1", "wave_smg1"}
})
-- lean
ix.act.Register("Lean", {"citizen_male", "citizen_female"}, {
start = {"idle_to_lean_back", "", ""},
sequence = {
{"lean_back", check = FacingWallBack},
{"plazaidle1", check = FacingWallBack},
{"plazaidle2", check = FacingWallBack}
},
untimed = true,
idle = true
})
ix.act.Register("Lean", {"metrocop"}, {
sequence = {
{"n7_male_lean01", check = FacingWallBack},
{"n7_male_lean02", check = FacingWallBack},
{"idle_baton", check = FacingWallBack},
},
untimed = true,
idle = true
})
ix.act.Register("Lean", "citizen_male", {
sequence = {
{"willard_male_male_lean01", check = FacingWallBack, offset = function(client)
return client:GetForward() * 4
end},
{"willard_male_male_lean02", check = FacingWallBack, offset = function(client)
return client:GetForward() * 3
end}
},
untimed = true,
idle = true
})
ix.act.Register("Lean", "metrocop_female", {
sequence = {
{"n7_female_lean01", check = FacingWallBack, offset = function(client)
return client:GetForward() * 6
end},
{"n7_female_lean02", check = FacingWallBack, offset = function(client)
return client:GetForward() * 4
end}
},
untimed = true,
idle = true
})
ix.act.Register("Lean", "citizen_female", {
sequence = {
{"willard_female_lean01", check = FacingWallBack, offset = function(client)
return client:GetForward() * 6
end},
{"willard_female_lean02", check = FacingWallBack, offset = function(client)
return client:GetForward() * 4
end}
},
untimed = true,
idle = true
})
-- injured
ix.act.Register("Injured", "metrocop", {
sequence = {"n7_male_injured"},
untimed = true,
idle = true
})
ix.act.Register("Injured", "citizen_male", {
sequence = {"willard_male_male_injured"},
untimed = true,
idle = true
})
ix.act.Register("Injured", "metrocop_female", {
sequence = "n7_female_injured",
untimed = true,
idle = true
})
ix.act.Register("Injured", "citizen_female", {
sequence = "willard_female_injured",
untimed = true,
idle = true
})
-- arrest
ix.act.Register("Arrest", "metrocop", {
sequence = {"n7_male_arrest", "n7_male_arrest_sit01", "n7_male_handsup"},
untimed = true
})
ix.act.Register("Arrest", "citizen_male", {
sequence = {"willard_male_male_arrest", "willard_male_male_arrest_sit01", "willard_male_male_handsup"},
untimed = true
})
ix.act.Register("Arrest", "metrocop_female", {
sequence = {"n7_female_arrest", "n7_female_arrest_sit01", "n7_female_handsup"},
untimed = true
})
ix.act.Register("Arrest", "citizen_female", {
sequence = {"willard_female_arrest", "willard_female_arrest_sit01", "willard_female_handsup"},
untimed = true
})
-- threat
ix.act.Register("Threat", "metrocop", {
sequence = {"plazathreat1", "plazathreat2"}
})
-- search
ix.act.Register("Search", "metrocop", {
sequence = "spreadwall",
})
-- deny
ix.act.Register("Deny", "metrocop", {
sequence = {"harassfront2", "harassfront1"}
})
-- motion
ix.act.Register("Motion", "metrocop", {
sequence = {"motionleft", "motionright", "luggagewarn"}
})
-- wave
ix.act.Register("Wave", {"citizen_male", "citizen_female"}, {
sequence = {{"wave", duration = 2.75}, {"wave_close", duration = 1.75}}
})
-- pant
ix.act.Register("Pant", {"citizen_male", "citizen_female"}, {
start = {"d2_coast03_postbattle_idle02_entry", "d2_coast03_postbattle_idle01_entry"},
sequence = {"d2_coast03_postbattle_idle02", {"d2_coast03_postbattle_idle01", check = FacingWall}},
untimed = true
})
-- window
ix.act.Register("Window", {"citizen_male", "metrocop"}, {
sequence = "d1_t03_tenements_look_out_window_idle",
untimed = true
})
ix.act.Register("Window", {"citizen_female", "metrocop_female"}, {
sequence = "d1_t03_lookoutwindow",
untimed = true
})
-- down
ix.act.Register("Down", "metrocop", {
sequence = {"n7_male_down01", "n7_male_down02", "n7_male_down03"},
untimed = true,
idle = true
})
ix.act.Register("Down", "citizen_male", {
sequence = {"willard_male_male_down01", "willard_male_male_down02", "willard_male_male_down03"},
untimed = true,
idle = true
})
ix.act.Register("Down", "metrocop_female", {
sequence = {"n7_female_down01", "n7_female_down02", "n7_female_down03"},
untimed = true,
idle = true
})
ix.act.Register("Down", "citizen_female", {
sequence = {"willard_female_down01", "willard_female_down02", "willard_female_down03"},
untimed = true,
idle = true
})
-- Check
ix.act.Register("Check", "metrocop", {
sequence = {"n7_male_check"},
untimed = true
})
ix.act.Register("Check", "citizen_male", {
sequence = {"willard_male_male_check"},
untimed = true
})
ix.act.Register("Check", "metrocop_female", {
sequence = {"n7_female_check"},
untimed = true
})
ix.act.Register("Check", "citizen_female", {
sequence = {"willard_female_check"},
untimed = true
})
-- Knock
ix.act.Register("KnockIdle", "metrocop", {
sequence = {"adoorcidle"},
untimed = true
})
ix.act.Register("Knock", "metrocop", {
sequence = {"adoorknock"},
untimed = true
})
ix.act.Register("Knock", "citizen_male", {
sequence = {"d1_town05_Leon_Door_Knock"}
})
end

View File

@@ -0,0 +1,285 @@
--[[
| 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/
--]]
--[[--
Provides players the ability to perform animations.
]]
-- @module ix.act
local PLUGIN = PLUGIN
PLUGIN.name = "Player Acts"
PLUGIN.description = "Adds animations that can be performed by certain models."
PLUGIN.author = "`impulse"
ix.act = ix.act or {}
ix.act.stored = ix.act.stored or {}
CAMI.RegisterPrivilege({
Name = "Helix - Player Acts",
MinAccess = "user"
})
--- Registers a sequence as a performable animation.
-- @realm shared
-- @string name Name of the animation (in CamelCase)
-- @string modelClass Model class to add this animation to
-- @tab data An `ActInfoStructure` table describing the animation
function ix.act.Register(name, modelClass, data)
ix.act.stored[name] = ix.act.stored[name] or {} -- might be adding onto an existing act
if (!data.sequence) then
return ErrorNoHalt(string.format(
"Act '%s' for '%s' tried to register without a provided sequence\n", name, modelClass
))
end
if (!istable(data.sequence)) then
data.sequence = {data.sequence}
end
if (data.start and istable(data.start) and #data.start != #data.sequence) then
return ErrorNoHalt(string.format(
"Act '%s' tried to register without matching number of enter sequences\n", name
))
end
if (data.finish and istable(data.finish) and #data.finish != #data.sequence) then
return ErrorNoHalt(string.format(
"Act '%s' tried to register without matching number of exit sequences\n", name
))
end
if (istable(modelClass)) then
for _, v in ipairs(modelClass) do
ix.act.stored[name][v] = data
end
else
ix.act.stored[name][modelClass] = data
end
end
--- Removes a sequence from being performable if it has been previously registered.
-- @realm shared
-- @string name Name of the animation
function ix.act.Remove(name)
ix.act.stored[name] = nil
ix.command.list["Act" .. name] = nil
end
ix.util.Include("sh_definitions.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("cl_hooks.lua")
function PLUGIN:InitializedPlugins()
hook.Run("SetupActs")
hook.Run("PostSetupActs")
end
function PLUGIN:ExitAct(client)
client.ixUntimedSequence = nil
client:SetNetVar("actEnterAngle")
hook.Run("OnPlayerExitAct", client)
net.Start("ixActLeave")
net.Send(client)
end
function PLUGIN:PostSetupActs()
-- create chat commands for all stored acts
for act, classes in pairs(ix.act.stored) do
local variants = 1
local COMMAND = {
privilege = "Player Acts"
}
-- check if this act has any variants (i.e /ActSit 2)
for _, v in pairs(classes) do
if (#v.sequence > 1) then
variants = math.max(variants, #v.sequence)
end
end
-- setup command arguments if there are variants for this act
if (variants > 1) then
COMMAND.arguments = bit.bor(ix.type.number, ix.type.optional)
COMMAND.argumentNames = {"variant (1-" .. variants .. ")"}
end
COMMAND.alias = "Anim" .. act -- Old habits die hard.
COMMAND.GetDescription = function(command)
return L("cmdAct", act)
end
local privilege = "Helix - " .. COMMAND.privilege
-- we'll perform a model class check in OnCheckAccess to prevent the command from showing up on the client at all
COMMAND.OnCheckAccess = function(command, client)
local bHasAccess, _ = CAMI.PlayerHasAccess(client, privilege, nil)
if (!bHasAccess) then
return false
end
local modelClass = ix.anim.GetModelClass(client:GetModel())
if (!classes[modelClass]) then
return false, "modelNoSeq"
end
return true
end
COMMAND.OnRun = function(command, client, variant)
-- Anti-Exploit measure. Just silently fail if near a door.
for _, entity in ipairs(ents.FindInSphere(client:GetPos(), 50)) do
if (entity:GetClass() == "func_door" or entity:GetClass() == "func_door_rotating" or entity:GetClass() == "prop_door_rotating") then return end
end
variant = math.Clamp(tonumber(variant) or 1, 1, variants)
if (client:GetNetVar("actEnterAngle")) then
return "@notNow"
end
local modelClass = ix.anim.GetModelClass(client:GetModel())
local bCanEnter, error = hook.Run("CanPlayerEnterAct", client, modelClass, variant, classes)
if (!bCanEnter) then
return error
end
local data = classes[modelClass]
local mainSequence = data.sequence[variant]
local mainDuration
-- check if the main sequence has any extra info
if (istable(mainSequence)) then
-- any validity checks to perform (i.e facing a wall)
if (mainSequence.check) then
local result = mainSequence.check(client)
if (result) then
return result
end
end
-- position offset
if (mainSequence.offset) then
client.ixOldPosition = client:GetPos()
client:SetPos(client:GetPos() + mainSequence.offset(client))
end
mainDuration = mainSequence.duration
mainSequence = mainSequence[1]
end
local startSequence = data.start and data.start[variant] or ""
local startDuration
if (istable(startSequence)) then
startDuration = startSequence.duration
startSequence = startSequence[1]
end
client:SetNetVar("actEnterAngle", client:GetAngles())
client:ForceSequence(startSequence, function()
-- we've finished the start sequence
client.ixUntimedSequence = data.untimed -- client can exit after the start sequence finishes playing
local duration = client:ForceSequence(mainSequence, function()
-- we've stopped playing the main sequence (either duration expired or user cancelled the act)
if (data.finish) then
local finishSequence = data.finish[variant]
local finishDuration
if (istable(finishSequence)) then
finishDuration = finishSequence.duration
finishSequence = finishSequence[1]
end
client:ForceSequence(finishSequence, function()
-- client has finished the end sequence and is no longer playing any animations
self:ExitAct(client)
end, finishDuration)
else
-- there's no end sequence so we can exit right away
self:ExitAct(client)
end
end, data.untimed and 0 or (mainDuration or nil))
if (!duration) then
-- the model doesn't support this variant
self:ExitAct(client)
client:NotifyLocalized("modelNoSeq")
return
end
end, startDuration, nil)
net.Start("ixActEnter")
net.WriteBool(data.idle or false)
net.Send(client)
client.ixNextAct = CurTime() + 4
end
ix.command.Add("Act" .. act, COMMAND)
end
-- setup exit act command
local COMMAND = {
privilege = "Player Acts",
OnRun = function(command, client)
-- Anti-Exploit measure. Just silently fail if near a door.
for _, entity in ipairs(ents.FindInSphere(client:GetPos(), 50)) do
if (entity:GetClass() == "func_door" or entity:GetClass() == "func_door_rotating" or entity:GetClass() == "prop_door_rotating") then return end
end
if (client.ixUntimedSequence) then
client:LeaveSequence()
hook.Run("OnPlayerExitAct", client)
end
end
}
if (CLIENT) then
-- hide this command from the command list
COMMAND.OnCheckAccess = function(client)
return false
end
end
ix.command.Add("ExitAct", COMMAND)
end
function PLUGIN:UpdateAnimation(client, moveData)
local angle = client:GetNetVar("actEnterAngle")
if (angle) then
client:SetRenderAngles(angle)
end
end
do
local keyBlacklist = IN_ATTACK + IN_ATTACK2
function PLUGIN:StartCommand(client, command)
if (client:GetNetVar("actEnterAngle")) then
command:RemoveKey(keyBlacklist)
end
end
end

View File

@@ -0,0 +1,65 @@
--[[
| 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 PLUGIN = PLUGIN
util.AddNetworkString("ixActEnter")
util.AddNetworkString("ixActLeave")
function PLUGIN:CanPlayerEnterAct(client, modelClass, variant, act)
if (!client:Alive() or client:GetLocalVar("ragdoll") or client:WaterLevel() > 0 or !client:IsOnGround()) then
return false, L("notNow", client)
end
-- check if player's model class has an entry in this act table
modelClass = modelClass or ix.anim.GetModelClass(client:GetModel())
local data = act[modelClass]
if (!data) then
return false, L("modelNoSeq", client)
end
-- some models don't support certain variants
local sequence = data.sequence[variant]
if (!sequence) then
hook.Run("OnPlayerExitAct", client)
return false, L("modelNoSeq", client)
end
return true
end
function PLUGIN:PlayerDeath(client)
if (client.ixUntimedSequence) then
client:SetNetVar("actEnterAngle")
client:LeaveSequence()
client.ixUntimedSequence = nil
hook.Run("OnPlayerExitAct", client)
end
end
function PLUGIN:PlayerSpawn(client)
if (client.ixUntimedSequence) then
client:SetNetVar("actEnterAngle")
client:LeaveSequence()
client.ixUntimedSequence = nil
end
end
function PLUGIN:OnCharacterFallover(client)
if (client.ixUntimedSequence) then
client:SetNetVar("actEnterAngle")
client:LeaveSequence()
client.ixUntimedSequence = nil
hook.Run("OnPlayerExitAct", client)
end
end