mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
123
gamemodes/helix/plugins/act/cl_hooks.lua
Normal file
123
gamemodes/helix/plugins/act/cl_hooks.lua
Normal 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)
|
||||
371
gamemodes/helix/plugins/act/sh_definitions.lua
Normal file
371
gamemodes/helix/plugins/act/sh_definitions.lua
Normal file
@@ -0,0 +1,371 @@
|
||||
--[[
|
||||
| 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},
|
||||
},
|
||||
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",
|
||||
})
|
||||
|
||||
-- deny
|
||||
ix.act.Register("Deny", "metrocop", {
|
||||
sequence = "harassfront2",
|
||||
})
|
||||
|
||||
-- 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
|
||||
285
gamemodes/helix/plugins/act/sh_plugin.lua
Normal file
285
gamemodes/helix/plugins/act/sh_plugin.lua
Normal 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
|
||||
65
gamemodes/helix/plugins/act/sv_hooks.lua
Normal file
65
gamemodes/helix/plugins/act/sv_hooks.lua
Normal 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
|
||||
Reference in New Issue
Block a user