This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 0e770b2b49
commit ba1fc01b16
7084 changed files with 2173495 additions and 14 deletions

View File

@@ -0,0 +1,160 @@
--[[
| 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 math = math
local L = L
local string = string
local timer = timer
local LocalPlayer = LocalPlayer
local CreateSound = CreateSound
local surface = surface
local ScrW, ScrH = ScrW, ScrH
local Color = Color
local ix = ix
local PLUGIN = PLUGIN
function PLUGIN:AdjustGasPoints(points)
if (!points) then return 0 end
if (points >= self.LETHAL_GAS) then return 1, true end
if (points <= 0) then return 0 end
local fl, cl = math.floor(points), math.ceil(points)
local divideBy = points >= 60 and PLUGIN.LETHAL_GAS or 61
if (fl == cl) then
return PLUGIN.gasToCooldown[fl] / PLUGIN.gasToCooldown[divideBy], points >= 60
else
return math.Remap(points, fl, cl, PLUGIN.gasToCooldown[fl], PLUGIN.gasToCooldown[cl]) / PLUGIN.gasToCooldown[divideBy], points >= 60
end
end
local gasMaterial = ix.util.GetMaterial("willardnetworks/nlrbleedout/gas-background.png")
function PLUGIN:DrawHUDOverlays(client, character)
local gasPoints = math.min(character:GetGasPoints() / self.LETHAL_GAS, 1)
if (gasPoints > 0.2) then
surface.SetDrawColor(Color(255, 255, 255, math.Remap(gasPoints, 0.2, 1, 0, 255)))
surface.SetMaterial(gasMaterial)
surface.DrawTexturedRect(0, 0, ScrW(), ScrH())
end
end
local gasIcon = ix.util.GetMaterial("willardnetworks/hud/toxic.png")
function PLUGIN:DrawBars(client, character, alwaysShow, minimalShow, DrawBar)
local faction = ix.faction.Get(client:Team())
if (!faction or faction.noGas) then return end
local gasPoints, secondary = self:AdjustGasPoints(character:GetGasPoints())
if (alwaysShow or gasPoints > 0 and !(secondary and gasPoints == 1)) then
if (alwaysShow or !minimalShow or (gasPoints > 0.5 and !secondary)) then
if (!secondary) then
DrawBar(gasIcon, gasPoints)
else
DrawBar(gasIcon, 1, nil, gasPoints)
end
end
end
end
function PLUGIN:DrawAlertBars(client, character, DrawBar)
local faction = ix.faction.Get(client:Team())
if (!faction or faction.noGas) then return end
local gasPoints, secondary = self:AdjustGasPoints(character:GetGasPoints())
if (secondary) then
DrawBar(L(gasPoints >= 1 and "gasLethal" or "gasHigh"))
end
end
function PLUGIN:GetPlayerESPText(client, toDraw, distance, alphaFar, alphaMid, alphaClose)
local character = client:GetCharacter()
local gasPoints = character:GetGasPoints()
if (gasPoints >= self.LETHAL_GAS) then
toDraw[#toDraw + 1] = {alpha = alphaMid, priority = 16, text = string.format("Gas: LETHAL (%dm left)", math.ceil(180 - gasPoints))}
elseif (gasPoints > 0) then
toDraw[#toDraw + 1] = {alpha = alphaClose, priority = 24, text = "Gas: "..math.Round(character:GetGasPoints(), 1)}
end
end
local heartbeatSound
local breathingSound
local breathingPlaying = false
function PLUGIN:InitPostEntity()
timer.Create("ixBetterGasHeartbeat", 5, 0, function()
local client = LocalPlayer()
local faction = ix.faction.Get(client:Team())
if (faction and faction.noGas) then return end
local timerDelay = 60
local playedHeartbeatSound = false
if (client:Alive() and client:GetCharacter()) then
local gasPointFraction = math.min(client:GetCharacter():GetGasPoints() / self.LETHAL_GAS, 1)
if (gasPointFraction > 0.5) then
if (!heartbeatSound) then
heartbeatSound = CreateSound(client, "player/heartbeat1.wav")
end
timerDelay = 0.75 + math.Remap(gasPointFraction, 0.5, 1, 1.25, 0)
heartbeatSound:PlayEx(math.Remap(gasPointFraction, 0.5, 1, 0.05, 0.75), 100)
playedHeartbeatSound = true
end
end
if (!playedHeartbeatSound and heartbeatSound) then
heartbeatSound:Stop()
end
timer.Adjust("ixBetterGasHeartbeat", timerDelay)
end)
timer.Create("ixBetterGasBreathing", 5, 0, function()
local client = LocalPlayer()
local faction = ix.faction.Get(client:Team())
if (faction and faction.noGas) then return end
if (breathingPlaying) then
breathingSound:Stop()
timer.Adjust("ixBetterGasBreathing", 5)
end
if (client:Alive() and client:GetCharacter()) then
local gasPointFraction = math.min(client:GetCharacter():GetGasPoints() / 100, 1)
if (gasPointFraction > 0.3) then
if (!breathingSound) then
breathingSound = CreateSound(client, "player/breathe1.wav")
end
local clamped = math.Clamp(gasPointFraction, 0.3, 1)
if (!breathingPlaying and math.Remap(clamped, 0.3, 1, 0, 1) >= math.random()) then
local delay = math.Remap(clamped, 0.3, 1, 60, 20)
local duration = math.Remap(clamped, 0.3, 1, 3, 20)
breathingSound:PlayEx(math.Remap(clamped, 0.3, 1, 0.05, 0.75), 100)
breathingPlaying = true
if (duration < delay) then
timer.Simple(duration, function()
breathingSound:Stop()
breathingPlaying = false
end)
end
timer.Adjust("ixBetterGasBreathing", delay)
return
end
timer.Adjust("ixBetterGasBreathing", 5)
else
timer.Adjust("ixBetterGasBreathing", 60)
end
end
end)
end
PLUGIN.OnReloaded = PLUGIN.InitPostEntity

View File

@@ -0,0 +1,242 @@
--[[
| 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 surface = surface
local derma = derma
local math = math
local IsValid = IsValid
local hook = hook
local table = table
ITEM.name = "Filter Base"
ITEM.model = Model("models/props_junk/TrafficCone001a.mdl")
ITEM.description = "A generic filter against smelly things and bad stuff in the air."
ITEM.filterQuality = 0.5 -- percentage protection
ITEM.maxFilterValue = 60 -- max duration in minutes
ITEM.refillItem = nil
ITEM.filterDecayStart = 0.1 -- percentage of filter value remaining where quality starts to drop linearly to 0
if (CLIENT) then
function ITEM:PaintOver(item, w, h)
if (item:GetData("equip")) then
surface.SetDrawColor(110, 255, 110, 100)
surface.DrawOutlinedRect(1, 1, w - 2, h - 2)
end
end
function ITEM:PopulateTooltip(tooltip)
if (self:GetData("equip")) then
local name = tooltip:GetRow("name")
name:SetBackgroundColor(derma.GetColor("Success", tooltip))
end
local panel = tooltip:AddRowAfter("name", "integrity")
panel:SetBackgroundColor(derma.GetColor("Warning", tooltip))
panel:SetText("Integrity: "..math.Round(self:GetFilterValue() * 100 / self.maxFilterValue, 1).."%\n"..
"Quality: "..math.Round(self:GetFilterQuality() * 100, 1).."%")
panel:SizeToContents()
end
end
function ITEM:GetFilterValue()
return self:GetData("filterValue", self.maxFilterValue)
end
function ITEM:GetFilterQuality()
if (self:GetFilterValue() > self.maxFilterValue * self.filterDecayStart) then
return self.filterQuality
else
return math.Remap(self:GetFilterValue(), 0, self.maxFilterValue * self.filterDecayStart, 0, self.filterQuality)
end
end
function ITEM:RemoveFilter(client)
self:SetData("equip", false)
local character = client:GetCharacter()
if (character:GetFilterItem() == self:GetID()) then
character:SetFilterItem(0)
end
end
ITEM:Hook("drop", function(item)
if (item:GetData("equip")) then
item:RemoveFilter(item:GetOwner())
end
end)
ITEM.functions.Refill = {
name = "Refill",
tip = "repairTip",
icon = "icon16/wrench.png",
OnRun = function(item)
item:Refill(item.player)
return false
end,
OnCanRun = function(item)
local client = item.player
return item.refillItem != nil and item:GetData("equip") == false and
!IsValid(item.entity) and IsValid(client) and
item:GetFilterValue() < item.maxFilterValue and
client:GetCharacter():GetInventory():HasItem(item.refillItem)
end
}
function ITEM:Refill(client, amount)
amount = amount or self.maxFilterValue
local refillItem = client:GetCharacter():GetInventory():HasItem(self.refillItem)
if (refillItem) then
refillItem:Remove()
self:SetData("filterValue", math.Clamp(self:GetFilterValue() + amount, 0, self.maxFilterValue))
end
end
ITEM.functions.EquipUn = { -- sorry, for name order.
name = "Unequip",
tip = "unequipTip",
icon = "icon16/cross.png",
OnRun = function(item)
if (item.player) then
item:RemoveFilter(item.player)
else
item:SetData("equip", false)
end
return false
end,
OnCanRun = function(item)
local client = item.player
return !IsValid(item.entity) and IsValid(client) and item:GetData("equip") == true and
hook.Run("CanPlayerUnequipItem", client, item) != false
end
}
ITEM.functions.Replace = {
name = "Replace",
tip = "equipTip",
icon = "icon16/tick.png",
OnRun = function(item)
local client = item.player
local character = client:GetCharacter()
local oldFilter = client:GetFilterItem()
oldFilter:RemoveFilter(client)
item:SetData("equip", true)
character:SetFilterItem(item:GetID())
return false
end,
OnCanRun = function(item)
local client = item.player
if item.factionList and !table.HasValue(item.factionList, client:GetCharacter():GetFaction()) then
return false
end
return !IsValid(item.entity) and IsValid(client) and item:GetData("equip") != true and
hook.Run("CanPlayerEquipItem", client, item) != false and item:CanReplaceFilter()
end
}
function ITEM:CanReplaceFilter()
local filterItem = self.player:GetFilterItem()
if (!filterItem or filterItem == self) then
return false
end
if (!filterItem.RemoveFilter or filterItem.noReplace) then
return false
end
if (!self.player:HasGasmask()) then
return false
end
return true
end
ITEM.functions.Equip = {
name = "Equip",
tip = "equipTip",
icon = "icon16/tick.png",
OnRun = function(item)
local client = item.player
local character = client:GetCharacter()
item:SetData("equip", true)
character:SetFilterItem(item:GetID())
return false
end,
OnCanRun = function(item)
local client = item.player
if item.factionList and !table.HasValue(item.factionList, client:GetCharacter():GetFaction()) then
return false
end
return !IsValid(item.entity) and IsValid(client) and item:GetData("equip") != true and
hook.Run("CanPlayerEquipItem", client, item) != false and item:CanEquipFilter()
end
}
function ITEM:CanEquipFilter()
if (self.player:GetFilterItem() != nil) then
return false
end
if (!self.player:HasGasmask()) then
return false
end
return true
end
function ITEM:CanTransfer(oldInventory, newInventory)
if (newInventory and self:GetData("equip")) then
return false
end
return true
end
function ITEM:OnInstanced()
self:SetData("filterValue", self.maxFilterValue)
end
function ITEM:OnRemoved()
if (self.invID != 0 and self:GetData("equip")) then
self.player = self:GetOwner()
self:RemoveFilter(self.player)
if self.OnUnEquip then
self:OnUnEquip()
end
self.player = nil
end
end
function ITEM:OnLoadout()
if (self:GetData("equip")) then
if (!self.player:HasGasmask()) then
self:SetData("equip", false)
return
end
local character = self.player:GetCharacter()
if (character:GetFilterItem() != 0 and character:GetFilterItem() != self:GetID()) then
self:SetData("equip", false)
else
character:SetFilterItem(self:GetID())
end
end
end

View File

@@ -0,0 +1,19 @@
--[[
| 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 = "Combine Filter"
ITEM.description = "A filter made by the Combine. It offers very good protection and doesn't decay, but doesn't last very long either. It cannot be refilled."
ITEM.model = Model("models/willardnetworks/props/cpfilter.mdl")
ITEM.category = "Combine"
ITEM.filterQuality = 0.95
ITEM.maxFilterValue = 40
ITEM.filterDecayStart = 0.1
ITEM.noUseOutGas = true

View File

@@ -0,0 +1,18 @@
--[[
| 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 = "High-Quality Filter"
ITEM.description = "A high quality filter, made with extreme care and precision to provide much better protection. Cannot be refilled."
ITEM.model = Model("models/willardnetworks/props/blackfilter.mdl")
ITEM.filterQuality = 0.9
ITEM.maxFilterValue = 200
ITEM.filterDecayStart = 0.05

View File

@@ -0,0 +1,19 @@
--[[
| 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 = "Makeshift Filter"
ITEM.description = "A homemade filter, which does a decent job at keeping you from breathing anything harmful. It doesn't last very long."
ITEM.model = Model("models/willardnetworks/props/sovietfilter.mdl")
ITEM.filterQuality = 0.7
ITEM.maxFilterValue = 120
ITEM.refillItem = "comp_charcoal_refill"
ITEM.filterDecayStart = 0.2

View File

@@ -0,0 +1,76 @@
--[[
| 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 pairs = pairs
local math = math
local ix = ix
local playerMeta = FindMetaTable("Player")
function playerMeta:HasGasmask()
local character = self:GetCharacter()
if (!character) then return false end
local inventory = character:GetInventory()
if (!inventory) then return false end
local clothingItems = inventory:GetItems(true)
for _, v in pairs(clothingItems) do
if (v.isGasmask and v:GetData("equip")) then
return true
end
end
end
function playerMeta:GetFilterItem()
if (!self:HasGasmask()) then return nil end
local itemID = self:GetCharacter():GetFilterItem()
if (ix.item.instances[itemID]) then
return ix.item.instances[itemID]
end
end
function playerMeta:GetFilterQuality()
local filter = self:GetFilterItem()
if (!filter) then return 0 end
if (filter.GetFilterQuality) then
return filter:GetFilterQuality()
else
return filter.filterQuality or 0.1
end
end
function playerMeta:GetFilterValue()
local filter = self:GetFilterItem()
if (!filter) then return 0 end
return filter:GetData("filterValue", filter.maxFilterValue)
end
function playerMeta:UpdateFilterValue(amount)
local filter = self:GetFilterItem()
if (!filter) then return end
local oldValue = filter:GetData("filterValue", filter.maxFilterValue)
filter:SetData("filterValue", math.Clamp(oldValue - amount, 0, filter.maxFilterValue))
if (ix.option.Get(self, "gasNotificationWarnings") and
oldValue >= filter.filterDecayStart * filter.maxFilterValue) then
if (filter:GetData("filterValue") == 0) then
self:NotifyLocalized("filterOut")
elseif (filter:GetData("filterValue") < filter.filterDecayStart * filter.maxFilterValue) then
self:NotifyLocalized("filterDecay")
end
end
end

View File

@@ -0,0 +1,27 @@
--[[
| 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 ix = ix
function PLUGIN:CanPlayerEquipItem(client, item)
if (item.isGasmask and client:HasGasmask()) then
return false
end
end
function PLUGIN:CanPlayerUnequipItem(client, item)
if (item.isGasmask and client:GetFilterItem() != nil and client:GetFilterItem() != item) then
return false
end
end
function PLUGIN:SetupAreaProperties()
ix.area.AddType("gas")
end

View File

@@ -0,0 +1,173 @@
--[[
| 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 CAMI = CAMI
local math = math
local ix = ix
local PLUGIN = PLUGIN
PLUGIN.name = "Better Gas"
PLUGIN.author = "Gr4Ss"
PLUGIN.description = "An improved gas zone system, aiming to facilitate roleplay both in and out of gas zones."
PLUGIN.TIMER_INTERVAL = 10
PLUGIN.LETHAL_GAS = 120
PLUGIN.GAS_DEATH = 180
PLUGIN.GAS_COOLDOWN_DELAY = 30
PLUGIN.GAS_DECREASE_DELAY = 2
ix.config.Add("gasPermakill", false, "Whether or not permakill from gas is activated.", nil, {
category = "Permakill"
})
ix.config.Add("gasPointGainScale", 1, "How much extra gas all characters gain while inside a gas area. This does not impact filters. 1 => 1 minute = 1 gas point, 2 => 1 minute = 2 gas points, 0.5 => 1 minute = 0.5 gas points", nil, {
data = {min = 0, max = 5, decimals = 2},
category = "Areas"
})
ix.config.Add("gasPointRecoveryPenalty", 1, "How longer all characters must recover from gas. 1 = same speed, 2 = twice as slow, 0.5 = twice as long", nil, {
data = {min = 0, max = 5, decimals = 2},
category = "Areas"
})
ix.config.Add("gasPointInjuryScale", 1, "How much extra gas injured characters gain while inside a gas area. Effect is applied progressively. Stated number is the 'goal' at 1hp. 1 = same speed as 100hp, 2 = twice as fast, 0.5 = half as long", nil, {
data = {min = 0, max = 5, decimals = 2},
category = "Areas"
})
ix.config.Add("gasPointInjuryRecoveryPenalty", 1, "How longer injured characters must recover from gas. Effect is applied progressively. Stated number is the 'goal' at 1hp. 1 = same speed as 100hp, 2 = twice as slow, 0.5 = twice as long", nil, {
data = {min = 0, max = 5, decimals = 2},
category = "Areas"
})
ix.config.Add("gasReverseZones", false, "Make the gas active everywhere on the map, except within gas areas.", nil, {
category = "Areas"
})
ix.lang.AddTable("english", {
gasDeathNotif = "%s został zabity przez gaz.",
gasLethal = "ŚMIERTELNY POZIOM ZATRUCIA",
gasHigh = "WYSOKI POZIOM ZATRUCIA",
optGasNotificationWarnings = "Ostrzeżenia o zagrożeniach gazowych",
optdGasNotificationWarnings = "Otrzymuj powiadomienia ostrzegawcze o wejściu w gaz i osiągnięciu wysokiego poziomu gazu.",
gasCDStart = "Przebywałeś poza kanałami wystarczająco długo, aby poziom zatrucia powoli spadał, gdy byłeś offline lub na innej postaci.",
gasEntered = "Powietrze ma tu nieprzyjemny zapach, od którego robi się niedobrze. Lepiej nie przebywać tu zbyt długo.",
gasHighNotif = "Powietrze zaczyna być coraz cięższe, a ciało zaczyna dziwnie mrowić. Jak długo to jeszcze wytrzymasz?",
gasNearLethalNotif = "Oddychanie staje się trudne, czujesz się zdezorientowany i bardzo zmęczony. Odejdź, póki jeszcze możesz, śmierć jest tuż za rogiem.",
gasLethalNotif = "Gdy każdy krok staje się wyzwaniem, gdzieś w głębi duszy możesz to poczuć: zostałeś zbyt długo i popchnąłeś swoje ciało zbyt daleko. Nie ma już powrotu, czeka Cię tylko śmierć.",
gasLethalNotifOOC = "Uwaga OOC: osiągnąłeś śmiertelną dawkę zatrucia. Nie ma na to lekarstwa. Masz trochę czasu, aby odegrać śmierć swojej postaci, wchodząc w szok septyczny.",
filterOut = "Filtr się wyczerpał.",
filterDecay = "Twój filtr zaczyna się zużywać, wkrótce przestanie Cię chronić."
})
ix.lang.AddTable("spanish", {
gasLethal = "NIVELES DE VENENO LETAL",
optdGasNotificationWarnings = "Obtenga notificaciones de advertencia cuando entre gas y cuando alcance niveles altos de gas.",
optGasNotificationWarnings = "Avisos de peligro gas",
gasDeathNotif = "%s fue asesinado por el gas.",
gasHigh = "ALTOS NIVELES DE VENENO",
gasLethalNotifOOC = "Nota OOC: has alcanzado cantidades letales de veneno. No hay cura o arreglo para ello. Se te permite un tiempo para rolear la muerte de tu personaje mientras entras en shock séptico.",
gasCDStart = "Has estado fuera de las alcantarillas el tiempo suficiente para que tus niveles de veneno sigan disminuyendo lentamente mientras estás desconectado o con otro personaje.",
gasLethalNotif = "A medida que cada paso se convierte en un desafío, en algún lugar de tu interior puedes sentirlo: Te has quedado mucho tiempo y has forzado tu cuerpo demasiado lejos. Ya no hay vuelta atrás, sólo te espera la muerte.",
gasNearLethalNotif = "Respiras con dificultad, te sientes confuso y estás muy cansado. Vete mientras puedas, la muerte está a la vuelta de la esquina.",
gasEntered = "El aire huele mal aquí, te pone enfermo. Es mejor no quedarse mucho tiempo.",
gasHighNotif = "El aire empieza a pesarte y tu cuerpo siente un extraño cosquilleo. ¿Cuánto tiempo más podrás seguir así?",
filterOut = "Tu filtro se ha agotado.",
filterDecay = "Tu filtro está empezando a deteriorarse, se agotará pronto."
})
ix.lang.AddTable("polish", {
gasDeathNotif = "%s został zabity przez gaz.",
gasLethal = "ŚMIERTELNY POZIOM ZATRUCIA",
gasHigh = "WYSOKI POZIOM ZATRUCIA",
optGasNotificationWarnings = "Ostrzeżenia o zagrożeniach gazowych",
optdGasNotificationWarnings = "Otrzymuj powiadomienia ostrzegawcze o wejściu w gaz i osiągnięciu wysokiego poziomu gazu.",
gasCDStart = "Przebywałeś poza kanałami wystarczająco długo, aby poziom zatrucia powoli spadał, gdy byłeś offline lub na innej postaci.",
gasEntered = "Powietrze ma tu nieprzyjemny zapach, od którego robi się niedobrze. Lepiej nie przebywać tu zbyt długo.",
gasHighNotif = "Powietrze zaczyna być coraz cięższe, a ciało zaczyna dziwnie mrowić. Jak długo to jeszcze wytrzymasz?",
gasNearLethalNotif = "Oddychanie staje się trudne, czujesz się zdezorientowany i bardzo zmęczony. Odejdź, póki jeszcze możesz, śmierć jest tuż za rogiem.",
gasLethalNotif = "Gdy każdy krok staje się wyzwaniem, gdzieś w głębi duszy możesz to poczuć: zostałeś zbyt długo i popchnąłeś swoje ciało zbyt daleko. Nie ma już powrotu, czeka Cię tylko śmierć.",
gasLethalNotifOOC = "Uwaga OOC: osiągnąłeś śmiertelną dawkę zatrucia. Nie ma na to lekarstwa. Masz trochę czasu, aby odegrać śmierć swojej postaci, wchodząc w szok septyczny.",
filterOut = "Filtr się wyczerpał.",
filterDecay = "Twój filtr zaczyna się zużywać, wkrótce przestanie Cię chronić."
})
ix.option.Add("gasNotificationWarnings", ix.type.bool, true, {
bNetworked = true,
category = "notice"
})
CAMI.RegisterPrivilege({
Name = "Helix - Manage Gas",
MinAccess = "admin"
})
do
local a, b, c = 50, 1.04, 49
local gasToCooldown = {b}
PLUGIN.gasToCooldown = gasToCooldown
for i = 2, PLUGIN.LETHAL_GAS do
gasToCooldown[i] = gasToCooldown[i - 1] * b
gasToCooldown[i - 1] = (gasToCooldown[i - 1] * a) - c
end
gasToCooldown[0] = a - c
gasToCooldown[PLUGIN.LETHAL_GAS] = (gasToCooldown[PLUGIN.LETHAL_GAS] * a) - c
end
ix.util.Include("meta/sh_player.lua")
ix.util.Include("cl_hooks.lua")
ix.util.Include("sh_hooks.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_plugin.lua")
-- Accumalated gas points
ix.char.RegisterVar("gasPoints", {
field = "gas_points",
fieldType = ix.type.number,
default = 0,
bNoDisplay = true,
})
-- Detection for when the player left a gas area
ix.char.RegisterVar("gasCooldownPoints", {
field = "gas_cd_points",
fieldType = ix.type.number,
default = 0,
bNoDisplay = true,
bNoNetworking = true
})
-- Time when player left character with enough points for gas cooldown
ix.char.RegisterVar("gasCooldownStart", {
field = "gas_cd_start",
fieldType = ix.type.number,
default = 0,
bNoDisplay = true,
bNoNetworking = true
})
ix.char.RegisterVar("filterItem", {
default = 0,
bNoDisplay = true,
isLocal = true,
})
ix.command.Add("CharSetGasPoints", {
description = "Set character's gas points (1 point = 1 minute in gas; more than "..PLUGIN.LETHAL_GAS.." = lethal; between 0 and "..PLUGIN.GAS_DEATH..")",
arguments = {
ix.type.character,
ix.type.number
},
privilege = "Manage Gas",
OnRun = function(self, client, character, amount)
character:SetGasPoints(math.Clamp(amount, 0, PLUGIN.GAS_DEATH))
client:Notify(character:GetName().."'s gas points were set to "..math.Clamp(amount, 0, PLUGIN.GAS_DEATH))
end
})

View File

@@ -0,0 +1,61 @@
--[[
| 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 timer = timer
local math = math
local os = os
local IsValid = IsValid
local ix = ix
local PLUGIN = PLUGIN
function PLUGIN:PlayerLoadedCharacter(client, character)
local uniqueID = "ixGas" .. client:SteamID64()
timer.Create(uniqueID, self.TIMER_INTERVAL, 0, function()
if (IsValid(client)) then
if (ix.faction.Get(client:Team()).noGas) then return end
PLUGIN:GasZoneTick(client)
else
timer.Remove(uniqueID)
end
end)
if (character:GetGasCooldownPoints() >= self.GAS_COOLDOWN_DELAY) then
local time = math.floor((os.time() - character:GetGasCooldownStart()) / 60)
if (time > 0) then
character:SetGasPoints(self:deductTime(client, character:GetGasPoints(), time / 2))
end
end
end
function PLUGIN:OnPlayerAreaChanged(client, oldID, newID)
if (ix.area.stored[newID].type == "gas") then
if (client:GetMoveType() == MOVETYPE_NOCLIP and !client:InVehicle()) then return end
if (ix.faction.Get(client:Team()).noGas) then return end
client:GetCharacter():SetGasCooldownPoints(0)
if (oldID and ix.area.stored[oldID] and ix.area.stored[oldID].type != "gas" and ix.option.Get(client, "gasNotificationWarnings")) then
client:ChatNotifyLocalized("gasEntered")
end
end
end
function PLUGIN:PlayerSpawn(client)
local character = client:GetCharacter()
if (!character) then return end
if (ix.config.Get("gasPermakill") and character:GetData("gasPermakill")) then
character:SetData("gasPermakill", nil)
character:Ban()
else
character:SetData("gasPermakill", nil)
end
end

View File

@@ -0,0 +1,171 @@
--[[
| 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 string = string
local CurTime = CurTime
local ipairs = ipairs
local player = player
local os = os
local math = math
local ix = ix
local PLUGIN = PLUGIN
ix.log.AddType("gasDeath", function(client, permakill)
return string.format("%s has died from lethal poison levels%s.", client:Name(), (permakill and " and will be permakilled") or "")
end, FLAG_DANGER)
function PLUGIN:deductTime(client, points, time)
if (points >= self.LETHAL_GAS) then
return points
end
if (points <= 0 or ix.config.Get("gasPointRecoveryPenalty") <= 0 or ix.config.Get("gasPointInjuryRecoveryPenalty") <= 0) then
return 0
end
local fl, cl = math.floor(points), math.ceil(points)
local y
if (fl == cl) then
y = self.gasToCooldown[fl]
else
y = math.Remap(points, fl, cl, self.gasToCooldown[fl], self.gasToCooldown[cl])
end
y = y - time / (ix.config.Get("gasPointRecoveryPenalty") * math.Remap(math.Clamp(client:Health() / client:GetMaxHealth(), 0, 1), 1, 0, 1, ix.config.Get("gasPointInjuryRecoveryPenalty")))
for i = cl, 1, -1 do
if (self.gasToCooldown[i - 1] <= y and y <= self.gasToCooldown[i]) then
return math.Remap(y, self.gasToCooldown[i - 1], self.gasToCooldown[i], i - 1, i)
end
end
return 0
end
function PLUGIN:GasZoneTick(client)
if (!client:Alive()) then return end
local character = client:GetCharacter()
if (!character) then return end
if (client:GetMoveType() == MOVETYPE_NOCLIP and !client:InVehicle()) then
if (character:GetGasCooldownPoints() <= 0) then return end
local gasPointLoss = self.TIMER_INTERVAL / 60
if (character:GetGasPoints() > 0) then
local cdPoints = character:GetGasCooldownPoints()
if (cdPoints < self.GAS_COOLDOWN_DELAY) then
cdPoints = cdPoints + self.TIMER_INTERVAL / 60
character:SetGasCooldownPoints(math.min(cdPoints, self.GAS_COOLDOWN_DELAY))
if (cdPoints == self.GAS_COOLDOWN_DELAY and ix.option.Get(client, "gasNotificationWarnings")) then
client:ChatNotifyLocalized("gasCDStart")
end
end
if (cdPoints == self.GAS_COOLDOWN_DELAY) then
character:SetGasCooldownStart(os.time())
end
if (cdPoints >= self.GAS_DECREASE_DELAY) then
character:SetGasPoints(self:deductTime(client, character:GetGasPoints(), gasPointLoss / 2))
end
end
return
end
if (character:GetGasPoints() >= self.LETHAL_GAS) then
if ((!client.ixGasCoughCD or client.ixGasCoughCD < CurTime()) and 0.5 > math.random()) then
client.ixGasCoughCD = CurTime() + 5
client:EmitSound("ambient/voices/cough"..math.random(1, 4)..".wav")
end
local gasDeathTicks = math.min(character:GetGasPoints() + self.TIMER_INTERVAL / 60, self.GAS_DEATH)
character:SetGasPoints(gasDeathTicks)
if (gasDeathTicks >= self.GAS_DEATH) then
local permaKill = ix.config.Get("gasPermakill")
ix.log.Add(client, "gasDeath", permaKill)
client:Kill()
character:SetGasPoints(0)
if (permaKill) then
character:SetData("gasPermakill", true)
end
for _, v in ipairs(player.GetAll()) do
if ((v:GetMoveType() == MOVETYPE_NOCLIP and !v:InVehicle()) or v:Team() == FACTION_SERVERADMIN) then
v:NotifyLocalized("gasDeathNotif", client:SteamName(), (permaKill and " and will be permakilled") or "")
end
end
end
return
end
local inArea = client.ixInArea and ix.area.stored[client.ixArea].type == "gas"
if ((inArea and !ix.config.Get("gasReverseZones")) or (ix.config.Get("gasReverseZones") and !inArea)) then
local filterValue = client:GetFilterValue()
local gasPointGain = self.TIMER_INTERVAL / 60
if (filterValue > 0) then
client:UpdateFilterValue(gasPointGain)
gasPointGain = gasPointGain * (1 - client:GetFilterQuality())
end
gasPointGain = gasPointGain * ix.config.Get("gasPointGainScale") * math.Remap(math.Clamp(client:Health() / client:GetMaxHealth(), 0, 1), 1, 0, 1, ix.config.Get("gasPointInjuryScale"))
local oldPoints = character:GetGasPoints()
local gasPoints = oldPoints + gasPointGain
character:SetGasPoints(gasPoints)
character:SetGasCooldownPoints(0)
if (gasPoints >= self.LETHAL_GAS) then
client:ChatNotifyLocalized("gasLethalNotif")
client:ChatNotifyLocalized("gasLethalNotifOOC")
else
if (ix.option.Get(client, "gasNotificationWarnings") and gasPoints >= 60 and oldPoints < 60) then
client:ChatNotifyLocalized("gasHighNotif")
elseif (gasPoints >= 100 and oldPoints < 100) then
client:ChatNotifyLocalized("gasNearLethalNotif")
end
end
if ((!client.ixGasCoughCD or client.ixGasCoughCD < CurTime()) and math.Clamp((gasPoints - 60) * (1 - client:GetFilterQuality()) / self.LETHAL_GAS, 0.01, 0.5) > math.random()) then
client.ixGasCoughCD = CurTime() + 5
client:EmitSound("ambient/voices/cough"..math.random(1, 4)..".wav")
end
else
local gasPointLoss = self.TIMER_INTERVAL / 60
local filterItem = client:GetFilterItem()
if (filterItem and !filterItem.noUseOutGas) then
client:UpdateFilterValue(gasPointLoss / 100)
end
if (character:GetGasPoints() > 0) then
local cdPoints = character:GetGasCooldownPoints()
if (cdPoints < self.GAS_COOLDOWN_DELAY) then
cdPoints = cdPoints + self.TIMER_INTERVAL / 60
character:SetGasCooldownPoints(math.min(cdPoints, self.GAS_COOLDOWN_DELAY))
if (cdPoints == self.GAS_COOLDOWN_DELAY and ix.option.Get(client, "gasNotificationWarnings")) then
client:ChatNotifyLocalized("gasCDStart")
end
end
if (cdPoints == self.GAS_COOLDOWN_DELAY) then
character:SetGasCooldownStart(os.time())
end
if (cdPoints >= self.GAS_DECREASE_DELAY) then
character:SetGasPoints(self:deductTime(client, character:GetGasPoints(), gasPointLoss))
end
end
end
end