This commit is contained in:
lifestorm
2024-08-05 18:40:29 +03:00
parent 9f505a0646
commit c6d9b6f580
8044 changed files with 1853472 additions and 21 deletions

View File

@@ -0,0 +1,64 @@
--[[
| 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/
--]]
do
local function vendorESP(client, entity, x, y, factor, distance)
local color = Color(255, 255, 255, 255)
local alpha = math.Remap(math.Clamp(distance, 1500, 2000), 1500, 2000, 255, 45)
color.a = alpha
ix.util.DrawText("Vending Machine", x, y + math.max(10, 32 * factor), color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, nil, alpha)
ix.util.DrawText("ID: " .. entity:GetID(), x, y + math.max(10, 32 * factor) + 20, color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, nil, alpha)
end
ix.observer:RegisterESPType("ix_customvendingmachine", vendorESP, "vendor")
end
net.Receive("ixVendingMachineManager", function()
local entity = net.ReadEntity()
vgui.Create("ixVendingMachineManager"):Populate({
entity = entity,
labels = entity:GetNetVar("labels", {}),
buttons = entity:GetNetVar("buttons", {}),
prices = entity:GetNetVar("prices", {}),
stocks = entity:GetNetVar("stocks", false),
credits = entity:GetNetVar("credits", 0)
})
end)
local function ExitCallback()
local machine = LocalPlayer().activeVendingMachine
LocalPlayer().activeVendingMachine = nil
net.Start("ixSelectVendingMachineCID")
net.WriteBool(false)
net.WriteEntity(machine)
net.SendToServer()
end
local function SelectCallback(idCardID, cid, cidName, ent)
net.Start("ixSelectVendingMachineCID")
net.WriteBool(true)
net.WriteEntity(ent)
net.WriteUInt(idCardID, 16)
net.SendToServer()
end
net.Receive("ixSelectVendingMachineCID", function()
LocalPlayer().activeVendingMachine = net.ReadEntity()
local cidSelector = vgui.Create("CIDSelector")
cidSelector.activeEntity = LocalPlayer().activeVendingMachine
cidSelector.ExitCallback = ExitCallback
cidSelector.SelectCallback = SelectCallback
end)

View File

@@ -0,0 +1,276 @@
--[[
| 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(ScrH() * 0.7, ScrH() * 0.71)
self:SetSize(ScrW(), ScrH())
self:SetAlpha(0)
self:AlphaTo(255, 0.5, 0)
self.Paint = function(self, width, height)
surface.SetDrawColor(Color(63, 58, 115, 220))
surface.DrawRect(0, 0, width, height)
Derma_DrawBackgroundBlur(self, 1)
end
self.innerContent = self:Add("Panel")
self.innerContent:SetSize(SScaleMin(700 / 3), SScaleMin(260 / 3))
self.innerContent:Center()
self.innerContent:MakePopup()
self.innerContent.Paint = function(self, w, h)
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, w, h)
end
Schema:AllowMessage(self.innerContent)
end
local color_green = Color(0, 255, 0, 255)
local color_red = Color(255, 0, 0, 255)
local color_orange = Color(255, 125, 0, 255)
function PANEL:Populate(data)
local topbar = self.innerContent:Add("Panel")
topbar:SetHeight(SScaleMin(50 / 3))
topbar:Dock(TOP)
topbar.Paint = function(self, width, height)
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, width, height)
end
local titleText = topbar:Add("DLabel")
titleText:SetFont("CharCreationBoldTitleNoClamp")
titleText:Dock(LEFT)
titleText:SetText("Vending Machine Manager")
titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
titleText:SetContentAlignment(4)
titleText:SizeToContents()
local exit = topbar:Add("DImageButton")
exit:SetImage("willardnetworks/tabmenu/navicons/exit.png")
exit:SetSize(SScaleMin(20 / 3), SScaleMin(20 / 3))
exit:DockMargin(0, SScaleMin(15 / 3), SScaleMin(10 / 3), SScaleMin(15 / 3))
exit:Dock(RIGHT)
exit.DoClick = function()
if (self.ExitCallback) then
self.ExitCallback()
end
self:Remove()
surface.PlaySound("helix/ui/press.wav")
end
local divider = topbar:Add("Panel")
divider:SetSize(1, topbar:GetTall())
divider:Dock(RIGHT)
divider:DockMargin(0, SScaleMin(10 / 3), SScaleMin(10 / 3), SScaleMin(10 / 3))
divider.Paint = function(self, w, h)
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
surface.DrawLine(0, 0, 0, h)
end
self.panels = {}
for i = 1, 8 do
self.panels[i] = {}
self.panels[i].index = self.innerContent:Add("DPanel")
self.panels[i].index:Dock(TOP)
self.panels[i].index:DockMargin(10, i == 1 and SScaleMin(10 / 3) or 0, 10, SScaleMin(10 / 3))
self.panels[i].index:SetHeight(SScaleMin(60 / 3))
self.panels[i].index.Paint = function(self, width, height)
surface.SetDrawColor(0, 0, 0, 130)
surface.DrawRect(0, 0, width, height)
end
self.panels[i].index.leftPanel = self.panels[i].index:Add("DPanel")
self.panels[i].index.leftPanel:Dock(LEFT)
self.panels[i].index.leftPanel:SetSize((self:GetWide() / 2) - 15, 0)
self.panels[i].index.leftPanel.Paint = function() end
self.panels[i].index.title = self.panels[i].index.leftPanel:Add("DLabel")
self.panels[i].index.title:SetFont("ixMediumFont")
self.panels[i].index.title:SetText((data.labels[i] != "" and data.labels[i] != " ") and data.labels[i] or "---")
self.panels[i].index.title:Dock(TOP)
self.panels[i].index.title:DockMargin(10, 10, 0, 0)
self.panels[i].index.title:SetColor(ix.config.Get("color", Color(255, 255, 255)))
self.panels[i].index.price = self.panels[i].index.leftPanel:Add("DLabel")
self.panels[i].index.price:SetFont("ixGenericFont")
self.panels[i].index.price:SetText("Price: " .. data.prices[i] .. " Credits")
self.panels[i].index.price:Dock(BOTTOM)
self.panels[i].index.price:DockMargin(10, 0, 0, 10)
self.panels[i].index.indicator = self.panels[i].index:Add("DPanel")
self.panels[i].index.indicator:SetSize(40, 0)
self.panels[i].index.indicator:Dock(RIGHT)
self.panels[i].index.indicator:DockMargin(10, 10, 10, 10)
self.panels[i].index.indicator.Paint = function(self, w, h)
if (data.labels[i] != "" and data.labels[i] != " ") then
if (data.buttons[i]) then
if (data.stocks[i]) then
surface.SetDrawColor(color_green)
else
surface.SetDrawColor(color_red)
end
else
surface.SetDrawColor(color_orange)
end
surface.DrawRect(0, 0, w, h)
end
end
self.panels[i].index.toggle = self.panels[i].index:Add("DButton")
self.panels[i].index.toggle:Dock(RIGHT)
self.panels[i].index.toggle:SetText("Toggle")
self.panels[i].index.toggle.DoClick = function()
net.Start("ixToggleVendingMachineButton")
net.WriteEntity(data.entity)
net.WriteFloat(i)
net.SendToServer()
data.buttons[i] = !data.buttons[i]
surface.PlaySound("helix/ui/press.wav")
end
self.panels[i].index.toggle.Paint = function() end
self.panels[i].index.reprice = self.panels[i].index:Add("DButton")
self.panels[i].index.reprice:Dock(RIGHT)
self.panels[i].index.reprice:SetText("Reprice")
self.panels[i].index.reprice.DoClick = function()
Derma_StringRequest(
"Change price",
"Change the price of this selection",
data.prices[i],
function(price)
price = tonumber(price or 0) or 0
price = math.Round(price)
if (price < 0) then
LocalPlayer():Notify("The price of a selection cannot be lower than 0!")
return
end
net.Start("ixSetVendingMachinePrice")
net.WriteEntity(data.entity)
net.WriteFloat(i)
net.WriteFloat(price)
net.SendToServer()
data.prices[i] = price
self.panels[i].index.price:SetText("Price: " .. price .. " Credits")
end
)
surface.PlaySound("helix/ui/press.wav")
end
self.panels[i].index.reprice.Paint = function() end
self.panels[i].index.rename = self.panels[i].index:Add("DButton")
self.panels[i].index.rename:Dock(RIGHT)
self.panels[i].index.rename:SetText("Rename")
self.panels[i].index.rename.DoClick = function()
Derma_StringRequest(
"Change label",
"Change the label of this selection",
data.labels[i],
function(label)
net.Start("ixSetVendingMachineLabel")
net.WriteEntity(data.entity)
net.WriteFloat(i)
net.WriteString(label)
net.SendToServer()
data.labels[i] = label
self.panels[i].index.title:SetText(label)
end
)
surface.PlaySound("helix/ui/press.wav")
end
self.panels[i].index.rename.Paint = function() end
self.innerContent:SetTall(self.innerContent:GetTall() + self.panels[i].index:GetTall() + (i == 1 and SScaleMin(10 / 3) or 0) + SScaleMin(10 / 3))
end
self.innerContent:Center()
local skinPanel = self.innerContent:Add("DPanel")
skinPanel:Dock(TOP)
skinPanel:DockMargin(10, 0, 10, 0)
skinPanel:SetTall(SScaleMin(50 / 3))
skinPanel.Paint = function() end
local skins = data.entity:SkinCount()
for i = 1, skins do
local skinButton = skinPanel:Add("DButton")
skinButton:Dock(LEFT)
skinButton:DockMargin(0, 0, i != skins and 10 or 0, 0)
skinButton:SetWidth((self.innerContent:GetWide() - 20 - 10 * (skins - 1)) / skins)
skinButton:SetFont("ixMediumFont")
skinButton:SetColor(Color(255, 255, 255, 255))
skinButton:SetText(i - 1)
skinButton.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
net.Start("ixSetVendingMachineSkin")
net.WriteEntity(data.entity)
net.WriteFloat(i - 1)
net.SendToServer()
end
end
local invButton = self.innerContent:Add("DButton")
invButton:Dock(TOP)
invButton:DockMargin(10, SScaleMin(10 / 3), 10, 0)
invButton:SetTall(SScaleMin(60 / 3))
invButton:SetFont("ixMediumFont")
invButton:SetColor(ix.config.Get("color", Color(255, 255, 255)))
invButton:SetText("OPEN INVENTORY")
invButton.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
net.Start("ixOpenVendingInventory")
net.WriteEntity(data.entity)
net.SendToServer()
self:Remove()
end
self.collectButton = self.innerContent:Add("DButton")
self.collectButton:Dock(TOP)
self.collectButton:DockMargin(10, SScaleMin(10 / 3), 10, 0)
self.collectButton:SetTall(SScaleMin(60 / 3))
self.collectButton:SetFont("ixMediumFont")
self.collectButton:SetColor(ix.config.Get("color", Color(255, 255, 255)))
self.collectButton:SetText("COLLECT CREDITS (" .. tostring(data.credits) .. ")")
self.collectButton.DoClick = function()
surface.PlaySound("helix/ui/press.wav")
net.Start("ixCollectVendingMachineCredits")
net.WriteEntity(data.entity)
net.SendToServer()
self:Remove()
end
end
vgui.Register("ixVendingMachineManager", PANEL, "EditablePanel")

View File

@@ -0,0 +1,90 @@
--[[
| 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")
local glowMaterial = Material("sprites/glow04_noz")
local color_green = Color(0, 255, 0, 255)
local color_red = Color(255, 0, 0, 255)
local color_orange = Color(255, 125, 0, 255)
function ENT:Draw()
self:DrawModel()
local position = self:GetPos()
local angles = self:GetAngles()
angles:RotateAroundAxis(angles:Up(), 90)
angles:RotateAroundAxis(angles:Forward(), 90)
local f, r, u = self:GetForward(), self:GetRight(), self:GetUp()
local spacing = 0
local labels = self:GetNetVar("labels")
local prices = self:GetNetVar("prices")
if (!labels or !prices) then return end
cam.Start3D2D(position + f * 17.6 + r * -18 + u * 4.6, angles, 0.06)
for i = 1, 8 do
if (labels[i] != "" and labels[i] != " ") then
draw.SimpleText("(" .. prices[i] .. ")" .. labels[i], "DebugFixedSmall", 90, spacing, color_white, TEXT_ALIGN_RIGHT)
end
spacing = spacing + 34
end
cam.End3D2D()
render.SetMaterial(glowMaterial)
if (self.buttons) then
local closest = self:GetNearestButton()
local stocks = self:GetNetVar("stocks")
local buttons = self:GetNetVar("buttons")
for k, v in pairs(self.buttons) do
if (labels[k] == "" or labels[k] == " ") then
continue
end
local color = color_green
if (stocks and !stocks[k]) then
color = color_red
color.a = 200
end
if (buttons and !buttons[k]) then
color = color_orange
color.a = 200
end
if (closest != k) then
color.a = color == color_red and 100 or 75
else
color.a = 230 + (math.sin(RealTime() * 7.5) * 25)
end
if (LocalPlayer():KeyDown(IN_USE) and closest == k) then
color = table.Copy(color)
color.r = math.min(color.r + 100, 255)
color.g = math.min(color.g + 100, 255)
color.b = math.min(color.b + 100, 255)
end
render.DrawSprite(v, 4, 4, color)
end
if (!self:GetLocked()) then
render.DrawSprite(position + f * 18.5 + r * -21 + u * 13, 7, 7, Color(50, 100, 255, 255))
end
end
end

View File

@@ -0,0 +1,259 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
local PLUGIN = PLUGIN
function ENT:SpawnFunction(client, trace)
if (!trace.Hit) then return end
local SpawnPosition = trace.HitPos + trace.HitNormal + Vector(0, 0, 45)
local SpawnAngle = client:EyeAngles()
SpawnAngle.p = 0
SpawnAngle.y = SpawnAngle.y + 180
local entity = ents.Create("ix_customvendingmachine")
entity:SetPos(SpawnPosition)
entity:SetAngles(SpawnAngle)
entity:Spawn()
entity:Activate()
ix.inventory.New(0, "vendingMachine", function(inventory)
if (!IsValid(entity)) then return end
if (inventory) then
inventory.vars.isBag = true
inventory.vars.isVendingMachine = true
entity:SetID(inventory:GetID())
ix.item.Spawn("vendingmachinekey", client, nil, nil, {vendingMachineID = entity:GetID()})
ix.item.Spawn("vendingmachinekey", client, nil, nil, {vendingMachineID = entity:GetID()})
ix.item.Spawn("vendingmachinekey", client, nil, nil, {vendingMachineID = entity:GetID()})
ix.saveEnts:SaveEntity(entity)
PLUGIN:SaveData()
end
end)
return entity
end
function ENT:CheckHasID(character)
local idCard = character:GetInventory():HasItem("id_card")
if (!idCard) then
self:EmitSound("buttons/button2.wav")
self.nextUse = CurTime() + 1
return false
end
return true
end
function ENT.CheckIDCard(idCard, genericData, client, entity, collecting)
if (idCard:GetData("active", false) == false) then
ix.combineNotify:AddImportantNotification("WRN:// Inactive Identification Card #" .. idCard:GetData("cid", 00000) .. " usage attempt detected", nil, client, client:GetPos())
entity:EmitSound("buttons/button2.wav")
entity.nextUse = CurTime() + 1
return
end
local isBOL = genericData.bol
local isAC = genericData.anticitizen
if (isBOL or isAC) then
local text = isBOL and "BOL Suspect" or "Anti-Citizen"
ix.combineNotify:AddImportantNotification("WRN:// " .. text .. " Identification Card activity detected", nil, client, client:GetPos())
end
if (collecting) then
idCard:GiveCredits(entity:GetNetVar("credits", 0), "Vending Machine", "Vending Machine (" .. entity:GetID() .. ") Credit Collection")
entity:SetNetVar("credits", 0)
ix.saveEnts:SaveEntity(entity)
else
entity:PostAuthorized(client, idCard)
end
end
function ENT.CheckIDError(_, entity)
entity:EmitSound("buttons/button2.wav")
end
function ENT:Use(activator)
if ((self.nextUse or 0) < CurTime()) then
self.nextUse = CurTime() + 1
else
return
end
local button = self:GetNearestButton(activator)
if (button) then
activator:EmitSound("buttons/lightswitch2.wav", 55, 125)
local character = activator:GetCharacter()
if (self:CheckHasID(character)) then
local idCards = character:GetInventory():GetItemsByUniqueID("id_card")
if (#idCards == 1) then
idCards[1]:LoadOwnerGenericData(self.CheckIDCard, self.CheckIDError, activator, self)
else
self.cidSelection = activator
net.Start("ixSelectVendingMachineCID")
net.WriteEntity(self)
net.Send(activator)
timer.Simple(30, function()
if (IsValid(self)) then
self.cidSelection = nil
end
end)
end
end
elseif (!self:GetLocked()) then
activator.ixVendingMachineEdit = self
activator:EmitSound("buttons/lightswitch2.wav", 55, 125)
self:EmitSound("buttons/button1.wav")
net.Start("ixVendingMachineManager")
net.WriteEntity(self)
net.Send(activator)
end
end
function ENT:PostAuthorized(activator, idCard)
local button = self:GetNearestButton(activator)
local prices = self:GetNetVar("prices")
local labels = self:GetNetVar("labels")
local buttons = self:GetNetVar("buttons")
if (!labels[button]) then
return
end
if (buttons[button]) then
local item = self:FindItemInRow(button)
if (item) then
local price = prices[button]
if (idCard:HasCredits(price)) then
local position = self:GetPos()
local f, r, u = self:GetForward(), self:GetRight(), self:GetUp()
local inventory = ix.item.inventories[self:GetID()]
item.invID = 0
inventory:Remove(item.id, false, true)
local query = mysql:Update("ix_items")
query:Update("inventory_id", 0)
query:Where("item_id", item.id)
query:Execute()
inventory = ix.item.inventories[0]
inventory[item:GetID()] = item
item:Spawn(position + f * 19 + r * 4 + u * -26)
idCard:TakeCredits(price, "Vending Machine", "\"" .. item:GetName() .. "\" Vending Machine (" .. self:GetID() .. ") purchase.")
self:EmitSound("buttons/button4.wav")
self:SetNetVar("credits", self:GetNetVar("credits", 0) + price)
activator:Notify("You have purchased a " .. labels[button] .. " for " .. price .. " Credits.")
else
self:EmitSound("buttons/button8.wav")
activator:Notify("You need a total of " .. price .. " Credits to purchase a " .. labels[button] .. "!")
end
-- Check again to see if we ran out. If we did, change to red.
self:UpdateStocks()
ix.saveEnts:SaveEntity(self)
else
self:EmitSound("buttons/button2.wav")
self:UpdateStocks()
end
else
self:EmitSound("buttons/combine_button_locked.wav")
end
end
function ENT:CollectCredits(activator)
local character = activator:GetCharacter()
if (!self:GetLocked() and self:CheckHasID(character)) then
local idCards = character:GetInventory():GetItemsByUniqueID("id_card")
if (#idCards == 1) then
idCards[1]:LoadOwnerGenericData(self.CheckIDCard, self.CheckIDError, activator, self, true)
else
self.cidSelection = activator
activator.isCollecting = true
net.Start("ixSelectVendingMachineCID")
net.WriteEntity(self)
net.Send(activator)
timer.Simple(30, function()
if (IsValid(self)) then
self.cidSelection = nil
end
if (IsValid(activator)) then
activator.isCollecting = nil
end
end)
end
end
end
function ENT:FindItemInRow(row)
local inventory = ix.item.inventories[self:GetID()]
if (inventory) then
for _, itemData in pairs(inventory:GetItems(true)) do
if (itemData.gridY == row) then
return itemData
end
end
end
end
function ENT:SetData(dataType, slot, value)
local data = self:GetNetVar(dataType, {})
if (data[slot] != value) then
data[slot] = value
self:SetNetVar(dataType, data)
end
end
function ENT:UpdateStocks()
for i = 1, 8 do
if (self:FindItemInRow(i)) then
self:SetData("stocks", i, true)
else
self:SetData("stocks", i, false)
end
end
end

View File

@@ -0,0 +1,156 @@
--[[
| 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 = "Vending Machine"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PhysgunDisable = true
ENT.PhysgunAllowAdmin = true
function ENT:SetupDataTables()
self:NetworkVar("Int", 0, "ID")
self:NetworkVar("Bool", 1, "Locked")
end
function ENT:Initialize()
self.buttons = {}
local position = self:GetPos()
local f, r, u = self:GetForward(), self:GetRight(), self:GetUp()
self.buttons[1] = position + f * 18 + r * -24.4 + u * 4.3
self.buttons[2] = position + f * 18 + r * -24.4 + u * 2.25
self.buttons[3] = position + f * 18 + r * -24.4 + u * 0.20
self.buttons[4] = position + f * 18 + r * -24.4 + u * -1.85
self.buttons[5] = position + f * 18 + r * -24.4 + u * -3.9
self.buttons[6] = position + f * 18 + r * -24.4 + u * -5.95
self.buttons[7] = position + f * 18 + r * -24.4 + u * -8
self.buttons[8] = position + f * 18 + r * -24.4 + u * -10.05
if (SERVER) then
self:SetModel("models/willardnetworks/misc/customvendingmachine.mdl")
self:PhysicsInit(SOLID_VPHYSICS)
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self:SetLocked(true)
local labels = {}
local buttons = {}
local prices = {}
local stocks = {}
for i = 1, 8 do
labels[i] = ""
buttons[i] = true
prices[i] = 0
stocks[i] = false
end
self:SetNetVar("labels", labels)
self:SetNetVar("buttons", buttons)
self:SetNetVar("prices", prices)
self:SetNetVar("stocks", stocks)
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Sleep()
end
else
local uniqueID = "VendingMachineAmbience" .. self:EntIndex()
local time = 1
timer.Simple(1, function()
timer.Adjust(uniqueID, 1.7461677789688)
end)
timer.Create(uniqueID, time, 0, function()
if (IsValid(self)) then
self:EmitSound("vendingmachinehum_loop.wav", 65, 100, 0.15)
else
timer.Remove(uniqueID)
end
end)
end
end
function ENT:GetNearestButton(client)
client = client or (CLIENT and LocalPlayer())
if (self.buttons) then
local position = self:GetPos()
local f, r, u = self:GetForward(), self:GetRight(), self:GetUp()
self.buttons[1] = position + f * 18 + r * -24.4 + u * 4.3
self.buttons[2] = position + f * 18 + r * -24.4 + u * 2.25
self.buttons[3] = position + f * 18 + r * -24.4 + u * 0.20
self.buttons[4] = position + f * 18 + r * -24.4 + u * -1.85
self.buttons[5] = position + f * 18 + r * -24.4 + u * -3.9
self.buttons[6] = position + f * 18 + r * -24.4 + u * -5.95
self.buttons[7] = position + f * 18 + r * -24.4 + u * -8
self.buttons[8] = position + f * 18 + r * -24.4 + u * -10.05
local data = {}
data.start = client:GetShootPos()
data.endpos = data.start + client:GetAimVector()*96
data.filter = client
local trace = util.TraceLine(data)
local hitPos = trace.HitPos
if (hitPos) then
for buttonNum, buttonPos in pairs(self.buttons) do
if (buttonPos:Distance(hitPos) <= 2) then
return buttonNum
end
end
end
end
end
function ENT:OnRemove()
if (SERVER) then
if (!ix.shuttingDown) then
local index = self:GetID()
if (!self.ixIsSafe and ix.entityDataLoaded and index) then
local inventory = index != 0 and ix.item.inventories[index]
if (inventory) then
ix.item.inventories[index] = nil
local query = mysql:Delete("ix_items")
query:Where("inventory_id", index)
query:Execute()
query = mysql:Delete("ix_inventories")
query:Where("inventory_id", index)
query:Execute()
hook.Run("ContainerRemoved", self, inventory)
end
end
end
else
self:StopSound("vendingmachinehum_loop.wav")
timer.Simple(0.1, function()
if (!IsValid(self)) then
timer.Remove("VendingMachineAmbience" .. self:EntIndex())
end
end)
end
end

View File

@@ -0,0 +1,55 @@
--[[
| 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 = "Vending Machine Key"
ITEM.description = "A small piece of metal consisting of a 'blade' with several cuts and a 'bow', used to operate a lock."
ITEM.model = "models/gibs/metal_gib4.mdl"
ITEM.category = "Tools"
function ITEM:PopulateTooltip(tooltip)
local ID = self:GetData("vendingMachineID", nil)
if (ID) then
local vendingMachineID = tooltip:AddRow("vendingMachineID")
vendingMachineID:SetBackgroundColor(derma.GetColor("Info", tooltip))
vendingMachineID:SetText("It has \"" .. ID .. "\" engraved on it.")
vendingMachineID:SizeToContents()
end
end
ITEM.functions.Insert = {
icon = "icon16/key.png",
OnRun = function(itemTable)
local client = itemTable.player
local trace = client:GetEyeTraceNoCursor()
local target = trace.Entity
if (target and target:GetClass() == "ix_customvendingmachine") then
if (trace.HitPos:Distance(client:GetShootPos()) < 200) then
if (itemTable:GetData("vendingMachineID", nil) == target:GetID()) then
target:SetLocked(!target:GetLocked())
target:EmitSound("buttons/combine_button" .. math.random(1, 3) .. ".wav")
else
client:Notify("This key does not fit in this Vending Machine!")
end
else
client:Notify("That Vending Machine is too far away!")
end
else
client:Notify("The Vending Machine Key can only be inserted into a vending machine!")
end
return false
end,
OnCanRun = function(itemTable)
return !itemTable.entity
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/
--]]
PLUGIN.name = "LN | Vending Machines"
PLUGIN.description = "Adds dynamic Vending Machines."
PLUGIN.author = "Aspect™ & Chessnut"
ix.util.Include("cl_plugin.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_plugin.lua")
function PLUGIN:InitializedPlugins()
ix.inventory.Register("vendingMachine", 10, 8)
end

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/
--]]
function PLUGIN:SaveData()
self:SaveVendingMachines()
end
function PLUGIN:LoadData()
if (!ix.config.Get("SaveEntsOldLoadingEnabled")) then return end
self:LoadVendingMachines()
end
-- Called to check if a player can transfer an item.
function PLUGIN:CanTransferItem(item, oldInv, newInv)
if (newInv.vars and newInv.vars.isVendingMachine) then
if (item.width > 1 or item.height > 1) then
return false
end
end
end
-- Called after an item has been transferred.
function PLUGIN:OnItemTransferred(item, oldInv, newInv)
if ((newInv.vars and newInv.vars.isVendingMachine) or (oldInv.vars and oldInv.vars.isVendingMachine)) then
local vendingMachine
for _, entity in ipairs(ents.FindByClass("ix_customvendingmachine")) do
if (entity:GetID() == newInv:GetID() or entity:GetID() == oldInv:GetID()) then
vendingMachine = entity
break
end
end
if (vendingMachine) then
vendingMachine:UpdateStocks()
end
end
end
-- Called after an item has been moved in the same inventory.
function PLUGIN:OnItemMoved(item, inventory)
if (inventory.vars.isVendingMachine) then
local vendingMachine
for _, entity in ipairs(ents.FindByClass("ix_customvendingmachine")) do
if (entity:GetID() == inventory:GetID()) then
vendingMachine = entity
break
end
end
if (vendingMachine) then
vendingMachine:UpdateStocks()
end
end
end

View File

@@ -0,0 +1,221 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
util.AddNetworkString("ixVendingMachineManager")
util.AddNetworkString("ixOpenVendingInventory")
util.AddNetworkString("ixSetVendingMachineLabel")
util.AddNetworkString("ixToggleVendingMachineButton")
util.AddNetworkString("ixSetVendingMachinePrice")
util.AddNetworkString("ixSelectVendingMachineCID")
util.AddNetworkString("ixCollectVendingMachineCredits")
util.AddNetworkString("ixSetVendingMachineSkin")
local fields = {
"credits", "labels", "buttons", "prices", "stocks"
}
function PLUGIN:RegisterSaveEnts()
ix.saveEnts:RegisterEntity("ix_customvendingmachine", true, true, true, {
OnSave = function(entity, data) --OnSave
local inventory = ix.item.inventories[entity:GetID()]
data.invID = inventory:GetID()
data.motion = false
for k, v in ipairs(fields) do
data[v] = entity:GetNetVar(v)
end
end,
OnRestore = function(entity, data) --OnRestore
ix.inventory.Restore(data.invID, 10, 8, function(inventory)
inventory.vars.isBag = true
inventory.vars.isVendingMachine = true
if (IsValid(entity)) then
entity:SetID(inventory:GetID())
entity:UpdateStocks()
end
end)
for k, v in ipairs(fields) do
entity:SetNetVar(v, data[v])
end
end,
ShouldSave = function(entity) --ShouldSave
local inventory = ix.item.inventories[entity:GetID()]
return inventory:GetID() >= 1
end,
ShouldRestore = function(data) --ShouldRestore
return data.invID >= 1
end
})
end
-- A function to save the Vending Machines.
function PLUGIN:SaveVendingMachines()
local data = {}
for _, v in ipairs(ents.FindByClass("ix_customvendingmachine")) do
local inventory = ix.item.inventories[v:GetID()]
data[#data + 1] = {
v:GetPos(),
v:GetAngles(),
inventory:GetID(),
v:GetNetVar("credits"),
v:GetNetVar("labels"),
v:GetNetVar("buttons"),
v:GetNetVar("prices"),
v:GetNetVar("stocks"),
v:GetSkin()
}
end
ix.data.Set("customVendingMachines", data)
end
-- A function to load the Vending Machines.
function PLUGIN:LoadVendingMachines()
for _, v in ipairs(ix.data.Get("customVendingMachines") or {}) do
local inventoryID = tonumber(v[3])
if (!inventoryID or inventoryID < 1) then
ErrorNoHalt(string.format("[Helix] Attempted to restore container inventory with invalid inventory ID '%s'\n", tostring(inventoryID)))
continue
end
local entity = ents.Create("ix_customvendingmachine")
entity:SetPos(v[1])
entity:SetAngles(v[2])
entity:Spawn()
ix.inventory.Restore(inventoryID, 10, 8, function(inventory)
inventory.vars.isBag = true
inventory.vars.isVendingMachine = true
if (IsValid(entity)) then
entity:SetID(inventory:GetID())
entity:UpdateStocks()
end
end)
entity:SetNetVar("credits", v[4])
entity:SetNetVar("labels", v[5])
entity:SetNetVar("buttons", v[6])
entity:SetNetVar("prices", v[7])
entity:SetNetVar("stocks", v[8])
entity:SetSkin(v[9])
local physicsObject = entity:GetPhysicsObject()
if (IsValid(physicsObject)) then
physicsObject:EnableMotion(false)
end
end
end
net.Receive("ixOpenVendingInventory", function(_, client)
local machine = net.ReadEntity()
if (!IsValid(client.ixVendingMachineEdit) or machine != client.ixVendingMachineEdit) then return end
local inventory = ix.item.inventories[machine:GetID()]
if (inventory) then
ix.storage.Open(client, inventory, {
name = "Vending Machine",
entity = machine,
searchTime = 0
})
end
end)
net.Receive("ixSetVendingMachineLabel", function(_, client)
local machine = net.ReadEntity()
if (!IsValid(client.ixVendingMachineEdit) or machine != client.ixVendingMachineEdit) then return end
local slot = net.ReadFloat()
local label = net.ReadString()
label = string.Left(label, 100)
machine:SetData("labels", slot, label)
ix.saveEnts:SaveEntity(machine)
end)
net.Receive("ixToggleVendingMachineButton", function(_, client)
local machine = net.ReadEntity()
if (!IsValid(client.ixVendingMachineEdit) or machine != client.ixVendingMachineEdit) then return end
local slot = net.ReadFloat()
local buttons = machine:GetNetVar("buttons", {})
buttons[slot] = !buttons[slot]
machine:SetNetVar("buttons", buttons)
ix.saveEnts:SaveEntity(machine)
end)
net.Receive("ixSetVendingMachinePrice", function(_, client)
local machine = net.ReadEntity()
if (!IsValid(client.ixVendingMachineEdit) or machine != client.ixVendingMachineEdit) then return end
local slot = net.ReadFloat()
local price = net.ReadFloat()
machine:SetData("prices", slot, price)
ix.saveEnts:SaveEntity(machine)
end)
net.Receive("ixSelectVendingMachineCID", function(_, client)
if (net.ReadBool()) then
local entity = net.ReadEntity()
if (IsValid(entity) and IsValid(client) and client == entity.cidSelection) then
local idCard = net.ReadUInt(16)
local idCardItem = ix.item.instances[idCard]
idCardItem:LoadOwnerGenericData(entity.CheckIDCard, entity.CheckIDError, client, entity, client.isCollecting)
entity.cidSelection = nil
end
else
local entity = net.ReadEntity()
if (IsValid(entity)) then
entity:EmitSound("buttons/button2.wav")
entity.cidSelection = nil
end
end
end)
net.Receive("ixCollectVendingMachineCredits", function(_, client)
local machine = net.ReadEntity()
if (!IsValid(client.ixVendingMachineEdit) or machine != client.ixVendingMachineEdit) then return end
if (machine and IsValid(machine)) then
machine:CollectCredits(client)
end
end)
net.Receive("ixSetVendingMachineSkin", function(_, client)
local machine = net.ReadEntity()
if (!IsValid(client.ixVendingMachineEdit) or machine != client.ixVendingMachineEdit) then return end
local skin = net.ReadFloat()
if (machine and IsValid(machine) and !machine:GetLocked()) then
machine:SetSkin(skin)
ix.saveEnts:SaveEntity(machine)
end
end)