This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 8064ba84d8
commit 73479cff9e
7338 changed files with 1718883 additions and 14 deletions

View File

@@ -0,0 +1,445 @@
--[[
| 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.ZipTiedActors = {}
PLUGIN.blur = ix.util.GetMaterial("pp/blurscreen")
do
PLUGIN.ZipTiedAngles = {}
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_L_UpperArm"] = Angle(20, 8.8, 0)
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_L_UpperArm"] = Angle(20, 8.8, 0)
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_L_Forearm"] = Angle(15, 0, 0)
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_L_Hand"] = Angle(0, 0, 75)
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_R_Forearm"] = Angle(-15, 0, 0)
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_R_Hand"] = Angle(0, 0, -75)
PLUGIN.ZipTiedAngles["ValveBiped.Bip01_R_UpperArm"] = Angle(-20, 16.6, 0)
end
PLUGIN.BaggedActors = {}
PLUGIN.LocalCharIsBagged = false
local BAG_MODEL_BASE = "models/willardnetworks/m1nt/burlap_bag_" -- thanks kawa!
local BAG_MODEL_MALE = "male.mdl"
local BAG_MODEL_FEM = "female.mdl"
local BAG_POS_FEM = Vector(-56, -25.1, 2)
local BAG_ANGLES_FEM = Angle(182.6, 113.8, 88)
local BAG_POS_MALE = Vector(-46, -42, -0.5)
local BAG_ANGLES_MALE = Angle(170, 130, 90)
local ResponseSelectRemoveBag = 1
local ResponseSelectUntie = 2
local ResponseSelectDrag = 3
local ResponseSelectRelease = 4
local BlackScreenShader = {
[ "$pp_colour_addr" ] = 0,
[ "$pp_colour_addg" ] = 0,
[ "$pp_colour_addb" ] = 0,
[ "$pp_colour_brightness" ] = 0.04,
[ "$pp_colour_contrast" ] = 0.1,
[ "$pp_colour_colour" ] = 0,
[ "$pp_colour_mulr" ] = 0,
[ "$pp_colour_mulg" ] = 0,
[ "$pp_colour_mulb" ] = 0
}
hook.Add("HUDPaint", "draw_bag_on_head", function()
if (PLUGIN.LocalCharIsBagged) then
surface.SetMaterial(PLUGIN.blur)
surface.SetDrawColor(255, 255, 255, 255)
local x, y = 0, 0
for i = -0.2, 1, 0.2 do
PLUGIN.blur:SetFloat("$blur", i * 35) -- extreme blur
-- only enough to see large objects right in front of them
PLUGIN.blur:Recompute()
render.UpdateScreenEffectTexture()
surface.DrawTexturedRect(x * -1, y * -1, ScrW(), ScrH())
end
DrawColorModify(BlackScreenShader)
draw.SimpleText(
"Un sac est sur votre tête.",
"WNBleedingTextNoClamp",
ScrW() * 0.5,
ScrH() - SScaleMin(250 / 3),
Color(255, 78, 69, 255),
TEXT_ALIGN_CENTER
)
end
end)
net.Receive("WNZipTieEnter", function(len)
local targetId = net.ReadString()
local targetPly = player.GetBySteamID64(targetId)
if (!targetPly) then return end
if (IsValid(targetPly) and targetPly:IsRestricted()) then
PLUGIN.ZipTiedActors[targetId] = targetPly
end
end)
net.Receive("WNZipTieExit", function(len)
local targetId = net.ReadString()
local targetPly = player.GetBySteamID64(targetId)
if (!targetPly) then return end
if (IsValid(targetPly)) then
PLUGIN.ZipTiedActors[targetId] = nil
PLUGIN:SetZipTiedBoneAngles(targetPly, true) -- reset bone angles
end
end)
net.Receive("WNBagEnter", function(len)
local targetId = net.ReadString()
local targetPly = player.GetBySteamID64(targetId)
if (!targetPly) then
return
end
-- no need to draw a bag on our own character. the screen is black anyways
if (targetId == LocalPlayer():SteamID64()) then
PLUGIN.LocalCharIsBagged = true
return
end
if (IsValid(targetPly)) then
PLUGIN.BaggedActors[targetId] = {}
PLUGIN.BaggedActors[targetId].actor = targetPly
PLUGIN.BaggedActors[targetId].bagEnt = nil
PLUGIN:SetupBagHead(targetId)
end
end)
net.Receive("WNBagExit", function(len)
local targetId = net.ReadString()
local targetPly = player.GetBySteamID64(targetId)
if (!targetPly) then return end
if (targetId == LocalPlayer():SteamID64()) then
PLUGIN.LocalCharIsBagged = false
return
end
if (IsValid(targetPly)) then
PLUGIN:RemoveBagHead(targetId)
end
end)
net.Receive("WNDragOrBagPrompt", function(len)
local isBagged = net.ReadBool()
local isTied = net.ReadBool()
local isFollowing = net.ReadBool()
local frame = vgui.Create("Panel")
frame:SetSize(SScaleMin(372 / 3), SScaleMin(300 / 3))
frame:Center()
frame:MakePopup()
frame.Paint = function(self, w, h)
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(111, 111, 136, 255 / 100 * 30))
surface.DrawRect(0, 0, w, h)
surface.DrawOutlinedRect(0, 0, w, h)
surface.SetMaterial(Material("willardnetworks/tabmenu/crafting/box_pattern.png", "noclamp"))
surface.DrawTexturedRectUV(0, 0, w, h, 0, 0, w / SScaleMin(300 / 3), h / SScaleMin(500 / 3))
end
local exit = frame:Add("DImageButton")
exit:SetImage("willardnetworks/tabmenu/navicons/exit.png")
exit:SetSize(SScaleMin(20 / 3), SScaleMin(20 / 3))
exit:SetPos(SScaleMin(345 / 3), SScaleMin(10 / 3))
exit:DockMargin(0, SScaleMin(15 / 3), SScaleMin(10 / 3), SScaleMin(15 / 3))
exit.DoClick = function()
net.Start("WNDragOrBagResponse")
net.WriteInt(0, 5)
net.SendToServer()
frame:Remove()
surface.PlaySound("helix/ui/press.wav")
end
local lastPosY = 100
local addButton = function (text, selection)
local button = vgui.Create("DButton", frame)
button:SetText(text)
button:SetFont("MenuFontNoClamp")
button:SetTextColor(Color(255,255,255))
button:CenterHorizontal()
button:SetPos((frame:GetWide() / 2) - (SScaleMin(150 / 3) / 2), lastPosY)
lastPosY = lastPosY + 60
button:SetSize(SScaleMin(150 / 3), SScaleMin(30 / 3))
button.Paint = function(self, w, h)
draw.RoundedBox(0, 0, 0, w, h, Color(63, 58, 115, 220))
surface.SetMaterial(Material("willardnetworks/tabmenu/crafting/box_pattern.png", "noclamp"))
surface.DrawTexturedRectUV(0, 0, w, h, 0, 0, w / SScaleMin(414 / 3), h / SScaleMin(677 / 3))
end
button.DoClick = function()
net.Start("WNDragOrBagResponse")
net.WriteInt(selection, 4)
net.SendToServer()
frame:Remove()
surface.PlaySound("helix/ui/press.wav")
end
end
if (isBagged) then
addButton("Enlever le sac", ResponseSelectRemoveBag)
end
if (isTied) then
addButton("Détacher", ResponseSelectUntie)
end
if (isFollowing) then
addButton("Relâcher", ResponseSelectRelease)
else
addButton("Trainer", ResponseSelectDrag)
end
end)
function PLUGIN:Think()
for _, actor in pairs(self.ZipTiedActors) do
PLUGIN:SetZipTiedBoneAngles(actor, false)
end
end
function PLUGIN:SetupBagHead(actorId)
local actor = self.BaggedActors[actorId].actor
if (!actor or !actor.IsFemale) then
return
end
local mdl_str = BAG_MODEL_BASE
if (actor:IsFemale()) then
mdl_str = mdl_str..BAG_MODEL_FEM
self.BaggedActors[actorId].pos = BAG_POS_FEM
self.BaggedActors[actorId].ang = BAG_ANGLES_FEM
else
mdl_str = mdl_str..BAG_MODEL_MALE
self.BaggedActors[actorId].pos = BAG_POS_MALE
self.BaggedActors[actorId].ang = BAG_ANGLES_MALE
end
local bag = ClientsideModel(
mdl_str,
RENDER_GROUP_OPAQUE_ENTITY
)
if (!bag or !bag.SetNoDraw) then
return
end
bag:SetNoDraw(true) -- remember, we're drawing manually here
if (!actor.GetModelScale or !actor.LookupBone) then
return
end
-- need to scale it up to set it to the model scale of the character (set by resizer plugin)
bag:SetModelScale(actor:GetModelScale() or 1)
local followBone = actor:LookupBone("ValveBiped.Bip01_Neck1")
-- for characters with nonbipedal models (or models with no neck), we cant draw head bags!
if (!followBone) then
return
end
bag:FollowBone(actor, followBone)
bag:SetPredictable(true)
bag:SetLocalPos(self.BaggedActors[actorId].pos)
bag:SetLocalAngles(self.BaggedActors[actorId].ang)
local headBone = actor:LookupBone("ValveBiped.Bip01_Head1")
if (!headBone) then
return
end
self.BaggedActors[actorId].bagEnt = bag
self.BaggedActors[actorId].headBone = headBone
end
function PLUGIN:RemoveBagHead(actorId)
if (!self.BaggedActors[actorId]) then
return
end
local actor = self.BaggedActors[actorId].actor
local bag = self.BaggedActors[actorId].bagEnt
if (IsValid(actor) and
actor.ManipulateBoneScale and
isnumber(self.BaggedActors[actorId].headBone)
) then
actor:ManipulateBoneScale(
self.BaggedActors[actorId].headBone, Vector(1, 1, 1))
-- reset head scale
end
if (bag and bag.Remove) then
bag:Remove()
end
self.BaggedActors[actorId] = nil
end
function PLUGIN:SetZipTiedBoneAngles(ply, bReset)
if (!IsValid(ply) or !ply.GetAbsVelocity or !ply.IsPlayer or !ply:IsPlayer()) then
return
end
if (bReset or ply:GetAbsVelocity() != Vector(0, 0, 0)) then
-- ManipulateBoneAngles sorta breaks on animations. So the hands behind the back thing should only be set when idle
local boneID
for bone, _ in pairs(self.ZipTiedAngles) do
boneID = ply:LookupBone(bone)
if (boneID) then
ply:ManipulateBoneAngles(boneID, Angle(0, 0, 0))
end
end
else
local boneID
for bone, angle in pairs(self.ZipTiedAngles) do
boneID = ply:LookupBone(bone)
if (boneID) then
ply:ManipulateBoneAngles(boneID, angle)
end
end
end
end
hook.Add("PostDrawOpaqueRenderables", "draw_head_bags", function(_)
-- I know this is a bit uncommon to do this in this particular hook
-- But for some reason when we ragdoll it just, stops calling post PVS hooks sometimes
-- Which means we can't use PostPlayerDraw here
local plyEnt
local pos
local ang
local ent
for id, actor in pairs(PLUGIN.BaggedActors) do
ent = actor.bagEnt
pos = actor.pos
ang = actor.ang
if (!ent or
!ent.SetLocalPos or
!isvector(pos) or
!isangle(ang) or
!isnumber(actor.headBone)
) then
-- yes we really do have to check this every frame
-- sorry (thanks garry)
PLUGIN:RemoveBagHead(id)
continue
else
plyEnt = ent:GetParent()
if (!plyEnt or !IsEntity(plyEnt) or !plyEnt:IsValid()) then
continue -- dont draw if there is no valid parent (yet)
end
-- call in a pcall so we can handle any of these lovely errors
local success, err = pcall(function()
-- local to the parent's bone
ent:SetLocalPos(pos)
ent:SetLocalAngles(ang)
ent:SetupBones()
ent:DrawModel()
-- do head shrinkage so it fits in da bag
plyEnt:ManipulateBoneScale(actor.headBone, Vector(0.1, 0.1, 0.1))
end)
if (!success) then
-- panic!
-- printing here in case we get any bug reports:
print("Error drawing head bag!")
print(err)
PLUGIN:RemoveBagHead(id)
end
end
end
end)
-- sanity function to check for ragdolls, players, and/or invalid players
local function checkBaggedEntList()
-- check all existing ragdolls to see if any of their players are bagged
-- if so then, we need to set them as bagged ;)
for _, ent in ipairs(ents.FindByClass("prop_ragdoll")) do
if (!ent or !IsEntity(ent) or !ent:IsValid()) then
-- NEVER trust gmod builtins
continue
end
local ply = ent:GetNetVar("player")
if (ply and
IsEntity(ply) and
IsValid(ply) and
ply.IsPlayer and
ply:IsPlayer() and
ply != LocalPlayer()
) then
local actor = PLUGIN.BaggedActors and PLUGIN.BaggedActors[ply:SteamID64()]
if (actor and istable(actor)) then
if (actor.bagEnt and
IsEntity(actor.bagEnt) and
actor.bagEnt:IsValid() and
actor.bagEnt:GetParent() != ent
) then
local followBone = ent:LookupBone("ValveBiped.Bip01_Neck1")
-- for characters with nonbipedal models (or models with no neck), we cant draw head bags!
if (!followBone) then
continue
end
actor.bagEnt:SetModelScale(ent:GetModelScale() or 1)
actor.bagEnt:FollowBone(ent, followBone)
end
end
end
end
-- check the BaggedActors table for any inconsistencies
for id, actor in pairs(PLUGIN.BaggedActors) do
if (!actor.actor or !IsEntity(actor.actor) or !actor.actor:IsValid()) then
PLUGIN:RemoveBagHead(id)
-- player isn't valid, for some reason
end
if (!actor.bagEnt or !IsEntity(actor.bagEnt) or !actor.bagEnt:IsValid()) then
PLUGIN:RemoveBagHead(id)
-- bag entity isn't valid, for some reason
end
local parent = actor.bagEnt:GetParent()
if (!IsEntity(parent) or !parent:IsValid()) then
-- happens when the character gets up after being ragdolled
PLUGIN:SetupBagHead(id) -- try to set up
-- if it is still not valid, remove
parent = actor.bagEnt:GetParent()
if (!IsEntity(parent) or !parent:IsValid()) then
PLUGIN:RemoveBagHead(id)
end
end
end
end
function PLUGIN:InitializedPlugins()
timer.Create("ValidateBaggedActors", 0.25, 0, function()
checkBaggedEntList()
end)
end

View File

@@ -0,0 +1,63 @@
--[[
| 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/
--]]
ITEM.name = "Sac en toile à cordon de serrage"
ITEM.description = "Un sac en toile à cordon de serrage qui est la taille parfaite pour mettre sur la tête de quelqu'un."
ITEM.price = 8
ITEM.category = "Autres"
ITEM.model = "models/props_junk/garbage_bag001a.mdl" -- < the "real" models dont have proper collisions
ITEM.functions.Use = {
name = "Utiliser",
OnRun = function(itemTable)
local client = itemTable.player
local data = {}
data.start = client:GetShootPos()
data.endpos = data.start + client:GetAimVector() * 96
data.filter = client
local target = util.TraceLine(data).Entity
if (IsValid(target) and target:IsPlayer() and target:GetCharacter() and target:IsRestricted()) then
itemTable.bBeingUsed = true
client:SetAction("Glisser dans le sac...", 2)
client:DoStaredAction(target, function()
target:NotifyLocalized("Un sac a été placé sur votre tête !")
itemTable:Remove()
net.Start("WNBagEnter")
net.WriteString(target:SteamID64())
net.Broadcast()
target:SetNetVar("WNBagged", true)
end, 3, function()
client:SetAction()
target:SetAction()
target:SetNetVar("WNBagged", true)
itemTable.bBeingUsed = false
end)
elseif (IsValid(target) and target:IsPlayer() and !target:IsRestricted()) then
client:NotifyLocalized("Le personnage doit être attachée en premier")
else
client:NotifyLocalized("plyNotValid")
end
return false
end,
OnCanRun = function(itemTable)
return !IsValid(itemTable.entity) or itemTable.bBeingUsed
end
}
function ITEM:CanTransfer(inventory, newInventory)
return !self.bBeingUsed
end

View File

@@ -0,0 +1,73 @@
--[[
| 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/
--]]
ITEM.name = "Cordon"
ITEM.description = "Un cordon pour attacher les gens."
ITEM.category = "Autres"
ITEM.price = 8
ITEM.model = "models/items/crossbowrounds.mdl"
ITEM.functions.Use = {
name = "Utiliser",
OnRun = function(itemTable)
local client = itemTable.player
local data = {}
data.start = client:GetShootPos()
data.endpos = data.start + client:GetAimVector() * 96
data.filter = client
local target = util.TraceLine(data).Entity
if (IsValid(target) and target:IsPlayer() and target:GetCharacter()
and !target:GetNetVar("tying") and !target:IsRestricted()) then
itemTable.bBeingUsed = true
client:SetAction("@tying", 5)
client:DoStaredAction(target, function()
target:SetRestricted(true)
target:SetNetVar("tying")
target:NotifyLocalized("fTiedUp")
if (target:IsCombine()) then
Schema:AddCombineDisplayMessage("@cLosingContact", Color(255, 255, 255, 255))
Schema:AddCombineDisplayMessage("@cLostContact", Color(255, 0, 0, 255))
end
itemTable:Remove()
target:SetWalkSpeed(target:GetWalkSpeed()/3)
net.Start("WNZipTieEnter")
net.WriteString(target:SteamID64())
net.Broadcast()
end, 5, function()
client:SetAction()
target:SetAction()
target:SetNetVar("tying")
itemTable.bBeingUsed = false
end)
target:SetNetVar("tying", true)
target:SetAction("@fBeingTied", 5)
else
itemTable.player:NotifyLocalized("plyNotValid")
end
return false
end,
OnCanRun = function(itemTable)
return !IsValid(itemTable.entity) or itemTable.bBeingUsed
end
}
function ITEM:CanTransfer(inventory, newInventory)
return !self.bBeingUsed
end

View File

@@ -0,0 +1,67 @@
--[[
| 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.name = "Better Zip Ties"
PLUGIN.description = "Adds the ability for players to drag around tied up characters"
PLUGIN.author = "M!NT"
ix.util.Include("sv_plugin.lua")
ix.util.Include("cl_plugin.lua")
ix.command.Add("RemoveHeadBag", {
description = "Remove the bag from the head of the person you are looking at.",
alias = "rhb",
OnRun = function(self, client)
if (client:IsRestricted() or client:GetLocalVar("ragdoll")) then
return "@notNow"
end
local data = {}
data.start = client:GetShootPos()
data.endpos = data.start + client:GetAimVector() * 96
data.filter = client
local target = util.TraceLine(data).Entity
if (!target or !target.IsPlayer or !target:IsPlayer() or !IsValid(target)) then
return "You are not looking at a valid player!"
end
if (!target:GetNetVar("WNBagged")) then
return "The character you are looking at does not have a bag on their head currently!"
end
PLUGIN:RemoveBag(client, target)
end
})
ix.command.Add("RemoveHeadBagSelf", {
description = "Remove the bag from your head if you are able to.",
alias = "rhbs",
OnRun = function(self, client)
if (client:IsRestricted() or client:GetLocalVar("ragdoll")) then
return "@notNow"
end
if (!client:GetNetVar("WNBagged")) then
return "There is no bag on your head currently.."
end
client:SetAction("You are removing the bag", 3, function()
net.Start("WNBagExit")
net.WriteString(client:SteamID64())
net.Broadcast()
client:SetNetVar("WNBagged", false)
end)
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/
--]]
local PLUGIN = PLUGIN
PLUGIN.Actors = {}
PLUGIN.StagingActors = {}
local PromptSelectRemoveBag = 1
local PromptSelectUntie = 2
local PromptSelectDrag = 3
local PromptSelectRelease = 4
util.AddNetworkString("WNZipTieExit")
util.AddNetworkString("WNZipTieEnter")
util.AddNetworkString("WNBagExit")
util.AddNetworkString("WNBagEnter")
util.AddNetworkString("WNDragOrBagPrompt")
util.AddNetworkString("WNDragOrBagResponse")
--[[
lua_run functions for debugging things live:
]]
function DebugAddHeadBag(client)
net.Start("WNBagEnter")
net.WriteString(client:SteamID64())
net.Broadcast()
client:SetNetVar("WNBagged", true)
end
function DebugRemoveHeadBag(client)
net.Start("WNBagExit")
net.WriteString(client:SteamID64())
net.Broadcast()
client:SetNetVar("WNBagged", false)
end
function DebugForceZiptieDraw(client)
client:SetRestricted(true)
client:SetNetVar("untying")
net.Start("WNZipTieEnter")
net.WriteString(client:SteamID64())
net.Broadcast()
end
function DebugForceStopZiptieDraw(client)
client:SetRestricted(false)
client:SetNetVar("untying")
net.Start("WNZipTieExit")
net.WriteString(client:SteamID64())
net.Broadcast()
end
--[[
lots of hooks for both zip ties and head bags:
]]
function PLUGIN:PlayerUse(client, entity)
if (!client:IsRestricted() and entity:IsPlayer() and entity:IsRestricted() and !entity:GetNetVar("untying")) then
local id = client:SteamID64()
if (self.StagingActors[id]) then return end
local flags = PLUGIN:GetFlags(id, client, entity)
if(!flags["bTied"] and !flags["bBagged"] and !flags["bDragging"]) then
return -- we have nothing to do. someone just pressed E on some random thing
end
if (client.ixLastTieUse and client.ixLastTieUse + 1 > CurTime()) then
return -- someone is spamming E or holding it for longer than 1 frame
end
client.ixLastTieUse = CurTime()
self.StagingActors[id] = {}
self.StagingActors[id]["client"] = client
self.StagingActors[id]["target"] = entity
net.Start("WNDragOrBagPrompt")
net.WriteBool(flags["bBagged"])
net.WriteBool(flags["bTied"])
net.WriteBool(flags["bDragging"])
net.Send(client)
end
end
function PLUGIN:HandleResponse(response, client, target)
if (!response) then return end
if (response == PromptSelectDrag) then
self:EnterDrag(client, target)
elseif (response == PromptSelectRelease) then
self:ExitDrag(client:SteamID64(), client, target)
elseif (response == PromptSelectRemoveBag) then
self:RemoveBag(client, target)
elseif (response == PromptSelectUntie) then
self:Untie(client, target)
end
end
net.Receive("WNDragOrBagResponse", function(len, ply)
if (!ply:IsValid() or !ply:IsPlayer()) then
return
end
local id = ply:SteamID64()
if (!PLUGIN.StagingActors[id]) then
return nil -- whomever sent this response has not been staged
end
local response = net.ReadInt(4) -- max 7 positions
if (response < 1 or response > 4) then
PLUGIN:ResetStagedActor(id)
return nil
end
local client = PLUGIN.StagingActors[id]["client"]
local target = PLUGIN.StagingActors[id]["target"]
local flags = PLUGIN:GetFlags(id, client, target)
-- validate their choice given what we know at this point (for sanity reasons or otherwise)
if (
(response == PromptSelectRemoveBag and !flags["bBagged"]) -- cannot remove bag if one is not already there
or (response == PromptSelectUntie and !flags["bTied"]) -- cannot initiate an untie if character is not tied, or is already being untied
or (response == PromptSelectDrag and flags["bDragging"]) -- cannot initiate a drag if character is already being dragged
or (response == PromptSelectRelease and !flags["bDragging"]) -- cannot release a player from a drag if they are not actively being dragged
) then
PLUGIN:ResetStagedActor(id)
return nil
end
PLUGIN:HandleResponse(response, client, target)
PLUGIN:ResetStagedActor(id)
end)
function PLUGIN:ResetStagedActor(actorId)
self.StagingActors[actorId] = nil
end
function PLUGIN:GetFlags(id, client, target)
local flags = {}
flags["bTied"] = target:IsRestricted() and !target:GetNetVar("untying")
flags["bBagged"] = target:GetNetVar("WNBagged") or false
if (id and client) then
flags["bDragging"] = self:TargetIsFollowingPlayer(id, client, target)
end
return flags
end
function PLUGIN:PlayerLoadedCharacter(client, character, _)
if (!character or !client or !client.IsRestricted) then
return
end
local steamid = client:SteamID64()
local flags = self:GetFlags(nil, nil, client)
-- make sure that the state is correct for everyone
if (flags.bBagged) then
net.Start("WNBagEnter")
net.WriteString(steamid)
net.Broadcast()
else
net.Start("WNBagExit")
net.WriteString(steamid)
net.Broadcast()
end
if (flags.bTied) then
net.Start("WNZipTieEnter")
net.WriteString(steamid)
net.Broadcast()
else
net.Start("WNZipTieExit")
net.WriteString(steamid)
net.Broadcast()
end
end
function PLUGIN:TargetIsFollowingPlayer(id, player, target)
return self.Actors[id] and self.Actors[id]["player"] == player and self.Actors[id]["target"] == target
end
function PLUGIN:RemoveBag(client, target)
target:SetAction("Le sac se retire de votre tête.", 3)
target:SetNetVar("unbagging", true)
client:SetAction("Vous retirez le sac.", 3)
client:DoStaredAction(target, function()
target:SetNetVar("unbagging")
net.Start("WNBagExit")
net.WriteString(target:SteamID64())
net.Broadcast()
target:SetNetVar("WNBagged", false)
end, 5, function()
if (IsValid(target)) then
target:SetNetVar("unbagging")
target:SetAction()
end
if (IsValid(client)) then
client:SetAction()
end
end)
end
function PLUGIN:EnterDrag(client, target)
local id = client:SteamID64()
self.Actors[id] = {}
self.Actors[id]["player"] = client
self.Actors[id]["target"] = target
client:Notify("Vous traînez maintenant la personne.")
timer.Create("WNDragging"..tostring(id), 0.1, 0, function()
if (IsValid(client) and IsValid(target) and client:Alive() and target:Alive() and target:IsRestricted()) then
local plyVec = client:GetPos()
local targetVec = target:GetPos()
local plyAng = (plyVec - target:GetShootPos()):Angle()
local distanceVec = targetVec:DistToSqr(plyVec)
if (distanceVec < 200 * 200 and distanceVec >= 50 * 50) then
target:SetEyeAngles(plyAng + Angle(-35,0,0))
target:SetVelocity((plyVec - targetVec) * 5)
end
else
self:ExitDrag(id, client, target)
end
end)
end
function PLUGIN:ExitDrag(id, client, target)
self.Actors[id] = nil
client:Notify("Vous ne traînez plus la personne.")
timer.Remove("WNDragging"..tostring(id))
end
function PLUGIN:Untie(client, target)
target:SetAction("@beingUntied", 5)
target:SetNetVar("untying", true)
client:SetAction("@unTying", 5)
client:DoStaredAction(target, function()
target:SetRestricted(false)
target:SetNetVar("untying")
local id = target:SteamID64()
net.Start("WNZipTieExit")
net.WriteString(id)
net.Broadcast()
target:SetWalkSpeed(target:GetWalkSpeed() * 3)
if (self:TargetIsFollowingPlayer(client:SteamID64(), client, target)) then
self:ExitDrag(client, target)
end
end, 5, function()
if (IsValid(target)) then
target:SetNetVar("untying")
target:SetAction()
end
if (IsValid(client)) then
client:SetAction()
end
end)
end