This commit is contained in:
lifestorm
2024-08-04 23:54:45 +03:00
parent 0e770b2b49
commit df294d03aa
7526 changed files with 4011945 additions and 15 deletions

View File

@@ -0,0 +1,191 @@
--[[
| 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
function PLUGIN:ShouldDrawCrosshair()
if (LocalPlayer():GetNetVar("InfestationEditMode")) then
return true
end
end
local gradient = ix.util.GetMaterial("gui/center_gradient")
local entityMat = CreateMaterial("GA0249aSFJ3","VertexLitGeneric",{
["$basetexture"] = "models/debug/debugwhite",
["$model"] = 1,
["$translucent"] = 1,
["$alpha"] = 1,
["$nocull"] = 1,
["$ignorez"] = 1
})
function PLUGIN:HUDPaint()
local client = LocalPlayer()
local infestationMode = client:GetNetVar("InfestationEditMode")
if (!infestationMode) then return end
local width = ScrW()
surface.SetDrawColor(25, 25, 25, 255)
surface.SetMaterial(gradient)
if (infestationMode == 0) then
surface.DrawTexturedRect(0, 30, width, 170)
draw.SimpleText(L("menuMainTitle"), "ixMediumFont", width * 0.5, 50, ix.config.Get("color"), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuMainEdit"), "ixMonoMediumFont", width * 0.5, 90, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuMainCreate"), "ixMonoMediumFont", width * 0.5, 120, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuMainExit"), "ixMonoMediumFont", width * 0.5, 150, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
cam.Start3D()
for _, entity in pairs(ents.FindByClass("ix_infestation_prop")) do
local clientPos = client:EyePos()
local targetPos = entity:GetPos()
local distance = clientPos:Distance(targetPos)
if (!entity:GetInfestation()) then continue end -- I'm sorry for the mess, but I'm not taking any chances.
if (!ix.infestation.stored[entity:GetInfestation()]) then continue end
if (!ix.infestation.stored[entity:GetInfestation()].type) then continue end
if (!ix.infestation.types[ix.infestation.stored[entity:GetInfestation()].type]) then continue end
if (!ix.infestation.types[ix.infestation.stored[entity:GetInfestation()].type].color) then continue end
local color = ix.infestation.types[ix.infestation.stored[entity:GetInfestation()].type].color
render.SuppressEngineLighting(true)
if (entity:GetCore()) then
render.SetColorModulation(255 / 255, 0 / 255, 0 / 255)
else
render.SetColorModulation(color.r / 255, color.g / 255, color.b / 255)
end
if (ix.option.Get("cheapBlur", false)) then
render.SetBlend(1)
else
render.SetBlend(math.Remap(math.Clamp(distance, 200, 4000), 200, 8000, 0.05, 1))
end
render.MaterialOverride(entityMat)
entity:DrawModel()
render.MaterialOverride()
render.SuppressEngineLighting(false)
end
cam.End3D()
elseif (infestationMode == 1) then
surface.DrawTexturedRect(0, 30, width, 200)
draw.SimpleText(L("menuCreateTitle"), "ixMediumFont", width * 0.5, 50, ix.config.Get("color"), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuCreateNotice"), "ixMonoMediumFont", width * 0.5, 90, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuCreateSave"), "ixMonoMediumFont", width * 0.5, 120, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuCreateCore"), "ixMonoMediumFont", width * 0.5, 150, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuCreateExit"), "ixMonoMediumFont", width * 0.5, 180, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
cam.Start3D()
for _, entity in pairs(ents.FindByClass("prop_physics")) do
if (!entity:GetNetVar("infestationProp") or entity:GetNetVar("infestationProp") != client:SteamID()) then continue end
local clientPos = client:EyePos()
local targetPos = entity:GetPos()
local distance = clientPos:Distance(targetPos)
render.SuppressEngineLighting(true)
if (entity:GetNetVar("infestationCore")) then
render.SetColorModulation(255 / 255, 0 / 255, 0 / 255)
else
render.SetColorModulation(255 / 255, 175 / 255, 0 / 255)
end
if (ix.option.Get("cheapBlur", false)) then
render.SetBlend(1)
else
render.SetBlend(math.Remap(math.Clamp(distance, 200, 4000), 200, 8000, 0.05, 1))
end
render.MaterialOverride(entityMat)
entity:DrawModel()
render.MaterialOverride()
render.SuppressEngineLighting(false)
end
cam.End3D()
elseif (infestationMode == 2) then
surface.DrawTexturedRect(0, 30, width, 140)
draw.SimpleText(L("menuEditTitle"), "ixMediumFont", width * 0.5, 50, ix.config.Get("color"), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuEditRemove"), "ixMonoMediumFont", width * 0.5, 90, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
draw.SimpleText(L("menuEditExit"), "ixMonoMediumFont", width * 0.5, 120, Color(255, 175, 0, 255), TEXT_ALIGN_CENTER)
cam.Start3D()
for _, entity in pairs(ents.FindByClass("ix_infestation_prop")) do
if (entity:GetInfestation() != client:GetNetVar("InfestationEditName")) then continue end
local clientPos = client:EyePos()
local targetPos = entity:GetPos()
local distance = clientPos:Distance(targetPos)
render.SuppressEngineLighting(true)
if (entity:GetCore()) then
render.SetColorModulation(255 / 255, 0 / 255, 0 / 255)
else
render.SetColorModulation(255 / 255, 175 / 255, 0 / 255)
end
if (ix.option.Get("cheapBlur", false)) then
render.SetBlend(1)
else
render.SetBlend(math.Remap(math.Clamp(distance, 200, 4000), 200, 8000, 0.05, 1))
end
render.MaterialOverride(entityMat)
entity:DrawModel()
render.MaterialOverride()
render.SuppressEngineLighting(false)
end
for name, data in pairs(ix.infestation.stored) do
if (name == client:GetNetVar("InfestationEditName")) then
for index, entityData in ipairs(data.entities) do
if (index > data.spreadProgress) then
local clientPos = client:EyePos()
local targetPos = entityData.position
local distance = clientPos:Distance(targetPos)
render.SuppressEngineLighting(true)
render.SetColorModulation(255 / 255, 255 / 255, 255 / 255)
if (ix.option.Get("cheapBlur", false)) then
render.SetBlend(1)
else
render.SetBlend(math.Remap(math.Clamp(distance, 200, 4000), 200, 8000, 0.05, 1))
end
render.MaterialOverride(entityMat)
render.Model({model = entityData.model, pos = entityData.position, angle = entityData.angles})
render.MaterialOverride()
render.SuppressEngineLighting(false)
end
end
end
end
cam.End3D()
end
end

View File

@@ -0,0 +1,20 @@
--[[
| 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/
--]]
net.Receive("ixInfestationZoneCreate", function()
vgui.Create("ixInfestationZoneCreate")
end)
net.Receive("ixInfestationZoneNetwork", function()
local storedTable = net.ReadTable()
ix.infestation.stored = storedTable
end)

View File

@@ -0,0 +1,172 @@
--[[
| 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
local PANEL = {}
function PANEL:Init()
if (IsValid(ix.gui.infestationEdit)) then
ix.gui.infestationEdit:Remove()
end
ix.gui.infestationEdit = self
self.list = {}
self.properties = {}
self:SetDeleteOnClose(true)
self:MakePopup()
self:SetTitle(L("infestationNew"))
-- scroll panel
self.canvas = self:Add("DScrollPanel")
self.canvas:Dock(FILL)
-- name entry
self.nameEntry = vgui.Create("ixTextEntry")
self.nameEntry:SetFont("ixMenuButtonFont")
self.nameEntry:SetText(L("infestationNew"))
local listRow = self.canvas:Add("ixListRow")
listRow:SetList(self.list)
listRow:SetLabelText(L("infestationName"))
listRow:SetRightPanel(self.nameEntry)
listRow:Dock(TOP)
listRow:SizeToContents()
listRow:SetLabelWidth(200)
-- type entry
self.typeEntry = self.canvas:Add("DComboBox")
self.typeEntry:Dock(RIGHT)
self.typeEntry:SetFont("ixMenuButtonFont")
self.typeEntry:SetTextColor(color_white)
self.typeEntry.OnSelect = function(panel)
panel:SizeToContents()
panel:SetWide(panel:GetWide() + 12) -- padding for arrow (nice)
end
for id, data in pairs(ix.infestation.types) do
self.typeEntry:AddChoice(data.name, id, id == "erebus")
end
listRow = self.canvas:Add("ixListRow")
listRow:SetList(self.list)
listRow:SetLabelText(L("infestationType"))
listRow:SetRightPanel(self.typeEntry)
listRow:Dock(TOP)
listRow:SizeToContents()
self.spreadEntry = vgui.Create("ixTextEntry")
self.spreadEntry:SetFont("ixMenuButtonFont")
self.spreadEntry:SetText("30")
self.spreadEntry.realGetValue = self.spreadEntry.GetValue
self.spreadEntry.GetValue = function()
return tonumber(self.spreadEntry:realGetValue()) or 30
end
listRow = self.canvas:Add("ixListRow")
listRow:SetList(self.list)
listRow:SetLabelText(L("infestationSpread"))
listRow:SetRightPanel(self.spreadEntry)
listRow:Dock(TOP)
listRow:SizeToContents()
-- save button
self.saveButton = self:Add("DButton")
self.saveButton:SetText(L("infestationSave"))
self.saveButton:SizeToContents()
self.saveButton:Dock(BOTTOM)
self.saveButton.DoClick = function()
self:Submit()
end
self:SizeToContents()
self:SetWide(ScrW() / 3)
self:Center()
end
function PANEL:SizeToContents()
local width = 64
local height = 50
for _, v in ipairs(self.canvas:GetCanvas():GetChildren()) do
width = math.max(width, v:GetLabelWidth())
height = height + v:GetTall()
end
self:SetWide(width + 200)
self:SetTall(height + self.saveButton:GetTall())
end
function PANEL:Submit()
local name = self.nameEntry:GetValue()
if (ix.infestation.stored[name]) then
LocalPlayer():Notify(L("infestationExists"))
return
end
local _, type = self.typeEntry:GetSelected()
local spread = self.spreadEntry:GetFloat()
if (spread and isnumber(spread)) then
spread = math.Round(spread)
if (spread <= 0) then
LocalPlayer():Notify(L("invalidSpread"))
return
end
else
LocalPlayer():Notify(L("invalidSpread"))
return
end
local coreFound = false
local infestationProps = {}
for _, entity in pairs(ents.FindByClass("prop_physics")) do
if (entity:GetNetVar("infestationProp") and entity:GetNetVar("infestationProp") == LocalPlayer():SteamID()) then
infestationProps[#infestationProps + 1] = true -- Just using it to count.
if (entity:GetNetVar("infestationCore")) then
coreFound = true
end
end
end
if (#infestationProps < 2) then
LocalPlayer():Notify(L("notEnoughProps"))
return
end
if (!coreFound) then
LocalPlayer():Notify(L("missingCore"))
return
end
net.Start("ixInfestationZoneCreate")
net.WriteString(name)
net.WriteString(type)
net.WriteFloat(spread)
net.SendToServer()
self:Remove()
end
vgui.Register("ixInfestationZoneCreate", PANEL, "DFrame")
if (IsValid(ix.gui.infestationEdit)) then
ix.gui.infestationEdit:Remove()
end

View File

@@ -0,0 +1,80 @@
--[[
| 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/
--]]
function EFFECT:Init( data )
self.Player = data:GetEntity()
self.Origin = data:GetOrigin()
self.Attachment = data:GetAttachment()
self.Forward = data:GetNormal()
self.Scale = data:GetScale()
self.ColorR = data:GetColor()
self.ColorG = data:GetHitBox()
self.ColorB = data:GetMagnitude()
if ( !IsValid( self.Player ) || !IsValid( self.Player:GetActiveWeapon() ) ) then return end
self.Angle = self.Forward:Angle()
self.Position = self:GetTracerShootPos( self.Origin, self.Player:GetActiveWeapon(), self.Attachment )
if ( self.Position == self.Origin ) then
local att = self.Player:GetAttachment( self.Player:LookupAttachment( "anim_attachment_RH" ) )
if ( att ) then self.Position = att.Pos + att.Ang:Forward() * -2 end
end
local teh_effect = ParticleEmitter( self.Player:GetPos(), true )
if ( !teh_effect ) then return end
for i = 1, 50 * self.Scale do
local particle = teh_effect:Add( "effects/splash4", self.Position )
if ( particle ) then
local Spread = 0.4
particle:SetVelocity( ( Vector( math.sin( math.Rand( 0, 360 ) ) * math.Rand( -Spread, Spread ), math.cos( math.Rand( 0, 360 ) ) * math.Rand( -Spread, Spread ), math.sin( math.random() ) * math.Rand( -Spread, Spread ) ) + self.Forward ) * 750 )
local ang = self.Angle
if ( i / 2 == math.floor( i / 2 ) ) then ang = ( self.Forward * -1 ):Angle() end
particle:SetAngles( ang )
particle:SetDieTime( 0.25 )
particle:SetColor( self.ColorR, self.ColorG, self.ColorB )
particle:SetStartAlpha( 255 )
particle:SetEndAlpha( 0 )
particle:SetStartSize( 8 )
particle:SetEndSize( 0 )
particle:SetCollide( 1 )
particle:SetCollideCallback( function( particleC, HitPos, normal )
particleC:SetAngleVelocity( Angle( 0, 0, 0 ) )
particleC:SetVelocity( Vector( 0, 0, 0 ) )
particleC:SetPos( HitPos + normal * 0.1 )
particleC:SetGravity( Vector( 0, 0, 0 ) )
local angles = normal:Angle()
angles:RotateAroundAxis( normal, particleC:GetAngles().y )
particleC:SetAngles( angles )
particleC:SetLifeTime( 0 )
particleC:SetDieTime( 60 )
particleC:SetStartSize( 8 )
particleC:SetEndSize( 0 )
particleC:SetStartAlpha( 128 )
particleC:SetEndAlpha( 0 )
end )
end
end
teh_effect:Finish()
end
function EFFECT:Think()
return false
end
function EFFECT:Render()
end

View File

@@ -0,0 +1,12 @@
--[[
| 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/
--]]
include("shared.lua")

View File

@@ -0,0 +1,111 @@
--[[
| 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/
--]]
include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
local PLUGIN = PLUGIN
function ENT:Initialize()
self:SetMoveType(MOVETYPE_VPHYSICS)
self:PhysicsInit(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self:SetSolid(SOLID_VPHYSICS)
self:SetTrigger(true)
local physicsObject = self:GetPhysicsObject()
if (IsValid(physicsObject)) then
physicsObject:Wake()
physicsObject:EnableMotion(false)
end
end
function ENT:OnRemove()
if (ix.shuttingDown) then return end
if (self:GetCore()) then
local identification = self:GetInfestation()
if (identification) then
local infestation = ix.infestation.stored[identification]
if (infestation) then
PLUGIN:UpdateInfestation(identification, nil)
end
end
end
end
function ENT:OnSprayed(color)
self:SetSprayed(true)
self:SetMaterial("models/antlion/antlion_innards")
self:SetColor(color)
timer.Simple(1800, function()
if (self and IsValid(self)) then
self:Remove()
end
end)
if (self:GetCore()) then
local identification = self:GetInfestation()
if (identification) then
local infestation = ix.infestation.stored[identification]
if (infestation) then
PLUGIN:UpdateInfestation(identification, nil)
end
end
end
end
function ENT:OnHarvested(client, damageType)
local OnHarvested = ix.infestation.types[self:GetType()].OnHarvested
if (OnHarvested) then
local success = OnHarvested(self, client, damageType)
if (success) then
self:SetHarvested(true)
self:SetColor(Color(127, 127, 127))
end
end
end
function ENT:StartTouch(entity)
local StartTouch = ix.infestation.types[self:GetType()].StartTouch
if (StartTouch) then
StartTouch(self, entity)
end
end
function ENT:EndTouch(entity)
local EndTouch = ix.infestation.types[self:GetType()].EndTouch
if (EndTouch) then
EndTouch(self, entity)
end
end
function ENT:OnTakeDamage(damageInfo)
if (!self:GetHarvested() and (damageInfo:GetDamageType() == DMG_SLASH or damageInfo:GetDamageType() == DMG_CLUB)) then
local attacker = damageInfo:GetAttacker()
if (attacker:IsPlayer()) then
self:OnHarvested(attacker, damageInfo:GetDamageType())
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/
--]]
DEFINE_BASECLASS("base_gmodentity")
ENT.Type = "anim"
ENT.Author = "Aspect™"
ENT.PrintName = "Infestation Prop"
ENT.Category = "HL2 RP"
ENT.Spawnable = false
ENT.AdminSpawnable = false
function ENT:SetupDataTables()
self:NetworkVar("Bool", 0, "Harvested")
self:NetworkVar("String", 1, "Infestation")
self:NetworkVar("String", 2, "Type")
self:NetworkVar("Bool", 3, "Core")
self:NetworkVar("Bool", 4, "Sprayed")
end

View File

@@ -0,0 +1,54 @@
--[[
| 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/
--]]
include("shared.lua")
ENT.PopulateEntityInfo = true
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText(L("infestationTank"))
name:SizeToContents()
local milk = self:GetChemicalVolume()
local success = derma.GetColor("Success", container)
local warning = derma.GetColor("Warning", container)
if (milk >= 75) then
backgroundColor = success
elseif (milk >= 50) then
backgroundColor = Color(75, 119, 190)
elseif (milk >= 25) then
backgroundColor = warning
else
backgroundColor = derma.GetColor("Error", container)
end
local tank = container:AddRow("tank")
tank:SetText(L("infestationTankVolume") .. milk .. "%")
tank:SetBackgroundColor(backgroundColor)
tank:SizeToContents()
local hoseAttached = self:GetHoseAttached() or self:GetHoseConnected()
local hose = container:AddRow("hose")
hose:SetText(hoseAttached and L("hoseAttached") or L("hoseDetached"))
hose:SetBackgroundColor(hoseAttached and success or warning)
hose:SizeToContents()
local applicatorAttached = self:GetApplicatorAttached()
local applicator = container:AddRow("applicator")
applicator:SetText(applicatorAttached and L("applicatorAttached") or L("applicatorDetached"))
applicator:SetBackgroundColor(applicatorAttached and success or warning)
applicator:SizeToContents()
end

View File

@@ -0,0 +1,109 @@
--[[
| 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/
--]]
include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
local PLUGIN = PLUGIN
function ENT:SpawnFunction(client, trace)
if (!trace.Hit) then return end
local SpawnPosition = trace.HitPos + trace.HitNormal
local SpawnAngle = client:EyeAngles()
SpawnAngle.p = 0
SpawnAngle.y = SpawnAngle.y + 180
local entity = ents.Create("ix_infestation_tank")
entity:SetPos(SpawnPosition)
entity:SetAngles(SpawnAngle)
entity:Spawn()
entity:Activate()
ix.saveEnts:SaveEntity(entity)
PLUGIN:SaveInfestationTanks()
return entity
end
function ENT:Initialize()
self:SetModel("models/jq/hlvr/props/xen/combine_foam_tank_set.mdl")
self:SetMoveType(MOVETYPE_VPHYSICS)
self:PhysicsInit(SOLID_VPHYSICS)
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self:SetSkin(1)
self:SetBodygroup(self:FindBodygroupByName("Hose"), 1)
self:SetBodygroup(self:FindBodygroupByName("Applicator"), 1)
local physicsObject = self:GetPhysicsObject()
if (IsValid(physicsObject)) then
physicsObject:Wake()
physicsObject:EnableMotion(false)
end
end
function ENT:OnOptionSelected(client, option, data)
if (option == "Detach Hose") then
if (self:GetHoseAttached()) then
if (!self:GetApplicatorAttached()) then
if (!client:GetCharacter():GetInventory():Add("ic_hose")) then
ix.item.Spawn("ic_hose", client)
end
self:SetHoseAttached(false)
self:SetBodygroup(self:FindBodygroupByName("Hose"), 1)
client:NotifyLocalized("hoseDetachedSuccess")
else
client:NotifyLocalized("hoseDetachedFailure")
end
else
client:NotifyLocalized("noHoseAttached")
end
elseif (option == "Detach Applicator") then
if (self:GetApplicatorAttached()) then
if (!client:GetCharacter():GetInventory():Add("applicator")) then
ix.item.Spawn("applicator", client)
end
self:SetApplicatorAttached(false)
self:SetBodygroup(self:FindBodygroupByName("Applicator"), 1)
client:NotifyLocalized("applicatorDetachedSuccess")
else
client:NotifyLocalized("noApplicatorAttached")
end
elseif (option == "Pack Up") then
if (self:GetApplicatorAttached()) then
client:NotifyLocalized("packUpFailureApplicator")
elseif (self:GetHoseAttached() or self:GetHoseConnected()) then
client:NotifyLocalized("packUpFailureHose")
else
local dataTable = {
ChemicalVolume = self:GetChemicalVolume(),
ChemicalType = self:GetChemicalType(),
TankColor = self:GetColor()
}
if (client:GetCharacter():GetInventory():Add("ic_tank", 1, dataTable)) then
self:Remove()
client:NotifyLocalized("packUpSuccess")
else
client:NotifyLocalized("packUpFailureInventory")
end
end
end
end

View File

@@ -0,0 +1,37 @@
--[[
| 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/
--]]
DEFINE_BASECLASS("base_gmodentity")
ENT.Type = "anim"
ENT.Author = "Aspect™"
ENT.PrintName = "Infestation Control Tank"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminSpawnable = true
function ENT:SetupDataTables()
self:NetworkVar("Float", 0, "ChemicalVolume")
self:NetworkVar("String", 1, "ChemicalType")
self:NetworkVar("Bool", 2, "HoseAttached")
self:NetworkVar("Bool", 3, "ApplicatorAttached")
self:NetworkVar("Bool", 4, "HoseConnected")
end
function ENT:GetEntityMenu(client)
local options = {}
options["Detach Hose"] = true
options["Detach Applicator"] = true
options["Pack Up"] = true
return options
end

View File

@@ -0,0 +1,328 @@
--[[
| 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/
--]]
-- Original code from https://steamcommunity.com/sharedfiles/filedetails/?id=104607228
-- I have only modified this code and I claim no credit for the original ~Aspect
AddCSLuaFile()
--AddCSLuaFile("effects/applicator_effect.lua")
SWEP.PrintName = "Foam Applicator"
SWEP.Author = "Robotboy655 & Aspect™"
SWEP.Category = "HL2 RP"
SWEP.Slot = 5
SWEP.SlotPos = 35
SWEP.Weight = 1
SWEP.DrawWeaponInfoBox = false
SWEP.UseHands = false
SWEP.ViewModel = "models/jq/hlvr/props/xen/combine_foam_applicator.mdl"
SWEP.ViewModelFOV = 75
SWEP.WorldModel = "models/jq/hlvr/props/xen/combine_foam_applicator.mdl"
SWEP.HoldType = "smg"
game.AddAmmoType({name = "applicator"})
SWEP.MaxAmmo = 500
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = SWEP.MaxAmmo
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "applicator"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.IronSightsPos = Vector(9, 13, -6)
SWEP.IronSightsAng = Vector(0, 0, 0)
if (CLIENT) then
function SWEP:CustomAmmoDisplay()
return {Draw = false}
end
local worldModel = ClientsideModel(SWEP.WorldModel)
worldModel:SetNoDraw(true)
function SWEP:DrawWorldModel()
local owner = self:GetOwner()
if (IsValid(owner)) then
-- Specify a good position
local offsetVec = Vector(5, -2.7, -3.4)
local offsetAng = Angle(180, 0, 0)
local boneid = owner:LookupBone("ValveBiped.Bip01_R_Hand")
if (!boneid) then return end
local matrix = owner:GetBoneMatrix(boneid)
if (!matrix) then return end
local newPos, newAng = LocalToWorld(offsetVec, offsetAng, matrix:GetTranslation(), matrix:GetAngles())
worldModel:SetPos(newPos)
worldModel:SetAngles(newAng)
worldModel:SetupBones()
else
worldModel:SetPos(self:GetPos())
worldModel:SetAngles(self:GetAngles())
end
worldModel:DrawModel()
end
end
function SWEP:Ammo1()
return 500
end
function SWEP:GetViewModelPosition(EyePos, EyeAng)
local Mul = 1.0
local Offset = self.IronSightsPos
if (self.IronSightsAng) then
EyeAng = EyeAng * 1
EyeAng:RotateAroundAxis(EyeAng:Right(), self.IronSightsAng.x * Mul)
EyeAng:RotateAroundAxis(EyeAng:Up(), self.IronSightsAng.y * Mul)
EyeAng:RotateAroundAxis(EyeAng:Forward(), self.IronSightsAng.z * Mul)
end
local Right = EyeAng:Right()
local Up = EyeAng:Up()
local Forward = EyeAng:Forward()
EyePos = EyePos + Offset.x * Right * Mul
EyePos = EyePos + Offset.y * Forward * Mul
EyePos = EyePos + Offset.z * Up * Mul
return EyePos, EyeAng
end
function SWEP:SetupDataTables()
self:NetworkVar("Float", 0, "NextIdle")
end
function SWEP:Initialize()
self:SetHoldType(self.HoldType)
end
function SWEP:Deploy()
self:SendWeaponAnim(ACT_VM_DRAW)
self:SetNextPrimaryFire(CurTime() + self:SequenceDuration())
self:Idle()
return true
end
function SWEP:Holster(weapon)
if (CLIENT) then return end
if (self.Sound) then
self.Sound:Stop()
self.Sound = nil
end
return true
end
function SWEP:OnDrop()
if (self.Sound) then
self.Sound:Stop()
self.Sound = nil
end
self.Primary.DefaultClip = 0
end
function SWEP:DoEffect(color)
if (!color) then return end
local effectData = EffectData()
effectData:SetAttachment(1)
effectData:SetEntity(self.Owner)
effectData:SetOrigin(self.Owner:GetShootPos())
effectData:SetNormal(self.Owner:GetAimVector())
effectData:SetColor(color.r)
effectData:SetHitBox(color.g) -- Please, don't judge.
effectData:SetMagnitude(color.b)
effectData:SetScale(1)
util.Effect("applicator_effect", effectData)
end
function SWEP:DoExtinguish(chemicalID)
if (self:Ammo1() < 1) then return end
if (!chemicalID) then return end
local chemicalItem = ix.item.list[chemicalID]
if (!chemicalItem) then return end
local chemicalColor = chemicalItem.chemicalColor
if (!chemicalColor) then return end
if (CLIENT) then
if (self.Owner == LocalPlayer()) then self:DoEffect(chemicalColor) end
return
end
local trace = self.Owner:GetEyeTrace()
local position = trace.HitPos
for _, entity in pairs(ents.FindInSphere(position, 80)) do
if (math.random(0, 100) > 90) then
if (IsValid(entity) and entity:GetPos():Distance(self:GetPos()) <= 256 and entity:GetClass() == "ix_infestation_prop" and !entity:GetSprayed()) then
local infestation = ix.infestation.types[entity:GetType()]
if (!infestation or !infestation.chemical or infestation.chemical != chemicalID) then return end
entity:OnSprayed(chemicalColor)
end
end
end
self:DoEffect(chemicalColor)
end
function SWEP:PrimaryAttack()
local client = self.Owner
local character = client:GetCharacter()
local inventoryID = character:GetInventory():GetID()
local inventory = ix.item.inventories[inventoryID]
local CurTime = CurTime()
local tankEnt
for _, items in pairs(inventory.slots) do
for _, item in pairs(items) do
local entity = item:GetData("connected", nil)
if (entity) then
entity = Entity(entity)
if (entity and IsValid(entity)) then
tankEnt = entity
if (entity:GetChemicalVolume() <= 0) then
entity:SetChemicalType("")
entity:SetColor(Color(255, 255, 255))
return
end
end
end
end
end
if (!tankEnt) then return end
if (self:GetNextPrimaryFire() > CurTime) then return end
if (IsFirstTimePredicted()) then
self:DoExtinguish(tankEnt:GetChemicalType())
if (SERVER) then
if (self.Owner:KeyPressed(IN_ATTACK) or !self.Sound) then
self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
self.Sound = CreateSound(self.Owner, Sound("weapons/applicator/fire1.wav"))
self:Idle()
end
if (self:Ammo1() > 0 and self.Sound) then self.Sound:Play() end
end
end
self:SetNextPrimaryFire(CurTime + 0.05)
local deductTime = self.nextTankDeduction or 0
if (deductTime <= CurTime) then
tankEnt:SetChemicalVolume(tankEnt:GetChemicalVolume() - 1)
self.nextTankDeduction = CurTime + 1
end
end
function SWEP:SecondaryAttack()
end
function SWEP:Reload()
end
function SWEP:PlaySound()
self:EmitSound("weapons/applicator/release1.wav", 100, math.random(95, 110))
end
function SWEP:Think()
if (self:GetNextIdle() > 0 and CurTime() > self:GetNextIdle()) then
self:DoIdleAnimation()
self:Idle()
end
if (self:GetNextSecondaryFire() > CurTime() or CLIENT) then return end
if (self.Sound and self.Sound:IsPlaying() and self:Ammo1() < 1) then
self.Sound:Stop()
self.Sound = nil
self:PlaySound()
self:DoIdleAnimation()
self:Idle()
end
if (self.Owner:KeyReleased(IN_ATTACK) or (!self.Owner:KeyDown(IN_ATTACK) and self.Sound)) then
self:SendWeaponAnim(ACT_VM_SECONDARYATTACK)
if (self.Sound) then
self.Sound:Stop()
self.Sound = nil
if (self:Ammo1() > 0) then
self:PlaySound()
if (!game.SinglePlayer()) then self:CallOnClient("PlaySound", "") end
end
end
self:SetNextPrimaryFire(CurTime() + self:SequenceDuration())
self:SetNextSecondaryFire(CurTime() + self:SequenceDuration())
self:Idle()
end
end
function SWEP:DoIdleAnimation()
if (self.Owner:KeyDown(IN_ATTACK) and self:Ammo1() > 0) then self:SendWeaponAnim(ACT_VM_IDLE_1) return end
if (self.Owner:KeyDown(IN_ATTACK) and self:Ammo1() < 1) then self:SendWeaponAnim(ACT_VM_IDLE_EMPTY) return end
self:SendWeaponAnim(ACT_VM_IDLE)
end
function SWEP:Idle()
self:SetNextIdle(CurTime() + self:GetAnimationTime())
end
function SWEP:GetAnimationTime()
local time = self:SequenceDuration()
if (time == 0 and IsValid(self.Owner) and !self.Owner:IsNPC() and IsValid(self.Owner:GetViewModel())) then
time = self.Owner:GetViewModel():SequenceDuration()
end
return time
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/
--]]
INFESTATION.name = "Erebus-Class Strain"
INFESTATION.color = Color(106, 168, 79)
INFESTATION.reading = {0, 35}
INFESTATION.chemical = "ic_hydrocarbon_foam"
INFESTATION.StartTouch = function(self, client)
if (!client:IsPlayer()) then return end
if (client:IsInfestationProtected()) then return end
if (timer.Exists("erebus_touch_" .. client:SteamID64())) then return end
client:SetNetVar("TouchingInfestation", true)
timer.Create("erebus_touch_" .. client:SteamID64(), 5, 1, function()
if (client:GetNetVar("TouchingInfestation")) then
client:GetCharacter():SetSpecialBoost("agility", -5, true)
client:GetCharacter():SetSpecialBoost("intelligence", -5, true)
client:GetCharacter():SetSpecialBoost("perception", -5, true)
client:GetCharacter():SetSpecialBoost("strength", -5, true)
client:SetNetVar("TouchingInfestation", false)
end
end)
end
INFESTATION.EndTouch = function(self, client)
if (!client:IsPlayer()) then return end
client:SetNetVar("TouchingInfestation", false)
end
INFESTATION.OnHarvested = function(self, client, damageType)
local inventory = client:GetCharacter():GetInventory()
local container = inventory:HasItem("junk_jar")
if (container) then
if (math.random(0, 10) > 3) then
container:Remove()
inventory:Add("ic_erebus_mucus")
client:NotifyLocalized("mucusCollectSuccess")
else
client:NotifyLocalized("mucusCollectFailureLuck")
end
return true
else
client:NotifyLocalized("mucusCollectFailureJar")
return false
end
end

View File

@@ -0,0 +1,41 @@
--[[
| 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/
--]]
INFESTATION.name = "Nosos-Class Strain"
INFESTATION.color = Color(255, 0, 0)
INFESTATION.reading = {40, 80}
INFESTATION.chemical = "ic_caustic_solution"
INFESTATION.StartTouch = function(self, client)
if (!client:IsPlayer()) then return end
if (client:IsInfestationProtected()) then return end
if (timer.Exists("erebus_touch_" .. client:SteamID64())) then return end
client:SetNetVar("TouchingInfestation", true)
timer.Create("nosos_touch_" .. client:SteamID64(), 5, 1, function()
if (client:GetNetVar("TouchingInfestation")) then
client:GetCharacter():SetSpecialBoost("agility", -10, false)
client:GetCharacter():SetSpecialBoost("intelligence", -10, false)
client:GetCharacter():SetSpecialBoost("perception", -10, false)
client:GetCharacter():SetSpecialBoost("strength", -10, false)
client:SetNetVar("TouchingInfestation", false)
end
end)
end
INFESTATION.EndTouch = function(self, client)
if (!client:IsPlayer()) then return end
client:SetNetVar("TouchingInfestation", false)
end

View File

@@ -0,0 +1,56 @@
--[[
| 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/
--]]
INFESTATION.name = "Thanarok-Class Strain"
INFESTATION.color = Color(0, 0, 0)
INFESTATION.reading = {70, 100}
INFESTATION.chemical = "ic_thermo_radio_solution"
INFESTATION.StartTouch = function(self, client)
if (!client:IsPlayer()) then return end
if (client:IsInfestationProtected()) then return end
if (timer.Exists("erebus_touch_" .. client:SteamID64())) then return end
client:SetNetVar("TouchingInfestation", true)
timer.Create("thanarok_touch_" .. client:SteamID64(), 5, 1, function()
if (client:GetNetVar("TouchingInfestation")) then
client:TakeDamage(25, self, self)
client:SetNetVar("TouchingInfestation", false)
end
end)
end
INFESTATION.EndTouch = function(self, client)
if (!client:IsPlayer()) then return end
client:SetNetVar("TouchingInfestation", false)
end
INFESTATION.OnHarvested = function(self, client, damageType)
if (damageType == DMG_SLASH) then
if (math.random(0, 10) > 9) then
if (!client:GetCharacter():GetInventory():Add("ic_thanarok_embryo")) then
ix.item.Spawn("ic_thanarok_embryo", client)
end
client:NotifyLocalized("thanarokCollectSuccess")
else
client:NotifyLocalized("thanarokCollectFailureLuck")
end
else
client:NotifyLocalized("thanarokCollectFailureWrongTool")
end
return true
end

View File

@@ -0,0 +1,56 @@
--[[
| 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/
--]]
INFESTATION.name = "Thanatos-Class Strain"
INFESTATION.color = Color(0, 0, 0)
INFESTATION.reading = {70, 100}
INFESTATION.chemical = "ic_anti_xenian_viviral"
INFESTATION.StartTouch = function(self, client)
if (!client:IsPlayer()) then return end
if (client:IsInfestationProtected()) then return end
if (timer.Exists("erebus_touch_" .. client:SteamID64())) then return end
client:SetNetVar("TouchingInfestation", true)
timer.Create("thanatos_touch_" .. client:SteamID64(), 5, 1, function()
if (client:GetNetVar("TouchingInfestation")) then
client:TakeDamage(25, self, self)
client:SetNetVar("TouchingInfestation", false)
end
end)
end
INFESTATION.EndTouch = function(self, client)
if (!client:IsPlayer()) then return end
client:SetNetVar("TouchingInfestation", false)
end
INFESTATION.OnHarvested = function(self, client, damageType)
if (damageType == DMG_SLASH) then
if (math.random(0, 10) > 9) then
if (!client:GetCharacter():GetInventory():Add("ic_thanatos_embryo")) then
ix.item.Spawn("ic_thanatos_embryo", client)
end
client:NotifyLocalized("thanatosCollectSuccess")
else
client:NotifyLocalized("thanatosCollectFailureLuck")
end
else
client:NotifyLocalized("thanatosCollectFailureWrongTool")
end
return true
end

View File

@@ -0,0 +1,29 @@
--[[
| 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/
--]]
INFESTATION.name = "Xipe-Class Strain"
INFESTATION.color = Color(256, 128, 4)
INFESTATION.reading = {25, 50}
INFESTATION.chemical = "ic_cryogenic_liquid"
INFESTATION.OnHarvested = function(self, client, damageType)
if (math.random(0, 10) > 5) then
if (!client:GetCharacter():GetInventory():Add("ic_cluster_hive")) then
ix.item.Spawn("ic_cluster_hive", client)
end
client:NotifyLocalized("xipeCollectSuccess")
else
client:NotifyLocalized("xipeCollectFailureLuck")
end
return true
end

View File

@@ -0,0 +1,53 @@
--[[
| 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 = "Chemical"
ITEM.model = Model("models/willardnetworks/skills/chemical_flask1.mdl")
ITEM.description = "A chemical used in Infestation Control."
ITEM.category = "Infestation Control"
ITEM.width = 1
ITEM.height = 2
ITEM.chemicalColor = Color(255, 255, 255)
ITEM.functions.Insert = {
icon = "icon16/paintcan.png",
OnRun = function(item)
local client = item.player
local trace = client:GetEyeTraceNoCursor()
local target = trace.Entity
if (target:GetClass() == "ix_infestation_tank" and trace.HitPos:Distance(client:GetShootPos()) <= 192) then
local chemicalType = target:GetChemicalType()
if (chemicalType == "" or chemicalType == item.uniqueID) then
if (target:GetChemicalVolume() < 100) then
target:SetChemicalType(item.uniqueID)
target:SetChemicalVolume(math.Clamp(target:GetChemicalVolume() + 25, 0, 100))
target:SetColor(item.chemicalColor)
client:NotifyLocalized("tankFilled", L(item.name, client))
else
client:NotifyLocalized("tankFull")
return false
end
else
client:NotifyLocalized("tankDifferentChemical")
return false
end
else
client:NotifyLocalized("invalidTank")
return false
end
end
}

View File

@@ -0,0 +1,16 @@
--[[
| 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 = "viviralItemName"
ITEM.model = Model("models/willardnetworks/skills/chemical_flask_big_1.mdl")
ITEM.skin = 2
ITEM.description = "viviralItemDesc"
ITEM.chemicalColor = Color(115, 30, 70)

View File

@@ -0,0 +1,16 @@
--[[
| 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 = "causticItemName"
ITEM.model = Model("models/willardnetworks/skills/chemical_flask_big_1.mdl")
ITEM.skin = 0
ITEM.description = "causticItemDesc"
ITEM.chemicalColor = Color(150, 195, 125)

View File

@@ -0,0 +1,16 @@
--[[
| 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 = "cryogenicItemname"
ITEM.model = Model("models/willardnetworks/skills/chemical_flask_big_1.mdl")
ITEM.skin = 3
ITEM.description = "cryogenicItemDesc"
ITEM.chemicalColor = Color(75, 135, 230)

View File

@@ -0,0 +1,16 @@
--[[
| 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 = "hydrocarbonItemName"
ITEM.model = Model("models/willardnetworks/skills/chemical_flask_big_1.mdl")
ITEM.skin = 1
ITEM.description = "hydrocarbonItemDesc"
ITEM.chemicalColor = Color(255, 150, 0)

View File

@@ -0,0 +1,16 @@
--[[
| 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 = "thermoradioItemName"
ITEM.model = Model("models/willardnetworks/skills/chemical_flask_big_1.mdl")
ITEM.skin = 2
ITEM.description = "thermoradioItemDesc"
ITEM.chemicalColor = Color(115, 30, 70)

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 = "Orange Hazmat Uniform"
ITEM.model = Model("models/props_c17/BriefCase001a.mdl")
ITEM.description = "An Orange Hazmat Uniform, capable of keeping its wearer safe from dangerous chemicals and gases."
ITEM.category = "Infestation Control"
ITEM.replacement = "models/hlvr/characters/hazmat_worker/npc/hazmat_worker_citizen.mdl"
ITEM.newSkin = 1
ITEM.isPPE = true
ITEM.isGasmask = true

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 = "White Hazmat Uniform"
ITEM.model = Model("models/props_c17/BriefCase001a.mdl")
ITEM.description = "A White Hazmat Uniform, capable of keeping its wearer safe from dangerous chemicals and gases."
ITEM.category = "Infestation Control"
ITEM.replacement = "models/hlvr/characters/hazmat_worker/npc/hazmat_worker_citizen.mdl"
ITEM.newSkin = 2
ITEM.isPPE = true
ITEM.isGasmask = true

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 = "Yellow Hazmat Uniform"
ITEM.model = Model("models/props_c17/BriefCase001a.mdl")
ITEM.description = "A Yellow Hazmat Uniform, capable of keeping its wearer safe from dangerous chemicals and gases."
ITEM.category = "Infestation Control"
ITEM.replacement = "models/hlvr/characters/hazmat_worker/npc/hazmat_worker_citizen.mdl"
ITEM.newSkin = 0
ITEM.isPPE = true
ITEM.isGasmask = true

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 = "clusterItemName"
ITEM.model = Model("models/jq/hlvr/props/xenpack/xen_bulb002.mdl")
ITEM.description = "clusterItemDesc"
ITEM.category = "Infestation Control"
ITEM.colorAppendix = {
["blue"] = "itemHarvestedCrafted",
["red"] = "itemSus"
}

View File

@@ -0,0 +1,256 @@
--[[
| 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 = "hoseItemName"
ITEM.model = Model("models/jq/hlvr/props/xen/combine_foam_hose.mdl")
ITEM.description = "hoseItemDesc"
ITEM.category = "Infestation Control"
ITEM.skin = 1
ITEM.exRender = true
ITEM.width = 4
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(178.91, 88.39, 13.04),
ang = Angle(3.85, 205.44, 0),
fov = 17.03
}
-- Inventory drawing
if (CLIENT) then
-- Draw camo if it is available.
function ITEM:PaintOver(item, w, h)
if (item:GetData("connected", false)) then
surface.SetDrawColor(110, 255, 110, 100)
surface.DrawRect(w - 14, h - 14, 8, 8)
end
end
else
-- Doing all this because the hose model has no physics model.
function ITEM:OnEntityCreated(itemEntity)
itemEntity:SetModel("models/squad/sf_plates/sf_plate3x3.mdl")
itemEntity:DrawShadow(false)
itemEntity:SetColor(Color(255, 255, 255, 0))
itemEntity:SetRenderMode(RENDERMODE_TRANSCOLOR)
itemEntity:PhysicsInit(SOLID_VPHYSICS)
itemEntity:SetSolid(SOLID_VPHYSICS)
local physObj = itemEntity:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(true)
physObj:Wake()
end
itemEntity.tube = ents.Create("prop_dynamic")
itemEntity.tube:DrawShadow(true)
itemEntity.tube:SetParent(itemEntity)
itemEntity.tube:SetModel("models/jq/hlvr/props/xen/combine_foam_hose.mdl")
itemEntity.tube:SetSkin(1)
local forward, right, up = itemEntity:GetForward(), itemEntity:GetRight(), itemEntity:GetUp()
itemEntity.tube:SetAngles(itemEntity:GetAngles())
itemEntity.tube:SetPos(itemEntity:GetPos() + forward * 18 + right * - 20 + up * 5)
itemEntity.tube:Spawn()
itemEntity:DeleteOnRemove(itemEntity.tube)
end
end
function ITEM:CanTransfer(oldInventory, newInventory)
if (newInventory and self:GetData("connected", false)) then
return false
end
return true
end
ITEM.functions.Attach = {
icon = "icon16/basket_put.png",
OnRun = function(item)
local client = item.player
local trace = client:GetEyeTraceNoCursor()
local target = trace.Entity
if (target:GetClass() == "ix_infestation_tank" and trace.HitPos:Distance(client:GetShootPos()) <= 192) then
if (target:GetDTBool(4) or target:GetDTBool(2)) then
client:NotifyLocalized("hoseAttachFailureAttached")
return false
end
if (item:GetData("connected", false)) then
ix.item.PerformInventoryAction(client, "ConnectDis", item.id, item.invID)
end
target:SetBodygroup(target:FindBodygroupByName("Hose"), 0)
target:SetDTBool(2, true)
client:NotifyLocalized("hoseAttachSuccess")
else
client:NotifyLocalized("invalidTank")
return false
end
end,
OnCanRun = function(item)
return !IsValid(item.entity)
end
}
ITEM.functions.Connect = {
icon = "icon16/link.png",
OnRun = function(item)
local client = item.player
local trace = client:GetEyeTraceNoCursor()
local target = trace.Entity
if (target:GetClass() == "ix_infestation_tank" and trace.HitPos:Distance(client:GetShootPos()) <= 192) then
if (target:GetDTBool(4) or target:GetDTBool(2)) then
client:NotifyLocalized("hoseConnectFailureConnected")
return false
end
local inventoryID = client:GetCharacter():GetInventory():GetID()
local inventory = ix.item.inventories[inventoryID]
local hasOtherHoseConnected = false
for _, items in pairs(inventory.slots) do
for _, item in pairs(items) do
if (item.uniqueID == "hose" and item:GetData("connected", false)) then
hasOtherHoseConnected = true
break
end
end
end
if (hasOtherHoseConnected) then
client:NotifyLocalized("hoseConnectFailureMultipleHoses")
return false
end
item:SetData("connected", target:EntIndex())
target:SetDTBool(4, true)
client:NotifyLocalized("hoseConnectSuccess")
local rope = constraint.Rope(client, target, 0, 0, Vector(0, 0, 20), Vector(0, 0, 0), 0, 750, 1, 4, "cable/combine_foam_tank_hose_rope")
rope:CallOnRemove("RopeBroken", function(entity)
if (item.functions.ConnectDis.OnCanRun(item)) then
item.functions.ConnectDis.OnRun(item, true, client)
end
end)
client:SetNetVar("tankHose", rope)
else
client:NotifyLocalized("invalidTank")
end
return false
end,
OnCanRun = function(item)
return !item:GetData("connected", false) and !IsValid(item.entity)
end
}
ITEM.functions.ConnectDis = { -- Sorry
name = "Disconnect",
icon = "icon16/link_break.png",
OnRun = function(item, forceUnequip, activator)
local client = item.player
if (forceUnequip == true) then
client = activator
end
local character
local inventory
-- This is retarded but better safe than sorry.
if (client) then
character = client:GetCharacter()
if (character) then
inventory = character:GetInventory()
if (!inventory) then
return false
end
else
return false
end
else
return false
end
if (client:HasWeapon("weapon_applicator")) then
if (forceUnequip == true) then
local applicator = inventory:HasItem("applicator")
if (applicator) then
ix.item.PerformInventoryAction(client, "EquipUn", applicator.id, applicator.invID)
end
else
client:NotifyLocalized("hoseDisconnectFailureApplicator")
return false
end
end
local target = item:GetData("connected", false)
if (target and isnumber(target)) then
target = Entity(target)
if (target and target:IsValid()) then
target:SetDTBool(4, false)
end
end
item:SetData("connected", false)
if (forceUnequip != true) then
client:NotifyLocalized("hoseDisconnectSuccess")
else
client:NotifyLocalized("hoseDisconnectForced")
end
local rope = client:GetNetVar("tankHose")
if (rope and IsValid(rope)) then
rope:Remove()
end
client:SetNetVar("tankHose", nil)
return false
end,
OnCanRun = function(item)
return item:GetData("connected", false) and !IsValid(item.entity)
end
}
function ITEM:OnLoadout()
local connected = self:GetData("connected", false)
if (connected and isnumber(connected)) then
connected = Entity(connected)
if (connected and connected:IsValid()) then
connected:SetDTBool(4, false)
end
end
self:SetData("connected", false)
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 = "nososItemName"
ITEM.model = Model("models/jq/hlvr/props/infestationv2/xen_v2_fungus.mdl")
ITEM.description = "nososItemDesc"
ITEM.category = "Infestation Control"
ITEM.colorAppendix = {
["blue"] = "itemHarvestedHeadcrab",
["red"] = "itemSus"
}

View File

@@ -0,0 +1,74 @@
--[[
| 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 = "tankItemName"
ITEM.model = Model("models/hlvr/combine_hazardprops/combinehazardprops_hoover.mdl")
ITEM.description = "tankItemDesc"
ITEM.category = "Infestation Control"
ITEM.width = 6
ITEM.height = 4
ITEM.functions.drop = {
icon = "icon16/world.png",
OnRun = function(itemTable)
local client = itemTable.player
local trace = client:GetEyeTraceNoCursor()
if (trace.HitPos:Distance(client:GetShootPos()) <= 192) then
local tank = ents.Create("ix_infestation_tank")
tank:SetPos(trace.HitPos)
tank:SetChemicalType(itemTable:GetData("ChemicalType", ""))
tank:SetChemicalVolume(itemTable:GetData("ChemicalVolume", 0))
tank:SetColor(itemTable:GetData("TankColor", Color(255, 255, 255)))
tank:Spawn()
ix.saveEnts:SaveEntity(tank)
client:EmitSound("npc/zombie/foot_slide" .. math.random(1, 3) .. ".wav", 75, math.random(90, 120), 1)
client:NotifyLocalized("tankDeploySuccess")
local currentItems = client:GetNetVar("visibleItems", {})
if (currentItems["tankItemName"]) then
currentItems["tankItemName"] = nil
end
client:SetNetVar("visibleItems", currentItems)
else
client:NotifyLocalized("tankDeployFailureDistance")
return false
end
end,
OnCanRun = function(itemTable)
return !IsValid(itemTable.entity)
end
}
if (CLIENT) then
function ITEM:PopulateTooltip(tooltip)
local type = self:GetData("ChemicalType")
local volume = self:GetData("ChemicalVolume")
type = ix.item.list[type] and ix.item.list[type].name or L("none")
volume = volume and volume .. "%" or L("empty")
local panel = tooltip:AddRowAfter("name", "type")
panel:SetBackgroundColor(derma.GetColor("Information", tooltip))
panel:SetText(L("chemicalType") .. type)
panel:SizeToContents()
panel = tooltip:AddRowAfter("type", "volume")
panel:SetBackgroundColor(derma.GetColor("Warning", tooltip))
panel:SetText(L("chemicalVolume") .. volume)
panel:SizeToContents()
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 = "thanarokItemName"
ITEM.model = Model("models/jq/hlvr/props/infestation/p1/xen_swelling.mdl")
ITEM.description = "thanarokItemDesc"
ITEM.category = "Infestation Control"
ITEM.colorAppendix = {
["blue"] = "itemHarvested",
["red"] = "itemSus"
}

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 = "thanatosItemName"
ITEM.model = Model("models/jq/hlvr/props/infestation/p1/xen_swelling.mdl")
ITEM.description = "thanatosItemDesc"
ITEM.category = "Infestation Control"
ITEM.colorAppendix = {
["blue"] = "itemHarvested",
["red"] = "itemSus"
}

View File

@@ -0,0 +1,53 @@
--[[
| 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 = "detectorItemName"
ITEM.model = Model("models/hlvr/combine_hazardprops/combinehazardprops_detector.mdl")
ITEM.description = "detectorItemDesc"
ITEM.category = "Infestation Control"
ITEM.functions.Calibrate = {
icon = "icon16/monitor_link.png",
OnRun = function(itemTable)
local client = itemTable.player
local reading = nil
for _, entity in ipairs(ents.FindInSphere(client:GetPos(), 192)) do
if (entity:GetClass() == "ix_infestation_prop") then
local readingData = ix.infestation.types[ix.infestation.stored[entity:GetInfestation()].type].reading
reading = math.random(readingData[1], readingData[2]) .. ", " .. math.random(readingData[1], readingData[2]) .. ", " .. math.random(readingData[1], readingData[2])
break
end
end
client:EmitSound("helix/ui/press.wav")
if (reading) then
ix.util.EmitQueuedSounds(client, {"player/geiger" .. math.random(1, 3) .. ".wav", "player/geiger" .. math.random(1, 3) .. ".wav", "player/geiger" .. math.random(1, 3) .. ".wav"})
end
itemTable:SetData("reading", reading)
return false
end
}
if (CLIENT) then
function ITEM:PopulateTooltip(tooltip)
local reading = self:GetData("reading", "0, 0, 0")
local panel = tooltip:AddRowAfter("name", "reading")
panel:SetBackgroundColor(derma.GetColor("Warning", tooltip))
panel:SetText(L("reading") .. reading)
panel:SizeToContents()
end
end

View File

@@ -0,0 +1,152 @@
--[[
| 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 = "applicatorItemName"
ITEM.model = Model("models/jq/hlvr/props/xen/combine_foam_applicator.mdl")
ITEM.description = "applicatorItemDesc"
ITEM.category = "Infestation Control"
ITEM.class = "weapon_applicator"
ITEM.weaponCategory = "primary"
ITEM.exRender = true
ITEM.width = 5
ITEM.height = 2
ITEM.iconCam = {
pos = Vector(0, 200, 0),
ang = Angle(0, 270, 0),
fov = 12.05
}
-- Inventory drawing
if (CLIENT) then
-- Draw camo if it is available.
function ITEM:PaintOver(item, w, h)
if (item:GetData("equip", false)) then
surface.SetDrawColor(110, 255, 110, 100)
surface.DrawRect(w - 14, h - 14, 8, 8)
end
end
end
ITEM.functions.Attach = {
icon = "icon16/basket_put.png",
OnRun = function(item)
local client = item.player
local trace = client:GetEyeTraceNoCursor()
local target = trace.Entity
if (target:GetClass() == "ix_infestation_tank" and trace.HitPos:Distance(client:GetShootPos()) <= 192) then
if (target:GetApplicatorAttached()) then
client:NotifyLocalized("applicatorAttachFailureAttached")
return false
end
if (!target:GetHoseAttached()) then
client:NotifyLocalized("applicatorAttachFailureNoHose")
return false
end
target:SetBodygroup(target:FindBodygroupByName("Applicator"), 0)
target:SetApplicatorAttached(true)
client:NotifyLocalized("applicatorAttachSuccess")
else
client:NotifyLocalized("invalidTank")
return false
end
end,
OnCanRun = function(item)
return !item:GetData("connected", false) and !IsValid(item.entity)
end
}
function ITEM:Equip(client, bNoSelect, bNoSound)
if (!client:GetNetVar("tankHose", nil)) then
client:NotifyLocalized("applicatorEquipFailureNoHose")
return false
end
local items = client:GetCharacter():GetInventory():GetItems()
client.carryWeapons = client.carryWeapons or {}
for _, v in pairs(items) do
if (v.id != self.id) then
local itemTable = ix.item.instances[v.id]
if (!itemTable) then
client:NotifyLocalized("tellAdmin", "wid!xt")
return false
else
if (itemTable.isWeapon and client.carryWeapons[self.weaponCategory] and itemTable:GetData("equip")) then
client:NotifyLocalized("weaponSlotFilled", self.weaponCategory)
return false
end
end
end
end
if (client:HasWeapon(self.class)) then
client:StripWeapon(self.class)
end
local weapon = client:Give(self.class, !self.isGrenade)
if (IsValid(weapon)) then
local ammoType = weapon:GetPrimaryAmmoType()
client.carryWeapons[self.weaponCategory] = weapon
if (!bNoSelect) then
client:SelectWeapon(weapon:GetClass())
end
if (!bNoSound) then
client:EmitSound(self.useSound, 80)
end
-- Remove default given ammo.
if (client:GetAmmoCount(ammoType) == weapon:Clip1() and self:GetData("ammo", 0) == 0) then
client:RemoveAmmo(weapon:Clip1(), ammoType)
end
-- assume that a weapon with -1 clip1 and clip2 would be a throwable (i.e hl2 grenade)
-- TODO: figure out if this interferes with any other weapons
if (weapon:GetMaxClip1() == -1 and weapon:GetMaxClip2() == -1 and client:GetAmmoCount(ammoType) == 0) then
client:SetAmmo(1, ammoType)
end
self:SetData("equip", true)
if (self.isGrenade) then
weapon:SetClip1(1)
client:SetAmmo(0, ammoType)
else
weapon:SetClip1(self:GetData("ammo", 0))
end
weapon.ixItem = self
if (self.OnEquipWeapon) then
self:OnEquipWeapon(client, weapon)
end
else
print(Format("[Helix] Cannot equip weapon - %s does not exist!", self.class))
end
end
function ITEM:OnLoadout()
self:SetData("equip", false)
end

View File

@@ -0,0 +1,124 @@
--[[
| 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/
--]]
LANGUAGE = {
infestationNew = "New Infestation Zone",
infestationName = "Zone Name",
infestationType = "Zone Type",
infestationSpread = "Spread Rate",
infestationSave = "Save Infestation Zone",
infestationExists = "That Infestation Zone already exists!",
invalidSpread = "That is not a valid Spread Rate!",
notEnoughProps = "Not enough Infestation Props found!",
missingCore = "No Infestation Zone Core found!",
infestationTank = "Infestation Control Tank",
infestationTankVolume = "Tank Volume: ",
hoseAttached = "Hose attached",
hoseDetached = "Hose detached",
applicatorAttached = "Applicator attached",
applicatorDetached = "Applicator detached",
hoseDetachedSuccess = "You detach the hose from the tank.",
hoseDetachedFailure = "You must detach the applicator before detaching the hose!",
noHoseAttached = "There is no hose attached to the tank!",
applicatorDetachedSuccess = "You detach the applicator from the tank.",
noApplicatorAttached = "There is no applicator attached to the tank!",
packUpFailureApplicator = "You must detach the applicator before packing up the tank!",
packUpFailureHose = "You must detach the hose before packing up the tank!",
packUpFailureInventory = "You do not have enough inventory space to carry this tank!",
packUpSuccess = "You pack up and begin carrying the entire tank around. ...How?",
mucusCollectSuccess = "You collect some Erebus Mucus from the growth and store it inside a Plastic Jar.",
mucusCollectFailureLuck = "You fail to find anything to harvest from this part of the growth!",
mucusCollectFailureJar = "You need an Empty Jar to harvest this growth!",
thanatosCollectSuccess = "You cut out a small thick stack from the growth. It pulsates slightly.",
thanatosCollectFailureLuck = "You fail to find anything to harvest from this part of the growth!",
thanatosCollectFailureWrongTool = "You used a blunt melee tool and this part of the growth was destroyed!",
thanarokCollectSuccess = "You cut out a small thick stack from the growth. It pulsates slightly.",
thanarokCollectFailureLuck = "You fail to find anything to harvest from this part of the growth!",
thanarokCollectFailureWrongTool = "You used a blunt melee tool and this part of the growth was destroyed!",
xipeCollectSuccess = "You slice off a piece of Cluster-Hive from the growth.",
xipeCollectFailureLuck = "You fail to find anything to harvest from this part of the growth!",
tankFilled = "You fill the tank with the %s.",
tankFull = "The tank is full!",
tankDifferentChemical = "That tank has a different chemical loaded into it!",
invalidTank = "You must be aiming at a valid tank!",
applicatorAttachFailureAttached = "There is another applicator attached to this tank!",
applicatorAttachFailureNoHose = "A hose must be attached to the tank before attaching the applicator!",
applicatorAttachSuccess = "You attach the applicator to the tank.",
applicatorEquipFailureNoHose = "You don't have a hose connected!",
hoseAttachFailureAttached = "There is another hose attached to this tank!",
hoseAttachSuccess = "You attach the orange hose to the tank.",
hoseConnectFailureConnected = "There is another hose connected to this tank!",
hoseConnectFailureMultipleHoses = "You can only carry one connected hose at once!",
hoseConnectSuccess = "You connect the orange hose to the tank.",
hoseDisconnectFailureApplicator = "You must unequip the applicator before disconnecting the hose!",
hoseDisconnectSuccess = "You disconnect the orange hose from the tank.",
hoseDisconnectForced = "The orange hose has disconnected from the tank because you moved too far!",
tankDeploySuccess = "You place the tank down. That must've been exhausting.",
tankDeployFailureDistance = "You cannot drop the Tank that far away!",
none = "None",
empty = "Empty",
chemicalType = "Chemical Type: ",
chemicalVolume = "Chemical Volume: ",
reading = "Reading: ",
menuMainTitle = "Infestation Edit Mode - Menu",
menuMainEdit = "To edit an existing infestation zone, press CTRL + SHIFT + RIGHT CLICK",
menuMainCreate = "To create a new infestation zone, press CTRL + SHIFT + LEFT CLICK",
menuMainExit = "To exit the Infestation Edit Mode, press CTRL + SHIFT + ALT",
menuCreateTitle = "Infestation Edit Mode - Create Infestation",
menuCreateNotice = "Any props spawned will be considered infestation props",
menuCreateSave = "To save changes and create a new infestation zone, press CTRL + SHIFT + LEFT CLICK",
menuCreateCore = "To define the infestation core prop, press CTRL + SHIFT + RIGHT CLICK",
menuCreateExit = "To exit and cancel all changes, press CTRL + SHIFT + ALT",
menuEditTitle = "Infestation Edit Mode - Edit Infestation",
menuEditRemove = "To completely remove the target infestation zone, press CTRL + SHIFT + RIGHT CLICK",
menuEditExit = "To exit and cancel all changes, press CTRL + SHIFT + ALT",
cmdInfestationEdit = "Enter the Infestation Edit mode.",
noPetFlags = "The Infestation Edit mode requires the use of PET flags; which you don't have!",
invalidZone = "That is not a valid infestation zone!",
invalidInfestationProp = "That is not a valid infestation prop!",
zoneRemoved = "Infestation zone removed.",
zoneCreated = "\"%s\" Infestation Zone created successfully.",
viviralItemName = "Anti-Xenian Viviral",
viviralItemDesc = "A synthesized virus created specifically to target Xenian-cell structures. This is an extremely formidable tool against Xenian infestations but exposure to humans is near-fatal as total organ shutdown will occur within two minutes. In order to ensure an outbreak does not occur, the virus dies three minutes outside of its special storage.",
thermoradioItemName = "Thermo-Radioactive Solution",
thermoradioItemDesc = "The complete popular opposite of Cryogenic Solution using both a mixture of creating the effect of EXTREME heat and a touch of radioactive chemicals to create the ultimate but highly dangerous and deadly solution to the Thanarok Strain. Standing in zones cleansed with this solution can lead to radiation posioning depending on the amount used, death if sprayed directly on you or consumed.",
causticItemName = "Caustic Solution",
causticItemDesc = "A very dangerous amalgamation of different corrosive chemical compounds used to melt down Xenian infestations. Operate with care as exposure can cause the quick melting of skin, muscle, and bone.",
cryogenicItemname = "Cryogenic Liquid",
cryogenicItemDesc = "A synthesized liquefied gas of very low temperatures capable of instantly freezing anything that it touches within seconds. Exposure will result in severe frostbite in a matter of seconds.",
hydrocarbonItemName = "Hydrocarbon Foam",
hydrocarbonItemDesc = "A potent cocktail of sensitive chemicals and hydrocarbons made to exterminate pesky Xenian growths and infestations by the extremely fast-heating foam. Handle with caution as exposure can result in severe burns.",
coarctateItemName = "Coarctate Mucus",
coarctateItemDesc = "A rather sticky and strong smelling mucus like fluid. To the trained eye, it seems to have some medical applications.",
itemCrafted = "This item can be created with the Crafting Skill.",
itemSus = "CPs will view you as suspicious if found with this item.",
itemHarvestedCrafted = "This item can be harvested from Infestation Growths and can be used with the Crafting Skill.",
erebusItemName = "Erebus Mucus",
erebusItemDesc = "A slippery, sticky, and stringy green fluid substance of a great many uses, contained in a large plastic jar.",
applicatorItemName = "Foam Applicator",
applicatorItemDesc = "A large weapon-like tool designed to convert substances into foam and spread them over an area.",
clusterItemName = "Cluster-Hive",
clusterItemDesc = "A faint orange cluster of honeycomb-like structures. They have a very dry texture to them.",
hoseItemName = "Orange Hose",
hoseItemDesc = "A large orange hose. It has two connection ports on either end.",
nososItemName = "Nosos Heart",
nososItemDesc = "An extremely veiny silk-like orb that appears to be still functioning due to its gently yet constant movements.",
itemHarvestedHeadcrab = "This item can be harvested from a live Headcrab.",
tankItemName = "Infestation Control Tank",
tankItemDesc = "A large Infestation Control Tank. How can you even carry this?!",
thanatosItemName = "Thanatos Embryo",
thanatosItemDesc = "A thick stack protects and engulfs an unknown living entity inside.",
thanarokItemName = "Thanarok Embryo",
thanarokItemDesc = "An almost impossible to destroy substance hides inside a very think layer of Xenian Flesh, hardened by many layers of protective materials.",
itemHarvested = "This item can be harvested from Infestation Growths.",
detectorItemName = "Infestation Detector",
detectorItemDesc = "A yellow infestation detector. It displays a reading at the front."
}

View File

@@ -0,0 +1,48 @@
--[[
| 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/
--]]
ix.infestation = ix.infestation or {}
ix.infestation.stored = ix.infestation.stored or {}
ix.infestation.types = {}
function ix.infestation.LoadFromDir(path)
for _, v in ipairs(file.Find(path .. "/*.lua", "LUA")) do
local niceName = v:sub(4, -5)
ix.infestation.RegisterInfestationType(niceName, path .. "/" .. v, false, nil)
end
end
function ix.infestation.RegisterInfestationType(uniqueID, path, luaGenerated, infestationTable)
INFESTATION = {index = table.Count(ix.infestation.types) + 1}
if (!luaGenerated and path) then
ix.util.Include(path, "shared")
elseif (luaGenerated and infestationTable) then
table.Merge(INFESTATION, infestationTable)
end
INFESTATION.name = INFESTATION.name or "Unknown"
INFESTATION.color = INFESTATION.color or Color(255, 175, 0)
INFESTATION.reading = INFESTATION.reading or {0, 0}
INFESTATION.chemical = INFESTATION.chemical or nil
INFESTATION.uniqueID = INFESTATION.uniqueID or uniqueID
ix.infestation.types[INFESTATION.uniqueID] = INFESTATION
INFESTATION = nil
end
function ix.infestation.Get(identifier)
return ix.infestation.types[identifier]
end
hook.Add("DoPluginIncludes", "ixInfestation", function(path, pluginTable)
ix.infestation.LoadFromDir(path .. "/infestations")
end)

View File

@@ -0,0 +1,43 @@
--[[
| 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 playerMeta = FindMetaTable("Player")
local protectiveItems = {
["yellow_hazmat_uniform"] = true,
["orange_hazmat_uniform"] = true,
["white_hazmat_uniform"] = true,
["hands_gloves"] = true
}
local protectedFactions = {
[FACTION_VORT] = true,
[FACTION_CP] = true,
[FACTION_HEADCRAB] = true,
[FACTION_OTA] = true,
}
function playerMeta:IsInfestationProtected()
local items = self:GetCharacter():GetInventory():GetItems()
if (self:HasActiveCombineSuit()) then return true end
if (protectedFactions[self:Team()]) then return true end
for _, v in pairs(items) do
local itemTable = ix.item.instances[v.id]
if (itemTable:GetData("equip") and protectiveItems[itemTable.uniqueID]) then
return true
end
end
return false
end

View File

@@ -0,0 +1,124 @@
--[[
| 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/
--]]
function PLUGIN:GenerateRecipes() -- Make sure crafting is initialized before we try to add recipes.
local RECIPE = ix.recipe:New()
RECIPE.uniqueID = "rec_leech_adhesive"
RECIPE.name = "Sülük Bazlı Yapıştırıcı"
RECIPE.description = "Nesneleri birbirine yapıştırmak için kullanılan bir yapıştırıcı. Çok yapışkan."
RECIPE.model = "models/willardnetworks/props/glue.mdl"
RECIPE.category = "Bileşenler"
RECIPE.ingredients = {["ic_erebus_mucus"] = 1, ["ing_raw_leech"] = 3}
RECIPE.result = {["comp_adhesive"] = 1}
RECIPE.hidden = false
RECIPE.skill = "crafting"
RECIPE.level = 0
RECIPE.experience = {
{level = 0, exp = 120}, -- full xp
{level = 10, exp = 60}, -- half xp
{level = 15, exp = 0} -- no xp
}
RECIPE:Register()
RECIPE = ix.recipe:New()
RECIPE.uniqueID = "rec_coarctate_mucus"
RECIPE.name = "Koarktat Mukus"
RECIPE.description = "Oldukça yapışkan ve güçlü kokulu mukus benzeri bir sıvı. Eğitimli bir göz için, bazı ilaç uygulamaları var gibi görünüyor"
RECIPE.model = "models/jq/hlvr/props/xenpack/xen_bulb002.mdl"
RECIPE.category = "Tıbbi"
RECIPE.ingredients = {["ic_erebus_mucus"] = 1, ["ic_cluster_hive"] = 1}
RECIPE.result = {["ic_coarctate_mucus"] = 1}
RECIPE.hidden = false
RECIPE.skill = "crafting"
RECIPE.level = 0
RECIPE.experience = {
{level = 0, exp = 120}, -- full xp
{level = 10, exp = 60}, -- half xp
{level = 15, exp = 0} -- no xp
}
RECIPE:Register()
RECIPE = ix.recipe:New()
RECIPE.uniqueID = "break_mucus_alcohol"
RECIPE.name = "Erebus Mukus Ekstratı"
RECIPE.description = "Erebus Mukusundan alkolü çıkarın."
RECIPE.model = "models/props_lab/jar01a.mdl"
RECIPE.category = "Alkol/kimyasal özütleme"
RECIPE.subcategory = "Alkol"
RECIPE.station = {"tool_oven", "tool_oven_rusty"}
RECIPE.ingredients = {["ic_erebus_mucus"] = 1, ["crafting_water"] = 1}
RECIPE.result = {["comp_alcohol"] = 1}
RECIPE.hidden = false
RECIPE.skill = "medicine"
RECIPE.level = 0
RECIPE.experience = {
{level = 0, exp = 120}, -- full xp
{level = 10, exp = 60}, -- half xp
{level = 15, exp = 0} -- no xp
}
RECIPE:Register()
RECIPE = ix.recipe:New()
RECIPE.uniqueID = "rec_strong_adhesive"
RECIPE.name = "Güçlü Yapıştırıcı"
RECIPE.description = "Nesneleri birbirine yapıştırmak için daha güçlü bir yapıştırıcı. Çok yapışkan."
RECIPE.model = "models/willardnetworks/props/spicyglue.mdl"
RECIPE.category = "Bileşenler"
RECIPE.ingredients = {["comp_adhesive"] = 1, ["ic_cluster_hive"] = 1}
RECIPE.result = {["comp_adhesive"] = 1}
RECIPE.hidden = false
RECIPE.skill = "crafting"
RECIPE.level = 0
RECIPE.experience = {
{level = 0, exp = 120}, -- full xp
{level = 10, exp = 60}, -- half xp
{level = 15, exp = 0} -- no xp
}
RECIPE:Register()
RECIPE = ix.recipe:New()
RECIPE.uniqueID = "break_cluster_mucus_chemical"
RECIPE.name = "Küme Kovanı/Erebus Mukusu Ekstratı"
RECIPE.description = "Bu iki yabancı maddeden rafine edilmemiş kimyasal bileşikler elde edin."
RECIPE.model = "models/jq/hlvr/props/xenpack/xen_bulb002.mdl"
RECIPE.category = "Alkol/kimyasal özütleme"
RECIPE.subcategory = "Rafine Edilmemiş Kimyasallar"
RECIPE.station = {"tool_oven", "tool_oven_rusty"}
RECIPE.ingredients = {["ic_erebus_mucus"] = 1, ["ic_cluster_hive"] = 1}
RECIPE.result = {["comp_chemicals"] = 2}
RECIPE.hidden = false
RECIPE.skill = "medicine"
RECIPE.level = 0
RECIPE.experience = {
{level = 0, exp = 120}, -- full xp
{level = 10, exp = 60}, -- half xp
{level = 15, exp = 0} -- no xp
}
RECIPE:Register()
RECIPE = ix.recipe:New()
RECIPE.uniqueID = "rec_comp_purifier_cluster"
RECIPE.name = "Arıtıcı"
RECIPE.description = "Herhangi bir karışımı veya maddeyi herhangi bir toksik bileşikten arındırabilen garip toz."
RECIPE.model = "models/willardnetworks/skills/pill_bottle.mdl"
RECIPE.category = "Bileşenler"
RECIPE.ingredients = {["ic_cluster_hive"] = 1, ["comp_chemicals"] = 1}
RECIPE.result = {["comp_purifier"] = 1}
RECIPE.hidden = false
RECIPE.skill = "crafting"
RECIPE.level = 0
RECIPE.experience = {
{level = 0, exp = 120}, -- full xp
{level = 10, exp = 60}, -- half xp
{level = 15, exp = 0} -- no xp
}
RECIPE:Register()
end

View File

@@ -0,0 +1,101 @@
--[[
| 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/
--]]
PLUGIN.name = "Infestation Control"
PLUGIN.author = "Aspect™"
PLUGIN.description = "Adds a comprehensive Infestation Control system."
ix.util.Include("cl_hooks.lua")
ix.util.Include("cl_plugin.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_plugin.lua")
ix.util.Include("meta/sh_player.lua")
ix.util.IncludeDir("darkrp/plugins/infestationcontrol/recipes", true)
ix.container.Register("models/hlvr/combine_hazardprops/combinehazardprops_crate.mdl", {
name = "Enfekte Kontrolü Kutusu",
description = "Sarı bir Enfekte Kontrolü kutusu.",
width = 7,
height = 7
})
ix.container.Register("models/hlvr/combine_hazardprops/combinehazardprops_container.mdl", {
name = "Enfekte Kontrolü Konteyneri",
description = "Sarı bir Enfekte Kontrolü konteyneri.",
width = 6,
height = 4
})
ix.container.Register("models/hlvr/combine_hazardprops/combinehazardprops_barrel.mdl", {
name = "Enfekte Kontrolü Varili",
description = "Sarı bir Enfekte Kontrolü varili.",
width = 4,
height = 6
})
ix.container.Register("models/hlvr/combine_hazardprops/combinehazardprops_barrel_lock.mdl", {
name = "Kilitli Enfekte Kontrolü Varili",
description = "Kilitli sarı bir Enfekte Kontrolü varili.",
width = 4,
height = 6
})
do
local COMMAND = {}
COMMAND.description = "@cmdInfestationEdit"
COMMAND.adminOnly = true
function COMMAND:OnRun(client)
if (!client:GetCharacter():HasFlags("pet")) then
return "@noPetFlags"
end
client:SetNetVar("InfestationEditMode", 0)
ix.log.Add(client, "infestationLog", client:GetName() .. " (" .. client:SteamID() .. ") " .. " has entered Infestation Edit Mode.")
end
ix.command.Add("InfestationEdit", COMMAND)
end
function PLUGIN:InitializedPlugins()
-- Generate medical items - need the medical base to be initialized first before creating them.
local ITEM = ix.item.Register("ic_coarctate_mucus", "base_medical", false, nil, true)
ITEM.name = "coarctateItemName"
ITEM.description = "coarctateItemDesc"
ITEM.model = Model("models/jq/hlvr/props/xenpack/xen_bulb002.mdl")
ITEM.width = 1
ITEM.height = 1
ITEM.category = "Infestation Control"
ITEM.colorAppendix = {
["blue"] = "itemCrafted",
["red"] = "itemSus"
}
ITEM.healing = {
painkillers = 20
}
ITEM = ix.item.Register("ic_erebus_mucus", "base_medical", false, nil, true)
ITEM.name = "erebusItemName"
ITEM.description = "erebusItemDesc"
ITEM.model = Model("models/props_lab/jar01a.mdl")
ITEM.width = 1
ITEM.height = 1
ITEM.category = "Infestation Control"
ITEM.colorAppendix = {
["blue"] = "itemHarvestedCrafted",
["red"] = "itemSus"
}
ITEM.healing = {
painkillers = 10
}
self:GenerateRecipes()
end

View File

@@ -0,0 +1,253 @@
--[[
| 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/
--]]
function PLUGIN:PlayerSpawnedProp(client, model, entity)
if (!client:GetNetVar("InfestationEditMode") or client:GetNetVar("InfestationEditMode") == 0) then return end
if (client:GetNetVar("InfestationEditMode") == 1) then
elseif (client:GetNetVar("InfestationEditMode") == 2) then
end
entity:SetNetVar("infestationProp", client:SteamID())
end
function PLUGIN:RegisterSaveEnts()
ix.saveEnts:RegisterEntity("ix_infestation_prop", true, true, true, {
OnSave = function(entity, data) --OnSave
data.model = entity:GetModel()
data.harvested = entity:GetHarvested()
data.infestation = entity:GetInfestation()
data.type = entity:GetType()
data.core = entity:GetCore()
data.sprayed = entity:GetSprayed()
end,
OnRestore = function(entity, data) --OnRestore
entity:SetModel(data.model)
entity:SetHarvested(data.harvested)
entity:SetInfestation(data.infestation)
entity:SetType(data.type)
entity:SetCore(data.core)
entity:SetColor(data.harvested and Color(127, 127, 127) or Color(255, 255, 255))
entity:SetSprayed(false)
end,
ShouldSave = function(entity) --ShouldSave
if (entity:GetSprayed() or !entity:GetInfestation() or !ix.infestation.stored[entity:GetInfestation()]) then
ix.saveEnts:DeleteEntity(entity)
return false
end
return true
end,
ShouldRestore = function(data) --ShouldRestore
return !data.sprayed, true
end
})
ix.saveEnts:RegisterEntity("ix_infestation_tank", true, true, true, {
OnSave = function(entity, data) --OnSave
data.chemVolume = entity:GetChemicalVolume()
data.chemType = entity:GetChemicalType()
data.hoseAttached = entity:GetHoseAttached()
data.applicatorAttached = entity:GetApplicatorAttached()
data.hoseConnected = entity:GetHoseConnected()
end,
OnRestore = function(entity, data) --OnRestore
entity:SetChemicalVolume(data.chemVolume)
entity:SetChemicalType(data.chemType)
entity:SetHoseAttached(data.hoseAttached)
entity:SetApplicatorAttached(data.applicatorAttached)
entity:SetHoseConnected(false)
entity:SetColor(data.color)
entity:Spawn()
entity:SetBodygroup(entity:FindBodygroupByName("Hose"), data.hoseAttached and 0 or 1)
entity:SetBodygroup(entity:FindBodygroupByName("Applicator"), data.applicatorAttached and 0 or 1)
end
})
end
function PLUGIN:SaveData()
ix.data.Set("infestationZones", ix.infestation.stored)
self:SaveInfestationProps()
self:SaveInfestationTanks()
end
function PLUGIN:LoadData()
local data = ix.data.Get("infestationZones", {})
ix.infestation.stored = data
for name, data in pairs(data) do
self:InfestationTimer(name, data.spread)
end
if (!ix.config.Get("SaveEntsOldLoadingEnabled")) then return end
for _, data in ipairs(ix.data.Get("infestationProps", {})) do
if (data.sprayed) then continue end
if (!data.infestation or !ix.infestation.stored[data.infestation]) then continue end
local entity = ents.Create("ix_infestation_prop")
entity:SetModel(data.model)
entity:SetPos(data.position)
entity:SetAngles(data.angles)
entity:SetHarvested(data.harvested)
entity:SetInfestation(data.infestation)
entity:SetType(data.type)
entity:SetCore(data.core)
entity:SetSprayed(false)
entity:SetColor(data.harvested and Color(127, 127, 127) or Color(255, 255, 255))
entity:Spawn()
end
for _, data in ipairs(ix.data.Get("infestationTanks", {})) do
local entity = ents.Create("ix_infestation_tank")
entity:SetPos(data.position)
entity:SetAngles(data.angles)
entity:SetChemicalVolume(data.chemVolume)
entity:SetChemicalType(data.chemType)
entity:SetHoseAttached(data.hoseAttached)
entity:SetApplicatorAttached(data.applicatorAttached)
entity:SetHoseConnected(false)
entity:SetColor(data.color)
entity:Spawn()
entity:SetBodygroup(entity:FindBodygroupByName("Hose"), data.hoseAttached and 0 or 1)
entity:SetBodygroup(entity:FindBodygroupByName("Applicator"), data.applicatorAttached and 0 or 1)
end
end
function PLUGIN:PlayerInitialSpawn(client)
net.Start("ixInfestationZoneNetwork")
net.WriteTable(ix.infestation.stored)
net.Send(client)
end
function PLUGIN:KeyPress(client, key)
local editMode = client:GetNetVar("InfestationEditMode")
if (!editMode) then return end
if (client:KeyDown(IN_DUCK) and client:KeyDown(IN_SPEED)) then
local desiredEditMode = false
if (editMode == 0) then -- Main menu.
if (client:KeyDown(IN_ATTACK)) then -- Create a new infestation zone.
desiredEditMode = 1
elseif (client:KeyDown(IN_ATTACK2)) then -- Edit an existing infestation zone.
local entity = client:GetEyeTraceNoCursor().Entity
if (entity and IsValid(entity) and entity:GetClass() == "ix_infestation_prop") then
desiredEditMode = 2
client:SetNetVar("InfestationEditName", entity:GetInfestation())
else
client:NotifyLocalized("invalidZone")
end
elseif (client:KeyDown(IN_WALK)) then -- Exit infestation edit mode.
desiredEditMode = nil
ix.log.Add(client, "infestationLog", client:GetName() .. " (" .. client:SteamID() .. ") has exited Infestation Edit Mode.")
end
elseif (editMode == 1) then -- Create infestation zone.
if (client:KeyDown(IN_ATTACK)) then -- Create a new infestation zone.
for _, prop in pairs(ents.FindByClass("prop_physics")) do
if (prop:GetNetVar("infestationProp") and prop:GetNetVar("infestationProp") == client:SteamID()) then
local physicsObject = prop:GetPhysicsObject()
if (IsValid(physicsObject)) then
physicsObject:EnableMotion(false)
end
end
end
net.Start("ixInfestationZoneCreate")
net.Send(client)
elseif (client:KeyDown(IN_ATTACK2)) then -- Define core prop.
local entity = client:GetEyeTraceNoCursor().Entity
if (entity and IsValid(entity) and entity:GetNetVar("infestationProp") and entity:GetNetVar("infestationProp") == client:SteamID()) then
for _, prop in pairs(ents.FindByClass("prop_physics")) do
if (prop and IsValid(prop) and prop:GetNetVar("infestationProp") and prop:GetNetVar("infestationProp") == client:SteamID() and prop:GetNetVar("infestationCore")) then
prop:SetNetVar("infestationCore", nil)
end
end
entity:SetNetVar("infestationCore", true)
else
client:NotifyLocalized("invalidInfestationProp")
end
elseif (client:KeyDown(IN_WALK)) then -- Go back to menu.
desiredEditMode = 0
for _, prop in pairs(ents.FindByClass("prop_physics")) do
if (prop:GetNetVar("infestationProp") and prop:GetNetVar("infestationProp") == client:SteamID()) then
prop:Remove()
end
end
end
elseif (editMode == 2) then -- Edit infestation zone.
if (client:KeyDown(IN_ATTACK)) then -- Save changes & open menu.
-- To be added. Maybe.
elseif (client:KeyDown(IN_ATTACK2)) then -- Remove infestation zone.
local targetInfestation = client:GetNetVar("InfestationEditName")
self:UpdateInfestation(targetInfestation, nil)
for _, entity in ipairs(ents.FindByClass("ix_infestation_prop")) do
if (entity:GetInfestation() == targetInfestation) then
entity:Remove()
end
end
self:SaveInfestationProps()
desiredEditMode = 0
client:NotifyLocalized("zoneRemoved")
ix.log.Add(client, "infestationLog", client:GetName() .. " (" .. client:SteamID() .. ") removed the \"" .. targetInfestation .. "\" Infestation Zone.")
elseif (client:KeyDown(IN_WALK)) then -- Go back to menu.
desiredEditMode = 0
for _, prop in pairs(ents.FindByClass("prop_physics")) do
if (prop:GetNetVar("infestationProp") and prop:GetNetVar("infestationProp") == client:SteamID()) then
prop:Remove()
end
end
end
end
if (desiredEditMode != false) then
client:SetNetVar("InfestationEditMode", desiredEditMode) -- Doing it this way purely to make the code a bit easier to read.
end
end
end
function PLUGIN:EntityTakeDamage(entity, damageInfo)
local client = damageInfo:GetAttacker()
if ((entity:GetClass() == "npc_headcrab" or entity:GetClass() == "npc_headcrab_black" or entity:GetClass() == "npc_headcrab_fast")
and (damageInfo:GetDamageType() == DMG_SLASH or (IsValid(client) and client:IsPlayer() and client:IsVortigaunt() and client:GetActiveWeapon() and IsValid(client:GetActiveWeapon()) and client:GetActiveWeapon():GetClass() == "ix_hands"))
and !entity:GetNetVar("heartHarvested")
and math.random(0, 10) > 8) then -- I hate this
if (!client:GetCharacter():GetInventory():Add("ing_headcrab_meat")) then
ix.item.Spawn("ing_headcrab_meat", client)
end
if (!entity or !IsValid(entity)) then return end
entity:Kill()
end
end

View File

@@ -0,0 +1,197 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PLUGIN = PLUGIN
util.AddNetworkString("ixInfestationZoneCreate")
util.AddNetworkString("ixInfestationZoneNetwork")
ix.log.AddType("infestationLog", function(_, log)
return "[INFESTATION] " .. log
end, FLAG_WARNING)
net.Receive("ixInfestationZoneCreate", function(length, client)
local name = net.ReadString()
local type = net.ReadString()
local spread = net.ReadFloat()
local infestationInfo = {
type = type,
spread = spread,
spreadProgress = 1,
entities = {},
paused = false
}
local corePos = Vector(0, 0, 0)
local infestationProps = {}
for _, entity in pairs(ents.FindByClass("prop_physics")) do
if (!entity:GetNetVar("infestationProp") or entity:GetNetVar("infestationProp") != client:SteamID()) then continue end
local entInfo = {
model = entity:GetModel(),
position = entity:GetPos(),
angles = entity:GetAngles(),
harvested = false,
core = false
}
if (entity:GetNetVar("infestationCore")) then
entInfo.core = true
corePos = entity:GetPos()
end
infestationProps[#infestationProps + 1] = entInfo
if (entity:GetNetVar("infestationCore")) then
local infestationCore = ents.Create("ix_infestation_prop")
infestationCore:SetModel(entity:GetModel())
infestationCore:SetPos(entity:GetPos())
infestationCore:SetAngles(entity:GetAngles())
infestationCore:SetHarvested(false)
infestationCore:SetInfestation(name)
infestationCore:SetType(type)
infestationCore:SetCore(true)
infestationCore:SetSprayed(false)
infestationCore:Spawn()
ix.saveEnts:SaveEntity(infestationCore)
end
entity:Remove()
end
table.sort(infestationProps, function(a, b)
return a.position:Distance(corePos) < b.position:Distance(corePos) -- Sort by closest to furthest.
end)
infestationInfo.entities = infestationProps
PLUGIN:UpdateInfestation(name, infestationInfo)
PLUGIN:InfestationTimer(name, spread)
client:SetNetVar("InfestationEditMode", 0)
client:NotifyLocalized("zoneCreated", name)
ix.log.Add(client, "infestationLog", client:GetName() .. " (" .. client:SteamID() .. ") created a new " .. type .. "-Class \"" .. name .. "\" Infestation Zone.")
end)
function PLUGIN:SpreadInfestation(identification)
local infestationInfo = ix.infestation.stored[identification]
if (!infestationInfo) then
if (timer.Exists("infestation_" .. identification .. "_timer")) then
timer.Remove("infestation_" .. identification .. "_timer")
return
end
end
if (infestationInfo.paused) then
if (timer.Exists("infestation_" .. identification .. "_timer")) then
timer.Remove("infestation_" .. identification .. "_timer")
end
return
end
local entityInfo = infestationInfo.entities[infestationInfo.spreadProgress + 1]
if (!entityInfo) then
infestationInfo.paused = true
self:UpdateInfestation(identification, infestationInfo)
return
end
local infestationProp = ents.Create("ix_infestation_prop")
infestationProp:SetModel(entityInfo.model)
infestationProp:SetPos(entityInfo.position)
infestationProp:SetAngles(entityInfo.angles)
infestationProp:SetHarvested(entityInfo.harvested)
infestationProp:SetInfestation(identification)
infestationProp:SetType(infestationInfo.type)
infestationProp:SetCore(entityInfo.core)
infestationProp:SetSprayed(false)
infestationProp:Spawn()
ix.saveEnts:SaveEntity(infestationProp)
infestationInfo.spreadProgress = infestationInfo.spreadProgress + 1
if (infestationInfo.spreadProgress >= #infestationInfo.entities) then
infestationInfo.paused = true
end
self:UpdateInfestation(identification, infestationInfo)
end
function PLUGIN:SaveInfestationProps()
local infestationProps = {}
for _, prop in ipairs(ents.FindByClass("ix_infestation_prop")) do
infestationProps[#infestationProps + 1] = {
model = prop:GetModel(),
position = prop:GetPos(),
angles = prop:GetAngles(),
harvested = prop:GetHarvested(),
infestation = prop:GetInfestation(),
type = prop:GetType(),
core = prop:GetCore(),
sprayed = prop:GetSprayed()
}
end
ix.data.Set("infestationProps", infestationProps)
end
function PLUGIN:UpdateInfestation(identification, data)
ix.infestation.stored[identification] = data
ix.data.Set("infestationZones", ix.infestation.stored)
net.Start("ixInfestationZoneNetwork")
net.WriteTable(ix.infestation.stored)
net.Broadcast()
ix.saveEnts:SaveClass("ix_infestation_prop")
self:SaveInfestationProps()
end
function PLUGIN:InfestationTimer(identification, time)
if (timer.Exists("infestation_" .. identification .. "_timer")) then
timer.Adjust("infestation_" .. identification .. "_timer", time, 0, function()
self:SpreadInfestation(identification)
end)
else
timer.Create("infestation_" .. identification .. "_timer", time, 0, function()
self:SpreadInfestation(identification)
end)
end
end
function PLUGIN:SaveInfestationTanks()
local data = {}
for _, tank in ipairs(ents.FindByClass("ix_infestation_tank")) do
data[#data + 1] = {
position = tank:GetPos(),
angles = tank:GetAngles(),
chemVolume = tank:GetChemicalVolume(),
chemType = tank:GetChemicalType(),
hoseAttached = tank:GetHoseAttached(),
applicatorAttached = tank:GetApplicatorAttached(),
hoseConnected = tank:GetHoseConnected(),
color = tank:GetColor()
}
end
ix.data.Set("infestationTanks", data)
end