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,122 @@
--[[
| 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 smallerIconSize = SScaleMin(16 / 3)
local function firstUpper(str)
return str:gsub("^%l", string.utf8upper)
end
function PLUGIN:PopulateHelpMenu(tabs)
local permitsList = ix.permits.get()
if (permitsList and !table.IsEmpty(permitsList)) then
tabs["Permis"] = function(container)
local permits = table.GetKeys(permitsList)
table.sort(permits)
for _, v in pairs(permits) do
local permitsButton = container:Add("DButton")
permitsButton:Dock(TOP)
permitsButton:SetText(Schema:FirstToUpper(v))
permitsButton:SetFont("TitlesFontNoClamp")
permitsButton:SizeToContents()
permitsButton.Paint = nil
permitsButton:SetContentAlignment(4)
permitsButton.DoClick = function()
LocalPlayer():NotifyLocalized("Permit ID '"..v.."' copied to clipboard")
SetClipboardText( v )
end
end
end
end
end
function PLUGIN:CreateExtraCharacterTabInfo(character, informationSubframe, CreatePart)
-- Permits
local permitsPanel = informationSubframe:Add("Panel")
local permitsData = LocalPlayer():GetCharacter():GetGenericdata().permits
if !istable(permitsData) then
CreatePart(permitsPanel, "Permis :", "Aucun permis", "licenses", true, false, true)
return
end
permitsData = table.GetKeys(LocalPlayer():GetCharacter():GetGenericdata().permits)
for k, v in pairs(permitsData) do
permitsData[k] = firstUpper(v)
end
if !table.IsEmpty(permitsData) then
CreatePart(permitsPanel, "Permis :", table.concat(permitsData, ", "), "licenses", true, false, true)
else
CreatePart(permitsPanel, "Permis :", "Aucun permis", "licenses", true, false, true)
end
end
function PLUGIN:AdjustInnerStatusPanel(innerStatus, CreateTitle, CreateSubBar)
if (ix.special) then
local attributesTitle = innerStatus:Add("DLabel")
CreateTitle(attributesTitle, "ATTRIBUTS")
local character = LocalPlayer():GetCharacter()
for _, v in pairs(ix.special.list) do
local attribute = innerStatus:Add("Panel")
local special = character:GetSpecial(tostring(v.uniqueID))
if v.name == "Force" then
CreateSubBar(attribute, "willardnetworks/tabmenu/inventory/inv_strength.png", v.name, special .. "/10", smallerIconSize, smallerIconSize)
end
if v.name == "Agilité" then
CreateSubBar(attribute, "willardnetworks/tabmenu/inventory/inv_agility.png", v.name, special .. "/10", smallerIconSize, smallerIconSize)
end
if v.name == "Intelligence" then
CreateSubBar(attribute, "willardnetworks/tabmenu/inventory/inv_intelligence.png", v.name, special .. "/10", smallerIconSize, smallerIconSize)
end
if v.name == "Perception" then
CreateSubBar(attribute, "willardnetworks/tabmenu/inventory/inv_perception.png", v.name, special .. "/10", smallerIconSize, smallerIconSize)
end
end
end
if (ix.skill) then
local character = LocalPlayer():GetCharacter()
local skillsTitle = innerStatus:Add("DLabel")
CreateTitle(skillsTitle, "COMPETENCES")
for skillID, skillInfo in pairs(ix.skill.list) do
if (skillInfo.name == "Vortessence" and !LocalPlayer():IsVortigaunt()) or skillInfo.name == "Bartering" then
continue
end
local skillsPanel = innerStatus:Add("Panel")
local level = character:GetSkillLevel(skillID)
CreateSubBar(skillsPanel, "willardnetworks/tabmenu/inventory/inv_" .. skillID .. ".png", skillInfo.name, level .. "/50", smallerIconSize, smallerIconSize)
end
local char = LocalPlayer().GetCharacter and LocalPlayer():GetCharacter()
-- Misc section
local miscTitle = innerStatus:Add("DLabel")
CreateTitle(miscTitle, "MISC")
if char then
local money = char.GetMoney and char:GetMoney() or 0
-- Display the amount of chips the player has
local chipsPanel = innerStatus:Add("Panel")
CreateSubBar(chipsPanel, "willardnetworks/tabmenu/charmenu/chips.png", "Chips", money, smallerIconSize, smallerIconSize)
end
end
end

View File

@@ -0,0 +1,33 @@
--[[
| 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
netstream.Hook("RebuildCrafting", function(data)
PLUGIN.craftingPanel:Rebuild()
end)
netstream.Hook("CraftTime", function(data)
ix.CraftCooldown = data
end)
netstream.Hook("SendMessageListToClient", function(messagelist, storedNewspapers)
LocalPlayer().messagelist = messagelist
local capda = vgui.Create("ixCAPDA")
capda.storedNewspapers = storedNewspapers
capda:CreateNewspaperButton()
end)
-- Called when the local player's crafting is rebuilt.
function PLUGIN:PlayerCraftingRebuilt(panel, categories) end
-- Called when the local player's crafting item should be adjusted.
function PLUGIN:PlayerAdjustCraftingRecipe(recipe) end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,493 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PANEL = {}
local padding = SScaleMin(10 / 3)
function PANEL:Init()
self:SetSize(ScrW(), ScrH())
self:SetAlpha(0)
self:AlphaTo(255, 0.5, 0)
self.Paint = function( self, w, h )
surface.SetDrawColor(Color(63, 58, 115, 220))
surface.DrawRect(0, 0, w, h)
Derma_DrawBackgroundBlur( self, 1 )
end
self.content = self:Add("EditablePanel")
self.content:SetSize(SScaleMin(400 / 3), SScaleMin(600 / 3))
self.content:Center()
self.content:MakePopup()
Schema:AllowMessage(self.content)
self.content.Paint = function(self, w, h)
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, w, h)
end
self.topbar = self.content:Add("Panel")
self.topbar:SetSize(self.content:GetWide(), SScaleMin(50 / 3))
self.topbar:Dock(TOP)
self.topbar.Paint = function( self, w, h )
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, w, h)
end
local titleText = self.topbar:Add("DLabel")
titleText:SetFont("LargerTitlesFontNoClamp")
titleText:Dock(LEFT)
titleText:SetText("UTC")
titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
titleText:SetContentAlignment(4)
titleText:SizeToContents()
local exit = self.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()
LocalPlayer().messagelist = nil
self:Remove()
surface.PlaySound("helix/ui/press.wav")
end
self:CreateInner()
end
local function PaintButton(self, w, h)
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, w, h)
end
function PANEL:CreateBackButton()
local divider = self.topbar:Add("DShape")
divider:SetType("Rect")
divider:Dock(RIGHT)
divider:DockMargin(padding, padding, padding, padding)
divider:SetWide(1)
divider:SetColor(Color(111, 111, 136, (255 / 100 * 30)))
local back = self.topbar:Add("DButton")
back:Dock(RIGHT)
back:SetText("RETOUR")
back:SetFont("TitlesFontNoClamp")
back.Paint = nil
back:SizeToContents()
back.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
self:Remove()
local panel = vgui.Create("ixCAPDA")
panel:SetAlpha(255)
end
end
function PANEL:CreateNewspaperButton()
self.newspapers = self.innerContent:Add("DButton")
self.newspapers:Dock(TOP)
self.newspapers:SetTall(SScaleMin(50 / 3))
self.newspapers:SetText("Journaux")
self.newspapers:SetFont("WNBleedingMinutesBoldNoClamp")
self.newspapers:SetContentAlignment(4)
self.newspapers:SetTextInset(SScaleMin(10 / 3), 0)
self.newspapers.Paint = function(self, w, h)
PaintButton(self, w, h)
end
self.newspapers:DockMargin(0, -1, 0, 0)
self.newspapers.DoClick = function()
self:CreateBackButton()
surface.PlaySound("helix/ui/press.wav")
self.innerContent:Clear()
for k, v in pairs(self.storedNewspapers) do
local newspaper = self.innerContent:Add("DButton")
newspaper:Dock(TOP)
newspaper:SetTall(SScaleMin(50 / 3))
newspaper:SetText(v[3][1].columnTitle.." | "..v[3][1].columnSubtitle)
newspaper:SetFont("WNBleedingMinutesBoldNoClamp")
newspaper:SetContentAlignment(4)
newspaper:SetTextInset(SScaleMin(10 / 3), 0)
newspaper.Paint = function(self, w, h)
PaintButton(self, w, h)
end
if k != 1 then
newspaper:DockMargin(0, -1, 0, 0)
end
newspaper.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
local areyousure = vgui.Create("Panel")
areyousure:SetSize(SScaleMin(300 / 3), SScaleMin(100 / 3))
areyousure:Center()
areyousure:MakePopup()
areyousure.Paint = function(self, w, h)
PaintButton(self, w, h)
end
local label = areyousure:Add("DLabel")
label:SetFont("WNBleedingMinutesBoldNoClamp")
label:SetText("Enlever les journeaux ?")
label:SizeToContents()
label:Dock(TOP)
label:SetContentAlignment(5)
local buttonpanel = areyousure:Add("Panel")
buttonpanel:Dock(BOTTOM)
buttonpanel:SetTall(SScaleMin(50 / 3))
local yes = buttonpanel:Add("DButton")
yes:Dock(LEFT)
yes:SetWide((areyousure:GetWide() * 0.5) - SScaleMin(5 / 3))
yes:SetText("Oui")
yes:SetFont("MenuFontNoClamp")
yes.Paint = function(self, w, h)
PaintButton(self, w, h)
end
yes.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
areyousure:Remove()
newspaper:Remove()
netstream.Start("RemoveStoredNewspaper", k)
end
local no = buttonpanel:Add("DButton")
no:Dock(RIGHT)
no:SetWide((areyousure:GetWide() * 0.5) - SScaleMin(5 / 3))
no:SetText("Non")
no:SetFont("MenuFontNoClamp")
no.Paint = function(self, w, h)
PaintButton(self, w, h)
end
no.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
areyousure:Remove()
end
end
end
end
end
function PANEL:CreateDoorAccessButton()
self.doorAccess = self.innerContent:Add("DButton")
self.doorAccess:Dock(TOP)
self.doorAccess:SetTall(SScaleMin(50 / 3))
self.doorAccess:SetText("Portes Combines")
self.doorAccess:SetFont("WNBleedingMinutesBoldNoClamp")
self.doorAccess:SetContentAlignment(4)
self.doorAccess:SetTextInset(SScaleMin(10 / 3), 0)
self.doorAccess.Paint = function(self, w, h)
PaintButton(self, w, h)
end
self.doorAccess:DockMargin(0, -1, 0, 0)
self.doorAccess.DoClick = function()
self:CreateBackButton()
surface.PlaySound("helix/ui/press.wav")
self.innerContent:Clear()
for k, v in ipairs(ents.GetAll()) do
if (v:IsDoor()) then
if (!v:HasSpawnFlags(256) and !v:HasSpawnFlags(1024) and v:GetNetVar("combineDoor")) then
local name = v:GetNetVar("combineDoor")
if name then
local doorNameButton = self.innerContent:Add("DButton")
doorNameButton:Dock(TOP)
doorNameButton:SetText(name)
doorNameButton:SetTall(SScaleMin(50 / 3))
doorNameButton:SetFont("WNBleedingMinutesBoldNoClamp")
doorNameButton:SetContentAlignment(4)
doorNameButton:SetTextInset(padding, 0)
doorNameButton.Paint = function(self, w, h)
PaintButton(self, w, h)
end
doorNameButton.DoClick = function()
Derma_StringRequest(
"Donner l'accès",
"Entrer CID",
"",
function(enteredCid)
for k2, v2 in pairs(ix.char.loaded) do
if v2:GetCid() == enteredCid then
netstream.Start("SetDoorAccessCID", v, k2)
break
end
end
end,
nil
)
end
end
end
end
end
end
end
function PANEL:CreateInner()
self.innerContent = self.content:Add("DScrollPanel")
self.innerContent:Dock(TOP)
self.innerContent:SetTall(self.content:GetTall() - SScaleMin(50 / 3))
self.barteringConfigs = self.innerContent:Add("DButton")
self.barteringConfigs:Dock(TOP)
self.barteringConfigs:SetTall(SScaleMin(50 / 3))
self.barteringConfigs:SetText("Commerce")
self.barteringConfigs:SetFont("WNBleedingMinutesBoldNoClamp")
self.barteringConfigs:SetContentAlignment(4)
self.barteringConfigs:SetTextInset(padding, 0)
self.barteringConfigs.Paint = function(self, w, h)
PaintButton(self, w, h)
end
self.barteringConfigs.DoClick = function()
self:CreateBackButton()
surface.PlaySound("helix/ui/press.wav")
self.innerContent:Clear()
local recipes = ix.recipe.stored
local categories = {}
for uniqueID, RECIPE in SortedPairs(recipes) do
if RECIPE.cost and RECIPE.skill == "bartering" then
if !table.HasValue(categories, RECIPE.category) then
table.insert(categories, RECIPE.category)
local priceMultiplier = self.innerContent:Add("DButton")
priceMultiplier:Dock(TOP)
priceMultiplier:SetText("Multiplicateur de prix : "..RECIPE.category)
priceMultiplier:SetTall(SScaleMin(50 / 3))
priceMultiplier:SetFont("WNBleedingMinutesBoldNoClamp")
priceMultiplier:SetContentAlignment(4)
priceMultiplier:SetTextInset(padding, 0)
priceMultiplier.Paint = function(self, w, h)
PaintButton(self, w, h)
end
priceMultiplier.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
Derma_StringRequest(
"Mettre le multiplicateur : "..RECIPE.category,
"Multiplicateur : "..RECIPE.category.." (1 décimale max, par défaut à 1.0)",
ix.config.Get("BarteringPriceMultiplier"..RECIPE.category),
function(number)
local toNumber = tonumber(number)
if isnumber(toNumber) then
local maxValue = ix.config.stored.BarteringPriceMultiplierClothing.data.data.max or 100
local minValue = ix.config.stored.BarteringPriceMultiplierClothing.data.data.min or 0
if (toNumber <= maxValue) and (toNumber >= minValue) then
netstream.Start("ixBarteringPriceMultiplier", RECIPE.category, tonumber(number))
LocalPlayer():NotifyLocalized("Mettre le multiplicateur de prix "..RECIPE.category.." à "..number)
else
LocalPlayer():NotifyLocalized("Le nombre doit être au dessus 0 et en dessous ou égal à 100.")
end
end
end,
nil
)
end
end
end
end
end
self.ration = self.innerContent:Add("DButton")
self.ration:Dock(TOP)
self.ration:SetTall(SScaleMin(50 / 3))
self.ration:SetText("Rations")
self.ration:SetFont("WNBleedingMinutesBoldNoClamp")
self.ration:SetContentAlignment(4)
self.ration:SetTextInset(padding, 0)
self.ration.Paint = function(self, w, h)
PaintButton(self, w, h)
end
self.ration:DockMargin(0, -1, 0, 0)
self.ration.DoClick = function()
self:CreateBackButton()
surface.PlaySound("helix/ui/press.wav")
self.innerContent:Clear()
local rationInterval = self.innerContent:Add("DButton")
rationInterval:Dock(TOP)
rationInterval:SetTall(SScaleMin(50 / 3))
rationInterval:SetText("Intervalle des rations")
rationInterval:SetFont("WNBleedingMinutesBoldNoClamp")
rationInterval:SetContentAlignment(4)
rationInterval:SetTextInset(padding, 0)
rationInterval.Paint = function(self, w, h)
PaintButton(self, w, h)
end
rationInterval.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
Derma_StringRequest(
"Changer l'intervalle des rations",
"Changer l'intervalle des rations (0 décimale, par défaut à 4)",
ix.config.Get("rationInterval"),
function(number)
local toNumber = tonumber(number)
if isnumber(toNumber) then
local maxValue = ix.config.stored.rationInterval.data.data.max or 10
local minValue = ix.config.stored.rationInterval.data.data.min or 1
if (toNumber <= maxValue) and (toNumber >= minValue) then
netstream.Start("SetRationIntervalPDA", tonumber(number))
LocalPlayer():NotifyLocalized("Intervalle des rations changée à "..number.. " heures")
else
LocalPlayer():NotifyLocalized("Le nombre doit être au dessus 0 et en dessous ou égal à 10.")
end
end
end,
nil)
end
end
if istable(LocalPlayer().messagelist) then
if !table.IsEmpty(LocalPlayer().messagelist) then
self.messages = self.innerContent:Add("DButton")
self.messages:Dock(TOP)
self.messages:SetTall(SScaleMin(50 / 3))
self.messages:SetText("Messages")
self.messages:SetFont("WNBleedingMinutesBoldNoClamp")
self.messages:SetContentAlignment(4)
self.messages:SetTextInset(padding, 0)
self.messages.Paint = function(self, w, h)
PaintButton(self, w, h)
end
self.messages:DockMargin(0, -1, 0, 0)
self.messages.DoClick = function()
self:CreateBackButton()
surface.PlaySound("helix/ui/press.wav")
self.innerContent:Clear()
local messagePanel = self.innerContent:Add("Panel")
messagePanel:Dock(TOP)
messagePanel:SetTall(self.innerContent:GetTall())
for k, v in pairs(LocalPlayer().messagelist) do
local message = messagePanel:Add("DButton")
message:Dock(TOP)
message:SetTall(SScaleMin(50 / 3))
message:SetText(v["message_date"].." | "..string.utf8sub(v["message_poster"], 1, 18).." | #"..v["message_cid"])
if v["message_reply"] then
message:SetTextColor(Color(210, 255, 255, 255))
else
message:SetTextColor(Color(255, 205, 205, 255))
end
message:SetFont("WNBleedingMinutesBold")
message:SetContentAlignment(4)
message:SetTextInset(padding, 0)
message.Paint = function(self, w, h)
PaintButton(self, w, h)
end
if k != 1 then
message:DockMargin(0, -1, 0, 0)
end
message.DoClick = function()
messagePanel:Clear()
surface.PlaySound("helix/ui/press.wav")
local textEntry = messagePanel:Add("DTextEntry")
textEntry:Dock(FILL)
textEntry:SetTextColor(Color(200, 200, 200, 255))
textEntry:SetMultiline( true )
textEntry:SetEditable(false)
textEntry:SetVerticalScrollbarEnabled( true )
textEntry:SetCursorColor(Color(200, 200, 200, 255))
textEntry:SetValue(v["message_text"])
textEntry.Paint = function(self, w, h)
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, w, h)
self:DrawTextEntryText( self:GetTextColor(), self:GetHighlightColor(), self:GetCursorColor() )
end
local optionsPanel = messagePanel:Add("Panel")
optionsPanel:Dock(BOTTOM)
optionsPanel:SetSize(self.content:GetWide(), SScaleMin(50 / 3))
local remove = optionsPanel:Add("DButton")
remove:Dock(FILL)
remove:SetText("RETIRER")
remove:SetFont("WNBleedingMinutesBoldNoClamp")
remove:SetContentAlignment(5)
remove.Paint = function(self, w, h)
PaintButton(self, w, h)
end
remove.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
LocalPlayer().messagelist[k] = nil
netstream.Start("RemoveCAMessage", v["message_id"])
self.innerContent:Remove()
self:CreateInner()
end
local sendReply = optionsPanel:Add("DButton")
sendReply:Dock(RIGHT)
sendReply:SetWide(optionsPanel:GetWide() * 0.5)
if v["message_reply"] then
sendReply:SetText("LIRE LA REPONSE")
else
sendReply:SetText("REPONDRE")
end
sendReply:SetFont("WNBleedingMinutesBold")
sendReply:SetContentAlignment(5)
sendReply.Paint = function(self, w, h)
PaintButton(self, w, h)
end
sendReply.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
if v["message_reply"] then
textEntry:SetValue(v["message_reply"])
return
end
textEntry:SetEditable(true)
sendReply:SetText("ENVOYER REPONSE")
textEntry:SetValue("Ecrivez votre réponse...")
sendReply.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
v["message_reply"] = textEntry:GetValue()
netstream.Start("SetCAMessageReply", v["message_id"], textEntry:GetValue())
self.innerContent:Remove()
self:CreateInner()
end
end
end
end
end
end
end
self:CreateDoorAccessButton()
end
vgui.Register("ixCAPDA", PANEL, "EditablePanel")

View File

@@ -0,0 +1,224 @@
--[[
| 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 = {}
function PANEL:Init()
self:SetSize(ScrW(), ScrH())
self:SetAlpha(0)
self:AlphaTo(255, 0.5, 0)
self.Paint = function(this, w, h)
surface.SetDrawColor(Color(63, 58, 115, 220))
surface.DrawRect(0, 0, w, h)
Derma_DrawBackgroundBlur( this, 1 )
end
self.innerContent = self:Add("Panel")
self.innerContent:SetSize(SScaleMin(500 / 3), SScaleMin(600 / 3))
self.innerContent:Center()
self.innerContent:MakePopup()
Schema:AllowMessage(self.innerContent)
self.innerContent.Paint = function(this, w, h)
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, w, h)
end
self:CreateTopBar()
self:CreateItems()
end
function PANEL:CreateTopBar()
local topbar = self.innerContent:Add("Panel")
topbar:SetSize(self.innerContent: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
self.titleText = topbar:Add("DLabel")
self.titleText:SetFont("CharCreationBoldTitleNoClamp")
self.titleText:Dock(LEFT)
self.titleText:SetText("Sélectionnez l'article à distribuer")
self.titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
self.titleText:SetContentAlignment(4)
self.titleText:SizeToContents()
self.exit = topbar:Add("DImageButton")
self.exit:SetImage("willardnetworks/tabmenu/navicons/exit.png")
self.exit:SetSize(SScaleMin(20 / 3), SScaleMin(20 / 3))
self.exit:DockMargin(0, SScaleMin(15 / 3), SScaleMin(10 / 3), SScaleMin(15 / 3))
self.exit:Dock(RIGHT)
self.exit.DoClick = function()
netstream.Start("ClosePanels", LocalPlayer().activePickupDispenser)
LocalPlayer().activePickupDispenser = nil
LocalPlayer().boughtItems = nil
self:Remove()
surface.PlaySound("helix/ui/press.wav")
end
local function createDivider(parent)
parent:SetSize(1, topbar:GetTall())
parent:Dock(RIGHT)
parent:DockMargin(0, SScaleMin(10 / 3), SScaleMin(SScaleMin(10 / 3) / 3), SScaleMin(10 / 3))
parent.Paint = function(this, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawLine(0, 0, 0, h)
end
end
local divider = topbar:Add("Panel")
createDivider(divider)
end
function PANEL:CreateItems()
if !LocalPlayer().boughtItems then
return
end
local scrollPanel = self.innerContent:Add("DScrollPanel")
scrollPanel:Dock(TOP)
scrollPanel:SetSize(self.innerContent:GetWide(), self.innerContent:GetTall() - SScaleMin(50 / 3))
for k, v in pairs (LocalPlayer().boughtItems) do
local character = LocalPlayer():GetCharacter()
local inventory = character:GetInventory()
local width = istable(v) and 1 or ix.item.list[k].width or 1
local height = istable(v) and 1 or ix.item.list[k].height or 1
local frame, modelPanel, textPanel, amountPanel, amount, title = self:CreateItem(scrollPanel, k, v)
local actualAmount = istable(v) and 1 or v or 1
local actualTitle = istable(v) and v.title or ix.item.list[k].name or "Boîte en carton"
if !inventory:FindEmptySlot(width, height) then
amount:SetTextColor(Color(150, 150, 150, 255))
title:SetTextColor(Color(150, 150, 150, 255))
end
self:CreateInvisibleButton(frame, modelPanel, textPanel, amountPanel, inventory, width, height, actualAmount, actualTitle, amount, k)
end
end
function PANEL:CreateInvisibleButton(frame, modelPanel, textPanel, amountPanel, inventory, width, height, actualAmount, actualTitle, amount, k)
local invisibleButton = frame:Add("DButton")
invisibleButton:SetSize(modelPanel:GetWide() + textPanel:GetWide() + amountPanel:GetWide(), frame:GetTall())
invisibleButton:SetText("")
invisibleButton.Paint = function(this, w, h)
if inventory then
if (this:IsHovered() and !inventory:FindEmptySlot(width, height)) then
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 15)))
surface.DrawOutlinedRect(SScaleMin(4 / 3), SScaleMin(4 / 3), w - SScaleMin(8 / 3), h - SScaleMin(8 / 3))
end
return
end
if (this:IsHovered()) then
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 15)))
surface.DrawOutlinedRect(SScaleMin(4 / 3), SScaleMin(4 / 3), w - SScaleMin(8 / 3), h - SScaleMin(8 / 3))
end
end
invisibleButton.DoClick = function()
if inventory then
if inventory:FindEmptySlot(width, height) then
actualAmount = actualAmount - 1
amount:SetText(actualAmount)
if actualAmount == 0 then
frame:Remove()
end
LocalPlayer():NotifyLocalized("Vous avez récupéré : "..actualTitle)
surface.PlaySound("helix/ui/press.wav")
netstream.Start("SetPurchasedItems", k, LocalPlayer().activePickupDispenser)
else
LocalPlayer():NotifyLocalized("Vous n'avez pas assez d'espace pour : "..actualTitle.."!")
end
end
end
return invisibleButton
end
function PANEL:CreateItem(scrollPanel, itemID, number)
local frame = scrollPanel:Add("Panel")
frame:Dock(TOP)
frame:DockMargin(0, 0, 0, -1)
frame:SetTall(SScaleMin(110 / 3) - 5)
frame.Paint = function(this, w, h)
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, w, h)
end
local modelPanel = frame:Add("Panel")
modelPanel:Dock(LEFT)
modelPanel:SetWide(scrollPanel:GetWide() / 3)
modelPanel.Paint = function(this, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawLine(w - 1, SScaleMin(10 / 3), w - 1, h - SScaleMin(10 / 3))
end
local modelIcon = modelPanel:Add("SpawnIcon")
local model = istable(number) and "models/props_c17/paper01.mdl" or ix.item.list[itemID].model or "models/props_junk/cardboard_box004a.mdl"
modelIcon:Dock(FILL)
modelIcon:DockMargin(SScaleMin(43 / 3), SScaleMin(10 / 3), SScaleMin(43 / 3), SScaleMin(10 / 3))
modelIcon:SetModel(model)
modelIcon.Paint = nil
modelIcon.PaintOver = nil
modelIcon:SetTooltip(nil)
local textPanel = frame:Add("Panel")
textPanel:Dock(LEFT)
textPanel:DockPadding(SScaleMin(10 / 3), 0, SScaleMin(10 / 3), 0)
textPanel:SetSize(scrollPanel:GetWide() / 2, frame:GetTall())
textPanel.Paint = function(this, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawLine(w - 1, SScaleMin(10 / 3), w - 1, h - SScaleMin(10 / 3))
end
local title = textPanel:Add("DLabel")
local actualTitle = istable(number) and number.title or ix.item.list[itemID].name or "Boîte en carton"
title:Dock(TOP)
title:SetText(actualTitle..(istable(number) and " - DEPUIS : "..number.fromName.." | "..number.fromCID or ""))
title:SetFont(istable(number) and "MenuFontBoldNoClamp" or "WNBleedingMinutesBoldNoClamp")
title:SetWrap(true)
title:SetAutoStretchVertical(true)
title.PerformLayout = function(this)
this:DockMargin(0, textPanel:GetTall() * 0.5 - this:GetTall() * 0.5, 0, textPanel:GetTall() * 0.5 - this:GetTall() * 0.5)
end
local amountPanel = frame:Add("Panel")
amountPanel:Dock(FILL)
amountPanel:SetSize(scrollPanel:GetWide() - modelPanel:GetWide() - textPanel:GetWide(), frame:GetTall())
if LocalPlayer().boughtItems and istable(LocalPlayer().boughtItems) then
if table.Count(LocalPlayer().boughtItems) >= 6 then
amountPanel:SetWide(amountPanel:GetWide() - SScaleMin(15 / 3))
end
end
local amount = amountPanel:Add("DLabel")
local actualAmount = istable(number) and 1 or number or 1
amount:SetContentAlignment(5)
amount:SetText(actualAmount)
amount:SetFont("WNBleedingMinutesBoldNoClamp")
amount:SizeToContents()
amount:Center()
return frame, modelPanel, textPanel, amountPanel, amount, title
end
vgui.Register("PickupDispenser", PANEL, "EditablePanel")

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/
--]]
local vgui = vgui
local PANEL = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Produits"
self.secondTitle = "Acheter"
self.thirdTitle = "Prévisualiser"
self.nothingSelected = "Aucun produits sélectionné"
self.requirementsTitleText = "Requis : "
self.skill = "bartering"
self.built = false
ix.city:SyncCityStock()
end
function PANEL:Proceed()
self.built = true
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
function PANEL:Remove()
if (self.model) then
self.model:Remove()
end
end
vgui.Register("BarteringBasePanel", PANEL, "EditablePanel")
local function CreateBarteringPanel(container)
local panel = container:Add("BarteringBasePanel")
ix.gui.barteringpanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "BarteringBasePanel", function(tabs)
tabs[ix.skill.list["bartering"].uniqueID] = CreateBarteringPanel
end)

View File

@@ -0,0 +1,58 @@
--[[
| 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 vgui = vgui
local PANEL = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Recettes"
self.secondTitle = "Cuisiner"
self.thirdTitle = "Prévisualiser"
self.nothingSelected = "Aucun objets sélectionné"
self.requirementsTitleText = "Requis : "
self.ingredientsTitleText = "Ingrédients :"
self.skill = "cooking"
self.craftSound = "willardnetworks/skills/skill_cooking.wav"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
function PANEL:Remove()
if (self.model) then
self.model:Remove()
end
end
vgui.Register("CookingBasePanel", PANEL, "EditablePanel")
local function CreateCookingPanel(container)
local panel = container:Add("CookingBasePanel")
ix.gui.cookingpanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "CookingBasePanel", function(tabs)
tabs[ix.skill.list["cooking"].uniqueID] = CreateCookingPanel
end)

View File

@@ -0,0 +1,102 @@
--[[
| 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 vgui = vgui
local PANEL = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
if parent then
if parent.contentPanel then
self:SetSize(parent.contentPanel:GetSize())
else
self:SetSize(ScrW() * 0.75, ScrH() * 0.70)
end
else
self:SetSize(ScrW() * 0.75, ScrH() * 0.70)
end
-- Config
self.firstTitle = "Plan"
self.secondTitle = "Craft"
self.thirdTitle = "Prévisualiser"
self.nothingSelected = "Aucun objets / plan sélectionné"
self.requirementsTitleText = "Requis : "
self.ingredientsTitleText = "Ingrédients :"
self.skill = "crafting"
self.craftSound = "willardnetworks/skills/skill_crafting.wav"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
function PANEL:Remove()
if (self.model) then
self.model:Remove()
end
end
vgui.Register("CraftingBasePanel", PANEL, "EditablePanel")
local function CreateCraftingPanel(container)
local panel = container:Add("CraftingBasePanel")
ix.gui.craftingpanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "CraftingBasePanel", function(tabs)
tabs[ix.skill.list["crafting"].uniqueID] = CreateCraftingPanel
end)
netstream.Hook("OpenCraftingMenu", function()
if ix.gui.craftingpanel then
if ix.gui.craftingpanel.Remove then
ix.gui.craftingpanel:Remove()
end
end
local parentPanel = vgui.Create("Panel")
parentPanel:SetSize(ScrW(), ScrH())
parentPanel:SetAlpha(0)
parentPanel:AlphaTo(200, 0.5, 0)
parentPanel.Paint = function(self, w, h)
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
end
local craftingPanel = parentPanel:Add("CraftingBasePanel")
craftingPanel:MakePopup()
craftingPanel:Center()
local close = craftingPanel:Add("DButton")
close:Dock(BOTTOM)
close:SetFont("TitlesFont")
close:SetText("FERMER")
close:DockMargin(((craftingPanel:GetWide() + 20) / 1.5), 0, 2, 0)
close:SetTall(math.Clamp(ScreenScale(50 / 3), 0, 50))
close.DoClick = function()
parentPanel:AlphaTo(0, 0.5, 0, function()
parentPanel:Remove()
end)
end
ix.gui.craftingpanel = craftingPanel
ix.gui.activeSkill = craftingPanel
end)

View File

@@ -0,0 +1,44 @@
--[[
| 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 = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Niveaux débloqués - Statistiques"
self.skill = "guns"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
vgui.Register("GunsBasePanel", PANEL, "EditablePanel")
local function CreateGunsPanel(container)
local panel = container:Add("GunsBasePanel")
ix.gui.gunspanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "GunsBasePanel", function(tabs)
tabs[ix.skill.list["guns"].uniqueID] = CreateGunsPanel
end)

View File

@@ -0,0 +1,58 @@
--[[
| 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 vgui = vgui
local PANEL = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Plan"
self.secondTitle = "Créer"
self.thirdTitle = "Prévisualiser"
self.nothingSelected = "Aucun objet / plan sélectionné"
self.requirementsTitleText = "Requis : "
self.ingredientsTitleText = "Ingrédients:"
self.skill = "medicine"
self.craftSound = "willardnetworks/skills/skill_medicine.wav"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
function PANEL:Remove()
if (self.model) then
self.model:Remove()
end
end
vgui.Register("MedicalBasePanel", PANEL, "EditablePanel")
local function CreateMedicalPanel(container)
local panel = container:Add("MedicalBasePanel")
ix.gui.medicalpanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "MedicalBasePanel", function(tabs)
tabs[ix.skill.list["medicine"].uniqueID] = CreateMedicalPanel
end)

View File

@@ -0,0 +1,44 @@
--[[
| 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 = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Niveaux débloqués - Statistiques"
self.skill = "melee"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
vgui.Register("MeleeBasePanel", PANEL, "EditablePanel")
local function CreateMeleePanel(container)
local panel = container:Add("MeleeBasePanel")
ix.gui.gunspanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "MeleeBasePanel", function(tabs)
tabs[ix.skill.list["melee"].uniqueID] = CreateMeleePanel
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/
--]]
local vgui = vgui
local PANEL = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Produits"
self.secondTitle = "Informations"
self.thirdTitle = "Prévisualiser"
self.nothingSelected = "Aucun objet sélectionné"
self.requirementsTitleText = "Requis : "
self.skill = "smuggling"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
function PANEL:Remove()
if (self.model) then
self.model:Remove()
end
end
vgui.Register("SmugglingBasePanel", PANEL, "EditablePanel")
local function CreateSmugglingPanel(container)
local panel = container:Add("SmugglingBasePanel")
ix.gui.smugglingpanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "SmugglingBasePanel", function(tabs)
tabs[ix.skill.list["smuggling"].uniqueID] = CreateSmugglingPanel
end)

View File

@@ -0,0 +1,44 @@
--[[
| 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 = {}
function PANEL:Init()
local parent = self:GetParent():GetParent()
self:SetSize(parent.contentPanel:GetSize())
-- Config
self.firstTitle = "Niveaux débloqués - Statistiques"
self.skill = "speed"
-- Create titles
self:Add("CraftingBaseTopTitleBase")
-- Create inner content
self:Add("CraftingBaseInnerContent")
-- Rebuild inner content
self:Add("CraftingBaseRebuild")
end
vgui.Register("SpeedBasePanel", PANEL, "EditablePanel")
local function CreateSpeedPanel(container)
local panel = container:Add("SpeedBasePanel")
ix.gui.speedpanel = panel
ix.gui.activeSkill = panel
return container
end
hook.Add("CreateSkillPanels", "SpeedBasePanel", function(tabs)
tabs[ix.skill.list["speed"].uniqueID] = CreateSpeedPanel
end)

View File

@@ -0,0 +1,722 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PANEL = {}
local PLUGIN = PLUGIN
local titlePushDown = SScaleMin(85 / 3)
local fixHeight = SScaleMin(55 / 3)
local scale780 = SScaleMin(780 / 3)
local scale120 = SScaleMin(120 / 3)
function PANEL:Init()
ix.gui.skills = self
local margin = SScaleMin(10 / 3)
local topPushDown = SScaleMin(150 / 3)
self:SetWide(ScrW() - (topPushDown * 2))
local sizeXtitle, sizeYtitle = self:GetWide(), scale120
local sizeXcontent, sizeYcontent = self:GetWide(), (scale780) - fixHeight
self.titlePanel = self:Add("Panel")
self.titlePanel:SetSize(sizeXtitle, sizeYtitle)
self.titlePanel:SetPos(self:GetWide() * 0.5 - self.titlePanel:GetWide() * 0.5)
self.contentPanel = self:Add("Panel")
self.contentPanel:SetSize(sizeXcontent, sizeYcontent)
self.contentPanel:SetPos(self:GetWide() * 0.5 - self.contentPanel:GetWide() * 0.5, titlePushDown)
self:SetTall(scale120 + scale780 - fixHeight + titlePushDown)
self:Center()
local skillsIcon = self.titlePanel:Add("DImage")
skillsIcon:SetImage("willardnetworks/tabmenu/navicons/crafting.png")
skillsIcon:SetSize(SScaleMin(18 / 3), SScaleMin(18 / 3))
skillsIcon:SetPos(0, SScaleMin(3 / 3))
local skillsTitle = self.titlePanel:Add("DLabel")
skillsTitle:SetFont("TitlesFontNoClamp")
skillsTitle:SetText(LocalPlayer():Name() .. "")
skillsTitle:SetPos(SScaleMin(26 / 3))
skillsTitle:SizeToContents()
local skillsDesc = self.titlePanel:Add("DLabel")
skillsDesc:SetFont("MenuFontLargerNoClamp")
skillsDesc:SetText("Rappel : le niveau maximal combiné est de " .. ix.config.Get("MaxTotalSkill", 0) .. ".")
skillsDesc:SetTextColor(Color(200, 200, 200, 255))
skillsDesc:SetPos(0, SScaleMin(25 / 3) + margin * 0.7)
skillsDesc:SizeToContents()
local skillsDesc2 = self.titlePanel:Add("DLabel")
skillsDesc2:SetFont("MenuFontLargerBoldNoFix")
skillsDesc2:SetTextColor(Color(255, 78, 69, 255))
skillsDesc2:SetText("Niveaux actuels : " .. LocalPlayer():GetCharacter():GetTotalSkillLevel() .. "/" .. ix.config.Get("MaxTotalSkill", 0))
skillsDesc2:SetPos(0, SScaleMin(42 / 3) + margin * 0.7)
skillsDesc2:SizeToContents()
self:CreateAttributesPanel()
self.panels = {}
hook.Run("CreateSkillPanels", self.panels) -- Create subpanels for example Crafting
self:CreateSkills()
end
function PANEL:CreateSkills()
if (self.skillPanels) then
for _, v in ipairs(self.skillPanels) do
v:Remove()
end
end
self.skillPanels = {}
local character = LocalPlayer():GetCharacter()
self.skillGrid = self.contentPanel:Add("DGrid")
self.skillGrid:Dock(FILL)
self.skillGrid:SetCols( 3 )
self.skillGrid:SetColWide( self.contentPanel:GetWide() / 3 )
self.skillGrid:SetRowHeight( self.contentPanel:GetTall() / 3 )
for skillID, skillInfo in SortedPairs(ix.skill.list) do
if character:GetFaction() != FACTION_VORT and skillInfo.name == "Vortessence" then
continue
end
self.skillPanels[skillID] = self:CreateSkillPanel(skillID, skillInfo)
end
end
function PANEL:CreateSkillPanel(skillID, skillInfo)
local bottomPanelH = SScaleMin(35 / 3)
local character = LocalPlayer():GetCharacter()
local skillPanel = vgui.Create("Panel")
skillPanel:SetSize((self.contentPanel:GetWide() / 3) - SScaleMin(10 / 3), (self.contentPanel:GetTall() / 3) - SScaleMin(10 / 3))
skillPanel:Center()
skillPanel.Paint = function(_, w, h)
surface.SetDrawColor(color_white)
surface.SetMaterial(ix.util.GetMaterial(skillInfo.image))
surface.DrawTexturedRect(0, 0, w, h - bottomPanelH)
surface.SetDrawColor(ColorAlpha(color_black, 100))
surface.DrawRect(0, h - bottomPanelH, w, bottomPanelH)
surface.SetDrawColor(Color(116, 113, 130, 255))
surface.DrawOutlinedRect(0, 0, w, h)
surface.DrawLine(0, h - bottomPanelH, w, h - bottomPanelH)
end
-- Bottom Panel
local dPadding = SScaleMin(5 / 3)
local bottomPanel = skillPanel:Add("Panel")
bottomPanel:Dock(BOTTOM)
bottomPanel:SetTall(bottomPanelH)
local skillName = bottomPanel:Add("DLabel")
self:CreateSkillLabel(skillName, skillInfo.name, "TitlesFontNoClamp", dPadding * 4, dPadding * 2)
skillPanel.skillLevel = bottomPanel:Add("DLabel")
self:CreateSkillLabel(skillPanel.skillLevel, "Niveau : " .. character:GetSkillLevel(skillID) .. "/" .. ix.skill.MAX_SKILL, "MenuFontLargerNoClamp", 0, 0, Color(255, 204, 0, 255))
local experiencePanel = bottomPanel:Add("Panel")
experiencePanel:Dock(RIGHT)
experiencePanel:SetWide(SScaleMin(200 / 3))
experiencePanel:DockMargin(dPadding * 2, dPadding, dPadding * 4, dPadding)
experiencePanel:DockPadding(dPadding, dPadding, dPadding, dPadding)
experiencePanel.Paint = function(_, w, h)
surface.SetDrawColor(ColorAlpha(color_black, 100))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(116, 113, 130, 255))
surface.DrawOutlinedRect(0, 0, w, h)
end
local skillProgress = math.Clamp(character:GetSkillStoredExp(skillID) / 1000, 0, 1)
skillPanel.progressBar = experiencePanel:Add("Panel")
skillPanel.progressBar:Dock(FILL)
skillPanel.progressBar.progress = skillProgress
skillPanel.progressBar.Paint = function(panel, w, h)
surface.SetDrawColor(Color(255, 78, 70, 255))
surface.DrawRect(0, 0, w * panel.progress, h)
end
skillPanel.processLabel = skillPanel.progressBar:Add("DLabel")
skillPanel.processLabel.skillID = skillID
skillPanel.processLabel.SetupText = function(panel, char)
if (char:GetSkill(skillID) == ix.skill.MAX_SKILL) then
panel:SetText("NIVEAU MAX")
elseif (char:GetTotalSkillLevel() == ix.config.Get("MaxTotalSkill")) then
panel:SetText("NIVEAU MAX TOTAL")
elseif (char:CanLevelSkill(panel.skillID)) then
panel:SetText("NIVEAU SUPÉRIEUR")
else
local skillProg = math.Clamp(character:GetSkillStoredExp(panel.skillID) / 1000, 0, 1)
panel:SetText((skillProg * 100) .. "%")
end
end
skillPanel.processLabel:SetupText(character)
skillPanel.processLabel:SetFont("MenuFontLargerNoClamp")
skillPanel.processLabel:SetContentAlignment(5)
skillPanel.processLabel:Dock(FILL)
local levelUp = skillPanel.progressBar:Add("DButton")
levelUp:Dock(FILL)
levelUp:SetText("")
levelUp.Paint = nil
levelUp.DoClick = function()
if character:CanLevelSkill(skillID) then
surface.PlaySound("helix/ui/press.wav")
net.Start("ixSkillLevelUp")
net.WriteString(skillID)
net.SendToServer()
end
end
local imagePanel = skillPanel:Add("Panel")
imagePanel:Dock(FILL)
local boostPanel = imagePanel:Add("Panel")
boostPanel:SetSize(skillPanel:GetWide(), skillPanel:GetTall() - bottomPanelH)
boostPanel:DockPadding(dPadding * 4, dPadding * 3, dPadding * 4, dPadding * 4)
boostPanel.Paint = self.CoolHover
local skillButton = imagePanel:Add("DButton")
skillButton:Dock(FILL)
skillButton:SetText("")
skillButton:DockPadding(dPadding * 4, dPadding * 4, dPadding * 4, dPadding * 4)
skillButton.Paint = nil
skillButton.OnCursorEntered = function()
surface.PlaySound("helix/ui/rollover.wav")
boostPanel.Paint = nil
end
skillButton.OnCursorExited = function()
boostPanel.Paint = self.CoolHover
end
skillButton.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
self:OpenSkillPanel(skillInfo)
end
self:CreateBoostInfo(boostPanel, skillInfo)
self:CheckForCurrent(skillInfo)
local autoLevel = skillButton:Add("DButton")
skillPanel.autoLevel = autoLevel
autoLevel.autoLevel = character:GetSkillAutoLevel(skillID)
autoLevel:Dock(BOTTOM)
autoLevel:SetTall(SScaleMin(20 / 3))
autoLevel:SetContentAlignment(4)
autoLevel:SetText("UP Automatique")
autoLevel:SetFont("MenuFontBoldNoClamp")
autoLevel:SetTextInset(SScaleMin(30 / 3), 0)
autoLevel:DockMargin(0, 0, skillPanel:GetWide() * 0.63, 0)
autoLevel.Paint = function(panel, w, h)
surface.SetDrawColor(color_white)
surface.DrawOutlinedRect(0, 0, SScaleMin(20 / 3), h)
if panel.autoLevel then
surface.SetMaterial(ix.util.GetMaterial("willardnetworks/tabmenu/skills_v2/tick.png"))
surface.DrawTexturedRect(SScaleMin(20 / 3) * 0.5 - SScaleMin(15 / 3) * 0.5, SScaleMin(20 / 3) * 0.5 - SScaleMin(10 / 3) * 0.5, SScaleMin(15 / 3), SScaleMin(11 / 3))
end
end
autoLevel.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
net.Start("ixSkillSetAutoLevel")
net.WriteString(skillID)
net.SendToServer()
autoLevel.autoLevel = !autoLevel.autoLevel
end
if skillInfo.name == "Bartering" then
experiencePanel:SetVisible(false)
skillPanel.skillLevel:SetText("Vous avez " .. (istable(character:GetPermits()) and table.Count(character:GetPermits()) or "0") .. " permis actifs.")
skillPanel.skillLevel:SizeToContents()
autoLevel:SetVisible(false)
end
self.skillGrid:AddItem( skillPanel )
return skillPanel
end
function PANEL:OpenSkillPanel(skill)
surface.PlaySound("helix/ui/press.wav")
if self.panels[skill.uniqueID] then
if (self.contentPanel) then
self.contentPanelOriginX, self.contentPanelOriginY = self.contentPanel:GetPos()
self.contentPanel:MoveTo(ScrW(), self.contentPanelOriginY, 1, 0)
end
for k, v in pairs(self.panels) do
if k == skill.uniqueID then
self:CreateNewContent(v, skill.uniqueID)
end
end
end
end
function PANEL:CheckForCurrent(skill)
if self.panels[skill.uniqueID] then
if self.contentPanel then
if LocalPlayer().lastSelectedSkill then
if LocalPlayer().lastSelectedSkill == skill.uniqueID then
self.contentPanelOriginX, self.contentPanelOriginY = self.contentPanel:GetPos()
self.contentPanel:SetPos(ScrW(), self.contentPanelOriginY)
for k, v in pairs(self.panels) do
if k == skill.uniqueID then
self:CreateNewContent(v, skill.uniqueID)
end
end
end
end
end
end
end
function PANEL.CoolHover(self, w, h)
surface.SetDrawColor(Color(0, 0, 0, 150))
surface.DrawRect(0, 0, w, h)
end
function PANEL:CreateBoostInfo(boostPanel, skill)
local character = LocalPlayer():GetCharacter()
local attributes = ix.special.list or {}
local skillAttributes = {}
-- Find the attributes that boost the skill
for _, v in pairs(attributes) do
if v.skills then
if v.skills[skill.uniqueID] then
skillAttributes[v.skills[skill.uniqueID]] = v
end
end
end
if skillAttributes[2] then
local boostedByLabel = boostPanel:Add("DLabel")
boostedByLabel:SetText("Boost majeur avec : " .. skillAttributes[2].name)
boostedByLabel:SetFont("MenuFontBoldNoClamp")
boostedByLabel:SetContentAlignment(4)
boostedByLabel:SizeToContents()
boostedByLabel:Dock(TOP)
end
if skillAttributes[1] then
local boostedByLabel = boostPanel:Add("DLabel")
boostedByLabel:SetText("Boost mineur avec : " .. skillAttributes[1].name)
boostedByLabel:SetFont("MenuFontBoldNoClamp")
boostedByLabel:SetContentAlignment(4)
boostedByLabel:SizeToContents()
boostedByLabel:Dock(TOP)
end
local varBoostLevel = character:GetSkillBoostLevels(skill.uniqueID)
local varNeedsLevel, reducedHunger, reducedThirst, reducedGas, reducedHealth = character:GetSkillNeedsReducing(skill.uniqueID)
if (varBoostLevel > 0) then
-- ATLE HAPPY
local boostedLevels = boostPanel:Add("DLabel")
boostedLevels:Dock(TOP)
boostedLevels:SetContentAlignment(4)
boostedLevels:SetFont("MenuFontLargerBoldNoFix")
boostedLevels:SetTextColor(Color(75, 238, 75))
boostedLevels:SetText("Niveau boosté : + " .. varBoostLevel)
boostedLevels:SizeToContents()
end
if (varNeedsLevel > 0) then
if (reducedHunger) then
local hungerReducing = boostPanel:Add("DLabel")
hungerReducing:Dock(TOP)
hungerReducing:SetContentAlignment(4)
hungerReducing:SetFont("MenuFontLargerBoldNoFix")
hungerReducing:SetTextColor(Color(238, 75, 75))
hungerReducing:SetText("-" .. math.Round(reducedHunger, 1) .. " niveau à cause de la faim")
hungerReducing:SizeToContents()
end
if (reducedThirst) then
local thirstReducing = boostPanel:Add("DLabel")
thirstReducing:Dock(TOP)
thirstReducing:SetContentAlignment(4)
thirstReducing:SetFont("MenuFontLargerBoldNoFix")
thirstReducing:SetTextColor(Color(238, 75, 75))
thirstReducing:SetText("-" .. math.Round(reducedThirst, 1) .. " niveau à cause de la soif")
thirstReducing:SizeToContents()
end
if (reducedGas) then
local gasReducing = boostPanel:Add("DLabel")
gasReducing:Dock(TOP)
gasReducing:SetContentAlignment(4)
gasReducing:SetFont("MenuFontLargerBoldNoFix")
gasReducing:SetTextColor(Color(238, 75, 75))
gasReducing:SetText("-" .. math.Round(reducedGas, 1) .. " niveau à cause des germes")
gasReducing:SizeToContents()
end
if (reducedHealth) then
local healthReducing = boostPanel:Add("DLabel")
healthReducing:Dock(TOP)
healthReducing:SetContentAlignment(4)
healthReducing:SetFont("MenuFontLargerBoldNoFix")
healthReducing:SetTextColor(Color(238, 75, 75))
healthReducing:SetText("-" .. math.Round(reducedHealth, 1) .. " niveau à cause des blessures")
healthReducing:SizeToContents()
end
local needsReducing = boostPanel:Add("DLabel")
needsReducing:Dock(TOP)
needsReducing:SetContentAlignment(4)
needsReducing:SetFont("MenuFontLargerBoldNoFix")
needsReducing:SetTextColor(Color(238, 75, 75))
needsReducing:SetText("Niveaux réduits totaux : -" .. varNeedsLevel)
needsReducing:SizeToContents()
end
end
function PANEL:CreateSkillLabel(parent, text, font, leftMargin, rightMargin, color)
parent:Dock(LEFT)
parent:SetFont(font)
parent:SetText(text or "")
parent:SetContentAlignment(4)
parent:DockMargin(leftMargin, 0, rightMargin, 0)
parent:SizeToContents()
parent:SetTextColor(color or color_white)
end
function PANEL:CreateNewContent(v, name)
local newContent = self:Add("Panel")
newContent:SetSize(self.contentPanel:GetSize())
newContent:SetPos(self:GetWide() * 0.5 - self.contentPanel:GetWide() * 0.5, titlePushDown)
local x, y = newContent:GetPos()
if !LocalPlayer().lastSelectedSkill then
newContent:SetPos(0 - ScrW(), y)
newContent:MoveTo(x, y, 1, 0)
else
newContent:SetPos(x, y)
end
LocalPlayer().lastSelectedSkill = name
if self.chosenSkillPanel then
self.chosenSkillPanel:Remove()
end
if self.backButton then
self.backButton:Remove()
end
self.chosenSkillPanel = v(newContent)
self.attributesButton:SetVisible(false)
self.backButton = self.titlePanel:Add("DButton")
self.backButton:Dock(RIGHT)
self.backButton:SetText("Retourner au menu")
self.backButton:SetFont("TitlesFontNoClamp")
self.backButton:SetContentAlignment(6)
self.backButton:SetAlpha(0)
self.backButton:AlphaTo(255, 1, 0)
self.backButton:SizeToContents()
self.backButton:DockMargin(0, self.titlePanel:GetTall() * 0.3 - self.backButton:GetTall(), 0, self.titlePanel:GetTall() * 0.5 - self.backButton:GetTall() * 0.5)
self.backButton.Paint = function(_, w, h) end
self.backButton.OnCursorEntered = function()
self.backButton:SetTextColor(Color(200, 200, 200, 255))
surface.PlaySound("willardnetworks/charactercreation/hover.wav")
end
self.backButton.OnCursorExited = function()
self.backButton:SetTextColor(Color(255, 255, 255, 255))
end
self.backButton.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
self.backButton:AlphaTo(0, 1, 0, function()
self.attributesButton:SetVisible(true)
self.attributesButton:SetAlpha(0)
self.attributesButton:AlphaTo(255, 0.5, 0)
end)
newContent:MoveTo(0 - ScrW(), y, 1, 0)
self.contentPanel:MoveTo(self:GetWide() * 0.5 - self.contentPanel:GetWide() * 0.5, self.contentPanelOriginY, 1, 0)
LocalPlayer().lastSelectedSkill = nil
end
end
function PANEL:CreateAttributesPanel()
self.attributesButton = self.titlePanel:Add("DButton")
self.attributesButton:Dock(RIGHT)
self.attributesButton:DockMargin(0, SScaleMin(25 / 3), 0, SScaleMin(63 / 3))
self.attributesButton:SetText("Boost de vos attributs")
self.attributesButton:SetFont("MenuFontBoldNoClamp")
self.attributesButton:SetWide(SScaleMin(170 / 3))
self.attributesButton.Paint = function(_, w, h)
surface.SetDrawColor(0, 0, 0, 100)
surface.DrawRect(0, 1, w - 2, h - 1)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, w, h)
end
self.attributesButton.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
self:CreateAttributePopup()
end
end
local attributePadding = SScaleMin(10 / 3)
function PANEL:CreateAttributeBar(parent, attributeID)
local character = LocalPlayer():GetCharacter()
local special = tonumber(character:GetSpecial(attributeID)) or 0
local attribute = ix.special:Find(attributeID)
local icon = attribute.icon or ""
local boost = tonumber(character:GetBoostedAttribute(attributeID)) or 0
local specialBoost = character:GetSpecialBoost()[attributeID] or {}
parent:SetTall(SScaleMin(100 / 3))
parent:Dock(TOP)
parent:DockMargin(attributePadding * 2, 0, attributePadding * 2, attributePadding)
local barPanel = parent:Add("Panel")
barPanel:Dock(TOP)
barPanel:SetTall(SScaleMin(27 / 3))
-- icon
local iconImage = barPanel:Add("DImage")
iconImage:Dock(LEFT)
iconImage:SetWide(SScaleMin(20 / 3))
iconImage:SetImage(icon)
iconImage:DockMargin(0, SScaleMin(2 / 3), attributePadding * 2, SScaleMin(2 / 3))
local backgroundBar = barPanel:Add("Panel")
backgroundBar:Dock(FILL)
backgroundBar.Paint = function(_, w, h)
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, w, h)
end
local positivePoints = 0
local negativePoints = 0
for _, v in pairs(specialBoost) do
if v.level > 0 then
positivePoints = positivePoints + v.level
elseif v.level < 0 then
negativePoints = negativePoints - v.level
end
end
local green = Color(138, 200, 97, 255)
local grey = Color(200, 200, 200, 255)
local red = Color(200, 97, 97, 255)
local baseBar = backgroundBar:Add("Panel")
baseBar:SetSize(SScaleMin(360 / 3), barPanel:GetTall())
baseBar.Paint = function(_, w, h)
if positivePoints > 0 then
surface.SetDrawColor(green)
surface.DrawRect(0, 0, (positivePoints + special) * (w / 10), h)
end
if special > 0 then
surface.SetDrawColor(Color(200, 200, 200, 255))
surface.DrawRect(0, 0, (special * w) / 10, h)
end
if negativePoints > 0 then
surface.SetDrawColor(red)
surface.DrawRect(math.max((positivePoints + special) - negativePoints, 0) * (w / 10), 0, negativePoints, h)
end
end
local attributeAmount = barPanel:Add("DLabel")
attributeAmount:Dock(RIGHT)
attributeAmount:SetText(boost .. "/10")
attributeAmount:SetTextColor((boost > special and green) or (boost < special and red) or grey)
attributeAmount:DockMargin(attributePadding * 2 + ((boost == 10 and SScaleMin(3 / 3)) or SScaleMin(11 / 3)), 0, 0, 0)
attributeAmount:SetFont("MenuFontNoClamp")
attributeAmount:SizeToContents()
if specialBoost.long then
local level = specialBoost.long.level
local longBoost = parent:Add("DLabel")
longBoost:Dock(TOP)
if (level != 0) then
local change = level > specialBoost.long.target and "diminue" or "augmente"
local sign = level > 0 and "+" or ""
longBoost:SetText(string.format("Actuellement %s%d boost de nourriture, %s par 1 dans %d minutes", sign, level, change, specialBoost.long.time))
elseif (specialBoost.long.time) then
local sign = specialBoost.long.target > 0 and "+" or "-"
longBoost:SetText(string.format("%s1 boost grâce à la nourriture | Actif dans : %d minutes", sign, specialBoost.long.time))
end
longBoost:SetContentAlignment(5)
longBoost:SetFont("MenuFontNoClamp")
longBoost:DockMargin(0, attributePadding, 0, attributePadding)
longBoost:SizeToContents()
end
if specialBoost.short then
local level = specialBoost.short.level
local shortBoost = parent:Add("DLabel")
shortBoost:Dock(TOP)
if (level != 0) then
local change = level > specialBoost.short.target and "diminue" or "augmente"
local sign = level > 0 and "+" or ""
shortBoost:SetText(string.format("Actuellement %s%d boost de drogue, %s par 1 dans %d secondes", sign, level, change, specialBoost.short.time))
elseif (specialBoost.short.time) then
local sign = specialBoost.short.target > 0 and "+" or "-"
shortBoost:SetText(string.format("%s1 boost grâce à la drogue | Actif dans : %d secondes", sign, specialBoost.short.time))
end
shortBoost:SetContentAlignment(5)
shortBoost:SetFont("MenuFontNoClamp")
shortBoost:DockMargin(0, attributePadding, 0, 0)
shortBoost:SizeToContents()
end
if specialBoost.neg then
local negativeBoost = parent:Add("DLabel")
negativeBoost:Dock(TOP)
negativeBoost:SetText("-" .. specialBoost.neg.level .. " à cause de la faim & la soif")
negativeBoost:SetContentAlignment(5)
negativeBoost:SetFont("MenuFontNoClamp")
negativeBoost:DockMargin(0, attributePadding, 0, 0)
negativeBoost:SizeToContents()
end
end
function PANEL:CreateAttributePopup()
if ix.gui.attributeFrame then
ix.gui.attributeFrame:Remove()
end
ix.gui.attributeFrame = vgui.Create("Panel")
local attributeFrame = ix.gui.attributeFrame
attributeFrame:SetSize(SScaleMin(500 / 3), SScaleMin(507 / 3))
attributeFrame:SetAlpha(0)
attributeFrame:AlphaTo(255, 0.5, 0)
attributeFrame:Center()
attributeFrame:MakePopup()
attributeFrame.Paint = function(panel, w, h)
local blur = Material("pp/blurscreen")
local x, y = panel:LocalToScreen(0, 0)
surface.SetDrawColor( 255, 255, 255 )
surface.SetMaterial( blur )
for i = 1, 6 do
blur:SetFloat( "$blur", (i / 6 ) * ( 3 ) )
blur:Recompute()
render.UpdateScreenEffectTexture()
surface.DrawTexturedRect( x * -1, y * -1, ScrW(), ScrH() )
end
surface.SetDrawColor(Color(0, 0, 0, 100))
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawOutlinedRect(0, 0, w, h)
end
attributeFrame.Think = function()
if !IsValid(PLUGIN.SkillsMenu) then
ix.gui.attributeFrame:Remove()
end
if ix.gui.attributeFrame then
ix.gui.attributeFrame:MoveToFront()
end
end
local topbar = attributeFrame:Add("Panel")
topbar:SetSize(attributeFrame:GetWide(), SScaleMin(50 / 3))
topbar:Dock(TOP)
topbar:DockMargin(0, 0, 0, attributePadding)
topbar.Paint = function( _, 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("Boost des attributs")
titleText:DockMargin(attributePadding, 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), attributePadding, SScaleMin(15 / 3))
exit:Dock(RIGHT)
exit.DoClick = function()
if !IsValid(self) then
return
end
if attributeFrame then
attributeFrame:Remove()
end
surface.PlaySound("helix/ui/press.wav")
end
local strength = attributeFrame:Add("Panel")
self:CreateAttributeBar(strength, "strength")
local intelligence = attributeFrame:Add("Panel")
self:CreateAttributeBar(intelligence, "intelligence")
local perception = attributeFrame:Add("Panel")
self:CreateAttributeBar(perception, "perception")
local agility = attributeFrame:Add("Panel")
self:CreateAttributeBar(agility, "agility")
end
vgui.Register("WNSkillPanel", PANEL, "EditablePanel")
hook.Add("CreateMenuButtons", "WNSkillPanel", function(tabs)
tabs["skills"] = {
RowNumber = 2,
Width = 18,
Height = 18,
Icon = "willardnetworks/tabmenu/navicons/crafting.png",
Create = function(info, container)
if PLUGIN.SkillsMenu then
PLUGIN.SkillsMenu:Remove()
end
PLUGIN.SkillsMenu = container:Add("WNSkillPanel")
end
}
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")
-- Called when the entity initializes.
function ENT:Initialize()
self.fireSize = 100
self.nextFlicker = 0
end
-- Called when the entity should draw.
function ENT:Draw()
self:DrawModel()
end
-- Called when the entity should think.
function ENT:Think()
local curTime = CurTime()
local dlight = DynamicLight( self:EntIndex() )
if (!self.nextFlicker) then
self.nextFlicker = curTime + math.random(0.1, 0.15)
end
if ( dlight ) then
local r, g, b, a = self:GetColor()
dlight.Pos = self:GetPos()
dlight.r = 250
dlight.g = 255
dlight.b = 125
dlight.Brightness = 0
dlight.Size = self.fireSize
dlight.Decay = 5
dlight.DieTime = CurTime() + 0.1
self:Flicker()
end
end
function ENT:Flicker()
local curTime = CurTime()
if (curTime >= self.nextFlicker) then
self.fireSize = math.random(300, 400)
self.nextFlicker = nil
end
end

View File

@@ -0,0 +1,117 @@
--[[
| 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")
-- Called when the entity initializes.
function ENT:Initialize()
self:SetModel("models/props_junk/rock001a.mdl")
self:PhysicsInit(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:SetSolid(SOLID_VPHYSICS)
self:SetMaterial("models/effects/splode1_sheet")
local phys = self:GetPhysicsObject()
if phys:IsValid() then
phys:Wake()
phys:EnableMotion(false)
end
self:SpawnProps()
self:startFire()
end
-- Called when the entity is spawned.
function ENT:SpawnProps()
local rotation1 = Vector(0, 0, 45)
local angle1 = self:GetAngles()
angle1:RotateAroundAxis(angle1:Forward(), rotation1.z)
local rotation2 = Vector(90, 0, 45)
local angle2 = self:GetAngles()
angle2:RotateAroundAxis(angle2:Up(), rotation2.x)
angle2:RotateAroundAxis(angle2:Forward(), rotation2.z)
local rotation3 = Vector(180, 0, 45)
local angle3 = self:GetAngles()
angle3:RotateAroundAxis(angle3:Up(), rotation3.x)
angle3:RotateAroundAxis(angle3:Forward(), rotation3.z)
local rotation4 = Vector(270, 0, 45)
local angle4 = self:GetAngles()
angle4:RotateAroundAxis(angle4:Up(), rotation4.x)
angle4:RotateAroundAxis(angle4:Forward(), rotation4.z)
local Up = 16
local wood1 = ents.Create("prop_dynamic")
wood1:SetPos(self:GetPos() + self:GetUp() * Up)
wood1:SetAngles(angle1)
wood1:SetModel("models/props_debris/wood_chunk01b.mdl")
wood1:Activate()
wood1:SetParent(self)
wood1:Spawn()
wood1:DeleteOnRemove(self)
local ground = ents.Create("prop_dynamic")
ground:SetPos(self:GetPos())
ground:SetAngles(self:GetAngles())
ground:SetModel("models/willardnetworks/skills/campfire.mdl")
ground:Activate()
ground:SetParent(self)
ground:Spawn()
ground:DeleteOnRemove(self)
local wood2 = ents.Create("prop_dynamic")
wood2:SetPos(self:GetPos() + self:GetUp() * Up)
wood2:SetAngles(angle2)
wood2:SetModel("models/props_debris/wood_chunk01b.mdl")
wood2:Activate()
wood2:SetParent(self)
wood2:Spawn()
wood2:DeleteOnRemove(self)
local wood3 = ents.Create("prop_dynamic")
wood3:SetPos(self:GetPos() + self:GetUp() * Up)
wood3:SetAngles(angle3)
wood3:SetModel("models/props_debris/wood_chunk01b.mdl")
wood3:Activate()
wood3:SetParent(self)
wood3:Spawn()
wood3:DeleteOnRemove(self)
local wood4 = ents.Create("prop_dynamic")
wood4:SetPos(self:GetPos() + self:GetUp() * Up)
wood4:SetAngles(angle4)
wood4:SetModel("models/props_debris/wood_chunk01b.mdl")
wood4:Activate()
wood4:SetParent(self)
wood4:Spawn()
wood4:DeleteOnRemove(self)
end
function ENT:OnRemove()
self:stopFire()
end
function ENT:startFire()
self:Ignite(1)
timer.Create( tostring(self:GetCreationID()), 1, 0,
function()
self:Ignite(1)
end)
end
function ENT:stopFire()
timer.Remove( tostring(self:GetCreationID()) )
self:Extinguish()
end

View File

@@ -0,0 +1,17 @@
--[[
| 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 = "RJ";
ENT.PrintName = "Feu de camp";
ENT.Spawnable = true;
ENT.AdminSpawnable = true;

View File

@@ -0,0 +1,65 @@
--[[
| 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
include('shared.lua')
netstream.Hook("OpenPickupDispenser", function(boughtItems, entity)
LocalPlayer().activePickupDispenser = entity
LocalPlayer().boughtItems = boughtItems
vgui.Create("PickupDispenser")
end)
netstream.Hook("OpenCIDSelector", function(entity)
LocalPlayer().activePickupDispenser = entity
local cidSelector = vgui.Create("CIDSelector")
cidSelector.activeEntity = entity
cidSelector.ExitCallback = function()
netstream.Start("ClosePanels", LocalPlayer().activePickupDispenser)
LocalPlayer().activePickupDispenser = nil
LocalPlayer().boughtItems = nil
end
cidSelector.SelectCallback = function(idCardID, cid, cidName, entity2)
netstream.Start("SelectCID", idCardID, cid, cidName, entity2)
end
end)
function ENT:Draw()
local position, angles = self:GetPos(), self:GetAngles()
local display = self.Displays[self:GetDisplay()] or self.Displays[6]
angles:RotateAroundAxis(angles:Forward(), 90)
angles:RotateAroundAxis(angles:Right(), 270)
cam.Start3D2D(position + self:GetForward() * 8.4 + self:GetRight()* 8.5 + self:GetUp() * 3, angles, 0.1)
render.PushFilterMin(TEXFILTER.NONE)
render.PushFilterMag(TEXFILTER.NONE)
surface.SetDrawColor(color_black)
surface.DrawRect(10, 16, 153, 40)
surface.SetDrawColor(60, 60, 60)
surface.DrawOutlinedRect(9, 16, 155, 40)
surface.SetDrawColor( Color( 255, 255, 255, 3 ) )
surface.DrawRect( 11, 36 + math.sin( CurTime() * 4 ) * 38 / 2, 151, 1 )
local alpha = 191 + 64 * math.sin( CurTime() * 4 )
local color = ColorAlpha(display[2], alpha)
draw.SimpleText(display[1], "MenuFont", 86, 36, color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
render.PopFilterMin()
render.PopFilterMag()
cam.End3D2D()
end

View File

@@ -0,0 +1,377 @@
--[[
| 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
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include('shared.lua')
function ENT:SpawnFunction(client, trace)
local dispenser = ents.Create("ix_pickupterminal")
dispenser:SetPos(trace.HitPos)
dispenser:SetAngles(trace.HitNormal:Angle())
dispenser:Spawn()
dispenser:Activate()
ix.saveEnts:SaveEntity(dispenser)
PLUGIN:SavePickupTerminals()
return dispenser
end
ix.log.AddType("pickupDispenserGotItem", function(client)
return string.format("[PICKUP DISPENSER] %s ( %s ) picked up an item from the pickup dispenser.", client:SteamName(), client:Name())
end)
function ENT:Initialize()
-- Because dispenser model has no physics object in order to allow pass through walls
self:SetModel("models/props_junk/watermelon01.mdl")
self:SetSolid(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:DrawShadow(false)
self:SetUseType(SIMPLE_USE)
self:SetDisplay(1)
self:PhysicsInit(SOLID_VPHYSICS)
self.dispenser = ents.Create("prop_dynamic")
self.dispenser:SetModel("models/props_combine/pickup_dispenser3.mdl")
self.dispenser:SetPos(self:GetPos())
self.dispenser:SetAngles(self:GetAngles())
self.dispenser:SetParent(self)
self.dispenser:Spawn()
self.dispenser:Activate()
self.dispenser:SetTrigger(true)
self:DeleteOnRemove(self.dispenser)
local physics = self.dispenser:GetPhysicsObject()
physics:EnableMotion(false)
physics:Wake()
self.canUse = true
self.nextUseTime = CurTime()
end
function ENT:ItemChoiceLogic(item, inventory, cid, purchasedItems)
if (item == "newspaper_printer") then
if (!inventory:Add(item, 1, {registeredCID = cid:GetData("cid")})) then
return false
end
elseif (item == "apartmentkey" or item == "shopkey") then
local housing = ix.plugin.list["housing"]
if housing and housing.GetApartmentByCID then
local cidData = cid:GetData("cid")
local appID = housing:GetApartmentByCID(cidData, item)
if appID then
if (!inventory:Add(item, 1, {cid = cidData, apartment = appID})) then
return false
end
end
end
elseif (string.find(item, "letter")) then
local itemData = purchasedItems[item]
if (!inventory:Add("paper", 1, {title = itemData.title, writingID = itemData.writingID, owner = itemData.currentOwner})) then
return false
end
else
if (!inventory:Add(item)) then
return false
end
end
return true
end
function ENT:GiveItem(client, item, cid)
local character = client:GetCharacter()
local inventory = character:GetInventory()
local itemTable = string.find(item, "letter") and ix.item.list["paper"] or ix.item.list[item]
if (!itemTable) then return false end
if (!inventory:FindEmptySlot(itemTable.width, itemTable.height)) then
return false
end
if !inventory:GetItemByID(cid.id) then
return false
end
if self.charLoaded then
if ix.char.loaded[self.charLoaded] then
local items = ix.char.loaded[self.charLoaded]:GetPurchasedItems()
if (!items[item] or (!istable(items[item]) and items[item] <= 0)) then
return false
end
if self:ItemChoiceLogic(item, inventory, cid, items) then
ix.char.loaded[self.charLoaded]:SetPurchasedItems(item)
ix.log.Add(client, "pickupDispenserGotItem")
end
end
else
if self.dbGeneric then
local queryObj = mysql:Select("ix_characters_data")
queryObj:Where("id", self.dbGeneric)
queryObj:Where("key", "purchasedItems")
queryObj:Select("data")
queryObj:Callback(function(result)
if (!istable(result) or !result[1]) then return end
if !result[1].data then return end
local items = util.JSONToTable(result[1].data)
if !items[item] then return end
if !istable(items[item]) then
if items[item] > 0 then
items[item] = items[item] - 1
if items[item] == 0 then
items[item] = nil
end
else
return
end
else
if items[item] then items[item] = nil end
end
if self:ItemChoiceLogic(item, inventory, cid, items) then
local updateQuery = mysql:Update("ix_characters_data")
updateQuery:Update("data", util.TableToJSON(items))
updateQuery:Where("id", self.dbGeneric)
updateQuery:Where("key", "purchasedItems")
updateQuery:Execute()
ix.log.Add(client, "pickupDispenserGotItem")
end
end)
queryObj:Execute()
end
end
self:EmitSound("buttons/button1.wav")
self:SetDisplay(3)
return true
end
function ENT:OpenCIDSelector(client)
netstream.Start(client, "OpenCIDSelector", self)
end
function ENT:CreateCombineAlert(client, message)
ix.combineNotify:AddImportantNotification(message, nil, client, self:GetPos())
end
function ENT.OpenDispenserFail(idCard, client, activeDispenser)
if (!IsValid(activeDispenser)) then return end
activeDispenser:SetDisplay(4)
activeDispenser:EmitSound("ambient/machines/combine_terminal_idle1.wav")
activeDispenser.charLoaded = nil
activeDispenser.dbGeneric = nil
activeDispenser.activeCID = nil
timer.Simple(2, function()
if IsValid(activeDispenser) then
activeDispenser:SetDisplay(1)
activeDispenser.canUse = true
end
end)
end
function ENT:CheckForVerdicts(client, idCard, genericData)
if (idCard:GetData("active", false) == false) then
self:CreateCombineAlert(client, "WRN:// Inactive Identification Card #" .. idCard:GetData("cid", 00000) .. " usage attempt detected")
self:SetDisplay(9)
timer.Simple(1.5, function()
if self then
self.OpenDispenserFail(nil, client, self)
end
end)
return
end
local isBOL = genericData.bol
local isAC = genericData.anticitizen
if (isBOL or isAC) then
local text = isBOL and "BOL Suspect" or "Anti-Citizen"
self:CreateCombineAlert(client, "WRN:// " .. text .. " Identification Card activity detected")
if isAC then
self:SetDisplay(9)
timer.Simple(1.5, function()
if self then
self.OpenDispenserFail(nil, client, self)
end
end)
end
return !isAC -- stop if isAC, continue for isBOL
end
return true
end
function ENT.OpenDispenser(idCard, genericData, client, activeTerminal)
if (!IsValid(activeTerminal)) then return end
activeTerminal:EmitSound("buttons/button4.wav")
activeTerminal:SetDisplay(2)
if (activeTerminal:CheckForVerdicts(client, idCard, genericData)) then
timer.Simple(2, function()
if table.IsEmpty(genericData) then
activeTerminal:SetDisplay(9)
activeTerminal:EmitSound("buttons/button2.wav")
timer.Simple(2, function()
if IsValid(activeTerminal) then
activeTerminal.charLoaded = nil
activeTerminal.dbGeneric = nil
activeTerminal.activeCID = nil
activeTerminal:SetDisplay(1)
activeTerminal.canUse = true
end
end)
else
activeTerminal:OnSuccess(idCard, genericData, client)
end
end)
end
end
function ENT:OnSuccess(idCard, genericData, client)
self:SetDisplay(7)
self:EmitSound("ambient/machines/combine_terminal_idle3.wav")
self.activeCID = idCard
if ix.char.loaded[genericData.id] then
self.charLoaded = genericData.id
netstream.Start(client, "OpenPickupDispenser", ix.char.loaded[genericData.id]:GetPurchasedItems(), self)
return
end
local queryObj = mysql:Select("ix_characters_data")
queryObj:Where("id", genericData.id)
queryObj:Where("key", "purchasedItems")
queryObj:Select("data")
queryObj:Callback(function(result)
if (!istable(result) or !result[1]) then return end
if !result[1].data then return end
netstream.Start(client, "OpenPickupDispenser", util.JSONToTable(result[1].data), self)
self.dbGeneric = genericData.id
end)
queryObj:Execute()
end
function ENT:CheckForCID(client)
local idCards = self.activeCharacter:GetInventory():GetItemsByUniqueID("id_card")
if (#idCards > 1) then
self:OpenCIDSelector(client)
return
end
if (#idCards == 1) then
idCards[1]:LoadOwnerGenericData(self.OpenDispenser, self.OpenDispenserFail, client, self)
else
self.canUse = false
self:EmitSound("buttons/button2.wav")
timer.Simple(1, function()
if (IsValid(self)) then
self.canUse = true
end
end)
end
end
function ENT:CheckGlobalUse(client)
if client.CantPlace then
client:NotifyLocalized("You need to wait before you can use this!")
return false
end
client.CantPlace = true
timer.Simple(3, function()
if client then
client.CantPlace = false
end
end)
return true
end
function ENT:CheckLocalUse(client)
if (!self.canUse and IsValid(self.activePlayer) and self.activePlayer:GetCharacter() == self.activeCharacter) then
return false
else
self.canUse = false
self.activePlayer = client
self.activeCharacter = client:GetCharacter()
return true
end
end
function ENT:StartTouch(entity)
if (entity:GetClass() != "ix_item") then return end
if !self.canUse then return end
self.canUse = false
local itemID = entity:GetItemID()
if ix.city:IsDisallowment(itemID) then
self:SetDisplay(11)
self:EmitSound("ambient/machines/combine_terminal_idle1.wav")
timer.Simple(2, function()
if IsValid(self) then
self:SetDisplay(1)
self.canUse = true
end
end)
else
ix.city.main:AddItem(itemID, entity:GetData("stack", 1))
entity:Remove()
self:SetDisplay(10)
self:EmitSound("ambient/machines/combine_terminal_idle1.wav")
timer.Simple(2, function()
if IsValid(self) then
self:SetDisplay(1)
self.canUse = true
end
end)
self:EmitSound("physics/metal/weapon_impact_soft" .. math.random(1, 3) .. ".wav")
end
end
function ENT:OnUse(client)
self:CheckForCID(client)
end
function ENT:Use(client)
if !self:CheckGlobalUse(client) then
return false
end
if !self:CheckLocalUse(client) then
return false
end
self:OnUse(client)
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 PLUGIN = PLUGIN
ENT.Type = "anim"
ENT.PrintName = "Terminal de dépôt"
ENT.Author = "Fruity"
ENT.Contact = "Willard Networks"
ENT.Purpose = "Ramasser les objets achetés avec certaines compétences."
ENT.Instructions = "Pressez E"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PhysgunDisable = true
ENT.bNoPersist = true
ENT.Displays = {
[1] = {"EN ATTENTE DU CID", Color( 255, 255, 180 ), true},
[2] = {"VÉRIFICATION", Color(255, 200, 0)},
[3] = {"DISTRIBUTION", Color(0, 255, 0)},
[4] = {"RECHARGEMENT", Color(255, 200, 0)},
[5] = {"HORS-LIGNE", Color(255, 0, 0), true},
[6] = {"EN ATTENTE DU CID", Color( 255, 255, 180 )},
[7] = {"PRÉPARATION", Color(0, 255, 0)},
[8] = {"AUCUN ARTICLE ACHETÉ", Color(0, 255, 0)},
[9] = {"CID INVALIDE", Color(255, 0, 0)},
[10] = {"OBJET AJOUTÉ", Color(0, 255, 0)},
[11] = {"OBJET RETIRÉ", Color(255, 0, 0), true},
}
function ENT:SetupDataTables()
self:NetworkVar("Int", 0, "Display")
end

View File

@@ -0,0 +1,564 @@
--[[
| 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
if (SERVER) then
AddCSLuaFile("shared.lua")
end
SWEP.PrintName = "CIVIL ADMINISTRATION PDA"
SWEP.Category = "Half-Life 2"
SWEP.Spawnable= true
SWEP.AdminSpawnable= true
SWEP.AdminOnly = false
SWEP.ViewModelFOV = 70
SWEP.ViewModel = "models/weapons/c_slam.mdl"
SWEP.WorldModel = "models/weapons/c_slam.mdl"
SWEP.ShowViewModel = false
SWEP.ShowWorldModel = false
SWEP.ViewModelFlip = false
SWEP.BobScale = 1
SWEP.SwayScale = 0
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false
SWEP.Weight = 0
SWEP.Slot = 0
SWEP.SlotPos = 1
SWEP.UseHands = true
SWEP.FireWhenLowered = true
SWEP.FiresUnderwater = true
SWEP.DrawAmmo = false
SWEP.CSMuzzleFlashes = 1
SWEP.Base = "weapon_base"
SWEP.IsAlwaysRaised = true
SWEP.HoldType = "knife"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = ""
SWEP.Primary.Damage = 5
SWEP.Primary.Delay = 0.75
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = 0
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = ""
SWEP.Secondary.Delay = 0.5
SWEP.MaxOffFlat = 80 -- Maximum degrees off of flat to be.
SWEP.LastFire = 0
SWEP.IronSightsPos = Vector(0, 0, 0)
SWEP.IronSightsAng = Vector(0, 0, 0)
SWEP.ViewModelBoneMods = {
["ValveBiped.Bip01_R_UpperArm"] = { scale = Vector(1, 1, 1), pos = Vector(-1, 1, 0), angle = Angle(5, 10, 5) },
["ValveBiped.Bip01_L_UpperArm"] = { scale = Vector(1, 1, 1), pos = Vector(-3.5,-1.8, 0.8), angle = Angle(12, -5, 0) },
["Slam_base"] = { scale = Vector(0.001, 0.001, 0.001), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) },
["Detonator"] = { scale = Vector(0.001, 0.001, 0.001), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
}
SWEP.VElements = {
["v_element"] = { type = "Model", model = "models/fruity/pda.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(4.68, 2.7514, -1.198), angle = Angle(-90, -50.392, 90), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
}
SWEP.WElements = {
["w_element"] = { type = "Model", model = "models/fruity/pda.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(5, 1.111, 0), angle = Angle(-90, -50.392, 90), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
}
function SWEP:Initialize()
self:SetWeaponHoldType( self.HoldType )
if CLIENT then
// Create a new table for every weapon instance
self.VElements = table.FullCopy( self.VElements )
self.WElements = table.FullCopy( self.WElements )
self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
self:SetWeaponHoldType( self.HoldType )
self:CreateModels(self.VElements) // create viewmodels
self:CreateModels(self.WElements) // create worldmodels
// init view model bone build function
if IsValid(self.Owner) then
local vm = self.Owner:GetViewModel()
if IsValid(vm) then
self:ResetBonePositions(vm)
// Init viewmodel visibility
if (self.ShowViewModel == nil or self.ShowViewModel) then
vm:SetColor(Color(255,255,255,255))
else
// we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
vm:SetColor(Color(255,255,255,1))
// ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
// however for some reason the view model resets to render mode 0 every frame so we just apply a debug material to prevent it from drawing
vm:SetMaterial("Debug/hsv")
end
end
end
end
end
////////////////////////////////////////////////////
if CLIENT then
SWEP.vRenderOrder = nil
function SWEP:ViewModelDrawn()
local vm = self.Owner:GetViewModel()
if !IsValid(vm) then return end
if (!self.VElements) then return end
self:UpdateBonePositions(vm)
if (!self.vRenderOrder) then
// we build a render order because sprites need to be drawn after models
self.vRenderOrder = {}
for k, v in pairs( self.VElements ) do
if (v.type == "Model") then
table.insert(self.vRenderOrder, 1, k)
elseif (v.type == "Sprite" or v.type == "Quad") then
table.insert(self.vRenderOrder, k)
end
end
end
for k, name in ipairs( self.vRenderOrder ) do
local v = self.VElements[name]
if (!v) then self.vRenderOrder = nil break end
if (v.hide) then continue end
local model = v.modelEnt
local sprite = v.spriteMaterial
if (!v.bone) then continue end
local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
if (!pos) then continue end
if (v.type == "Model" and IsValid(model)) then
model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
model:SetAngles(ang)
//model:SetModelScale(v.size)
local matrix = Matrix()
matrix:Scale(v.size)
model:EnableMatrix( "RenderMultiply", matrix )
if (v.material == "") then
model:SetMaterial("")
elseif (model:GetMaterial() != v.material) then
model:SetMaterial( v.material )
end
model:SetSkin(0)
if (v.bodygroup) then
for k, v in pairs( v.bodygroup ) do
if (model:GetBodygroup(k) != v) then
model:SetBodygroup(k, v)
end
end
end
if (v.surpresslightning) then
render.SuppressEngineLighting(true)
end
render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
render.SetBlend(v.color.a/255)
model:DrawModel()
render.SetBlend(1)
render.SetColorModulation(1, 1, 1)
if (v.surpresslightning) then
render.SuppressEngineLighting(false)
end
elseif (v.type == "Sprite" and sprite) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
render.SetMaterial(sprite)
render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
elseif (v.type == "Quad" and v.draw_func) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
cam.Start3D2D(drawpos, ang, v.size)
v.draw_func( self )
cam.End3D2D()
end
end
end
SWEP.wRenderOrder = nil
function SWEP:DrawWorldModel()
if (self.ShowWorldModel == nil or self.ShowWorldModel) then
end
if (!self.WElements) then return end
if (!self.wRenderOrder) then
self.wRenderOrder = {}
for k, v in pairs( self.WElements ) do
if (v.type == "Model") then
table.insert(self.wRenderOrder, 1, k)
elseif (v.type == "Sprite" or v.type == "Quad") then
table.insert(self.wRenderOrder, k)
end
end
end
if (IsValid(self.Owner)) then
bone_ent = self.Owner
else
// when the weapon is dropped
bone_ent = self
end
for k, name in pairs( self.wRenderOrder ) do
local v = self.WElements[name]
if (!v) then self.wRenderOrder = nil break end
if (v.hide) then continue end
local pos, ang
if (v.bone) then
pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
else
pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
end
if (!pos) then continue end
local model = v.modelEnt
local sprite = v.spriteMaterial
if (v.type == "Model" and IsValid(model)) then
model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
model:SetAngles(ang)
//model:SetModelScale(v.size)
local matrix = Matrix()
matrix:Scale(v.size)
model:EnableMatrix( "RenderMultiply", matrix )
if (v.material == "") then
model:SetMaterial("")
elseif (model:GetMaterial() != v.material) then
model:SetMaterial( v.material )
end
model:SetSkin(0)
if (v.bodygroup) then
for k, v in pairs( v.bodygroup ) do
if (model:GetBodygroup(k) != v) then
model:SetBodygroup(k, v)
end
end
end
if (v.surpresslightning) then
render.SuppressEngineLighting(true)
end
render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
render.SetBlend(v.color.a/255)
model:DrawModel()
render.SetBlend(1)
render.SetColorModulation(1, 1, 1)
if (v.surpresslightning) then
render.SuppressEngineLighting(false)
end
elseif (v.type == "Sprite" and sprite) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
render.SetMaterial(sprite)
render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
elseif (v.type == "Quad" and v.draw_func) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
cam.Start3D2D(drawpos, ang, v.size)
v.draw_func( self )
cam.End3D2D()
end
end
end
function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
local bone, pos, ang
if (tab.rel and tab.rel != "") then
local v = basetab[tab.rel]
if (!v) then return end
pos, ang = self:GetBoneOrientation( basetab, v, ent )
if (!pos) then return end
pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
else
bone = ent:LookupBone(bone_override or tab.bone)
if (!bone) then return end
pos, ang = Vector(0,0,0), Angle(0,0,0)
local m = ent:GetBoneMatrix(bone)
if (m) then
pos, ang = m:GetTranslation(), m:GetAngles()
end
if (IsValid(self.Owner) and self.Owner:IsPlayer() and
ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
ang.r = -ang.r // Fixes mirrored models
end
end
return pos, ang
end
function SWEP:CreateModels( tab )
if (!tab) then return end
for k, v in pairs( tab ) do
if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
if (IsValid(v.modelEnt)) then
v.modelEnt:SetPos(self:GetPos())
v.modelEnt:SetAngles(self:GetAngles())
v.modelEnt:SetParent(self)
v.modelEnt:SetNoDraw(true)
v.createdModel = v.model
else
v.modelEnt = nil
end
elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
local name = v.sprite.."-"
local params = { ["$basetexture"] = v.sprite }
// make sure we create a unique name based on the selected options
local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
for i, j in pairs( tocheck ) do
if (v[j]) then
params["$"..j] = 1
name = name.."1"
else
name = name.."0"
end
end
v.createdSprite = v.sprite
v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
end
end
end
local allbones
local hasGarryFixedBoneScalingYet = false
function SWEP:UpdateBonePositions(vm)
if self.ViewModelBoneMods then
if (!vm:GetBoneCount()) then return end
// !! WORKAROUND !! //
// We need to check all model names :/
local loopthrough = self.ViewModelBoneMods
if (!hasGarryFixedBoneScalingYet) then
allbones = {}
for i=0, vm:GetBoneCount() do
local bonename = vm:GetBoneName(i)
if (self.ViewModelBoneMods[bonename]) then
allbones[bonename] = self.ViewModelBoneMods[bonename]
else
allbones[bonename] = {
scale = Vector(1,1,1),
pos = Vector(0,0,0),
angle = Angle(0,0,0)
}
end
end
loopthrough = allbones
end
// !! ----------- !! //
for k, v in pairs( loopthrough ) do
local bone = vm:LookupBone(k)
if (!bone) then continue end
// !! WORKAROUND !! //
local s = Vector(v.scale.x,v.scale.y,v.scale.z)
local p = Vector(v.pos.x,v.pos.y,v.pos.z)
local ms = Vector(1,1,1)
if (!hasGarryFixedBoneScalingYet) then
local cur = vm:GetBoneParent(bone)
while(cur >= 0) do
local pscale = loopthrough[vm:GetBoneName(cur)].scale
ms = ms * pscale
cur = vm:GetBoneParent(cur)
end
end
s = s * ms
// !! ----------- !! //
if vm:GetManipulateBoneScale(bone) != s then
vm:ManipulateBoneScale( bone, s )
end
if vm:GetManipulateBoneAngles(bone) != v.angle then
vm:ManipulateBoneAngles( bone, v.angle )
end
if vm:GetManipulateBonePosition(bone) != p then
vm:ManipulateBonePosition( bone, p )
end
end
else
self:ResetBonePositions(vm)
end
end
function SWEP:ResetBonePositions(vm)
if (!vm:GetBoneCount()) then return end
for i=0, vm:GetBoneCount() do
vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
end
end
function table.FullCopy( tab )
if (!tab) then return nil end
local res = {}
for k, v in pairs( tab ) do
if (type(v) == "table") then
res[k] = table.FullCopy(v)
elseif (type(v) == "Vector") then
res[k] = Vector(v.x, v.y, v.z)
elseif (type(v) == "Angle") then
res[k] = Angle(v.p, v.y, v.r)
else
res[k] = v
end
end
return res
end
end
////////////////////////////////////////////////////
function SWEP:Deploy()
--if !IsValid(self.Owner.C4s) then self.Owner.C4s = {} end
self.Weapon:SendWeaponAnim(ACT_SLAM_TRIPMINE_DRAW)
end
function SWEP:PrimaryAttack()
self:EmitSound( "UI/buttonclick.wav" )
self:SetNextPrimaryFire( CurTime()+2 )
if CLIENT and IsFirstTimePredicted() then
if self.Owner:GetCharacter() then
if self.Owner:GetCharacter():GetFaction() == FACTION_ADMIN then
if IsValid(self.Owner) then
netstream.Start("GetMessageList")
end
end
end
end
end
function SWEP:SecondaryAttack()
end
function SWEP:Holster()
if CLIENT and IsValid(self.Owner) then
local vm = self.Owner:GetViewModel()
if IsValid(vm) then
self:ResetBonePositions(vm)
end
end
return true
end
function SWEP:OnRemove()
self:Holster()
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/
--]]
AddCSLuaFile()
SWEP.PrintName = "Placeur d'établi"
SWEP.Author = "JohnyReaper/Fruity"
SWEP.Purpose = ""
SWEP.Category = "HL2 RP"
SWEP.Slot = 0
SWEP.SlotPos = 1
SWEP.ViewModel = Model("")
SWEP.WorldModel = Model("")
SWEP.ViewModelFOV = 70
SWEP.UseHands = false
SWEP.HoldType = "normal"
SWEP.Ent = "ix_item"
SWEP.BarricadePlace = nil
SWEP.item = false
SWEP.PreviewModel = false
SWEP.Spawnable = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.DrawAmmo = false
SWEP.IsAlwaysLowered = true
SWEP.FireWhenLowered = true
function SWEP:Initialize()
self:SetWeaponHoldType(self.HoldType)
if CLIENT then
self:GhostProp()
end
end
function SWEP:Deploy()
if CLIENT then
self:GhostProp()
end
end
if (CLIENT) then
SWEP.nextModelRequest = CurTime()
net.Receive("ixRequestWorkBenchGhostModel", function()
local model = net.ReadString()
if LocalPlayer().ghostProp and IsValid(LocalPlayer().ghostProp) then
LocalPlayer().ghostProp:SetModel(model)
end
end)
else
util.AddNetworkString("ixRequestWorkBenchGhostModel")
net.Receive("ixRequestWorkBenchGhostModel", function(_, client)
local weapon = client:GetActiveWeapon()
if IsValid(weapon) and weapon.GetClass and weapon:GetClass() == "weapon_workbench_placer" then
net.Start("ixRequestWorkBenchGhostModel")
net.WriteString(weapon.PreviewModel)
net.Send(client)
end
end)
end
function SWEP:GhostProp()
if (IsValid(self.ghostProp)) then self.ghostProp:Remove() end
self.ghostProp = ents.CreateClientProp()
local curTime = CurTime()
if !self.PreviewModel and self.nextModelRequest <= curTime then
LocalPlayer().ghostProp = self.ghostProp
net.Start("ixRequestWorkBenchGhostModel")
net.SendToServer()
self.nextModelRequest = curTime + 2
return
end
-- self.ghostProp:SetMaterial("models/wireframe")
self.ghostProp:Spawn()
self.ghostProp:Activate()
self.ghostProp:SetParent(self.Owner)
self.ghostProp:SetRenderMode(RENDERMODE_TRANSALPHA)
end
function SWEP:CalcViewModelView(vm, oldPos, oldAng, pos, ang)
local newPos = pos + ang:Up() * 5 + ang:Forward()
return newPos, ang
end
function SWEP:SetInfo(uniqueID, model)
self.item = uniqueID
self.PreviewModel = model
end
function SWEP:PrimaryAttack()
local tr = self.Owner:GetEyeTrace()
if (game.SinglePlayer()) then self:CallOnClient("PrimaryAttack") end
if (SERVER) then
self.Owner:SetAnimation(PLAYER_ATTACK1)
end
if (tr.HitWorld) then
if (!self.BarricadePlace) then
self.BarricadePlace = self.Owner:GetPos() + Angle(0, self.Owner:GetAngles().y, 0):Forward() * 50 + Angle(0, self.Owner:GetAngles().y, 0):Right() * -10 + Angle(0, self.Owner:GetAngles().y, 0):Up()
self.testowyang = Angle(0, self.Owner:GetAngles().y + 180, 0):SnapTo("y", 1)
end
if (SERVER) then
if (self.BarricadePlace) then
local angles = self.testowyang
angles.p = 0
angles.r = 0
angles:RotateAroundAxis(angles:Up(), 360)
if (self.item) then
local client = self:GetOwner()
local char = client.GetCharacter and client:GetCharacter()
local id = char and char.GetID and char:GetID()
local actualItem = char:GetInventory():HasItem(self.item)
if (actualItem) then
actualItem:Remove()
local currentItems = client:GetNetVar("visibleItems", {})
local itemName = ix.item.list[self.item].name
if (currentItems[itemName]) then
currentItems[itemName] = nil
end
client:SetNetVar("visibleItems", currentItems)
if (id) then
ix.item.Spawn(self.item, self.BarricadePlace, function(_, entity)
if IsValid(entity) then
local physObj = entity:GetPhysicsObject()
if IsValid(physObj) then
physObj:EnableMotion( false )
end
end
end, angles, {placer = id})
end
end
end
if (self.Owner.previousWep) then
self.Owner:SelectWeapon(self.Owner.previousWep)
self.Owner.previousWep = nil
end
self:Remove()
end
end
self.Owner:EmitSound("physics/metal/metal_canister_impact_soft"..math.random(1,3)..".wav", 60, 100, 0.5)
end
end
function SWEP:SecondaryAttack()
if (SERVER) then
local char = self.Owner:GetCharacter()
local inventory = char:GetInventory()
if (self.Owner.previousWep) then
self.Owner:SelectWeapon(self.Owner.previousWep)
self.Owner.previousWep = nil
end
self:Remove()
end
end
if (CLIENT) then
function SWEP:DrawHUD()
local ply = LocalPlayer()
if (!ply:Alive()) then return end
draw.SimpleTextOutlined("CLIQUE GAUCHE pour placer", "DermaLarge", ScrW() / 2, ScrH()-230, Color(250,250,250), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(25, 25, 25, 250))
draw.SimpleTextOutlined("CLIQUE DROIT pour annuler", "DermaLarge", ScrW() / 2, ScrH()-200, Color(250,250,250), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(25, 25, 25, 250))
end
end
function SWEP:Think()
if (CLIENT) then
if (IsValid(self.ghostProp)) then
self.ghostProp:SetPos(self.Owner:GetPos() + Angle(0, self.Owner:GetAngles().y, 0):Forward() * 50 + Angle(0, self.Owner:GetAngles().y, 0):Right() * -10 + Angle(0, self.Owner:GetAngles().y, 0):Up() )
self.ghostProp:SetAngles(Angle(0, self.Owner:GetAngles().y + 180, 0):SnapTo("y", 1))
else
self:GhostProp()
end
end
end
function SWEP:PreDrawViewModel()
if (CLIENT) then
if (!IsValid(self.ghostProp)) then
self:GhostProp()
end
end
end
function SWEP:Holster()
if (CLIENT) then
if (IsValid(self.ghostProp)) then
self.ghostProp:Remove()
end
end
if (SERVER) then
self:Remove()
end
return true
end
function SWEP:OnDrop()
self:Remove()
end
function SWEP:OnRemove()
if (CLIENT) then
if (IsValid(self.ghostProp)) then
self.ghostProp:Remove()
end
end
end

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "tool_ammunitionbench_assembly"
ITEM.name = "Kit de montage - Table de munitions"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_ammunitionbench"
ITEM.openRequirementAmount = 1
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,21 @@
--[[
| 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.uniqueID = "tool_chembench_assembly"
ITEM.name = "Kit de montage - Établi de chimie"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_chembench"
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,21 @@
--[[
| 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.uniqueID = "tool_craftingbench_assembly"
ITEM.name = "Kit de montage - Table de craft"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_craftingbench"
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "tool_creammachine_assembly"
ITEM.name = "Ice Cream Machine Assembly Kit"
ITEM.description = "Alongside a set of instructions, this wooden package contains a high ordeal of different component pieces for Crafting apperatus."
ITEM.category = "Tools"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_creammachine"
ITEM.openRequirementAmount = 1
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "tool_metalbench_assembly"
ITEM.name = "Kit de montage - Table de métalurgie"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_metalbench"
ITEM.openRequirementAmount = 1
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,21 @@
--[[
| 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.uniqueID = "tool_oven_assembly"
ITEM.name = "Kit de montage du four"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_oven"
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,21 @@
--[[
| 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.uniqueID = "tool_oven_rusty_assembly"
ITEM.name = "Kit dassemblage de four rouillé"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_oven_rusty"
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,21 @@
--[[
| 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.uniqueID = "tool_refinery_assembly"
ITEM.name = "Kit dassemblage de raffinerie"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_refinery"
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "tool_vehiclebench_assembly"
ITEM.name = "Ensemble banc de véhicule"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette station."
ITEM.category = "Outils"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_vehiclebench"
ITEM.openRequirementAmount = 1
ITEM.openRequirement = "tool_toolkit"

View File

@@ -0,0 +1,82 @@
--[[
| 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.uniqueID = "base_assembly"
ITEM.name = "Kit d'assemblage de base"
ITEM.description = "Alongside a set of instructions, this wooden package contains a high ordeal of different component pieces for Crafting apperatus."
ITEM.category = "Tools"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.useSound = "physics/metal/metal_box_break1.wav"
ITEM.openedItem = "tool_craftingbench"
ITEM.openRequirement = "tool_toolkit"
ITEM.functions.Assemble = {
icon = "icon16/wrench.png",
OnCanRun = function(item)
return !IsValid(item.entity)
end,
OnRun = function(item)
local client = item.player
if (client.CantPlace) then
client:NotifyLocalized("assembleCant")
return false
end
client.CantPlace = true
timer.Simple(3, function()
if (client) then
client.CantPlace = false
end
end)
local character = client:GetCharacter()
local inventory = character:GetInventory()
local requirementTable = ix.item.list[item.openRequirement]
local requirementName = requirementTable.name or item.openRequirement
local openerItem = inventory:HasItem(item.openRequirement)
if (!openerItem) then
client:NotifyLocalized("assembleMissingRequirement", requirementName)
return false
else
if (item.openedItem) then
local openedItemName = ix.item.list[item.openedItem].name or item.openedItem
local openedItemWidth, openedItemHeight = ix.item.list[item.openedItem].width, ix.item.list[item.openedItem].height
timer.Simple(0.25, function()
if (inventory:FindEmptySlot(openedItemWidth, openedItemHeight)) then
inventory:Add(item.openedItem)
if (openerItem.isTool) then
openerItem:DamageDurability(1)
end
client:EmitSound(item.useSound)
client:NotifyLocalized("assembleSuccess", openedItemName)
else
client:NotifyLocalized("assembleNoSpace", openedItemWidth, openedItemHeight)
inventory:Add(item.uniqueID)
end
end)
else
return false
end
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 = "Base de composants d'artisanat"
ITEM.description = "Just for file structuring, not an item."
ITEM.category = "Crafting Components"
ITEM.base = "base_stackable"
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,13 @@
--[[
| 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 = "Socle factice"
ITEM.description = "Juste pour structurer un fichier, pas un élément."
ITEM.category = "Dummy"

View File

@@ -0,0 +1,13 @@
--[[
| 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 = "Expedition Base"
ITEM.description = "Just for file structuring, not an item."
ITEM.category = "Expedition"

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 = "Ingredient Base"
ITEM.description = "Just for file structuring, not an item."
ITEM.category = "Ingredients"
ITEM.base = "base_stackable"
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,13 @@
--[[
| 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 = "Junk Base"
ITEM.description = "Just for file structuring, not an item."
ITEM.category = "Junk"

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 = "Medical Components Base"
ITEM.description = "Just for file structuring, not an item."
ITEM.category = "Medical Components"
ITEM.base = "base_stackable"
ITEM.maxStackSize = 4

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/
--]]
ITEM.name = "Workbench Base"
ITEM.description = "It is a workbench. Can only be picked up by the first person to place it."
ITEM.category = "Workbenches"
ITEM.isWorkbench = true
ITEM.functions.place = {
name = "Placer",
tip = "Place the workbench",
icon = "icon16/brick_add.png",
OnRun = function(item)
local client = item.player
if (!client:Alive()) then return false end
client:EmitSound("physics/cardboard/cardboard_box_break3.wav")
client.previousWep = client:GetActiveWeapon():GetClass()
client:Give("weapon_workbench_placer")
client:SelectWeapon("weapon_workbench_placer")
local weapon = client:GetActiveWeapon()
weapon:SetInfo(item.uniqueID, item.model)
return false
end,
OnCanRun = function(item)
return (!IsValid(item.entity))
end
}
ITEM.functions.Use = {
name = "Utiliser",
icon = "icon16/wrench.png",
OnCanRun = function(itemTable)
return IsValid(itemTable.entity)
end,
OnClick = function(itemTable)
LocalPlayer().lastSelectedSkill = itemTable.workbenchSkill
ix.gui.lastMenuTab = 3
if (!IsValid(ix.gui.menu)) then
vgui.Create("ixMenu")
end
end,
OnRun = function(itemTable)
return false
end
}
ITEM.functions.PackUp = {
name = "Emballer",
icon = "icon16/box.png",
OnRun = function(item)
local client = item.player
local character = client and IsValid(client) and client.GetCharacter and client:GetCharacter()
local inventory = character:GetInventory()
local toolkit = inventory:HasItem("tool_toolkit")
if (!toolkit) then
client:Notify("Vous avez besoin d'une trousse à outil pour emballer cela !")
return false
end
if (item:GetData("bolted", false)) then
client:Notify("Cette station est visée !")
return false
end
local placerData = item:GetData("placer", false)
if placerData and character:GetID() != placerData then
client:Notify("Vous ne possédez pas cela !")
return false
end
client:SetAction("Emballage en cours...", 10, function()
if (inventory:Add(item.uniqueID .. "_assembly")) then
toolkit:DamageDurability(1)
client:Notify("Station emballée.")
else
client:Notify("Vous n'avez pas assez de place pour emballer cela !")
return false
end
end)
end,
OnCanRun = function(item)
return !item.noPackUp
end
}
ITEM.functions.Bolt = {
name = "Viser",
icon = "icon16/wrench.png",
OnRun = function(item)
local client = item.player
local inventory = client:GetCharacter():GetInventory()
local toolkit = inventory:HasItem("tool_toolkit")
if (!toolkit) then
client:Notify("Vous avez besoin d'une caisse à outil !")
return false
end
client:SetAction("Vous vissez la station.", 10, function()
item:SetData("bolted", true)
client:Notify("Vous avez visé la station.")
end)
toolkit:DamageDurability(1)
return false
end,
OnCanRun = function(itemTable)
return itemTable.entity and itemTable.entity:IsValid() and !itemTable:GetData("bolted", false)
end
}
ITEM.functions.UnBolt = {
name = "Déviser",
icon = "icon16/wrench_orange.png",
OnRun = function(item)
local client = item.player
if (client:IsAdmin()) then
item:SetData("bolted", false)
client:Notify("Table dévisée.")
else
client:Notify("Nécessite la supervision d'un Admin.")
end
return false
end,
OnCanRun = function(itemTable)
return itemTable.entity and itemTable.entity:IsValid() and itemTable:GetData("bolted", false)
end
}
ITEM.postHooks.drop = function(item, result)
if (item.player and !item:GetData("placer")) then
item:SetData("placer", item.player:GetCharacter():GetID())
end
end
function ITEM:CanTransfer(oldInventory, newInventory)
local placerData = self:GetData("placer", false)
local newInvOwner = newInventory and newInventory.GetOwner and newInventory:GetOwner()
if newInventory and newInvOwner then
if newInvOwner and IsValid(newInvOwner) then
if placerData and newInvOwner.GetCharacter and newInvOwner:GetCharacter():GetID() != placerData then
newInvOwner:Notify("Vous n'êtes pas le propriétaire !")
return false
end
end
end
return true
end
function ITEM:OnEntityCreated(entity)
timer.Simple(1, function()
if (IsValid(entity)) then
local physObj = entity:GetPhysicsObject()
physObj:EnableMotion(false)
end
end)
end
function ITEM:OnEntityTakeDamage(entity, damage)
return false
end

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Kit d'assemblage d'arcade"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette machine d'arcade."
ITEM.category = "Autres"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.colorAppendix = {["red"] = "Contactez un administrateur pour le convertir en une entité de machine d'arcade."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,17 @@
--[[
| 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 = "Matériaux de construction"
ITEM.description = "Matériaux de construction fournis par la zone logistique de l'UTC."
ITEM.category = "Autres"
ITEM.width = 2
ITEM.height = 2
ITEM.model = "models/props_junk/cardboard_box001a.mdl"
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Kit d'assemblage de table à dames"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire une table à dames."
ITEM.category = "Autres"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.colorAppendix = {["red"] = "Contact an admin to convert this into a checkers table entity."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Kit d'assemblage de table d'échecs"
ITEM.description = "En plus dun ensemble dinstructions, cette caisse en bois contient une inscription avec les différents composants pour construire cette table d'échecs."
ITEM.category = "Autres"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.colorAppendix = {["red"] = "Contact an admin to convert this into a chess table entity."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,28 @@
--[[
| 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.uniqueID = "comp_charcoal"
ITEM.name = "Charbon"
ITEM.description = "Ce bloc de charbon rugueux et solide est prêt à être utilisé pour alimenter le feu et vous fournir de la chaleur et de la lumière dans votre aventure."
ITEM.description = "Un petit morceau de charbon noir et solide, issu de la combustion du bois ou du charbon."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/props/charcoal.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat.", ["red"] = "Les unités PC vous considéreront comme suspect s'ils vous trouvent avec cet objet."}
ITEM.iconCam = {
pos = Vector(1642.86, 1354.28, 862.92),
ang = Angle(22.03, 219.49, 0),
fov = 0.27
}
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,24 @@
--[[
| 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.uniqueID = "comp_charcoal_refill"
ITEM.name = "Recharge de filtre à charbon"
ITEM.description = "Cette recharge de filtre à charbon permet de purifier l'air et de maintenir l'efficacité de votre système de ventilation, garantissant une respiration saine dans les environnements les plus extrêmes."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/props/charcoal.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat."}
ITEM.maxStackSize = 2
ITEM.iconCam = {
pos = Vector(1642.86, 1354.28, 862.92),
ang = Angle(22.03, 219.49, 0),
fov = 0.27
}

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.uniqueID = "comp_cloth"
ITEM.name = "Tissu sale"
ITEM.description = "Cette pièce de tissu sale semble avoir été utilisée pendant un certain temps et nécessite un bon nettoyage avant de pouvoir être utilisée à nouveau."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/cloth.mdl"
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "Il est suspect de transporter plus de 8 objets de ce genre."}
ITEM.maxStackSize = 8

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.uniqueID = "comp_condensed_resin"
ITEM.name = "Résine condensé"
ITEM.description = "Une substance cylindrique solide grise qui semble douce au toucher. Légère et facilement cassable... pourrait être utilisée dans une machine compatible"
ITEM.category = "Crafting"
ITEM.model = "models/willardnetworks/props_combine/resin_puck.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(173.79, 146.1, 107.55),
ang = Angle(25.1, 219.9, 0),
fov = 3.8
}
ITEM.outlineColor = Color(255, 102, 0)

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 = "Circuits électroniques"
ITEM.description = "Cet ensemble complexe de circuits électroniques brille légèrement à la lumière, évoquant la puissance de la technologie moderne et les innombrables possibilités qu'elle offre."
ITEM.name = "Circuit électronique"
ITEM.description = "Une mince plaque de matériau isolant avec une série de composants électroniques interconnectés."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/circuit.mdl"
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "Il est suspect de transporter plus de 8 objets de ce genre."}
ITEM.maxStackSize = 8

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "comp_explosive"
ITEM.name = "Matériau hautement explosif"
ITEM.description = "Ce matériau instable est enveloppé d'une substance dangereuse. La moindre étincelle pourrait déclencher une réaction en chaîne dévastatrice. Mieux vaut le manipuler avec prudence, car la moindre erreur pourrait avoir des conséquences désastreuses pour tous les gens autour de vous."
ITEM.description = "Ce matériau instable est enveloppé dans une petite valise. La moindre étincelle pourrait déclencher une réaction en chaîne dévastatrice."
ITEM.category = "Crafting"
ITEM.width = 2
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/explosive_material.mdl"
ITEM.maxStackSize = 2

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.uniqueID = "comp_fabric"
ITEM.name = "Tissu travaillé"
ITEM.description = "Cette pièce de tissu doux et soyeux est agréable au toucher, offrant une texture confortable et une apparence élégante. Parfait pour les vêtements ou les travaux de couture, ce tissu est une excellente addition à tout inventaire d'artisanat."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/fabric.mdl"
ITEM.colorAppendix = {["red"] = "La PC vous considéreront comme suspect si vous êtes trouvé en possession de cet objet."}
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,24 @@
--[[
| 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.uniqueID = "comp_glass"
ITEM.name = "Éclat de verre"
ITEM.description = "Cet éclat de verre pointu et scintillant est le résultat d'une destruction brutale. Manipulez-le avec précaution pour éviter les blessures, mais il peut être utile pour fabriquer des outils tranchants ou des miroirs improvisés"
ITEM.category = "Crafting"
ITEM.model = "models/props/de_aztec/hr_aztec/aztec_lighting/aztec_lighting_lantern_01_glass_unlit_shard_3.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(173.79, 146.1, 107.55),
ang = Angle(25.1, 220.03, 0),
fov = 5.26
}
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "ATTENTION : cet élément peut être supprimé"}
ITEM.maxStackSize = 8

View File

@@ -0,0 +1,17 @@
--[[
| 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 = "Étui à grenades vide"
ITEM.description = "Cet étui à grenades vides est robuste et résistant, mais actuellement vide et inutile. Il pourrait toutefois être utile pour être transformé en un objet pratique pour votre aventure."
ITEM.category = "Crafting"
ITEM.model = "models/weapons/tfa_mmod/w_grenade_thrown.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.maxStackSize = 2

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "comp_improved_nails_screws"
ITEM.name = "Boîte de boulons"
ITEM.description = "Cette boîte de boulons contient une variété de tailles et de formes, allant des plus petits aux plus grands. Parfaits pour les réparations, les constructions ou pour improviser des outils, ces boulons peuvent s'avérer utiles dans de nombreuses situations au cours de votre aventure."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_lab/box01a.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriquer avec la compétence de Craft.", ["red"] = "La protection civile vous trouvera suspect avec cet objet."}
ITEM.outlineColor = Color(255, 204, 0, 100)
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,28 @@
--[[
| 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.uniqueID = "comp_metal"
ITEM.name = "Morceau de ferraille"
ITEM.description = "Ce petit morceau de ferraille semble avoir été abandonné depuis longtemps, peut-être après avoir été détaché d'une machine ou d'un véhicule. Bien qu'apparemment inutile, il pourrait être transformé en quelque chose d'utile par ceux qui ont l'expertise et les outils nécessaires pour travailler avec les métaux."
ITEM.description = "Ce petit morceau de ferraille semble avoir été abandonné depuis longtemps, peut-être après avoir été détaché d'une machine ou d'un véhicule. Il pourrait être transformé en quelque chose d'utile par ceux qui ont l'expertise et les outils nécessaires."
ITEM.category = "Crafting"
ITEM.model = "models/willardnetworks/props/scrap.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(509.64, 427.61, 310.24),
ang = Angle(25, 220, 0),
fov = 1.27
}
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "Il est suspect de transporter plus de 8 objets de ce genre."}
ITEM.maxStackSize = 8

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Circuit imprimé de qualité militaire"
ITEM.description = "Circuit imprimé de qualité militaire est un composant électronique de haute précision, conçu pour résister aux environnements les plus extrêmes et offrir des performances fiables dans des conditions de combat intenses. Cette pièce peut être utilisée pour réparer ou améliorer les équipements électroniques existants, ou pour créer des gadgets de haute technologie pour aider dans votre mission."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_lab/reciever01d.mdl"
ITEM.maxStackSize = 4

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.uniqueID = "comp_nails_screws"
ITEM.name = "Tas de vis"
ITEM.description = "Ce tas de vis contient une grande variété de tailles et de types de vis, allant des plus petits aux plus grands. Bien qu'apparemment banal, ces vis peuvent être très utiles pour les bricoleurs et les artisans, leur permettant de fixer solidement les pièces ensemble ou de créer de nouveaux assemblages. Avec suffisamment de vis et de créativité, les possibilités sont infinies."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/screws.mdl"
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "Il est suspect de transporter plus de 8 objets de ce genre."}
ITEM.maxStackSize = 8

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.uniqueID = "comp_plastic"
ITEM.name = "Déchets plastique"
ITEM.description = "Ces déchets plastiques semblent avoir été abandonnés depuis longtemps, jetés sans égard pour l'environnement. Bien qu'ils ne soient pas utiles en l'état, ils pourraient être recyclés ou transformés en quelque chose d'utile avec un peu d'imagination et de créativité. Peut-être pouvez-vous leur donner une seconde vie en les transformant en un objet pratique."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_junk/garbage_bag001a.mdl"
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "Il est suspect de transporter plus de 8 objets de ce genre."}
ITEM.maxStackSize = 8

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.uniqueID = "comp_refined_metal"
ITEM.name = "Acier"
ITEM.description = "Cet acier est un métal robuste et résistant, capable de résister aux environnements les plus difficiles et de supporter des charges importantes. Que vous cherchiez à construire des structures robustes, à fabriquer des armes puissantes ou à renforcer des pièces existantes, cet acier pourrait être un ingrédient clé pour réaliser vos projets les plus ambitieux."
ITEM.description = "Un matériau solide et polyvalent. Sa composition lui confère une résistance exceptionnelle, en faisant un matériau prisé dans de nombreux domaines."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/gibs/scanner_gib02.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat.", ["red"] = "Les unités PC vous considéreront comme suspect si ils vous trouvent avec cet objet."}
ITEM.maxStackSize = 4

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/
--]]
ITEM.uniqueID = "comp_refined_plastic"
ITEM.name = "Feuilles de plastique"
ITEM.description = "Ces feuilles de plastique sont souples et légères, mais résistantes et durables. Elles peuvent être utilisées pour tout, comme à la réparation de tentes et de bâches. Avec un peu d'imagination et de savoir-faire, ces feuilles de plastique pourraient être la solution idéale pour vos besoins en matière de construction et de réparation en extérieur."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/food/snack01.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat.", ["red"] = "Les uinités PC vous considéreront comme suspect si ils vous trouvent avec cet objet."}
ITEM.outlineColor = Color(255, 204, 0, 100)
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,28 @@
--[[
| 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.uniqueID = "comp_reshaped_metal"
ITEM.name = "Fer"
ITEM.description = "Ce fer est un matériau robuste et durable qui peut être utilisé pour une grande variété de projets. Que vous cherchiez à construire des outils, des armes, des pièces de véhicules, ou des éléments de décoration, le fer peut être le matériau parfait pour répondre à vos besoins. Avec suffisamment de compétences et d'outils, ce fer pourrait être transformé en quelque chose de beau et d'utile."
ITEM.description = "Un solide morceau de métal ferreux, robuste et résistant à la corrosion. Sa surface est lisse et peut présenter des nuances de gris foncé."
ITEM.category = "Crafting"
ITEM.model = "models/willardnetworks/props/reshaped_metal.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(509.64, 427.61, 310.24),
ang = Angle(25, 220, 0),
fov = 1.27
}
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat.", ["red"] = "Les uinités PC vous considéreront comme suspect si ils vous trouvent avec cet objet."}
ITEM.maxStackSize = 4

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.uniqueID = "comp_resin"
ITEM.name = "Résine"
ITEM.description = "Un cylindre solide gris, d'une substance douce au toucher. Léger et facilement cassable... pourrait être utilisé dans une machine compatible"
ITEM.category = "Crafting"
ITEM.model = "models/willardnetworks/props_combine/resin_puck.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(173.79, 146.1, 107.55),
ang = Angle(25.1, 219.9, 0),
fov = 3.8
}
ITEM.outlineColor = Color(255, 204, 0)

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.uniqueID = "comp_stitched_cloth"
ITEM.name = "Tissu cousu"
ITEM.description = "Ce tissu cousu est doux, flexible et résistant. Il peut être utilisé pour tout, de la fabrication de vêtements résistants aux intempéries à la réparation de sacs et de tentes. Les coutures sont solides et durables, ce qui signifie que ce tissu cousu peut résister à l'usure et aux déchirures. Avec un peu d'imagination, ce tissu cousu peut être transformé en quelque chose de beau et de pratique pour répondre à vos besoins."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/stitched_cloth.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat.", ["red"] = "Les uinités PC vous considéreront comme suspect si ils vous trouvent avec cet objet."}
ITEM.maxStackSize = 4

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/
--]]
ITEM.uniqueID = "comp_weapon_parts"
ITEM.name = "Pièces d'armes légères"
ITEM.description = "Ces pièces d'armes légères sont un trésor pour les bricoleurs et les amateurs d'armes. Elles peuvent être utilisées pour la fabrication et la réparation d'armes légères, telles que les pistolets et les fusils. Les ressorts, les mécanismes de déclenchement et les plaques de serrage peuvent tous être récupérés et réutilisés pour créer des armes personnalisées. Avec ces pièces d'armes légères, vous êtes à un pas de plus vers la création de votre arme de rêve."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/skills/weaponparts.mdl"
ITEM.outlineColor = Color(255, 204, 0, 100)
ITEM.maxStackSize = 3

View File

@@ -0,0 +1,38 @@
--[[
| 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.uniqueID = "comp_wood"
ITEM.name = "Bout de bois"
ITEM.description = "Ce bout de bois peut sembler banal, mais il peut être utilisé pour une variété de projets créatifs. Il peut être taillé pour créer une sculpture, utilisé comme poignée pour un outil, ou même transformé en un jouet artisanal pour enfant. Le bois est un matériau naturellement durable, résistant à la décomposition et facile à travailler. Avec un peu d'inspiration, ce simple bout de bois peut devenir l'élément clé d'un projet créatif qui sera apprécié pendant des années."
ITEM.description = "Un morceau naturel et brut de bois, probablement tombé d'un arbre. Sa surface est rugueuse, portant les stries et les marques de l'écorce qui l'entourait autrefois. "
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/Gibs/wood_gib01a.mdl"
ITEM.colorAppendix = {["blue"] = "Vous pouvez acquérir cet objet via la fonctionnalité de répartition des compétences d'artisanat ou en recherchant des tas de déchets.", ["red"] = "Il est suspect de transporter plus de 8 objets de ce genre."}
ITEM.maxStackSize = 8
ITEM.functions.Breakdown = {
icon = "icon16/link_break.png",
name = "Briser",
OnRun = function(item)
local client = item.player
client:GetCharacter():GetInventory():Add("woodstick", 10)
end,
OnCanRun = function(item)
return !IsValid(item.entity) and item.player:Team() == FACTION_BIRD
end
}

View File

@@ -0,0 +1,24 @@
--[[
| 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.uniqueID = "comp_craftwork_wood"
ITEM.name = "Planche de bois"
ITEM.description = "Cette planche de bois est un matériau de construction de base qui peut être utilisé pour créer une variété d'objets. Que vous cherchiez à construire un meuble, à réparer un bâtiment ou à créer des jouets pour enfants, cette planche de bois peut être l'élément essentiel pour mener à bien votre projet. Avec un peu de créativité et d'efforts, cette simple planche de bois peut être transformée en quelque chose de beau et d'utile pour répondre à vos besoins."
ITEM.category = "Crafting"
ITEM.model = "models/props_debris/wood_board06a.mdl"
ITEM.width = 1
ITEM.height = 2
ITEM.iconCam = {
pos = Vector(-891.43, -17, 114.92),
ang = Angle(7.34, 361.09, 0),
fov = 2.29
}
ITEM.colorAppendix = {["blue"] = "Cet objet peut être fabriqué avec la compétence Artisanat.", ["red"] = "Les uinités PC vous considéreront comme suspect si ils vous trouvent avec cet objet."}
ITEM.maxStackSize = 8

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 = "Grand conteneur"
ITEM.description = "Ce grand conteneur est idéal pour le stockage de gros volumes de marchandises. Sa taille généreuse offre suffisamment d'espace pour stocker des objets volumineux et lourds tels que des matériaux de construction, des meubles etc. La construction robuste du conteneur garantit que son contenu est protégé des dommages pendant votre aventure. Avec ce grand conteneur, vous pouvez être sûr que vos objets sont stockées en toute sécurité."
ITEM.category = "Stockage"
ITEM.width = 2
ITEM.height = 4
ITEM.model = "models/props_wasteland/controlroom_storagecloset001a.mdl"
ITEM.colorAppendix = {["red"] = "Contactez un administrateur pour le convertir en conteneur. Nécessite un groupe de minimum 5 membres.", ["blue"] = "Nous avons une limite de 2 petits conteneurs personnels OU 1 moyen par joueur.\nLes groupes peuvent également obtenir 3 grands conteneurs."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Grande caisse"
ITEM.description = "Cette grande caisse est un choix parfait pour le stockage et la protection de vos biens précieux. Sa taille généreuse permet de stocker des objets de grande taille tels que des outils, des équipements de camping, des fournitures de bureau, des livres et des vêtements, tout en les protégeant de la poussière, de la saleté et des dommages. La construction solide de la caisse garantit que votre contenu est protégé contre les éléments et les impacts. Avec cette grande caisse, vous pouvez être assuré que vos biens sont stockés en toute sécurité et facilement accessibles lorsque vous en avez besoin."
ITEM.category = "Stockage"
ITEM.width = 4
ITEM.height = 4
ITEM.model = "models/props_junk/wood_crate002a.mdl"
ITEM.colorAppendix = {["red"] = "Contactez un administrateur pour le convertir en une caisse fonctionnel.", ["blue"] = "Selon les limitations, vous ne pouvez avoir qu'une seule caisse en votre possession."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Conteneur moyen"
ITEM.description = "Ce conteneur moyen est idéal pour le stockage de gros volumes de marchandises. Sa taille généreuse offre suffisamment d'espace pour stocker des objets volumineux et lourds tels que des matériaux de construction, des meubles etc. La construction robuste du conteneur garantit que son contenu est protégé des dommages pendant votre aventure. Avec ce conteneur, vous pouvez être sûr que vos objets sont stockées en toute sécurité."
ITEM.category = "Stockage"
ITEM.width = 2
ITEM.height = 3
ITEM.model = "models/props_wasteland/controlroom_filecabinet002a.mdl"
ITEM.colorAppendix = {["red"] = "Contactez un administrateur pour le convertir en un conteneur fonctionnel.", ["blue"] = "Nous avons une limite de 2 petits conteneurs personnels OU 1 moyen par joueur.\nLes groupes peuvent également obtenir 3 grands conteneurs."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Caisse standard"
ITEM.description = "Ce conteneur est idéal pour le stockage de gros volumes de marchandises. Sa taille généreuse offre suffisamment d'espace pour stocker des objets volumineux et lourds tels que des matériaux de construction, des meubles etc. La construction robuste du conteneur garantit que son contenu est protégé des dommages pendant votre aventure. Avec ce conteneur, vous pouvez être sûr que vos objets sont stockées en toute sécurité."
ITEM.category = "Stockage"
ITEM.width = 2
ITEM.height = 2
ITEM.model = "models/props_junk/wood_crate001a.mdl"
ITEM.colorAppendix = {["red"] = "Contactez un administrateur pour le convertir en un conteneur fonctionnel.", ["blue"] = "Selon les limitations, vous ne pouvez avoir qu'une seule caisse en votre possession."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.name = "Petit conteneur"
ITEM.description = "Ce petit conteneur est idéal pour le stockage de petit volumes de marchandises. Sa taille offre suffisamment d'espace pour stocker des objets légers et tels que des matériaux de construction. La construction robuste du conteneur garantit que son contenu est protégé des dommages pendant votre aventure. Avec ce petit conteneur, vous pouvez être sûr que vos objets sont stockées en toute sécurité."
ITEM.category = "Stockage"
ITEM.width = 2
ITEM.height = 2
ITEM.model = "models/props_lab/filecabinet02.mdl"
ITEM.colorAppendix = {["red"] = "Contactez un administrateur pour le convertir en un conteneur fonctionnel.", ["blue"] = "Nous avons une limite de 2 petits conteneurs personnels OU 1 moyen par joueur.\nLes groupes peuvent également obtenir 3 grands conteneurs."}
ITEM.maxStackSize = 1

View File

@@ -0,0 +1,24 @@
--[[
| 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 = "Canette vide"
ITEM.description = "Une canette en aluminium usagée qui a déjà contenu de l'eau. Elle est désormais vide et prête à être recyclée."
ITEM.category = "Crafting"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_junk/popcan01a.mdl"
ITEM.iconCam = {
pos = Vector(509.64, 427.61, 310.24),
ang = Angle(25.01, 220.01, 0),
fov = 0.6
}
ITEM.maxStackSize = 4

View File

@@ -0,0 +1,51 @@
--[[
| 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.uniqueID = "dummy_biolock_ar2"
ITEM.name = "Biolocked Pulse-Rifle"
ITEM.description = "An Overwatch Pulse-Rifle dropped by a Comine Soldier... it seems to be locked by some form of internal component. It requires a Vortigaunt to unlock this."
ITEM.category = "Dummy"
ITEM.width = 4
ITEM.height = 2
ITEM.model = "models/weapons/w_IRifle.mdl"
ITEM.useSound = "ambient/energy/weld1.wav"
ITEM.unlockedItem = "pulse"
ITEM.unlockRequirementAmount = 1
ITEM.functions.Unlock = {
OnRun = function(item)
local client = item.player
local position = item.player:GetPos()
local character = item.player:GetCharacter()
local inventory = character:GetInventory()
client:EmitSound(item.useSound)
-- Spawn the opened item if it exists
local requirementAmount = item.unlockRequirementAmount or 1
if (character:GetFaction() == FACTION_VORT) then
if (item.unlockedItem) then
local openedItemName = ix.item.list[item.unlockedItem].name or item.unlockedItem
if (!inventory:Add(item.unlockedItem, requirementAmount)) then
client:NotifyLocalized("You need "..requirementAmount.." inventory spaces to open this item.")
return
end
client:NotifyLocalized("You have unlocked a "..item.name.." and been given a "..openedItemName)
end
else
return false
end
end,
OnCanRun = function(item)
if (IsValid(item.entity) or !IsValid(item.player)) then return false end
end
}

View File

@@ -0,0 +1,51 @@
--[[
| 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.uniqueID = "dummy_biolock_expar2"
ITEM.name = "Odd Combine Rifle (Biolocked)"
ITEM.description = "An odd looking Combine Rifle that seems to be restricted in terms of use, but looks different from that which you are used to."
ITEM.category = "Dummy"
ITEM.width = 4
ITEM.height = 2
ITEM.model = "models/weapons/irifle2/w_irifle2.mdl"
ITEM.useSound = "ambient/energy/weld1.wav"
ITEM.unlockedItem = "suppressionrifle"
ITEM.unlockRequirementAmount = 1
ITEM.functions.Unlock = {
OnRun = function(item)
local client = item.player
local position = item.player:GetPos()
local character = item.player:GetCharacter()
local inventory = character:GetInventory()
client:EmitSound(item.useSound)
-- Spawn the opened item if it exists
local requirementAmount = item.unlockRequirementAmount or 1
if (character:GetFaction() == FACTION_VORT) then
if (item.unlockedItem) then
local openedItemName = ix.item.list[item.unlockedItem].name or item.unlockedItem
if (!inventory:Add(item.unlockedItem, requirementAmount)) then
client:NotifyLocalized("You need "..requirementAmount.." inventory spaces to open this item.")
return
end
client:NotifyLocalized("You have unlocked a "..item.name.." and been given a "..openedItemName)
end
else
return false
end
end,
OnCanRun = function(item)
if (IsValid(item.entity) or !IsValid(item.player)) then return false end
end
}

View File

@@ -0,0 +1,51 @@
--[[
| 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.uniqueID = "dummy_biolock_sr1"
ITEM.name = "Biolocked Ordinal Rifle"
ITEM.description = "An Ordninal Rifle of the Combine Overwatch. Seems to be unusable though."
ITEM.category = "Dummy"
ITEM.width = 4
ITEM.height = 2
ITEM.model = "models/weapons/oar/w_orifle.mdl"
ITEM.useSound = "ambient/energy/weld1.wav"
ITEM.unlockedItem = "pulsecarbine"
ITEM.unlockRequirementAmount = 1
ITEM.functions.Unlock = {
OnRun = function(item)
local client = item.player
local position = item.player:GetPos()
local character = item.player:GetCharacter()
local inventory = character:GetInventory()
client:EmitSound(item.useSound)
-- Spawn the opened item if it exists
local requirementAmount = item.unlockRequirementAmount or 1
if (character:GetFaction() == FACTION_VORT) then
if (item.unlockedItem) then
local openedItemName = ix.item.list[item.unlockedItem].name or item.unlockedItem
if (!inventory:Add(item.unlockedItem, requirementAmount)) then
client:NotifyLocalized("You need "..requirementAmount.." inventory spaces to open this item.")
return
end
client:NotifyLocalized("You have unlocked a "..item.name.." and been given a "..openedItemName)
end
else
return false
end
end,
OnCanRun = function(item)
if (IsValid(item.entity) or !IsValid(item.player)) then return false end
end
}

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.uniqueID = "dummy_emp"
ITEM.name = "Dispositif de Bombe IEM"
ITEM.description = "A small one-time use EMP device used to disable electronics. It can now also be used on Combine tech- capable of disabling forcefields for 5 minutes, turrets for 10 minutes and disable scanners for good."
ITEM.category = "Dummy"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/Items/car_battery01.mdl"
ITEM.colorAppendix = {["blue"] = "This is an RP item, call a GM to use. This improved version can disable all forms of combine tech- excluding Synthetics or advanced Combine tech"}

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.uniqueID = "dummy_largebomb"
ITEM.name = "Large Bomb"
ITEM.description = "The largest sized bomb one can make out of the scraps available to them in the Outlands with the schematics of old, containing upto 10KG of TNT, this bomb is capable of tearing down multiple buildings at once and causing major damage to a District."
ITEM.category = "Dummy"
ITEM.width = 3
ITEM.height = 3
ITEM.model = "models/Items/car_battery01.mdl"
ITEM.colorAppendix = {["blue"] = "This is an RP item, call a GM to use.", ["red"] = "THIS CANNOT BE SPAWNED OR GIVEN WITHOUT APPROVAL FROM SERVER COUNCIL!"}

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.uniqueID = "dummy_littlebomb"
ITEM.name = "Little Bomb"
ITEM.description = "A small improvised bomb not capable of much damage. Mainly used as a Anti-Personnel Mine or Trap, incapable of destroying a wall. It is made using Composition B explosive at around 13oz."
ITEM.category = "Dummy"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/Items/car_battery01.mdl"
ITEM.colorAppendix = {["blue"] = "This is an RP item, call a GM to use."}

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.uniqueID = "dummy_mediumbomb"
ITEM.name = "Medium Bomb"
ITEM.description = "A medium sized bomb in the shape of a C4 or IED, capable of a force equal to that of 4 kilograms of TNT. Perfectly suited for blowing up buildings or Combine Checkpoints."
ITEM.category = "Dummy"
ITEM.width = 2
ITEM.height = 2
ITEM.model = "models/Items/car_battery01.mdl"
ITEM.colorAppendix = {["blue"] = "This is an RP item, call a GM to use."}

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.uniqueID = "dummy_smallbomb"
ITEM.name = "Small Bomb"
ITEM.description = "Unlike the little bomb, this bomb is capable of producing an explosive worth 1KG worth of TNT. It can blow open walls but may not do much structucal damage to a building. It is also made from Composition B Explosive at around 36oz."
ITEM.category = "Dummy"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/Items/car_battery01.mdl"
ITEM.colorAppendix = {["blue"] = "This is an RP item, call a GM to use."}

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "expo_battery"
ITEM.name = "Batterie de voiture (pleine)"
ITEM.description = "Cette batterie de voiture pleine est un élément crucial pour assurer que votre véhicule démarre en toute fiabilité. Elle fournit l'énergie nécessaire pour faire fonctionner tous les systèmes électriques de la voiture, y compris les lumières, les phares, la radio, la climatisation et bien plus encore. Cette batterie est chargée et prête à l'emploi, vous pouvez donc l'installer facilement et en toute sécurité dans votre véhicule sans vous soucier de problèmes de démarrage. Avec cette batterie de voiture pleine, vous pouvez conduire en toute confiance et en toute tranquillité d'esprit."
ITEM.description = "Cette batterie de voiture pleine est un élément crucial pour assurer que votre véhicule démarre en toute fiabilité. Elle fournit l'énergie nécessaire pour faire fonctionner tous les systèmes électriques de la voiture."
ITEM.category = "Expédition"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/Mechanics/gears/gear12x6_small.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet est purement utilisé en RP et n'a aucune fonction réelle dans le jeu."}

View File

@@ -0,0 +1,22 @@
--[[
| 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.uniqueID = "expo_campingbag"
ITEM.name = "Sac de camping"
ITEM.description = "Ce sac de camping est un équipement essentiel pour tout aventurier en herbe. Il est conçu avec des matériaux de qualité supérieure pour assurer une grande résistance à l'usure, à la déchirure et aux intempéries. Le sac offre suffisamment d'espace pour ranger tout votre équipement de camping, y compris votre tente, votre sac de couchage, vos vêtements, votre nourriture et vos accessoires. De plus, il est doté de bretelles réglables et d'un dos rembourré pour un confort optimal lors du transport sur de longues distances. Que vous partiez en randonnée, en camping ou en excursion, ce sac de camping vous permettra de voyager en toute sécurité et avec tout le nécessaire à portée de main. Il pourrait accueillir jusqu'à 3 personnes."
ITEM.description = "Ce sac de camping est un équipement essentiel pour tout aventurier en herbe. Il est conçu avec des matériaux de qualité supérieure pour assurer une grande résistance à l'usure, à la déchirure et aux intempéries. Il pourrait accueillir jusqu'à 3 personnes."
ITEM.category = "Expédition"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_survival/cash/dufflebag.mdl"
ITEM.colorAppendix = {["blue"] = "Cet objet est purement utilisé en RP et n'a aucune fonction réelle dans le jeu."}

View File

@@ -0,0 +1,18 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ITEM.uniqueID = "expo_settlementkit"
ITEM.name = "Kit de construction"
ITEM.description = "Kit de construction, très utile pour ceux voulant fabriquer des barricades ou une petite habitation."
ITEM.category = "Expédition"
ITEM.width = 2
ITEM.height = 2
ITEM.model = "models/props/de_inferno/hr_i/concrete_bag_a/concrete_bags_stack_a.mdl"
ITEM.colorAppendix = {["blue"] = "This item is purely RP usage and has no actual ingame function."}

View File

@@ -0,0 +1,22 @@
--[[
| 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 = "Plat épicé de viande de fourmilion"
ITEM.description = "Ce plat de mélange d'ingrédients d'un autre monde semble étrangement plutôt appétissant."
ITEM.category = "Nourriture"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/food/canned_food4.mdl"
ITEM.hunger = 40
ITEM.boosts = {
strength = 3
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

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/
--]]
ITEM.name = "Viande de fourmilion rôtie"
ITEM.description = "Une tranche de viande de fourmilion rôtie ne vous remplit pas autant que vous le voudriez, mais elle est assez filandreuse et a une texture étrange."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/cooked_alienmeat.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(125.61, 104.91, 78.59),
ang = Angle(25.01, 219.94, 0),
fov = 4
}
ITEM.hunger = 30
ITEM.boosts = {
strength = 2
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

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/
--]]
ITEM.name = "Sandwich au Fourmilion"
ITEM.description = "Deux tranches de pain garnies de viande de fourmilion grillée et d'ingrédients frais."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/sandwich.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.color = Color(217, 243, 217)
ITEM.iconCam = {
pos = Vector(509.64, 427.61, 310.24),
ang = Angle(24.9, 219.85, 0),
fov = 0.75
}
ITEM.hunger = 45
ITEM.boosts = {
strength = 3,
perception = 1
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

View File

@@ -0,0 +1,28 @@
--[[
| 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 = "Brochette de viande de fourmilion"
ITEM.description = "Des morceaux de viande de fourmilion grillés sur une brochette en bois."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/meatskewer.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(150.5, 126.23, 92.34),
ang = Angle(25.07, 219.54, 0),
fov = 2.7
}
ITEM.hunger = 6
ITEM.boosts = {
strength = 1
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"
ITEM.maxStackSize = 3

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/
--]]
ITEM.name = "Ragoût d'Antlion"
ITEM.description = "Un plat chaud et épicé rempli de viande de fourmilion mijotée."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/meatysoup.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(125.61, 104.91, 78.59),
ang = Angle(24.78, 219.86, 0),
fov = 3
}
ITEM.hunger = 65
ITEM.thirst = 15
ITEM.boosts = {
strength = 5
}
ITEM.spoil = true
ITEM.useSound = "ambient/levels/canals/toxic_slime_gurgle4.wav"
ITEM.addVE = 20
function ITEM:OnConsume(client, character)
if character:IsVortigaunt() then
local percentage = ix.config.Get("maxVortalEnergy", 100) / 100
percentage = percentage * self.addVE
character:AddVortalEnergy(percentage)
end
end

View File

@@ -0,0 +1,24 @@
--[[
| 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 = "Tranche de Fromage Artificiel"
ITEM.description = "Les produits laitiers non substituts sont difficiles à trouver de nos jours, les vaches sont gardées dans des usines réparties dans le monde entier et ne sont pas faciles à trouver."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/cheesewheel2c.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(169.82, 142.5, 102.64),
ang = Angle(24.34, 220.07, 0),
fov = 1.76
}
ITEM.hunger = 7
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

View File

@@ -0,0 +1,30 @@
--[[
| 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 = "Pâte de fromage artificielle"
ITEM.description = "Pot blanc de pâte artificielle gluante, complétée par du fromage pour une texture et un remplissage légèrement améliorés."
ITEM.category = "Nourriture"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_lab/jar01b.mdl"
ITEM.color = Color(254, 255, 212)
ITEM.hunger = 35
ITEM.boosts = {
perception = 2,
intelligence = 2
}
ITEM.spoil = true
ITEM.useSound = "ambient/levels/canals/toxic_slime_gurgle4.wav"
ITEM.junk = "junk_jar"
ITEM.iconCam = {
pos = Vector(6.22, -199.61, 10.73),
ang = Angle(3.12, 91.84, 0),
fov = 3.64
}

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/
--]]
ITEM.name = "Viande artificielle rôtie"
ITEM.description = "De la viande artificielle cuite à la rôtissoire pour une saveur grillée."
ITEM.category = "Nourriture"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/willardnetworks/food/steak2.mdl"
ITEM.hunger = 30
ITEM.boosts = {
intelligence = 2
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"
ITEM.iconCam = {
pos = Vector(509.64, 427.61, 310.24),
ang = Angle(24.99, 220.01, 0),
fov = 0.62
}

View File

@@ -0,0 +1,30 @@
--[[
| 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 = "Pâte de viande artificielle"
ITEM.description = "Une pâte à base de viande artificielle pour cuisiner divers plats."
ITEM.category = "Nourriture"
ITEM.width = 1
ITEM.height = 1
ITEM.model = "models/props_lab/jar01b.mdl"
ITEM.color = Color(243, 217, 217)
ITEM.hunger = 60
ITEM.boosts = {
strength = 2,
intelligence = 2
}
ITEM.spoil = true
ITEM.useSound = "ambient/levels/canals/toxic_slime_gurgle4.wav"
ITEM.junk = "junk_jar"
ITEM.iconCam = {
pos = Vector(6.22, -199.61, 10.73),
ang = Angle(3.12, 91.84, 0),
fov = 3.64
}

View File

@@ -0,0 +1,28 @@
--[[
| 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 = "Brochette de viande artificielle"
ITEM.description = "Des morceaux de viande artificielle piqués sur un bâton pour une présentation pratique."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/meatskewer2.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(150.5, 126.23, 92.34),
ang = Angle(25.07, 219.54, 0),
fov = 2.7
}
ITEM.hunger = 6
ITEM.boosts = {
intelligence = 1
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"
ITEM.maxStackSize = 3

View File

@@ -0,0 +1,28 @@
--[[
| 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 = "Ragoût de viande artificielle"
ITEM.description = "Un plat en sauce à base de viande artificielle et d'autres ingrédients cuits lentement."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/meatysoup2.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(125.61, 104.91, 78.59),
ang = Angle(24.78, 219.86, 0),
fov = 3
}
ITEM.hunger = 65
ITEM.thirst = 15
ITEM.boosts = {
intelligence = 5
}
ITEM.spoil = true
ITEM.useSound = "ambient/levels/canals/toxic_slime_gurgle4.wav"

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/
--]]
ITEM.name = "Sauté de viande artificielle"
ITEM.description = "De la viande artificielle sautée dans une poêle avec d'autres ingrédients pour un plat savoureux."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/canned_food2.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(69.87, 58.63, 44.49),
ang = Angle(24.95, 220, 0),
fov = 4.27
}
ITEM.hunger = 40
ITEM.boosts = {
intelligence = 3
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

View File

@@ -0,0 +1,28 @@
--[[
| 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 = "Tarte aux pommes"
ITEM.description = "Une tarte sucrée et croustillante remplie de pommes fraîches et parfumées."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/pie.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(169.82, 142.5, 102.64),
ang = Angle(24.95, 219.95, 0),
fov = 2.78
}
ITEM.hunger = 65
ITEM.boosts = {
strength = 3,
intelligence = 5
}
ITEM.spoil = true
ITEM.useSound = "npc/antlion_grub/squashed.wav"

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/
--]]
ITEM.name = "Beignet"
ITEM.description = "Un beignet moelleux recouvert de sucre en poudre."
ITEM.model = "models/willardnetworks/food/bagel2.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(509.64, 427.61, 310.24),
ang = Angle(24.94, 219.98, 0),
fov = 0.58
}
ITEM.category = "Nourriture"
ITEM.hunger = 20
ITEM.boosts = {
intelligence = 2
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

View File

@@ -0,0 +1,71 @@
--[[
| 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 = "Pain complet"
ITEM.description = "Même dans des moments comme ceux-ci, le pain fait maison peut faire toute la différence."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/bread_loaf.mdl"
ITEM.width = 2
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(258.35, 217.47, 159.76),
ang = Angle(25.18, 220.07, 0),
fov = 2.39
}
ITEM.hunger = 40
ITEM.boosts = {
strength = 3,
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch3.wav"
ITEM.openedItem = "baking_bread_half" -- the uniqueID e.g what comes after 'sh_' in the file name unless ITEM.uniqueID is specified
ITEM.openRequirementAmount = 2
ITEM.openRequirements = {"tool_knife", "cleaver", "hatchet", "kitknife", "machete"} -- same desc as above
ITEM.functions.Slice = {
OnRun = function(item)
local client = item.player
local character = item.player:GetCharacter()
local inventory = character:GetInventory()
local openerItem
if (item.openRequirements) then
for k, v in ipairs(item.openRequirements) do
if inventory:HasItem(v) then
openerItem = inventory:HasItem(v)
break
end
end
if !openerItem then
client:NotifyLocalized("Vous n'avez pas d'outil requis pour assembler cet article")
return false
else
if (openerItem.isTool) then
openerItem:DamageDurability(1)
end
end
end
client:EmitSound(item.useSound)
-- Spawn the opened item if it exists
local requirementAmount = item.openRequirementAmount or 1
if (item.openedItem) then
local openedItemName = ix.item.list[item.openedItem].name or item.openedItem
if (!inventory:Add(item.openedItem, requirementAmount)) then
client:NotifyLocalized("Vous avez besoin de "..requirementAmount.." d'espaces d'inventaire pour trancher cet article.")
return
end
client:NotifyLocalized("Vous avez tranché un "..item.name.." et reçu un "..openedItemName)
end
end
}

View File

@@ -0,0 +1,71 @@
--[[
| 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 = "Pain coupé en deux"
ITEM.description = "Une demi-miche de pain prête à être consommée."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/bread_half.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(258.35, 217.47, 159.76),
ang = Angle(25.14, 219.92, 0),
fov = 1.49
}
ITEM.hunger = 20
ITEM.boosts = {
strength = 2
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch3.wav"
ITEM.openedItem = "baking_bread_slice" -- the uniqueID e.g what comes after 'sh_' in the file name unless ITEM.uniqueID is specified
ITEM.openRequirementAmount = 4
ITEM.openRequirements = {"tool_knife", "cleaver", "hatchet", "kitknife", "machete"} -- same desc as above
ITEM.functions.Slice = {
OnRun = function(item)
local client = item.player
local character = item.player:GetCharacter()
local inventory = character:GetInventory()
local openerItem
if (item.openRequirements) then
for k, v in ipairs(item.openRequirements) do
if inventory:HasItem(v) then
openerItem = inventory:HasItem(v)
break
end
end
if !openerItem then
client:NotifyLocalized("Vous n'avez pas d'outil requis pour assembler cet article")
return false
else
if (openerItem.isTool) then
openerItem:DamageDurability(1)
end
end
end
client:EmitSound(item.useSound)
-- Spawn the opened item if it exists
local requirementAmount = item.openRequirementAmount or 1
if (item.openedItem) then
local openedItemName = ix.item.list[item.openedItem].name or item.openedItem
if (!inventory:Add(item.openedItem, requirementAmount)) then
client:NotifyLocalized("Vous avez besoin de "..requirementAmount.." d'espaces d'inventaire pour trancher cet article.")
return
end
client:NotifyLocalized("Vous avez tranché un "..item.name.." et reçu un "..openedItemName)
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/
--]]
ITEM.name = "Tranche de pain"
ITEM.description = "Une tranche de pain frais. Ne vous remplit pas beaucoup tout seul mais ça ira."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/bread_slice.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(258.35, 217.47, 159.76),
ang = Angle(25.26, 220.13, 0),
fov = 1.25
}
ITEM.hunger = 10
ITEM.boosts = {
strength = 1
}
ITEM.spoil = true
ITEM.useSound = "npc/barnacle/barnacle_crunch2.wav"

View File

@@ -0,0 +1,32 @@
--[[
| 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 = "cheesecake"
ITEM.name = "Cheesecake"
ITEM.description = "Un dessert crémeux et riche, garni de fruits frais ou de coulis."
ITEM.category = "Nourriture"
ITEM.model = "models/willardnetworks/food/cake.mdl"
ITEM.width = 1
ITEM.height = 1
ITEM.iconCam = {
pos = Vector(258.35, 217.47, 159.76),
ang = Angle(25.18, 220.07, 0),
fov = 0.96
}
ITEM.hunger = 65
ITEM.boosts = {
perception = 5,
intelligence = 3
}
ITEM.spoil = true
ITEM.useSound = "npc/antlion_grub/squashed.wav"

Some files were not shown because too many files have changed in this diff Show More