mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
213
gamemodes/helix/plugins/doors/cl_plugin.lua
Normal file
213
gamemodes/helix/plugins/doors/cl_plugin.lua
Normal file
@@ -0,0 +1,213 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
-- luacheck: globals ACCESS_LABELS
|
||||
ACCESS_LABELS = {}
|
||||
ACCESS_LABELS[DOOR_OWNER] = "owner"
|
||||
ACCESS_LABELS[DOOR_TENANT] = "tenant"
|
||||
ACCESS_LABELS[DOOR_GUEST] = "guest"
|
||||
ACCESS_LABELS[DOOR_NONE] = "none"
|
||||
|
||||
function PLUGIN:GetDefaultDoorInfo(door)
|
||||
local owner = IsValid(door:GetDTEntity(0)) and door:GetDTEntity(0) or nil
|
||||
local name = door:GetNetVar("title", door:GetNetVar("name", IsValid(owner) and L"dTitleOwned" or L"dTitle"))
|
||||
local description = door:GetNetVar("ownable") and L("dIsOwnable") or L("dIsNotOwnable")
|
||||
local color = ix.config.Get("color")
|
||||
local faction = door:GetNetVar("faction")
|
||||
local class = door:GetNetVar("class")
|
||||
|
||||
if (class) then
|
||||
local classData = ix.class.list[class]
|
||||
|
||||
if (classData) then
|
||||
if (classData.color) then
|
||||
color = classData.color
|
||||
end
|
||||
|
||||
if (!owner) then
|
||||
description = L("dOwnedBy", L2(classData.name) or classData.name)
|
||||
end
|
||||
end
|
||||
elseif (faction) then
|
||||
local info = ix.faction.indices[faction]
|
||||
color = team.GetColor(faction)
|
||||
|
||||
if (info and !owner) then
|
||||
description = L("dOwnedBy", L2(info.name) or info.name)
|
||||
end
|
||||
end
|
||||
|
||||
if (owner) then
|
||||
description = L("dOwnedBy", owner:GetName())
|
||||
end
|
||||
|
||||
return {
|
||||
name = name,
|
||||
description = description,
|
||||
color = color
|
||||
}
|
||||
end
|
||||
|
||||
function PLUGIN:DrawDoorInfo(door, width, position, angles, scale, clientPosition)
|
||||
local alpha = math.max((1 - clientPosition:DistToSqr(door:GetPos()) / 65536) * 255, 0)
|
||||
|
||||
if (alpha < 1) then
|
||||
return
|
||||
end
|
||||
|
||||
local info = hook.Run("GetDoorInfo", door) or self:GetDefaultDoorInfo(door)
|
||||
|
||||
if (!istable(info) or table.IsEmpty(info)) then
|
||||
return
|
||||
end
|
||||
|
||||
-- title + background
|
||||
surface.SetFont("ix3D2DMediumFont")
|
||||
local nameWidth, nameHeight = surface.GetTextSize(info.name)
|
||||
|
||||
derma.SkinFunc("DrawImportantBackground", -width * 0.5, -nameHeight * 0.5,
|
||||
width, nameHeight, ColorAlpha(info.color, alpha * 0.5))
|
||||
|
||||
surface.SetTextColor(ColorAlpha(color_white, alpha))
|
||||
surface.SetTextPos(-nameWidth * 0.5, -nameHeight * 0.5)
|
||||
surface.DrawText(info.name)
|
||||
|
||||
-- description
|
||||
local lines = ix.util.WrapText(info.description, width, "ix3D2DSmallFont")
|
||||
local y = nameHeight * 0.5 + 4
|
||||
|
||||
for i = 1, #lines do
|
||||
local line = lines[i]
|
||||
local textWidth, textHeight = surface.GetTextSize(line)
|
||||
|
||||
surface.SetTextPos(-textWidth * 0.5, y)
|
||||
surface.DrawText(line)
|
||||
|
||||
y = y + textHeight
|
||||
end
|
||||
|
||||
-- background blur
|
||||
ix.util.PushBlur(function()
|
||||
cam.Start3D2D(position, angles, scale)
|
||||
surface.SetDrawColor(11, 11, 11, math.max(alpha - 100, 0))
|
||||
surface.DrawRect(-width * 0.5, -nameHeight * 0.5, width, y + nameHeight * 0.5 + 4)
|
||||
cam.End3D2D()
|
||||
end)
|
||||
end
|
||||
|
||||
function PLUGIN:PostDrawTranslucentRenderables(bDepth, bSkybox)
|
||||
if (bDepth or bSkybox or !LocalPlayer():GetCharacter()) then
|
||||
return
|
||||
end
|
||||
|
||||
local entities = ents.FindInSphere(EyePos(), 256)
|
||||
local clientPosition = LocalPlayer():GetPos()
|
||||
|
||||
for _, v in ipairs(entities) do
|
||||
if (!IsValid(v) or !v:IsDoor() or !v:GetNetVar("visible")) then
|
||||
continue
|
||||
end
|
||||
|
||||
local color = v:GetColor()
|
||||
|
||||
if (v:IsEffectActive(EF_NODRAW) or color.a <= 0) then
|
||||
continue
|
||||
end
|
||||
|
||||
local position = v:LocalToWorld(v:OBBCenter())
|
||||
local mins, maxs = v:GetCollisionBounds()
|
||||
local width = 0
|
||||
local size = maxs - mins
|
||||
local trace = {
|
||||
collisiongroup = COLLISION_GROUP_WORLD,
|
||||
ignoreworld = true,
|
||||
endpos = position
|
||||
}
|
||||
|
||||
-- trace from shortest side to center to get correct position for rendering
|
||||
if (size.z < size.x and size.z < size.y) then
|
||||
trace.start = position - v:GetUp() * size.z
|
||||
width = size.y
|
||||
elseif (size.x < size.y) then
|
||||
trace.start = position - v:GetForward() * size.x
|
||||
width = size.y
|
||||
elseif (size.y < size.x) then
|
||||
trace.start = position - v:GetRight() * size.y
|
||||
width = size.x
|
||||
end
|
||||
|
||||
width = math.max(width, 12)
|
||||
trace = util.TraceLine(trace)
|
||||
|
||||
local angles = trace.HitNormal:Angle()
|
||||
local anglesOpposite = trace.HitNormal:Angle()
|
||||
|
||||
angles:RotateAroundAxis(angles:Forward(), 90)
|
||||
angles:RotateAroundAxis(angles:Right(), 90)
|
||||
anglesOpposite:RotateAroundAxis(anglesOpposite:Forward(), 90)
|
||||
anglesOpposite:RotateAroundAxis(anglesOpposite:Right(), -90)
|
||||
|
||||
local positionFront = trace.HitPos - (((position - trace.HitPos):Length() * 2) + 1) * trace.HitNormal
|
||||
local positionOpposite = trace.HitPos + (trace.HitNormal * 2)
|
||||
|
||||
if (trace.HitNormal:Dot((clientPosition - position):GetNormalized()) < 0) then
|
||||
-- draw front
|
||||
cam.Start3D2D(positionFront, angles, 0.1)
|
||||
self:DrawDoorInfo(v, width * 8, positionFront, angles, 0.1, clientPosition)
|
||||
cam.End3D2D()
|
||||
else
|
||||
-- draw back
|
||||
cam.Start3D2D(positionOpposite, anglesOpposite, 0.1)
|
||||
self:DrawDoorInfo(v, width * 8, positionOpposite, anglesOpposite, 0.1, clientPosition)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
net.Receive("ixDoorMenu", function()
|
||||
if (IsValid(ix.gui.door)) then
|
||||
return ix.gui.door:Remove()
|
||||
end
|
||||
|
||||
local door = net.ReadEntity()
|
||||
local access = net.ReadTable()
|
||||
local entity = net.ReadEntity()
|
||||
|
||||
if (IsValid(door)) then
|
||||
ix.gui.door = vgui.Create("ixDoorMenu")
|
||||
ix.gui.door:SetDoor(door, access, entity)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ixDoorPermission", function()
|
||||
local door = net.ReadEntity()
|
||||
|
||||
if (!IsValid(door)) then
|
||||
return
|
||||
end
|
||||
|
||||
local target = net.ReadEntity()
|
||||
local access = net.ReadUInt(4)
|
||||
|
||||
local panel = door.ixPanel
|
||||
|
||||
if (IsValid(panel) and IsValid(target)) then
|
||||
panel.access[target] = access
|
||||
|
||||
for _, v in ipairs(panel.access:GetLines()) do
|
||||
if (v.player == target) then
|
||||
v:SetColumnText(2, L(ACCESS_LABELS[access or 0]))
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
116
gamemodes/helix/plugins/doors/derma/cl_door.lua
Normal file
116
gamemodes/helix/plugins/doors/derma/cl_door.lua
Normal file
@@ -0,0 +1,116 @@
|
||||
--[[
|
||||
| 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 PANEL = {}
|
||||
|
||||
local function DoorSetPermission(door, target, permission)
|
||||
net.Start("ixDoorPermission")
|
||||
net.WriteEntity(door)
|
||||
net.WriteEntity(target)
|
||||
net.WriteUInt(permission, 4)
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetSize(280, 240)
|
||||
self:SetTitle(L"doorSettings")
|
||||
self:Center()
|
||||
self:MakePopup()
|
||||
|
||||
self.access = self:Add("DListView")
|
||||
self.access:Dock(FILL)
|
||||
self.access:AddColumn(L"name").Header:SetTextColor(Color(25, 25, 25))
|
||||
self.access:AddColumn(L"access").Header:SetTextColor(Color(25, 25, 25))
|
||||
self.access.OnClickLine = function(this, line, selected)
|
||||
if (IsValid(line.player)) then
|
||||
local menu = DermaMenu()
|
||||
menu:AddOption(L"tenant", function()
|
||||
if (self.accessData and self.accessData[line.player] != DOOR_TENANT) then
|
||||
DoorSetPermission(self.door, line.player, DOOR_TENANT)
|
||||
end
|
||||
end):SetImage("icon16/user_add.png")
|
||||
menu:AddOption(L"guest", function()
|
||||
if (self.accessData and self.accessData[line.player] != DOOR_GUEST) then
|
||||
DoorSetPermission(self.door, line.player, DOOR_GUEST)
|
||||
end
|
||||
end):SetImage("icon16/user_green.png")
|
||||
menu:AddOption(L"none", function()
|
||||
if (self.accessData and self.accessData[line.player] != DOOR_NONE) then
|
||||
DoorSetPermission(self.door, line.player, DOOR_NONE)
|
||||
end
|
||||
end):SetImage("icon16/user_red.png")
|
||||
menu:Open()
|
||||
|
||||
for _, v in pairs(menu:GetChildren()[1]:GetChildren()) do
|
||||
v:SetFont("MenuFontNoClamp")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:SetDoor(door, access, door2)
|
||||
door.ixPanel = self
|
||||
|
||||
self.accessData = access
|
||||
self.door = door
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if (v != LocalPlayer() and v:GetCharacter()) then
|
||||
self.access:AddLine(v:Name(), L(ACCESS_LABELS[access[v] or 0])).player = v
|
||||
end
|
||||
end
|
||||
|
||||
if (self:CheckAccess(DOOR_OWNER)) then
|
||||
self.sell = self:Add("DButton")
|
||||
self.sell:Dock(BOTTOM)
|
||||
self.sell:SetText(L"sell")
|
||||
self.sell:SetTextColor(color_white)
|
||||
self.sell:DockMargin(0, 5, 0, 0)
|
||||
self.sell.DoClick = function(this)
|
||||
self:Remove()
|
||||
ix.command.Send("doorsell")
|
||||
end
|
||||
end
|
||||
|
||||
if (self:CheckAccess(DOOR_TENANT)) then
|
||||
self.name = self:Add("DTextEntry")
|
||||
self.name:Dock(TOP)
|
||||
self.name:DockMargin(0, 0, 0, 5)
|
||||
self.name.Think = function(this)
|
||||
if (!this:IsEditing()) then
|
||||
local entity = IsValid(door2) and door2 or door
|
||||
|
||||
self.name:SetText(entity:GetNetVar("title", L"dTitleOwned"))
|
||||
end
|
||||
end
|
||||
self.name.OnEnter = function(this)
|
||||
ix.command.Send("doorsettitle", this:GetText())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:CheckAccess(access)
|
||||
access = access or DOOR_GUEST
|
||||
|
||||
if ((self.accessData[LocalPlayer()] or 0) >= access) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
if (self.accessData and !IsValid(self.door) and self:CheckAccess()) then
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("ixDoorMenu", PANEL, "DFrame")
|
||||
211
gamemodes/helix/plugins/doors/entities/weapons/ix_keys.lua
Normal file
211
gamemodes/helix/plugins/doors/entities/weapons/ix_keys.lua
Normal file
@@ -0,0 +1,211 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
if (CLIENT) then
|
||||
SWEP.PrintName = "Keys"
|
||||
SWEP.Slot = 0
|
||||
SWEP.SlotPos = 2
|
||||
SWEP.DrawAmmo = false
|
||||
SWEP.DrawCrosshair = false
|
||||
end
|
||||
|
||||
SWEP.Author = "Chessnut"
|
||||
SWEP.Instructions = "Primary Fire: Lock\nSecondary Fire: Unlock"
|
||||
SWEP.Purpose = "Hitting things and knocking on doors."
|
||||
SWEP.Drop = false
|
||||
|
||||
SWEP.ViewModelFOV = 45
|
||||
SWEP.ViewModelFlip = false
|
||||
SWEP.AnimPrefix = "rpg"
|
||||
|
||||
SWEP.ViewTranslation = 4
|
||||
|
||||
SWEP.Primary.ClipSize = -1
|
||||
SWEP.Primary.DefaultClip = -1
|
||||
SWEP.Primary.Automatic = false
|
||||
SWEP.Primary.Ammo = ""
|
||||
SWEP.Primary.Damage = 5
|
||||
SWEP.Primary.Delay = 0.75
|
||||
|
||||
SWEP.Secondary.ClipSize = -1
|
||||
SWEP.Secondary.DefaultClip = 0
|
||||
SWEP.Secondary.Automatic = false
|
||||
SWEP.Secondary.Ammo = ""
|
||||
|
||||
SWEP.ViewModel = Model("models/weapons/c_arms_animations.mdl")
|
||||
SWEP.WorldModel = ""
|
||||
|
||||
SWEP.UseHands = false
|
||||
SWEP.LowerAngles = Angle(0, 5, -14)
|
||||
SWEP.LowerAngles2 = Angle(0, 5, -22)
|
||||
|
||||
SWEP.IsAlwaysLowered = true
|
||||
SWEP.FireWhenLowered = true
|
||||
SWEP.HoldType = "passive"
|
||||
|
||||
-- luacheck: globals ACT_VM_FISTS_DRAW ACT_VM_FISTS_HOLSTER
|
||||
ACT_VM_FISTS_DRAW = 2
|
||||
ACT_VM_FISTS_HOLSTER = 1
|
||||
|
||||
function SWEP:Holster()
|
||||
if (!IsValid(self.Owner)) then
|
||||
return
|
||||
end
|
||||
|
||||
local viewModel = self.Owner:GetViewModel()
|
||||
|
||||
if (IsValid(viewModel)) then
|
||||
viewModel:SetPlaybackRate(1)
|
||||
viewModel:ResetSequence(ACT_VM_FISTS_HOLSTER)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function SWEP:Precache()
|
||||
end
|
||||
|
||||
function SWEP:Initialize()
|
||||
self:SetHoldType(self.HoldType)
|
||||
end
|
||||
|
||||
function SWEP:PrimaryAttack()
|
||||
local time = ix.config.Get("doorLockTime", 1)
|
||||
local time2 = math.max(time, 1)
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + time2)
|
||||
self:SetNextSecondaryFire(CurTime() + time2)
|
||||
|
||||
if (!IsFirstTimePredicted()) then
|
||||
return
|
||||
end
|
||||
|
||||
if (CLIENT) then
|
||||
return
|
||||
end
|
||||
|
||||
local data = {}
|
||||
data.start = self.Owner:GetShootPos()
|
||||
data.endpos = data.start + self.Owner:GetAimVector()*96
|
||||
data.filter = self.Owner
|
||||
local entity = util.TraceLine(data).Entity
|
||||
|
||||
--[[
|
||||
Locks the entity if the contiditon fits:
|
||||
1. The entity is door and client has access to the door.
|
||||
2. The entity is vehicle and the "owner" variable is same as client's character ID.
|
||||
--]]
|
||||
if (IsValid(entity) and
|
||||
(
|
||||
(entity:IsDoor() and entity:CheckDoorAccess(self.Owner)) or
|
||||
(entity:IsVehicle() and entity.CPPIGetOwner and entity:CPPIGetOwner() == self.Owner)
|
||||
)
|
||||
) then
|
||||
self.Owner:SetAction("@locking", time, function()
|
||||
self:ToggleLock(entity, true)
|
||||
end)
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:ToggleLock(door, state)
|
||||
if (IsValid(self.Owner) and self.Owner:GetPos():Distance(door:GetPos()) > 96) then
|
||||
return
|
||||
end
|
||||
|
||||
if (door:IsDoor()) then
|
||||
local partner = door:GetDoorPartner()
|
||||
|
||||
if (state) then
|
||||
if (IsValid(partner)) then
|
||||
partner:Fire("lock")
|
||||
end
|
||||
|
||||
door:Fire("lock")
|
||||
self.Owner:EmitSound("doors/door_latch3.wav")
|
||||
|
||||
hook.Run("PlayerLockedDoor", self.Owner, door, partner)
|
||||
else
|
||||
if (IsValid(partner)) then
|
||||
partner:Fire("unlock")
|
||||
end
|
||||
|
||||
door:Fire("unlock")
|
||||
self.Owner:EmitSound("doors/door_latch1.wav")
|
||||
|
||||
hook.Run("PlayerUnlockedDoor", self.Owner, door, partner)
|
||||
end
|
||||
elseif (door:IsVehicle()) then
|
||||
if (state) then
|
||||
door:Fire("lock")
|
||||
|
||||
if (door.IsSimfphyscar) then
|
||||
door.IsLocked = true
|
||||
end
|
||||
|
||||
self.Owner:EmitSound("doors/door_latch3.wav")
|
||||
hook.Run("PlayerLockedVehicle", self.Owner, door)
|
||||
else
|
||||
door:Fire("unlock")
|
||||
|
||||
if (door.IsSimfphyscar) then
|
||||
door.IsLocked = nil
|
||||
end
|
||||
|
||||
self.Owner:EmitSound("doors/door_latch1.wav")
|
||||
hook.Run("PlayerUnlockedVehicle", self.Owner, door)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SWEP:SecondaryAttack()
|
||||
local time = ix.config.Get("doorLockTime", 1)
|
||||
local time2 = math.max(time, 1)
|
||||
|
||||
self:SetNextPrimaryFire(CurTime() + time2)
|
||||
self:SetNextSecondaryFire(CurTime() + time2)
|
||||
|
||||
if (!IsFirstTimePredicted()) then
|
||||
return
|
||||
end
|
||||
|
||||
if (CLIENT) then
|
||||
return
|
||||
end
|
||||
|
||||
local data = {}
|
||||
data.start = self.Owner:GetShootPos()
|
||||
data.endpos = data.start + self.Owner:GetAimVector()*96
|
||||
data.filter = self.Owner
|
||||
local entity = util.TraceLine(data).Entity
|
||||
|
||||
|
||||
--[[
|
||||
Unlocks the entity if the contiditon fits:
|
||||
1. The entity is door and client has access to the door.
|
||||
2. The entity is vehicle and the "owner" variable is same as client's character ID.
|
||||
]]--
|
||||
if (IsValid(entity) and
|
||||
(
|
||||
(entity:IsDoor() and entity:CheckDoorAccess(self.Owner)) or
|
||||
(entity:IsVehicle() and entity.CPPIGetOwner and entity:CPPIGetOwner() == self.Owner)
|
||||
)
|
||||
) then
|
||||
self.Owner:SetAction("@unlocking", time, function()
|
||||
self:ToggleLock(entity, false)
|
||||
end)
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
509
gamemodes/helix/plugins/doors/sh_commands.lua
Normal file
509
gamemodes/helix/plugins/doors/sh_commands.lua
Normal file
@@ -0,0 +1,509 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
ix.command.Add("DoorSell", {
|
||||
description = "@cmdDoorSell",
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the entity 96 units infront of the player.
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
local entity = trace.Entity
|
||||
|
||||
-- Check if the entity is a valid door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
-- Check if the player owners the door.
|
||||
if (client == entity:GetDTEntity(0)) then
|
||||
entity = IsValid(entity.ixParent) and entity.ixParent or entity
|
||||
|
||||
-- Get the price that the door is sold for.
|
||||
local price = math.Round(entity:GetNetVar("price", ix.config.Get("doorCost")) * ix.config.Get("doorSellRatio"))
|
||||
local character = client:GetCharacter()
|
||||
|
||||
-- Remove old door information.
|
||||
entity:RemoveDoorAccessData()
|
||||
|
||||
local doors = character:GetVar("doors") or {}
|
||||
|
||||
for k, v in ipairs(doors) do
|
||||
if (v == entity) then
|
||||
table.remove(doors, k)
|
||||
end
|
||||
end
|
||||
|
||||
character:SetVar("doors", doors, true)
|
||||
|
||||
-- Take their money and notify them.
|
||||
character:GiveMoney(price)
|
||||
hook.Run("OnPlayerPurchaseDoor", client, entity, false, PLUGIN.CallOnDoorChildren)
|
||||
|
||||
ix.log.Add(client, "selldoor")
|
||||
return "@dSold", ix.currency.Get(price)
|
||||
else
|
||||
-- Otherwise tell them they can not.
|
||||
return "@notOwner"
|
||||
end
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorBuy", {
|
||||
description = "@cmdDoorBuy",
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the entity 96 units infront of the player.
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
local entity = trace.Entity
|
||||
|
||||
-- Check if the entity is a valid door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
if (!entity:GetNetVar("ownable") or entity:GetNetVar("faction") or entity:GetNetVar("class")) then
|
||||
return "@dNotAllowedToOwn"
|
||||
end
|
||||
|
||||
if (IsValid(entity:GetDTEntity(0))) then
|
||||
return "@dOwnedBy", entity:GetDTEntity(0):Name()
|
||||
end
|
||||
|
||||
entity = IsValid(entity.ixParent) and entity.ixParent or entity
|
||||
|
||||
-- Get the price that the door is bought for.
|
||||
local price = entity:GetNetVar("price", ix.config.Get("doorCost"))
|
||||
local character = client:GetCharacter()
|
||||
|
||||
-- Check if the player can actually afford it.
|
||||
if (character:HasMoney(price)) then
|
||||
-- Set the door to be owned by this player.
|
||||
entity:SetDTEntity(0, client)
|
||||
entity.ixAccess = {
|
||||
[client] = DOOR_OWNER
|
||||
}
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child:SetDTEntity(0, client)
|
||||
end)
|
||||
|
||||
local doors = character:GetVar("doors") or {}
|
||||
doors[#doors + 1] = entity
|
||||
character:SetVar("doors", doors, true)
|
||||
|
||||
-- Take their money and notify them.
|
||||
character:TakeMoney(price)
|
||||
hook.Run("OnPlayerPurchaseDoor", client, entity, true, PLUGIN.CallOnDoorChildren)
|
||||
|
||||
ix.log.Add(client, "buydoor")
|
||||
return "@dPurchased", ix.currency.Get(price)
|
||||
else
|
||||
-- Otherwise tell them they can not.
|
||||
return "@canNotAfford"
|
||||
end
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetUnownable", {
|
||||
description = "@cmdDoorSetUnownable",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
arguments = ix.type.text,
|
||||
OnRun = function(self, client, name)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
-- Set it so it is unownable.
|
||||
entity:SetNetVar("ownable", nil)
|
||||
|
||||
-- Change the name of the door if needed.
|
||||
if (name:find("%S")) then
|
||||
entity:SetNetVar("name", name)
|
||||
end
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child:SetNetVar("ownable", nil)
|
||||
|
||||
if (name:find("%S")) then
|
||||
child:SetNetVar("name", name)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Save the door information.
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dMadeUnownable"
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetOwnable", {
|
||||
description = "@cmdDoorSetOwnable",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
arguments = ix.type.text,
|
||||
OnRun = function(self, client, name)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
-- Set it so it is ownable.
|
||||
entity:SetNetVar("ownable", true)
|
||||
entity:SetNetVar("visible", true)
|
||||
|
||||
-- Update the name.
|
||||
if (name:find("%S")) then
|
||||
entity:SetNetVar("name", name)
|
||||
end
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child:SetNetVar("ownable", true)
|
||||
child:SetNetVar("visible", true)
|
||||
|
||||
if (name:find("%S")) then
|
||||
child:SetNetVar("name", name)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Save the door information.
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dMadeOwnable"
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetFaction", {
|
||||
description = "@cmdDoorSetFaction",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
arguments = bit.bor(ix.type.text, ix.type.optional),
|
||||
OnRun = function(self, client, name)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
if (!name or name == "") then
|
||||
entity.ixFactionID = nil
|
||||
entity:SetNetVar("faction", nil)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function()
|
||||
entity.ixFactionID = nil
|
||||
entity:SetNetVar("faction", nil)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dRemoveFaction"
|
||||
end
|
||||
|
||||
local faction
|
||||
|
||||
-- Loop through each faction, checking the uniqueID and name.
|
||||
for k, v in pairs(ix.faction.teams) do
|
||||
if (ix.util.StringMatches(k, name) or ix.util.StringMatches(L(v.name, client), name)) then
|
||||
-- This faction matches the provided string.
|
||||
faction = v
|
||||
|
||||
-- Escape the loop.
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if a faction was found.
|
||||
if (faction) then
|
||||
entity.ixFactionID = faction.uniqueID
|
||||
entity:SetNetVar("faction", faction.index)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function()
|
||||
entity.ixFactionID = faction.uniqueID
|
||||
entity:SetNetVar("faction", faction.index)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dSetFaction", L(faction.name, client)
|
||||
-- The faction was not found.
|
||||
else
|
||||
return "@invalidFaction"
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetDisabled", {
|
||||
description = "@cmdDoorSetDisabled",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
arguments = ix.type.bool,
|
||||
OnRun = function(self, client, bDisabled)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor()) then
|
||||
-- Set it so it is ownable.
|
||||
entity:SetNetVar("disabled", bDisabled)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child:SetNetVar("disabled", bDisabled)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
|
||||
-- Tell the player they have made the door (un)disabled.
|
||||
return "@dSet" .. (bDisabled and "" or "Not") .. "Disabled"
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetTitle", {
|
||||
description = "@cmdDoorSetTitle",
|
||||
arguments = ix.type.text,
|
||||
OnRun = function(self, client, name)
|
||||
-- Get the door infront of the player.
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
local entity = trace.Entity
|
||||
|
||||
-- Validate the door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
-- Make sure the name contains actual characters.
|
||||
if (!name:find("%S")) then
|
||||
return "@invalidArg", 1
|
||||
end
|
||||
|
||||
--[[
|
||||
NOTE: Here, we are setting two different networked names.
|
||||
The title is a temporary name, while the other name is the
|
||||
default name for the door. The reason for this is so when the
|
||||
server closes while someone owns the door, it doesn't save THEIR
|
||||
title, which could lead to unwanted things.
|
||||
--]]
|
||||
|
||||
name = name:utf8sub(1, 24)
|
||||
|
||||
-- Check if they are allowed to change the door's name.
|
||||
if (entity:CheckDoorAccess(client, DOOR_TENANT)) then
|
||||
entity:SetNetVar("title", name)
|
||||
elseif (CAMI.PlayerHasAccess(client, "Helix - Manage Doors", nil)) then
|
||||
entity:SetNetVar("name", name)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child:SetNetVar("name", name)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
else
|
||||
-- Otherwise notify the player he/she can't.
|
||||
return "@notOwner"
|
||||
end
|
||||
else
|
||||
-- Notification of the door not being valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetParent", {
|
||||
description = "@cmdDoorSetParent",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
client.ixDoorParent = entity
|
||||
return "@dSetParentDoor"
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetChild", {
|
||||
description = "@cmdDoorSetChild",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
if (client.ixDoorParent == entity) then
|
||||
return "@dCanNotSetAsChild"
|
||||
end
|
||||
|
||||
-- Check if the player has set a door as a parent.
|
||||
if (IsValid(client.ixDoorParent)) then
|
||||
-- Add the door to the parent's list of children.
|
||||
client.ixDoorParent.ixChildren = client.ixDoorParent.ixChildren or {}
|
||||
client.ixDoorParent.ixChildren[entity:MapCreationID()] = true
|
||||
|
||||
-- Set the door's parent to the parent.
|
||||
entity.ixParent = client.ixDoorParent
|
||||
|
||||
-- Save the door information.
|
||||
PLUGIN:SaveDoorData()
|
||||
PLUGIN:CopyParentDoor(entity)
|
||||
|
||||
return "@dAddChildDoor"
|
||||
else
|
||||
-- Tell the player they do not have a door parent.
|
||||
return "@dNoParentDoor"
|
||||
end
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorRemoveChild", {
|
||||
description = "@cmdDoorRemoveChild",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
if (client.ixDoorParent == entity) then
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child.ixParent = nil
|
||||
end)
|
||||
|
||||
entity.ixChildren = nil
|
||||
return "@dRemoveChildren"
|
||||
end
|
||||
|
||||
-- Check if the player has set a door as a parent.
|
||||
if (IsValid(entity.ixParent) and entity.ixParent.ixChildren) then
|
||||
-- Remove the door from the list of children.
|
||||
entity.ixParent.ixChildren[entity:MapCreationID()] = nil
|
||||
-- Remove the variable for the parent.
|
||||
entity.ixParent = nil
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dRemoveChildDoor"
|
||||
end
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetHidden", {
|
||||
description = "@cmdDoorSetHidden",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
arguments = ix.type.bool,
|
||||
OnRun = function(self, client, bHidden)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor()) then
|
||||
entity:SetNetVar("visible", !bHidden)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function(child)
|
||||
child:SetNetVar("visible", !bHidden)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
|
||||
-- Tell the player they have made the door (un)hidden.
|
||||
return "@dSet" .. (bHidden and "" or "Not") .. "Hidden"
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSetClass", {
|
||||
description = "@cmdDoorSetClass",
|
||||
privilege = "Manage Doors",
|
||||
adminOnly = true,
|
||||
arguments = bit.bor(ix.type.text, ix.type.optional),
|
||||
OnRun = function(self, client, name)
|
||||
-- Get the door the player is looking at.
|
||||
local entity = client:GetEyeTrace().Entity
|
||||
|
||||
-- Validate it is a door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
if (!name or name == "") then
|
||||
entity:SetNetVar("class", nil)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function()
|
||||
entity:SetNetVar("class", nil)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dRemoveClass"
|
||||
end
|
||||
|
||||
local class, classData
|
||||
|
||||
for k, v in pairs(ix.class.list) do
|
||||
if (ix.util.StringMatches(v.name, name) or ix.util.StringMatches(L(v.name, client), name)) then
|
||||
class, classData = k, v
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if a faction was found.
|
||||
if (class) then
|
||||
entity.ixClassID = class
|
||||
entity:SetNetVar("class", class)
|
||||
|
||||
PLUGIN:CallOnDoorChildren(entity, function()
|
||||
entity.ixClassID = class
|
||||
entity:SetNetVar("class", class)
|
||||
end)
|
||||
|
||||
PLUGIN:SaveDoorData()
|
||||
return "@dSetClass", L(classData.name, client)
|
||||
else
|
||||
return "@invalidClass"
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
91
gamemodes/helix/plugins/doors/sh_plugin.lua
Normal file
91
gamemodes/helix/plugins/doors/sh_plugin.lua
Normal file
@@ -0,0 +1,91 @@
|
||||
--[[
|
||||
| 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 = "Doors"
|
||||
PLUGIN.author = "Chessnut"
|
||||
PLUGIN.description = "A simple door system."
|
||||
|
||||
-- luacheck: globals DOOR_OWNER DOOR_TENANT DOOR_GUEST DOOR_NONE
|
||||
DOOR_OWNER = 3
|
||||
DOOR_TENANT = 2
|
||||
DOOR_GUEST = 1
|
||||
DOOR_NONE = 0
|
||||
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
ix.util.Include("cl_plugin.lua")
|
||||
ix.util.Include("sh_commands.lua")
|
||||
|
||||
do
|
||||
local entityMeta = FindMetaTable("Entity")
|
||||
|
||||
function entityMeta:CheckDoorAccess(client, access)
|
||||
if (!self:IsDoor()) then
|
||||
return false
|
||||
end
|
||||
|
||||
access = access or DOOR_GUEST
|
||||
|
||||
local parent = self.ixParent
|
||||
|
||||
if (IsValid(parent)) then
|
||||
return parent:CheckDoorAccess(client, access)
|
||||
end
|
||||
|
||||
if (hook.Run("CanPlayerAccessDoor", client, self, access)) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (self.ixAccess and (self.ixAccess[client] or 0) >= access) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
function entityMeta:RemoveDoorAccessData()
|
||||
local receivers = {}
|
||||
|
||||
for k, _ in pairs(self.ixAccess or {}) do
|
||||
receivers[#receivers + 1] = k
|
||||
end
|
||||
|
||||
if (#receivers > 0) then
|
||||
net.Start("ixDoorMenu")
|
||||
net.Send(receivers)
|
||||
end
|
||||
|
||||
self.ixAccess = {}
|
||||
self:SetDTEntity(0, nil)
|
||||
|
||||
-- Remove door information on child doors
|
||||
PLUGIN:CallOnDoorChildren(self, function(child)
|
||||
child:SetDTEntity(0, nil)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Configurations for door prices.
|
||||
ix.config.Add("doorCost", 10, "The price to purchase a door.", nil, {
|
||||
data = {min = 0, max = 500},
|
||||
category = "dConfigName"
|
||||
})
|
||||
ix.config.Add("doorSellRatio", 0.5, "How much of the door price is returned when selling a door.", nil, {
|
||||
data = {min = 0, max = 1.0, decimals = 1},
|
||||
category = "dConfigName"
|
||||
})
|
||||
ix.config.Add("doorLockTime", 1, "How long it takes to (un)lock a door.", nil, {
|
||||
data = {min = 0, max = 10.0, decimals = 1},
|
||||
category = "dConfigName"
|
||||
})
|
||||
304
gamemodes/helix/plugins/doors/sv_plugin.lua
Normal file
304
gamemodes/helix/plugins/doors/sv_plugin.lua
Normal file
@@ -0,0 +1,304 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
util.AddNetworkString("ixDoorMenu")
|
||||
util.AddNetworkString("ixDoorPermission")
|
||||
|
||||
-- Variables for door data.
|
||||
local variables = {
|
||||
-- Whether or not the door will be disabled.
|
||||
"disabled",
|
||||
-- The name of the door.
|
||||
"name",
|
||||
-- Price of the door.
|
||||
"price",
|
||||
-- If the door is ownable.
|
||||
"ownable",
|
||||
-- The faction that owns a door.
|
||||
"faction",
|
||||
-- The class that owns a door.
|
||||
"class",
|
||||
-- Whether or not the door will be hidden.
|
||||
"visible"
|
||||
}
|
||||
|
||||
function PLUGIN:CallOnDoorChildren(entity, callback)
|
||||
local parent
|
||||
|
||||
if (entity.ixChildren) then
|
||||
parent = entity
|
||||
elseif (entity.ixParent) then
|
||||
parent = entity.ixParent
|
||||
end
|
||||
|
||||
if (IsValid(parent)) then
|
||||
callback(parent)
|
||||
|
||||
for k, _ in pairs(parent.ixChildren) do
|
||||
local child = ents.GetMapCreatedEntity(k)
|
||||
|
||||
if (IsValid(child)) then
|
||||
callback(child)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:CopyParentDoor(child)
|
||||
local parent = child.ixParent
|
||||
|
||||
if (IsValid(parent)) then
|
||||
for _, v in ipairs(variables) do
|
||||
local value = parent:GetNetVar(v)
|
||||
|
||||
if (child:GetNetVar(v) != value) then
|
||||
child:SetNetVar(v, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Called after the entities have loaded.
|
||||
function PLUGIN:LoadData()
|
||||
-- Restore the saved door information.
|
||||
local data = self:GetData()
|
||||
|
||||
if (!data) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Loop through all of the saved doors.
|
||||
for k, v in pairs(data) do
|
||||
-- Get the door entity from the saved ID.
|
||||
local entity = ents.GetMapCreatedEntity(k)
|
||||
|
||||
-- Check it is a valid door in-case something went wrong.
|
||||
if (IsValid(entity) and entity:IsDoor()) then
|
||||
-- Loop through all of our door variables.
|
||||
for k2, v2 in pairs(v) do
|
||||
if (k2 == "children") then
|
||||
entity.ixChildren = v2
|
||||
|
||||
for index, _ in pairs(v2) do
|
||||
local door = ents.GetMapCreatedEntity(index)
|
||||
|
||||
if (IsValid(door)) then
|
||||
door.ixParent = entity
|
||||
end
|
||||
end
|
||||
elseif (k2 == "combineDoor") then
|
||||
entity.ixCombineDoor = v2
|
||||
entity:SetNetVar("combineDoor", v2)
|
||||
elseif (k2 == "faction") then
|
||||
for k3, v3 in pairs(ix.faction.teams) do
|
||||
if (k3 == v2) then
|
||||
entity.ixFactionID = k3
|
||||
entity:SetNetVar("faction", v3.index)
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
entity:SetNetVar(k2, v2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Called before the gamemode shuts down.
|
||||
function PLUGIN:SaveDoorData()
|
||||
-- Create an empty table to save information in.
|
||||
local data = {}
|
||||
local doors = {}
|
||||
|
||||
for _, v in ipairs(ents.GetAll()) do
|
||||
if (v:IsDoor()) then
|
||||
doors[v:MapCreationID()] = v
|
||||
end
|
||||
end
|
||||
|
||||
local doorData
|
||||
|
||||
-- Loop through doors with information.
|
||||
for k, v in pairs(doors) do
|
||||
-- Another empty table for actual information regarding the door.
|
||||
doorData = {}
|
||||
|
||||
-- Save all of the needed variables to the doorData table.
|
||||
for _, v2 in ipairs(variables) do
|
||||
local value = v:GetNetVar(v2)
|
||||
|
||||
if (value) then
|
||||
doorData[v2] = v:GetNetVar(v2)
|
||||
end
|
||||
end
|
||||
|
||||
if (v.ixChildren) then
|
||||
doorData.children = v.ixChildren
|
||||
end
|
||||
|
||||
if (v.ixClassID) then
|
||||
doorData.class = v.ixClassID
|
||||
end
|
||||
|
||||
if (v.ixFactionID) then
|
||||
doorData.faction = v.ixFactionID
|
||||
end
|
||||
|
||||
if (v.ixCombineDoor) then
|
||||
doorData.combineDoor = v.ixCombineDoor
|
||||
end
|
||||
|
||||
-- Add the door to the door information.
|
||||
if (!table.IsEmpty(doorData)) then
|
||||
data[k] = doorData
|
||||
end
|
||||
end
|
||||
-- Save all of the door information.
|
||||
self:SetData(data)
|
||||
end
|
||||
|
||||
function PLUGIN:CanPlayerUseDoor(client, entity)
|
||||
if (entity:GetNetVar("disabled")) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Whether or not a player a player has any abilities over the door, such as locking.
|
||||
function PLUGIN:CanPlayerAccessDoor(client, door, access)
|
||||
local faction = door:GetNetVar("faction")
|
||||
|
||||
-- If the door has a faction set which the client is a member of, allow access.
|
||||
if (faction and client:Team() == faction) then
|
||||
return true
|
||||
end
|
||||
|
||||
local class = door:GetNetVar("class")
|
||||
|
||||
-- If the door has a faction set which the client is a member of, allow access.
|
||||
local classData = ix.class.list[class]
|
||||
local charClass = client:GetCharacter():GetClass()
|
||||
local classData2 = ix.class.list[charClass]
|
||||
|
||||
if (class and classData and classData2) then
|
||||
if (classData.team) then
|
||||
if (classData.team != classData2.team) then
|
||||
return false
|
||||
end
|
||||
else
|
||||
if (charClass != class) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:PostPlayerLoadout(client)
|
||||
client:Give("ix_keys")
|
||||
end
|
||||
|
||||
function PLUGIN:ShowTeam(client)
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
local entity = trace.Entity
|
||||
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("faction") and !entity:GetNetVar("class")) then
|
||||
if (entity:CheckDoorAccess(client, DOOR_TENANT)) then
|
||||
local door = entity
|
||||
|
||||
if (IsValid(door.ixParent)) then
|
||||
door = door.ixParent
|
||||
end
|
||||
|
||||
if door.ixAccess and istable(door.ixAccess) then
|
||||
net.Start("ixDoorMenu")
|
||||
net.WriteEntity(door)
|
||||
net.WriteTable(door.ixAccess)
|
||||
net.WriteEntity(entity)
|
||||
net.Send(client)
|
||||
end
|
||||
elseif (!IsValid(entity:GetDTEntity(0))) then
|
||||
ix.command.Run(client, "doorbuy")
|
||||
else
|
||||
client:NotifyLocalized("notAllowed")
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:PlayerLoadedCharacter(client, curChar, prevChar)
|
||||
if (prevChar) then
|
||||
local doors = prevChar:GetVar("doors") or {}
|
||||
|
||||
for _, v in ipairs(doors) do
|
||||
if (IsValid(v) and v:IsDoor() and v:GetDTEntity(0) == client) then
|
||||
v:RemoveDoorAccessData()
|
||||
end
|
||||
end
|
||||
|
||||
prevChar:SetVar("doors", nil)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:PlayerDisconnected(client)
|
||||
local character = client:GetCharacter()
|
||||
|
||||
if (character) then
|
||||
local doors = character:GetVar("doors") or {}
|
||||
|
||||
for _, v in ipairs(doors) do
|
||||
if (IsValid(v) and v:IsDoor() and v:GetDTEntity(0) == client) then
|
||||
v:RemoveDoorAccessData()
|
||||
end
|
||||
end
|
||||
|
||||
character:SetVar("doors", nil)
|
||||
end
|
||||
end
|
||||
|
||||
net.Receive("ixDoorPermission", function(length, client)
|
||||
local door = net.ReadEntity()
|
||||
local target = net.ReadEntity()
|
||||
local access = net.ReadUInt(4)
|
||||
|
||||
if (IsValid(target) and target:GetCharacter() and door.ixAccess and door:GetDTEntity(0) == client and target != client) then
|
||||
access = math.Clamp(access or 0, DOOR_NONE, DOOR_TENANT)
|
||||
|
||||
if (access == door.ixAccess[target]) then
|
||||
return
|
||||
end
|
||||
|
||||
door.ixAccess[target] = access
|
||||
|
||||
local recipient = {}
|
||||
|
||||
for k, v in pairs(door.ixAccess) do
|
||||
if (v > DOOR_GUEST) then
|
||||
recipient[#recipient + 1] = k
|
||||
end
|
||||
end
|
||||
|
||||
if (#recipient > 0) then
|
||||
net.Start("ixDoorPermission")
|
||||
net.WriteEntity(door)
|
||||
net.WriteEntity(target)
|
||||
net.WriteUInt(access, 4)
|
||||
net.Send(recipient)
|
||||
end
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user