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

View File

@@ -0,0 +1,233 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PANEL = {}
AccessorFunc(PANEL, "actionType", "ActionType")
AccessorFunc(PANEL, "lootableEntity", "LootableEntity")
function PANEL:Init()
if (IsValid(ix.gui.interactable)) then
ix.gui.interactable:Remove()
end
self:SetSize(SScaleMin(550 / 3), SScaleMin(100 / 3))
self:Center()
ix.gui.interactable = self
local topbar = self:Add("Panel")
topbar:SetSize(self:GetWide(), SScaleMin(50 / 3))
topbar:Dock(TOP)
topbar.Paint = function( this, w, h )
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, w, h)
end
local titleText = topbar:Add("DLabel")
titleText:SetFont("CharCreationBoldTitleNoClamp")
titleText:Dock(LEFT)
titleText:SetText("OPTIONS DE CAISSE")
titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
titleText:SetContentAlignment(4)
titleText:SizeToContents()
local exit = topbar:Add("DImageButton")
exit:SetImage("willardnetworks/tabmenu/navicons/exit.png")
exit:SetSize(SScaleMin(20 / 3), SScaleMin(20 / 3))
exit:DockMargin(0, SScaleMin(15 / 3), SScaleMin(10 / 3), SScaleMin(15 / 3))
exit:Dock(RIGHT)
exit.DoClick = function()
self:Remove()
surface.PlaySound("helix/ui/press.wav")
end
local buttonBox = self:Add("Panel")
buttonBox:Dock(TOP)
buttonBox:SetTall(SScaleMin(50 / 3))
self.optionLeft = buttonBox:Add("ixInteractButton")
self.optionLeft:Dock(LEFT)
self.optionLeft:SetWide(self:GetWide() / 3)
self.optionRight = buttonBox:Add("ixInteractButton")
self.optionRight:Dock(LEFT)
self.optionRight:SetWide(self:GetWide() / 3)
self.optionDown = buttonBox:Add("ixInteractButton")
self.optionDown:Dock(LEFT)
self.optionDown:SetWide(self:GetWide() / 3)
self:MakePopup()
end
function PANEL:UpdateButtons()
local character = LocalPlayer():GetCharacter()
local inv = character:GetInventory()
if self:GetActionType() == 1 then
self.optionLeft:SetText("ENFREINDRE")
self.optionLeft.DoClick = function()
if not ix.loot:IsHavingTool(inv) then return LocalPlayer():Notify("You don't have any tools for it.") end
netstream.Start("ixLootProceed", {tool = ix.loot:IsHavingTool(inv), act = self:GetActionType(), ent = self:GetLootableEntity(), tpy = 1})
self:Remove()
end
self.optionLeft:SetHelixTooltip(function(tooltip)
local lockpick = tooltip:AddRow("lockpick")
lockpick:SetText("Briser avec des outils")
lockpick:SizeToContents()
local lockpick2 = tooltip:AddRow("lockpick2")
lockpick2:SetText("Nécessite un outil spécial pour cette action. Violation du conteneur GARANTIE de laisser tomber tout le butin que ce conteneur peut avoir.")
lockpick2:SizeToContents()
if ix.loot:IsHavingTool(inv) then
local lockpick3 = tooltip:AddRow("lockpick3")
lockpick3:SetText("[VOUS AVEZ LES OUTILS POUR CETTE ACTION]")
lockpick3:SizeToContents()
lockpick3:SetBackgroundColor(Color(166, 255, 49))
elseif not ix.loot:IsHavingTool(inv) then
local lockpick3 = tooltip:AddRow("lockpick3")
lockpick3:SetText("[VOUS N'AVEZ PAS D'OUTILS POUR CETTE ACTION]")
lockpick3:SizeToContents()
lockpick3:SetBackgroundColor(Color(255, 73, 49))
end
tooltip:SizeToContents()
end)
self.optionRight:SetText("OUVRIR")
self.optionRight.DoClick = function()
netstream.Start("ixLootProceed", {tool = false, act = self:GetActionType(), ent = self:GetLootableEntity(), tpy = 1})
self:Remove()
end
self.optionRight:SetHelixTooltip(function(tooltip)
local open1 = tooltip:AddRow("open1")
open1:SetText("Caisse ouverte")
open1:SizeToContents()
local open2 = tooltip:AddRow("open2")
open2:SetText("Vous avez la possibilité d'ouvrir ce conteneur, mais N'EST PAS GARANTI d'un butin complet.")
open2:SizeToContents()
tooltip:SizeToContents()
end)
self.optionDown:SetText("OUVERT DE FORCE")
self.optionDown.DoClick = function()
netstream.Start("ixLootProceed", {tool = false, act = self:GetActionType(), ent = self:GetLootableEntity(), tpy = 2})
self:Remove()
end
self.optionDown:SetHelixTooltip(function(tooltip)
local notif1 = tooltip:AddRow("notif1")
notif1:SetText("Ouvrir en utilisant la force")
notif1:SizeToContents()
local notif2 = tooltip:AddRow("notif2")
notif2:SetText("Vous ouvrirez ce conteneur instantanément, mais vous n'aurez pas de butin supplémentaire.")
notif2:SizeToContents()
tooltip:SizeToContents()
end)
elseif self:GetActionType() == 2 then
if IsValid(self.optionRight) then self.optionRight:Remove() end
if IsValid(self.optionLeft) then self.optionLeft:Remove() end
self.optionDown:SetText("ENFREINDRE")
self.optionDown:SetWide(self:GetWide() / 1)
self.optionDown.DoClick = function()
netstream.Start("ixLootProceed", {tool = ix.loot:IsHavingTool(inv), act = self:GetActionType(), ent = self:GetLootableEntity(), tpy = 1})
self:Remove()
end
self.optionDown:SetHelixTooltip(function(tooltip)
local notif1 = tooltip:AddRow("notif1")
notif1:SetText("Enfreindre")
notif1:SizeToContents()
local notif2 = tooltip:AddRow("notif2")
notif2:SetText("Vous ne pouvez ouvrir ce conteneur qu'en le [INFRACTION].")
notif2:SizeToContents()
if ix.loot:IsHavingTool(inv) then
local lockpick3 = tooltip:AddRow("lockpick3")
lockpick3:SetText("[VOUS AVEZ DES OUTILS POUR CETTE ACTION]")
lockpick3:SizeToContents()
lockpick3:SetBackgroundColor(Color(166, 255, 49))
elseif not ix.loot:IsHavingTool(inv) then
local lockpick3 = tooltip:AddRow("lockpick3")
lockpick3:SetText("[VOUS N'AVEZ PAS D'OUTILS POUR CETTE ACTION]")
lockpick3:SizeToContents()
lockpick3:SetBackgroundColor(Color(255, 73, 49))
end
tooltip:SizeToContents()
end)
elseif self:GetActionType() == 3 then
if IsValid(self.optionRight) then self.optionRight:Remove() end
if IsValid(self.optionLeft) then self.optionLeft:Remove() end
self.optionDown:SetText("Utiliser la clé")
self.optionDown:SetWide(self:GetWide() / 1)
self.optionDown.DoClick = function()
if not ix.loot:IsHavingKey(inv, self:GetLootableEntity().lootKey) then return end
netstream.Start("ixLootProceed", {key = self:GetLootableEntity().lootKey, act = self:GetActionType(), ent = self:GetLootableEntity(), tpy = 1})
self:Remove()
end
self.optionDown:SetHelixTooltip(function(tooltip)
local notif1 = tooltip:AddRow("notif1")
notif1:SetText("Clé")
notif1:SizeToContents()
local notif2 = tooltip:AddRow("notif2")
notif2:SetText("Vous ne pouvez ouvrir cette caisse qu'en [UTILISANT] une clé spéciale dessus.")
notif2:SizeToContents()
if ix.loot:IsHavingKey(inv, self:GetLootableEntity().lootKey) then
local lockpick3 = tooltip:AddRow("lockpick3")
lockpick3:SetText("[VOUS AVEZ LA CLE DE CETTE CAISSE]")
lockpick3:SizeToContents()
lockpick3:SetBackgroundColor(Color(166, 255, 49))
elseif not ix.loot:IsHavingKey(inv, self:GetLootableEntity().lootKey) then
local lockpick3 = tooltip:AddRow("lockpick3")
lockpick3:SetText("[VOUS N'AVEZ PAS LA CLE POUR CETTE CAISSE]")
lockpick3:SizeToContents()
lockpick3:SetBackgroundColor(Color(255, 73, 49))
end
tooltip:SizeToContents()
end)
end
end
function PANEL:Think()
self:UpdateButtons()
end
function PANEL:Paint(width, height)
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, width, height)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, width, height)
end
vgui.Register("ixInteractBasic", PANEL, "Panel")
netstream.Hook("IntToggle", function(data)
if !IsValid(ix.gui.interactable) then
vgui.Create("ixInteractBasic")
else
ix.gui.interactable:Remove()
end
end)
netstream.Hook("ixLootInteractStart", function(data)
local action = data.act
local ent = data.ent
if !IsValid(ix.gui.interactable) then
local int = vgui.Create("ixInteractBasic")
int:SetActionType(action)
int:SetLootableEntity(ent)
else
ix.gui.interactable:Remove()
end
end)

View File

@@ -0,0 +1,188 @@
--[[
| 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 blur = Material("pp/blurscreen")
function draw.Blur(panel, amount)
local x, y = panel:LocalToScreen(0, 0)
local scrW, scrH = ScrW(), ScrH()
surface.SetDrawColor(255, 255, 255)
surface.SetMaterial(blur)
for i = 1, 3 do
blur:SetFloat("$blur", (i / 3) * (amount or 6))
blur:Recompute()
render.UpdateScreenEffectTexture()
surface.DrawTexturedRect(x * -1, y * -1, scrW, scrH)
end
end
local function DrawOutlined(w,h)
surface.SetDrawColor( 255, 94, 94)
--surface.DrawLine(w, h, w-w, h)
surface.DrawLine(w-w, h-1, w, h-1)
surface.DrawLine(w-w, h-h, w-w, h)
surface.DrawLine(w-w, h-h, w, h-h)
surface.DrawLine(w-1, h-h, w-1, h)
end
local buttonPadding = ScreenScale(14) * 0.5
local animationTime = 0.5
-- base menu button
DEFINE_BASECLASS("DButton")
local PANEL = {}
AccessorFunc(PANEL, "backgroundColor", "BackgroundColor")
AccessorFunc(PANEL, "backgroundAlpha", "BackgroundAlpha")
function PANEL:Init()
self:SetFont("MenuFontNoClamp")
self:SetTextColor(color_white)
self:SetPaintBackground(false)
self:SetContentAlignment(5)
self:SetTextInset(buttonPadding, 0)
self.padding = {32, 12, 32, 12} -- left, top, right, bottom
self.backgroundColor = Color(0, 0, 0)
self.backgroundAlpha = 128
self.currentBackgroundAlpha = 0
end
function PANEL:GetPadding()
return self.padding
end
function PANEL:SetPadding(left, top, right, bottom)
self.padding = {
left or self.padding[1],
top or self.padding[2],
right or self.padding[3],
bottom or self.padding[4]
}
end
function PANEL:SetText(text, noTranslation)
BaseClass.SetText(self, noTranslation and text:utf8upper() or L(text):utf8upper())
end
function PANEL:SizeToContents()
BaseClass.SizeToContents(self)
local width, height = self:GetSize()
self:SetSize(width + self.padding[1] + self.padding[3], height + self.padding[2] + self.padding[4])
end
--function PANEL:PaintBackground(width, height)
-- surface.SetDrawColor(ColorAlpha(self.backgroundColor, self.currentBackgroundAlpha))
-- surface.DrawRect(0, 0, width, height)
--end
function PANEL:Paint(width, height)
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, width, height)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, width, height)
end
function PANEL:SetTextColorInternal(color)
BaseClass.SetTextColor(self, color)
self:SetFGColor(color)
end
function PANEL:SetTextColor(color)
self:SetTextColorInternal(color)
self.color = color
end
function PANEL:SetDisabled(bValue)
local color = self.color
if (bValue) then
self:SetTextColorInternal(Color(math.max(color.r - 60, 0), math.max(color.g - 60, 0), math.max(color.b - 60, 0)))
else
self:SetTextColorInternal(color)
end
BaseClass.SetDisabled(self, bValue)
end
function PANEL:OnCursorEntered()
if (self:GetDisabled()) then
return
end
local w = self:GetWide()
local h = self:GetTall()
local color = self:GetTextColor()
self:SetTextColorInternal(Color(math.max(color.r - 25, 0), math.max(color.g - 25, 0), math.max(color.b - 25, 0)))
self:CreateAnimation(0.15, {
target = {currentBackgroundAlpha = self.backgroundAlpha}
})
LocalPlayer():EmitSound("Helix.Rollover")
end
function PANEL:OnCursorExited()
if (self:GetDisabled()) then
return
end
if (self.color) then
self:SetTextColor(self.color)
else
self:SetTextColor(color_white)
end
self:CreateAnimation(0.15, {
target = {currentBackgroundAlpha = 0}
})
end
function PANEL:OnMousePressed(code)
if (self:GetDisabled()) then
return
end
if (self.color) then
self:SetTextColor(self.color)
else
self:SetTextColor(ix.config.Get("color"))
end
LocalPlayer():EmitSound("Helix.Press")
if (code == MOUSE_LEFT and self.DoClick) then
self:DoClick(self)
elseif (code == MOUSE_RIGHT and self.DoRightClick) then
self:DoRightClick(self)
end
end
function PANEL:OnMouseReleased(key)
if (self:GetDisabled()) then
return
end
if (self.color) then
self:SetTextColor(self.color)
else
self:SetTextColor(color_white)
end
end
vgui.Register("ixInteractButton", PANEL, "DButton")

View File

@@ -0,0 +1,95 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Advanced Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.models = {"models/wn7new/advcrates/n7_cabinet.mdl", "models/wn7new/advcrates/n7_drawer.mdl", "models/wn7new/advcrates/n7_locker.mdl"}
ENT.acting = 1
ENT.canBeLooted = true
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel(self.models[math.random(1, #self.models)])
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.lootTable = ix.loot.tables["Advanced"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Le serveur n'a pas assez de joueurs pour débloquer le pillage des caisses.")
return
end
if not self.canBeLooted then return activator:Notify("Quelqu'un a déjà pillé ce conteneur !") end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
if not self.canBeLooted then return end
self:ResetSequence("locker_open_seq")
self:SetPlaybackRate(1)
self:EmitSound("items/ammocrate_open.wav")
timer.Simple(2.6, function()
if not IsValid(self) then return end
self:EmitSound("items/ammocrate_close.wav")
self:ResetSequence("locker_close_seq")
self:SetPlaybackRate(1)
end)
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
if #items <= 1 then
self:EmitSound("physics/metal/metal_computer_impact_hard2.wav")
end
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetUp()*20 + self:GetForward()*20 + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Marquer pour destruction " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self.canBeLooted = false
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Conteneur")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] pour intéragir.")
description:SizeToContents()
end
function ENT:Draw()
self:DrawModel()
end
end

View File

@@ -0,0 +1,81 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Ammunition Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.acting = 1
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel("models/Items/item_item_crate.mdl")
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self:PrecacheGibs()
self.lootTable = ix.loot.tables["Ammo"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
//self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Server doesn't have enough players to unblock crate looting.")
return
end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
self:GibBreakServer( self:GetUp() * 100 )
self:EmitSound("physics/wood/wood_plank_break1.wav")
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Mark for destruct " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self:Remove()
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Ammo crate")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] for interaction.")
description:SizeToContents()
end
function ENT:Draw()
self:DrawModel()
end
end

View File

@@ -0,0 +1,81 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Basic Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.acting = 1
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel("models/props_junk/wood_crate001a_damaged.mdl")
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self:PrecacheGibs()
self.lootTable = ix.loot.tables["Basic"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
//self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Le serveur n'a pas assez de joueurs pour débloquer le pillage des caisses.")
return
end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
self:GibBreakServer( self:GetUp() * 100 )
self:EmitSound("physics/wood/wood_plank_break1.wav")
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Marquer pour destruction " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self:Remove()
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Caisse en bois")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] pour intéragir.")
description:SizeToContents()
end
function ENT:Draw()
self:DrawModel()
end
end

View File

@@ -0,0 +1,103 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Combine Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.models = {"models/wn7new/advcrates/n7_crate.mdl"}
ENT.acting = 3
ENT.canBeLooted = true
ENT.lootKey = "cmbkey"
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel(self.models[math.random(1, #self.models)])
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.lootTable = ix.loot.tables["CMB"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Le serveur n'a pas assez de joueurs pour débloquer le pillage des caisses.")
return
end
if not self.canBeLooted then return activator:Notify("Quelqu'un a déjà pillé ce conteneur!") end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
if not self.canBeLooted then return end
self:ResetSequence("locker_open_seq")
self:SetPlaybackRate(1)
self:EmitSound("buttons/button19.wav")
timer.Simple(2.6, function()
if not IsValid(self) then return end
self:EmitSound("items/ammocrate_close.wav")
self:ResetSequence("locker_close_seq")
self:SetPlaybackRate(1)
end)
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
if #items <= 1 then
self:EmitSound("physics/metal/metal_computer_impact_hard2.wav")
end
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetUp()*20 + self:GetForward()*20 + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Marquer pour destruction " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self.canBeLooted = false
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Caisse Combine")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] pour l'interaction.")
description:SizeToContents()
end
local glowMaterial = ix.util.GetMaterial("sprites/glow04_noz")
function ENT:Draw()
self:DrawModel()
if self:GetSequenceName(self:GetSequence()) == "locker_open_seq" then return end
local color = Color(0, 100, 255, 180)
local position = self:GetPos() + self:GetUp() * 12 + self:GetForward() * 13.5
render.SetMaterial(glowMaterial)
render.DrawSprite(position, 10, 10, color)
end
end

View File

@@ -0,0 +1,85 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Loot spawner"
ENT.Category = "WN7"
ENT.Spawnable = false
ENT.bNoPersist = true
ENT.PhysgunDisable = true
if (SERVER) then
function ENT:Initialize()
self:PhysicsInit(SOLID_NONE)
self:SetSolid(SOLID_NONE)
self:SetUseType(SIMPLE_USE)
self:SetModel("models/props_junk/sawblade001a.mdl")
self:DrawShadow( false )
self:SetCollisionGroup(COLLISION_GROUP_WORLD)
self:SetMoveType(MOVETYPE_NONE)
self:SetNoDraw( true )
self.nextSpawn = CurTime()
local phy = self:GetPhysicsObject()
if IsValid(phy) then
phy:Sleep()
end
local id = self:EntIndex()
timer.Create("lootySpawner" .. id, 1, 0, function()
if not IsValid(self) then
timer.Remove("lootySpawner" .. id)
return
end
self:SpawnLoot()
end)
end
function ENT:GetLootEnt()
for k, v in pairs(ix.loot.entities) do
if k == self:GetLootType() then
return v
end
end
end
function ENT:SpawnLoot()
if CurTime() < self.nextSpawn then
return
end
if IsValid(self.loot) then
self.loot:Remove()
end
self:UpdateTimer()
self.loot = ents.Create(self:GetLootEnt())
self.loot:SetPos(self:GetPos() + self:GetUp()*20)
self.loot:SetAngles(self:GetAngles())
self.loot:Spawn()
end
function ENT:UpdateTimer()
self.nextSpawn = CurTime() + (ix.config.Get("lootTimer", 1) * 60)
end
function ENT:Think()
self:NextThink( CurTime() + 2 )
self:SetNetVar("lootSpawn", ix.config.Get("lootTimer", 1))
return true
end
function ENT:OnRemove()
if IsValid(self.loot) then
self.loot:Remove()
end
end
function ENT:SetLootType(type)
self:SetNetVar("lootType", type)
end
function ENT:GetLootType()
return self:GetNetVar("lootType", "Basic")
end
else
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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Infestation Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.models = {"models/wn7new/advcrates/n7_container.mdl"}
ENT.acting = 2
ENT.canBeLooted = true
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel(self.models[math.random(1, #self.models)])
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.lootTable = ix.loot.tables["InfestationControl"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Le serveur n'a pas assez de joueurs pour débloquer le pillage des caisses.")
return
end
if not self.canBeLooted then return activator:Notify("Someone already looted this container!") end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
if not self.canBeLooted then return end
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
self:ResetSequence("locker_open_seq")
self:SetPlaybackRate(1)
self:EmitSound("buttons/button19.wav")
self:EmitSound("buttons/lever2.wav")
local eff = EffectData()
eff:SetOrigin(self:GetPos() + self:GetForward()*15 + self:GetUp()*5)
eff:SetNormal(self:GetForward()*1)
eff:SetAngles(self:GetAngles())
util.Effect("ManhackSparks", eff)
timer.Simple(2.6, function()
if not IsValid(self) then return end
self:EmitSound("buttons/lever6.wav")
self:ResetSequence("locker_close_seq")
self:SetPlaybackRate(1)
end)
if #items <= 1 then
self:EmitSound("physics/metal/metal_computer_impact_hard2.wav")
else
self:EmitSound("items/ammocrate_close.wav")
end
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetUp()*20 + self:GetForward()*20 + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Marquer pour destruction " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self.canBeLooted = false
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Conteneur de contrôle des infestations")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] pour intéragir.")
description:SizeToContents()
end
local glowMaterial = ix.util.GetMaterial("sprites/glow04_noz")
function ENT:Draw()
self:DrawModel()
if self:GetSequenceName(self:GetSequence()) == "locker_open_seq" then return end
local color = Color(255, 238, 0, 180)
local position = self:GetPos() + self:GetUp() * 15 + self:GetForward() * 9.7
render.SetMaterial(glowMaterial)
render.DrawSprite(position, 5, 5, color)
end
end

View File

@@ -0,0 +1,97 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Military Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.models = {"models/wn7new/advcrates/n7_military_crate.mdl"}
ENT.acting = 3
ENT.canBeLooted = true
ENT.lootKey = "militarykey"
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel(self.models[math.random(1, #self.models)])
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.lootTable = ix.loot.tables["Military"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Le serveur n'a pas assez de joueurs pour débloquer le pillage des caisses.")
return
end
if not self.canBeLooted then return activator:Notify("Someone already looted this container!") end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
if not self.canBeLooted then return end
self:ResetSequence("locker_open_seq")
self:SetPlaybackRate(1)
self:EmitSound("buttons/button19.wav")
timer.Simple(2.6, function()
if not IsValid(self) then return end
self:EmitSound("items/ammocrate_close.wav")
self:ResetSequence("locker_close_seq")
self:SetPlaybackRate(1)
end)
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
if #items <= 1 then
self:EmitSound("physics/metal/metal_computer_impact_hard2.wav")
end
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetUp()*20 + self:GetForward()*20 + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Mark for destruct " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self.canBeLooted = false
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Caisse militaire")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] pour intéragir.")
description:SizeToContents()
end
function ENT:Draw()
self:DrawModel()
end
end

View File

@@ -0,0 +1,96 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Supply Container"
ENT.Category = "[WN7] Lootable"
ENT.Spawnable = true
ENT.bNoPersist = true
ENT.AutomaticFrameAdvance = true
ENT.models = {"models/wn7new/advcrates/n7_supply_crate.mdl"}
ENT.acting = 1
ENT.canBeLooted = true
local PLUGIN = PLUGIN
if (SERVER) then
function ENT:Initialize()
self:SetModel(self.models[math.random(1, #self.models)])
self:PhysicsInit(SOLID_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.lootTable = ix.loot.tables["Supply"]
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:Sleep()
physObj:EnableMotion( false )
end
self:DropToFloor()
end
function ENT:Use( activator )
if #player.GetAll() < ix.config.Get("PlayersToLoot", 8) then
activator:Notify("Le serveur n'a pas assez de joueurs pour débloquer le pillage des caisses.")
return
end
if not self.canBeLooted then return activator:Notify("Quelqu'un a déjà pillé ce conteneur !") end
local data = {act = self.acting, ent = self}
netstream.Start(activator, "ixLootInteractStart", data)
end
function ENT:FinalizeLoot(character, shouldChance, noAddLoot)
if not self.canBeLooted then return end
self:ResetSequence("locker_open_seq")
self:SetPlaybackRate(1)
timer.Simple(2.6, function()
if not IsValid(self) then return end
self:EmitSound("items/ammocrate_close.wav")
self:ResetSequence("locker_close_seq")
self:SetPlaybackRate(1)
end)
local items = PLUGIN:CalculateLoot(self.lootTable, shouldChance, noAddLoot)
if #items <= 1 then
self:EmitSound("physics/metal/metal_computer_impact_hard2.wav")
else
self:EmitSound("items/ammocrate_close.wav")
end
for _, item in ipairs(items) do
ix.item.Spawn(item, self:GetPos() + self:GetUp()*20 + self:GetForward()*20 + self:GetRight()*math.random(-20, 20), function(item, ent)
timer.Create("Marquer pour destruction " .. ent:GetCreationID(), ix.config.Get("lootDelete", 10), 1, function()
if ent:IsValid() then
ent:Remove()
end
end)
end)
end
self.canBeLooted = false
end
function ENT:Think()
self:NextThink( CurTime() + 0.1 )
return true
end
else
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText("Conteneur d'approvisionnement")
name:SizeToContents()
local description = container:AddRow("Description")
description:SetText("[E] pour intéragir.")
description:SizeToContents()
end
function ENT:Draw()
self:DrawModel()
end
end

View File

@@ -0,0 +1,23 @@
--[[
| 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 = "Carte-clé pour caisse Combine"
ITEM.model = "models/n7/props/n7_cid_card.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(-11.93, 0.18, 199.64),
ang = Angle(87.17, -0.88, 0),
fov = 5.59
}
ITEM.description = "Ressemble à une carte-clé pouvant ouvrir des caisses du Cartel."
ITEM.category = "Autres"
ITEM.desccolor = Color(183, 149, 11)

View File

@@ -0,0 +1,23 @@
--[[
| 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 = "Carte-clé pour caisse militaire"
ITEM.model = "models/n7/props/n7_cid_card.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(-11.93, 0.18, 199.64),
ang = Angle(87.17, -0.88, 0),
fov = 5.59
}
ITEM.description = "Ressemble à une carte-clé militaire pour ouvrir des caisses."
ITEM.category = "Autres"
ITEM.desccolor = Color(183, 149, 11)

View File

@@ -0,0 +1,187 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PLUGIN = PLUGIN
PLUGIN.name = "Loot System"
PLUGIN.author = "Naast"
PLUGIN.description = "Adds lootable containers with editable loot tables."
ix.loot = ix.loot or {}
ix.loot.LootLockpicks = {"fubar", "crowbar", "sledgehammer"} // tools which is breaching the containers
ix.config.Add("LootChance", 50, "La chance d'obtenir plus d'articles d'une boîte lors de son ouverture. IL n'est PAS utilisé lors de l'ouverture à l'aide d'outils spéciaux.", nil, {
data = {min = 30, max = 100},
category = "Loot"
})
ix.config.Add("PlayersToLoot", 8, "Le nombre de joueurs requis pour pouvoir obtenir le butin des conteneurs.", nil, {
data = {min = 1, max = 30},
category = "Loot"
})
ix.config.Add("lootTimer", 1, "Combien de temps faudra-t-il avant de mettre à jour tous les conteneurs sur la map? (En minutes)", nil, {
data = {min = 1, max = 360},
category = "Loot"
})
ix.config.Add("lootDelete", 15, "Combien de temps faudra-t-il avant de retirer les objets tombés des conteneurs ? (En secondes)", nil, {
data = {min = 5, max = 360},
category = "Loot"
})
ix.command.Add("CreateLootContainerSpawn", {
description = "Crée un point d'apparition de butin.",
adminOnly = true,
arguments = {
ix.type.text
},
OnRun = function(self, client, container)
local curStat
for k, v in pairs(ix.loot.entities) do
if k == container then
curStat = true
client:Notify("Vous avez créé le spawnner.")
break
else
curStat = false
end
end
if not curStat then return client:Notify("Type de conteneur non valide.") end
local spawner = ents.Create("ix_containerspawn")
spawner:SetPos(client:GetEyeTrace().HitPos)
local angles = (client:GetEyeTrace().HitPos - client:GetPos()):Angle()
angles.r = 0
angles.p = 0
angles.y = angles.y + 180
spawner:SetAngles(angles)
spawner:SetLootType(container)
spawner:Spawn()
end
})
ix.command.Add("RemoveLootSpawner", {
description = "Supprime tous les générateurs de butin dans la zone que vous regardez, dans le rayon que vous avez défini.",
adminOnly = true,
arguments = {
ix.type.number
},
OnRun = function(self, client, rangeToFind)
local dlt = 0
for k, v in ipairs(ents.FindInSphere(client:GetEyeTrace().HitPos, rangeToFind)) do
if v:GetClass() == "ix_containerspawn" then
v:Remove()
dlt = dlt + 1
end
end
client:Notify("vous venez de supprimer " .. dlt .. " spawners.")
end
})
ix.loot.entities = {
["Basic"] = "ix_basiccontainer",
["Ammo"] = "ix_ammunitioncontainer",
["Advanced"] = "ix_advancedcontainer",
["InfestationControl"] = "ix_infestationcontainer",
["Supply"] = "ix_supplycontainer",
["Military"] = "ix_militarycontainer",
["CMB"] = "ix_cmbcontainer"
}
ix.loot.tables = {
["Basic"] = {
["Tier_I"] = {"junk_carton", "junk_keyboard", "junk_shoe", "junk_mug", "crafting_water", "junk_jar", "junk_plastic_bucket", "junk_plantpot", "junk_empty_vodka", "junk_computerparts", "junk_brown_bottle", "junk_receiver", "junk_empty_wine", "junk_jug", "junk_takeaway"},
["Tier_II"] = {"comp_metal", "comp_plastic", "comp_wood", "comp_electronics", "comp_cloth", "comp_glass", "comp_nails_screws"},
["Tier_III"] = {"comp_adhesive", "comp_purifier", "comp_stiched_cloth", "comp_refined_plastic", "comp_reshaped_metal", "comp_improved_nails_screws"}
},
["Ammo"] = {
["Tier_I"] = {"bullets_pistol", "magazine_makeshift_15rnd", "magazine_makeshift_8rnd", "magazine_popper_6rnd", "magazine_usp_15rnd", "magazine_fiveseven_20rnd"},
["Tier_II"] = {"bullets_357", "bullets_smg1", "magazine_model870_8rnd", "magazine_mp_30rnd"},
["Tier_III"] = {"bullets_buckshot", "bullets_assaultrifle", "magazine_ak_30rnd", "magazine_556_30rnd"}
},
["Advanced"] = {
["Tier_I"] = {"junk_carton", "junk_keyboard", "junk_shoe", "junk_mug", "crafting_water", "junk_jar", "junk_plastic_bucket", "junk_plantpot", "junk_empty_vodka", "junk_computerparts", "junk_brown_bottle", "junk_receiver", "junk_empty_wine", "junk_jug", "junk_takeaway"},
["Tier_II"] = {"comp_purifier", "comp_stiched_cloth", "comp_adhesive", "comp_refined_plastic", "comp_reshaped_metal", "comp_improved_nails_screws"},
["Tier_III"] = {"comp_refined_metal", "comp_strong_adhesive", "comp_military_electronics", "comp_wooden_craftwork", "comp_fabric", "comp_charcoal", "torso_medical_rebel_uniform"}
},
["InfestationControl"] = {
["Tier_I"] = {"cont_lock_t1", "watervalve", "waterbottle", "infestation_detector", "tool_spoon", "flashlight"},
["Tier_II"] = {"ic_hydrocarbon_foam", "tool_wrench", "tool_knife", "lighter", "hatchet", "comp_syringe", "torso_blue_rebel_uniform", "torso_green_rebel_uniform"},
["Tier_III"] = {"worker_uniform", "torso_labcoat", "ic_caustic_solution", "ic_anti_xenian_viviral", "tool_toolkit"}
},
["Supply"] = {
["Tier_I"] = {"makeshift_bandage", "disinfectant_bottle", "bandage", "basic_red", "basic_yellow", "basic_green", "basic_blue", "disinfected_bandage"},
["Tier_II"] = {"adrenaline", "bloodbag", "bloodstabilizer", "improved_blue", "improved_red", "improved_green", "improved_yellow", "morphine"},
["Tier_III"] = {"surgerykit", "quality_yellow", "quality_green", "quality_red", "quality_blue", "firstaid", "torso_medical_rebel_uniform", "torso_blue_rebel_uniform", "torso_green_rebel_uniform"}
},
["Military"] = {
["Tier_I"] = {"cont_lock_t1", "smallbag", "largebag", "head_military_cap", "flashlight", "flash_grenade", "smoke_grenade", "tool_toolkit", "comp_weapon_parts", "old_radio", "usp", "torso_blue_kevlar", "torso_green_kevlar"},
["Tier_II"] = {"firstaid", "bloodbag", "tool_repair", "lockbreacher", "comp_grenadecase", "comp_explosive", "comp_weapon_parts", "frag_grenade", "flare", "head_helmet", "head_boonie_hat", "head_gasmask2", "fiveseven"},
["Tier_III"] = {"handheld_radio", "incendiary_grenade", "dummy_emp", "highquality_filter", "torso_medical_kevlar", "zippolighter", "comp_charcoal_refill", "mp5a3", "mp7a1", "torso_green_kevlar_t2"}
},
["CMB"] = {
["Tier_I"] = {"smallbag", "cont_lock_t1", "flash_grenade", "flare", "torso_blue_kevlar", "torso_green_kevlar"},
["Tier_II"] = {"largebag", "highquality_filter", "handheld_radio", "frag_grenade", "torso_medical_rebel_uniform", "rappel_gear", "torso_green_kevlar_t2"},
["Tier_III"] = {"comp_weapon_parts", "incendiary_grenade", "dummy_emp", "torso_medical_kevlar", "expo_energycell", "dummy_biolock_ociw"}
},
}
function ix.loot.CheckDist(client, ent)
local dist = ent:GetPos():Distance(client:GetPos())
return dist
end
function ix.loot:IsHavingTool(inv)
for _, tool in ipairs(ix.loot.LootLockpicks) do
if inv:HasItem(tool) then
return inv:HasItem(tool)
end
end
end
function ix.loot:IsHavingKey(inv, key)
if inv:HasItem(key) then
return inv:HasItem(key)
else
return false
end
end
function PLUGIN:ValidateItems(items)
local curStat
for itemCount, item in ipairs(items) do
local toValidate = ix.item.Get(item)
if toValidate == nil or table.IsEmpty(toValidate) then
return false
else
curStat = true
end
end
if curStat then return true end
end
function PLUGIN:CalculateLoot(tbl, noRandom, noAddLoot)
local chance
if noRandom then
chance = 100
else
chance = ix.config.Get("LootChance", 30)
end
if noAddLoot then
chance = 0
end
local itemsToDrop = {}
local tier1, tier2, tier3 = tbl["Tier_I"], tbl["Tier_II"], tbl["Tier_III"]
local allItems = tier1, tier2, tier3
if not tbl then return end
if not self:ValidateItems(allItems) then return error( "ERREUR : Vous avez configuré des items non valides.", 1 ) end
itemsToDrop[#itemsToDrop + 1] = tier1[math.random(1, #tier1)]
if math.random(1, 100) <= chance then
itemsToDrop[#itemsToDrop + 1] = tier2[math.random(1, #tier2)]
itemsToDrop[#itemsToDrop + 1] = tier3[math.random(1, #tier3)]
end
return itemsToDrop
end
ix.util.Include("derma/cl_interact.lua")
ix.util.Include("derma/cl_interactbutton.lua")
ix.util.Include("sv_plugin.lua")

View File

@@ -0,0 +1,104 @@
--[[
| 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/
--]]
netstream.Hook("ixLootProceed", function(client, data)
local ent = data.ent
local action = data.act
local tool = data.tool or false
local key = data.key
local tpy = data.tpy // 1 = default, 2 = without action and additional loot.
local getTool
if tool then
getTool = client:GetCharacter():GetInventory():GetItemByID(tool.id, false)
if (getTool.isTool) then
getTool:DamageDurability(1)
end
end
if action == 1 then
if tpy == 1 then
ent:EmitSound("willardnetworks/inventory/inv_bandage.wav")
client:SetAction("Vous interagissez avec le conteneur.", 3.5, function()
if not ent:IsValid() then return client:Notify("Ce conteneur est vide !") end
if ix.loot.CheckDist(client, ent) <= 200 then
ent:FinalizeLoot(client:GetCharacter(), tool)
else
client:Notify("Tu es trop loin !")
end
end)
elseif tpy == 2 then
ent:FinalizeLoot(client:GetCharacter(), tool, true)
end
elseif action == 2 then
if tpy == 1 then
if not getTool then
return client:Notify("Vous n'avez pas les outils requis.")
end
ent:EmitSound("willardnetworks/inventory/inv_bandage.wav")
client:SetAction("Vous interagissez avec le conteneur.", 3.5, function()
if not ent:IsValid() then return client:Notify("Ce conteneur est vide !") end
if ix.loot.CheckDist(client, ent) <= 200 then
ent:FinalizeLoot(client:GetCharacter(), false)
else
client:Notify("Tu es trop loin !")
end
end)
end
elseif action == 3 then
local getKey = client:GetCharacter():GetInventory():HasItem(key)
if not getKey then
return client:Notify("Vous n'avez pas les clés requises.")
else
getKey:Remove()
end
client:Notify("Vous venez d'utiliser la clé !")
ent:EmitSound("willardnetworks/inventory/inv_bandage.wav")
client:SetAction("Vous interagissez avec le conteneur.", 3.5, function()
if not ent:IsValid() then return client:Notify("Le conteneur a déjà été fouillé par quelqu'un d'autre !") end
if ix.loot.CheckDist(client, ent) <= 200 then
ent:FinalizeLoot(client:GetCharacter(), false)
else
client:Notify("Tu es trop loin !")
end
end)
end
end)
netstream.Hook("ixLootInt", function(client, data)
local action = data.act
local ent = data.ent
netstream.Start(client, "ixLootInteractStart", {act = action, ent = ent})
end)
function PLUGIN:LoadData()
local contSpawns = ix.data.Get("contSpawns")
if contSpawns then
for k, v in pairs(contSpawns) do
local entity = ents.Create("ix_containerspawn")
entity:SetAngles(v[1])
entity:SetPos(v[2])
entity:SetLootType(v[3])
entity:Spawn()
end
end
end
function PLUGIN:SaveData()
local contSpawns = {}
for k, v in pairs(ents.FindByClass("ix_containerspawn")) do
contSpawns[#contSpawns + 1] = {
v:GetAngles(),
v:GetPos(),
v:GetLootType()
}
end
ix.data.Set("contSpawns", contSpawns)
end