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,308 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PANEL = {}
AccessorFunc(PANEL, "bReadOnly", "ReadOnly", FORCE_BOOL)
function PANEL:Init()
self:SetSize(ScrW() * 0.45, ScrH() * 0.65)
self:SetTitle("")
self:MakePopup()
self:Center()
self.playerCurrency = ""
end
function PANEL:Populate(playerCredits)
local header = self:Add("DPanel")
header:SetTall(34)
header:Dock(TOP)
self.vendorName = header:Add("DLabel")
self.vendorName:Dock(LEFT)
self.vendorName:SetWide(self:GetWide() * 0.5 - 7)
self.vendorName:SetText("John Doe")
self.vendorName:SetTextInset(4, 0)
self.vendorName:SetTextColor(color_white)
self.vendorName:SetFont("ixMediumFont")
if (!playerCredits) then
self.playerCurrency = ix.currency.Get(LocalPlayer():GetCharacter():GetMoney())
else
self.playerCurrency = L("vendorNCredits", playerCredits)
end
self.useCredits = playerCredits and true or false
self.ourName = header:Add("DLabel")
self.ourName:Dock(RIGHT)
self.ourName:SetWide(self:GetWide() * 0.5 - 7)
self.ourName:SetTextInset(0, 0)
self.ourName:SetTextColor(color_white)
self.ourName:SetFont("ixMediumFont")
local footer = self:Add("DPanel")
footer:SetTall(34)
footer:Dock(BOTTOM)
footer:SetPaintBackground(false)
self.vendorSell = footer:Add("DButton")
self.vendorSell:SetFont("ixMediumFont")
self.vendorSell:SetWide(self.vendorName:GetWide())
self.vendorSell:Dock(LEFT)
self.vendorSell:SetContentAlignment(5)
-- The text says purchase but the vendor is selling it to us.
self.vendorSell:SetText(L"purchase")
self.vendorSell:SetTextColor(color_white)
self.vendorSell.DoClick = function(this)
if (IsValid(self.activeSell)) then
net.Start("ixVendorTrade")
net.WriteString(self.activeSell.item)
net.WriteBool(false)
net.SendToServer()
end
end
self.vendorBuy = footer:Add("DButton")
self.vendorBuy:SetFont("ixMediumFont")
self.vendorBuy:SetWide(self.ourName:GetWide())
self.vendorBuy:Dock(RIGHT)
self.vendorBuy:SetContentAlignment(5)
self.vendorBuy:SetText(L"sell")
self.vendorBuy:SetTextColor(color_white)
self.vendorBuy.DoClick = function(this)
if (IsValid(self.activeBuy)) then
net.Start("ixVendorTrade")
net.WriteString(self.activeBuy.item)
net.WriteBool(true)
net.SendToServer()
end
end
self.selling = self:Add("DScrollPanel")
self.selling:SetWide(self:GetWide() * 0.5 - 7)
self.selling:Dock(LEFT)
self.selling:DockMargin(0, 4, 0, 4)
self.selling:SetPaintBackground(true)
self.sellingItems = self.selling:Add("DListLayout")
self.sellingItems:SetSize(self.selling:GetSize())
self.sellingItems:DockPadding(0, 0, 0, 4)
self.sellingItems:SetTall(ScrH())
self.buying = self:Add("DScrollPanel")
self.buying:SetWide(self:GetWide() * 0.5 - 7)
self.buying:Dock(RIGHT)
self.buying:DockMargin(0, 4, 0, 4)
self.buying:SetPaintBackground(true)
self.buyingItems = self.buying:Add("DListLayout")
self.buyingItems:SetSize(self.buying:GetSize())
self.buyingItems:DockPadding(0, 0, 0, 4)
self.sellingList = {}
self.buyingList = {}
end
function PANEL:addItem(uniqueID, listID)
local entity = self.entity
local items = entity.items
local data = items[uniqueID]
if ((!listID or listID == "selling") and !IsValid(self.sellingList[uniqueID])
and ix.item.list[uniqueID]) then
if (data and data[VENDOR_MODE] and data[VENDOR_MODE] != VENDOR_BUYONLY) then
local item = self.sellingItems:Add("ixVendorItem")
item:Setup(uniqueID)
self.sellingList[uniqueID] = item
self.sellingItems:InvalidateLayout()
end
end
if ((!listID or listID == "buying") and !IsValid(self.buyingList[uniqueID])
and LocalPlayer():GetCharacter():GetInventory():HasItem(uniqueID)) then
if (data and data[VENDOR_MODE] and data[VENDOR_MODE] != VENDOR_SELLONLY) then
local item = self.buyingItems:Add("ixVendorItem")
item:Setup(uniqueID)
item.isLocal = true
self.buyingList[uniqueID] = item
self.buyingItems:InvalidateLayout()
end
end
end
function PANEL:removeItem(uniqueID, listID)
if (!listID or listID == "selling") then
if (IsValid(self.sellingList[uniqueID])) then
self.sellingList[uniqueID]:Remove()
self.sellingItems:InvalidateLayout()
end
end
if (!listID or listID == "buying") then
if (IsValid(self.buyingList[uniqueID])) then
self.buyingList[uniqueID]:Remove()
self.buyingItems:InvalidateLayout()
end
end
end
function PANEL:Setup(entity)
self.entity = entity
self:SetTitle(entity:GetDisplayName())
self.vendorBuy:SetEnabled(!self:GetReadOnly())
self.vendorSell:SetEnabled(!self:GetReadOnly())
for k, _ in SortedPairs(entity.items) do
self:addItem(k, "selling")
end
for _, v in SortedPairs(LocalPlayer():GetCharacter():GetInventory():GetItems()) do
self:addItem(v.uniqueID, "buying")
end
end
function PANEL:OnRemove()
net.Start("ixVendorClose")
net.SendToServer()
if (IsValid(ix.gui.vendorEditor)) then
ix.gui.vendorEditor:Remove()
end
end
function PANEL:Think()
local entity = self.entity
if (!IsValid(entity)) then
self:Remove()
return
end
if ((self.nextUpdate or 0) < CurTime()) then
local moneyAmount = self.useCredits and L("vendorNCredits", entity.money) or ix.currency.Get(entity.money)
self:SetTitle(entity:GetDisplayName())
self.vendorName:SetText(entity:GetDisplayName() .. (entity.money and " (" .. moneyAmount .. ")" or ""))
self.ourName:SetText(L"you" .. " (" .. self.playerCurrency .. ")")
self.nextUpdate = CurTime() + 0.25
end
end
function PANEL:OnItemSelected(panel)
local price = self.entity:GetPrice(panel.item, panel.isLocal)
local priceString = !self.useCredits and ix.currency.Get(price) or L("vendorNCredits", price)
if (panel.isLocal) then
self.vendorBuy:SetText(L("vendorSellText", L("sell"), priceString))
else
self.vendorSell:SetText(L("vendorSellText", L("purchase"), priceString))
end
end
vgui.Register("ixVendor", PANEL, "DFrame")
PANEL = {}
function PANEL:Init()
self:SetTall(36)
self:DockMargin(4, 4, 4, 0)
self.icon = self:Add("SpawnIcon")
self.icon:SetPos(2, 2)
self.icon:SetSize(32, 32)
self.icon:SetModel("models/error.mdl")
self.name = self:Add("DLabel")
self.name:Dock(FILL)
self.name:DockMargin(42, 0, 0, 0)
self.name:SetFont("ixChatFont")
self.name:SetTextColor(color_white)
self.name:SetExpensiveShadow(1, Color(0, 0, 0, 200))
self.click = self:Add("DButton")
self.click:Dock(FILL)
self.click:SetText("")
self.click.Paint = function() end
self.click.DoClick = function(this)
if (self.isLocal) then
ix.gui.vendor.activeBuy = self
else
ix.gui.vendor.activeSell = self
end
ix.gui.vendor:OnItemSelected(self)
end
end
function PANEL:SetCallback(callback)
self.click.DoClick = function(this)
callback()
self.selected = true
end
end
function PANEL:Setup(uniqueID)
local item = ix.item.list[uniqueID]
if (item) then
self.item = uniqueID
self.icon:SetModel(item:GetModel(), item:GetSkin())
self.name:SetText(item:GetName())
self.itemName = item:GetName()
self.click:SetHelixTooltip(function(tooltip)
ix.hud.PopulateItemTooltip(tooltip, item)
local entity = ix.gui.vendor.entity
if (entity and entity.items[self.item] and entity.items[self.item][VENDOR_MAXSTOCK]) then
local info = entity.items[self.item]
local stock = tooltip:AddRowAfter("name", "stock")
stock:SetText(string.format("Stock: %d/%d", info[VENDOR_STOCK], info[VENDOR_MAXSTOCK]))
stock:SetBackgroundColor(derma.GetColor("Info", self))
stock:SizeToContents()
end
end)
end
end
function PANEL:Think()
if ((self.nextUpdate or 0) < CurTime()) then
local entity = ix.gui.vendor.entity
if (entity and self.isLocal) then
local count = LocalPlayer():GetCharacter():GetInventory():GetItemCount(self.item)
if (count == 0) then
self:Remove()
end
end
self.nextUpdate = CurTime() + 0.1
end
end
function PANEL:Paint(w, h)
if (ix.gui.vendor.activeBuy == self or ix.gui.vendor.activeSell == self) then
surface.SetDrawColor(ix.config.Get("color"))
else
surface.SetDrawColor(0, 0, 0, 100)
end
surface.DrawRect(0, 0, w, h)
end
vgui.Register("ixVendorItem", PANEL, "DPanel")

View File

@@ -0,0 +1,307 @@
--[[
| 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 entity = ix.gui.vendor.entity
self:SetSize(320, 480)
self:MoveLeftOf(ix.gui.vendor, 8)
self:MakePopup()
self:CenterVertical()
self:SetTitle(L"vendorEditor")
self.lblTitle:SetTextColor(color_white)
self.name = self:Add("DTextEntry")
self.name:Dock(TOP)
self.name:SetText(entity:GetDisplayName())
self.name:SetPlaceholderText(L"name")
self.name.OnEnter = function(this)
if (entity:GetDisplayName() != this:GetText()) then
self:updateVendor("name", this:GetText())
end
end
self.description = self:Add("DTextEntry")
self.description:Dock(TOP)
self.description:DockMargin(0, 4, 0, 0)
self.description:SetText(entity:GetDescription())
self.description:SetPlaceholderText(L"description")
self.description.OnEnter = function(this)
if (entity:GetDescription() != this:GetText()) then
self:updateVendor("description", this:GetText())
end
end
self.model = self:Add("DTextEntry")
self.model:Dock(TOP)
self.model:DockMargin(0, 4, 0, 0)
self.model:SetText(entity:GetModel())
self.model:SetPlaceholderText(L"model")
self.model.OnEnter = function(this)
if (entity:GetModel():lower() != this:GetText():lower()) then
self:updateVendor("model", this:GetText():lower())
end
end
local useMoney = tonumber(entity.money) != nil
self.money = self:Add("DTextEntry")
self.money:Dock(TOP)
self.money:DockMargin(0, 4, 0, 0)
self.money:SetText(!useMoney and "" or entity.money)
self.money:SetPlaceholderText(L"money")
self.money:SetDisabled(!useMoney)
self.money:SetEnabled(useMoney)
self.money:SetNumeric(true)
self.money.OnEnter = function(this)
local value = tonumber(this:GetText()) or entity.money
if (value == entity.money) then
return
end
self:updateVendor("money", value)
end
self.bubble = self:Add("DCheckBoxLabel")
self.bubble:SetText(L"vendorNoBubble")
self.bubble:Dock(TOP)
self.bubble:DockMargin(0, 4, 0, 0)
self.bubble:SetValue(entity:GetNoBubble() and 1 or 0)
self.bubble.OnChange = function(this, value)
if (this.noSend) then
this.noSend = nil
else
self:updateVendor("bubble", value)
end
end
self.useMoney = self:Add("DCheckBoxLabel")
self.useMoney:SetText(L"vendorUseMoney")
self.useMoney:Dock(TOP)
self.useMoney:DockMargin(0, 4, 0, 0)
self.useMoney:SetChecked(useMoney)
self.useMoney.OnChange = function(this, value)
self:updateVendor("useMoney")
end
local useCredits = entity:GetUseCredits()
self.useCredits = self:Add("DCheckBoxLabel")
self.useCredits:SetText(L"vendorUseCredits")
self.useCredits:Dock(TOP)
self.useCredits:DockMargin(0, 4, 0, 0)
self.useCredits:SetChecked(useCredits)
self.useCredits.OnChange = function(this, value)
self:updateVendor("useCredits", value)
end
self.sellScale = self:Add("DNumSlider")
self.sellScale:Dock(TOP)
self.sellScale:DockMargin(0, 4, 0, 0)
self.sellScale:SetText(L"vendorSellScale")
self.sellScale.Label:SetTextColor(color_white)
self.sellScale.TextArea:SetTextColor(color_white)
self.sellScale:SetDecimals(1)
self.sellScale.noSend = true
self.sellScale:SetValue(entity.scale)
self.sellScale.OnValueChanged = function(this, value)
if (this.noSend) then
this.noSend = nil
else
timer.Create("ixVendorScale", 1, 1, function()
if (IsValid(self) and IsValid(self.sellScale)) then
value = self.sellScale:GetValue()
if (value != entity.scale) then
self:updateVendor("scale", value)
end
end
end)
end
end
self.faction = self:Add("DButton")
self.faction:SetText(L"vendorFaction")
self.faction:Dock(TOP)
self.faction:SetTextColor(color_white)
self.faction:DockMargin(0, 4, 0, 0)
self.faction.DoClick = function(this)
if (IsValid(ix.gui.editorFaction)) then
ix.gui.editorFaction:Remove()
end
ix.gui.editorFaction = vgui.Create("ixVendorFactionEditor")
ix.gui.editorFaction.updateVendor = self.updateVendor
ix.gui.editorFaction.entity = entity
ix.gui.editorFaction:Setup()
end
self.searchBar = self:Add("DTextEntry")
self.searchBar:Dock(TOP)
self.searchBar:DockMargin(0, 4, 0, 0)
self.searchBar:SetUpdateOnType(true)
self.searchBar:SetPlaceholderText("Search...")
self.searchBar.OnValueChange = function(this, value)
self:ReloadItemList(value)
end
local menu
self.items = self:Add("DListView")
self.items:Dock(FILL)
self.items:DockMargin(0, 4, 0, 0)
self.items:AddColumn(L"name").Header:SetTextColor(color_black)
self.items:AddColumn(L"category").Header:SetTextColor(color_black)
self.items:AddColumn(L"mode").Header:SetTextColor(color_black)
self.items:AddColumn(L"price").Header:SetTextColor(color_black)
self.items:AddColumn(L"stock").Header:SetTextColor(color_black)
self.items:SetMultiSelect(false)
self.items.OnRowRightClick = function(this, index, line)
if (IsValid(menu)) then
menu:Remove()
end
local uniqueID = line.item
menu = DermaMenu()
-- Modes of the item.
local mode, panel = menu:AddSubMenu(L"mode")
panel:SetImage("icon16/key.png")
-- Disable buying/selling of the item.
mode:AddOption(L"none", function()
self:updateVendor("mode", {uniqueID, nil})
end):SetImage("icon16/cog_error.png")
-- Allow the vendor to sell and buy this item.
mode:AddOption(L"vendorBoth", function()
self:updateVendor("mode", {uniqueID, VENDOR_SELLANDBUY})
end):SetImage("icon16/cog.png")
-- Only allow the vendor to buy this item from players.
mode:AddOption(L"vendorBuy", function()
self:updateVendor("mode", {uniqueID, VENDOR_BUYONLY})
end):SetImage("icon16/cog_delete.png")
-- Only allow the vendor to sell this item to players.
mode:AddOption(L"vendorSell", function()
self:updateVendor("mode", {uniqueID, VENDOR_SELLONLY})
end):SetImage("icon16/cog_add.png")
local itemTable = ix.item.list[uniqueID]
-- Set the price of the item.
menu:AddOption(L"price", function()
Derma_StringRequest(
itemTable.GetName and itemTable:GetName() or L(itemTable.name),
L"vendorPriceReq",
entity:GetPrice(uniqueID),
function(text)
text = tonumber(text)
if (text == itemTable.price) then
text = nil
end
self:updateVendor("price", {uniqueID, text})
end
)
end):SetImage("icon16/coins.png")
-- Set the stock of the item or disable it.
local stock, menuPanel = menu:AddSubMenu(L"stock")
menuPanel:SetImage("icon16/table.png")
-- Disable the use of stocks for this item.
stock:AddOption(L"disable", function()
self:updateVendor("stockDisable", uniqueID)
end):SetImage("icon16/table_delete.png")
-- Edit the maximum stock for this item.
stock:AddOption(L"edit", function()
local _, max = entity:GetStock(uniqueID)
Derma_StringRequest(
itemTable.GetName and itemTable:GetName() or L(itemTable.name),
L"vendorStockReq",
max or 1,
function(text)
self:updateVendor("stockMax", {uniqueID, text})
end
)
end):SetImage("icon16/table_edit.png")
-- Edit the current stock of this item.
stock:AddOption(L"vendorEditCurStock", function()
Derma_StringRequest(
itemTable.GetName and itemTable:GetName() or L(itemTable.name),
L"vendorStockCurReq",
entity:GetStock(uniqueID) or 0,
function(text)
self:updateVendor("stock", {uniqueID, text})
end
)
end):SetImage("icon16/table_edit.png")
menu:Open()
end
self:ReloadItemList()
end
function PANEL:ReloadItemList(filter)
local entity = ix.gui.vendor.entity
self.lines = {}
self.items:Clear()
for k, v in SortedPairs(ix.item.list) do
local itemName = v.GetName and v:GetName() or L(v.name)
if (filter and !itemName:lower():find(filter:lower(), 1, false)) then
continue
end
local mode = entity.items[k] and entity.items[k][VENDOR_MODE]
local current, max = entity:GetStock(k)
local panel = self.items:AddLine(
itemName,
v.category or L"none",
mode and L(VENDOR_TEXT[mode]) or L"none",
entity:GetPrice(k),
max and current.."/"..max or "-"
)
panel.item = k
self.lines[k] = panel
end
end
function PANEL:OnRemove()
if (IsValid(ix.gui.vendor)) then
ix.gui.vendor:Remove()
end
if (IsValid(ix.gui.editorFaction)) then
ix.gui.editorFaction:Remove()
end
end
function PANEL:updateVendor(key, value)
net.Start("ixVendorEdit")
net.WriteString(key)
net.WriteType(value)
net.SendToServer()
end
vgui.Register("ixVendorEditor", PANEL, "DFrame")

View File

@@ -0,0 +1,70 @@
--[[
| 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(256, 280)
self:Center()
self:MakePopup()
self:SetTitle(L"vendorFaction")
self.scroll = self:Add("DScrollPanel")
self.scroll:Dock(FILL)
self.scroll:DockPadding(0, 0, 0, 4)
self.factions = {}
self.classes = {}
for k, v in ipairs(ix.faction.indices) do
local panel = self.scroll:Add("DPanel")
panel:Dock(TOP)
panel:DockPadding(4, 4, 4, 4)
panel:DockMargin(0, 0, 0, 4)
local faction = panel:Add("DCheckBoxLabel")
faction:Dock(TOP)
faction:SetText(L(v.name))
faction:DockMargin(0, 0, 0, 4)
faction.OnChange = function(this, state)
self:updateVendor("faction", v.uniqueID)
end
self.factions[v.uniqueID] = faction
for _, v2 in ipairs(ix.class.list) do
if (v2.faction == k) then
local class = panel:Add("DCheckBoxLabel")
class:Dock(TOP)
class:DockMargin(16, 0, 0, 4)
class:SetText(L(v2.name))
class.OnChange = function(this, state)
self:updateVendor("class", v2.uniqueID)
end
self.classes[v2.uniqueID] = class
panel:SetTall(panel:GetTall() + class:GetTall() + 4)
end
end
end
end
function PANEL:Setup()
for k, _ in pairs(self.entity.factions or {}) do
self.factions[k]:SetChecked(true)
end
for k, _ in pairs(self.entity.classes or {}) do
self.classes[k]:SetChecked(true)
end
end
vgui.Register("ixVendorFactionEditor", PANEL, "DFrame")

View File

@@ -0,0 +1,396 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ENT.Type = "anim"
ENT.PrintName = "Vendor"
ENT.Category = "Helix"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.isVendor = true
ENT.bNoPersist = true
function ENT:SetupDataTables()
self:NetworkVar("Bool", 0, "NoBubble")
self:NetworkVar("String", 0, "DisplayName")
self:NetworkVar("String", 1, "Description")
self:NetworkVar("Bool", 1, "UseCredits")
end
function ENT:Initialize()
if (SERVER) then
self:SetModel("models/mossman.mdl")
self:SetUseType(SIMPLE_USE)
self:SetMoveType(MOVETYPE_NONE)
self:DrawShadow(true)
self:SetSolid(SOLID_BBOX)
self:PhysicsInit(SOLID_BBOX)
self.items = {}
self.messages = {}
self.factions = {}
self.classes = {}
self:SetDisplayName("John Doe")
self:SetDescription("")
self.receivers = {}
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Sleep()
end
end
timer.Simple(1, function()
if (IsValid(self)) then
self:SetAnim()
end
end)
end
function ENT:CanAccess(client)
local bAccess = false
local uniqueID = ix.faction.indices[client:Team()].uniqueID
local character = client:GetCharacter()
if (!character) then
return false
end
for i, classTable in ipairs(ix.class.list) do
if (self.classes[classTable.uniqueID] and classTable.accessFlag and character:HasFlags(classTable.accessFlag)) then
return true
end
end
if (self.factions and !table.IsEmpty(self.factions)) then
if (self.factions[uniqueID]) then
bAccess = true
else
return false
end
end
if (bAccess and self.classes and !table.IsEmpty(self.classes)) then
local class = ix.class.list[client:GetCharacter():GetClass()]
local classID = class and class.uniqueID
if (classID and !self.classes[classID]) then
return false
end
end
return true
end
function ENT:GetStock(uniqueID)
if (self.items[uniqueID] and self.items[uniqueID][VENDOR_MAXSTOCK]) then
return self.items[uniqueID][VENDOR_STOCK] or 0, self.items[uniqueID][VENDOR_MAXSTOCK]
end
end
function ENT:GetPrice(uniqueID, selling)
local price = ix.item.list[uniqueID] and self.items[uniqueID] and
self.items[uniqueID][VENDOR_PRICE] or ix.item.list[uniqueID].price or 0
if (selling) then
price = math.floor(price * (self.scale or 0.5))
end
return price
end
function ENT:CanSellToPlayer(client, uniqueID)
local data = self.items[uniqueID]
if (!data or !client:GetCharacter() or !ix.item.list[uniqueID]) then
return false
end
if (data[VENDOR_MODE] == VENDOR_BUYONLY) then
return false
end
if (!client:GetCharacter():HasMoney(self:GetPrice(uniqueID))) then
return false
end
if (data[VENDOR_STOCK] and data[VENDOR_STOCK] < 1) then
return false
end
return true
end
function ENT:CanBuyFromPlayer(client, uniqueID)
local data = self.items[uniqueID]
if (!data or !client:GetCharacter() or !ix.item.list[uniqueID]) then
return false
end
if (data[VENDOR_MODE] != VENDOR_SELLONLY) then
return false
end
if (!self:HasMoney(data[VENDOR_PRICE] or ix.item.list[uniqueID].price or 0)) then
return false
end
return true
end
function ENT:HasMoney(amount)
-- Vendor not using money system so they can always afford it.
if (!self.money) then
return true
end
return self.money >= amount
end
function ENT:SetAnim()
for k, v in ipairs(self:GetSequenceList()) do
if (v:lower():find("idle") and v != "idlenoise") then
return self:ResetSequence(k)
end
end
if (self:GetSequenceCount() > 1) then
self:ResetSequence(4)
end
end
if (SERVER) then
local PLUGIN = PLUGIN
function ENT:SpawnFunction(client, trace)
local angles = (trace.HitPos - client:GetPos()):Angle()
angles.r = 0
angles.p = 0
angles.y = angles.y + 180
local entity = ents.Create("ix_vendor")
entity:SetPos(trace.HitPos)
entity:SetAngles(angles)
entity:Spawn()
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(entity)
end
PLUGIN:SaveData()
return entity
end
function ENT:Use(activator)
local character = activator:GetCharacter()
if (!self:CanAccess(activator) or hook.Run("CanPlayerUseVendor", activator) == false) then
if (self.messages[VENDOR_NOTRADE]) then
activator:ChatPrint(self:GetDisplayName()..": "..self.messages[VENDOR_NOTRADE])
else
activator:NotifyLocalized("vendorNoTrade")
end
return
end
self.receivers[#self.receivers + 1] = activator
if (self.messages[VENDOR_WELCOME]) then
activator:ChatPrint(self:GetDisplayName()..": "..self.messages[VENDOR_WELCOME])
end
local items = {}
-- Only send what is needed.
for k, v in pairs(self.items) do
if (!table.IsEmpty(v) and (CAMI.PlayerHasAccess(activator, "Helix - Manage Vendors", nil) or v[VENDOR_MODE])) then
items[k] = v
end
end
self.scale = self.scale or 1
activator.ixVendor = self
local inventory = character:GetInventory()
-- force sync to prevent outdated inventories while buying/selling
if (character) then
inventory:Sync(activator, true)
end
if (self:GetUseCredits()) then
if (inventory:HasItem("id_card")) then
local idCards = inventory:GetItemsByUniqueID("id_card")
if (#idCards == 1) then
idCards[1]:LoadOwnerGenericData(self.UseVendor, nil, items, activator, self)
else
-- I can't be fucking arsed lol, sorry - maybe later
activator:Notify("You cannot carry more than one ID Card when trading with Vendors!")
return
end
else
activator:Notify("You need an ID Card to trade with this vendor!")
return
end
else
net.Start("ixVendorOpen")
net.WriteEntity(self)
net.WriteUInt(self.money or 0, 16)
net.WriteTable(items)
net.WriteFloat(self.scale or 1)
net.WriteBool(false)
net.Send(activator)
end
ix.log.Add(activator, "vendorUse", self:GetDisplayName())
end
function ENT.UseVendor(idCard, genericData, items, client, entity)
if (idCard:GetData("active", false) == false) then
return
end
timer.Simple(0.2, function()
net.Start("ixVendorOpen")
net.WriteEntity(entity)
net.WriteUInt(entity.money or 0, 16)
net.WriteTable(items)
net.WriteFloat(entity.scale or 1)
net.WriteBool(true)
net.WriteFloat(idCard:GetCredits())
net.Send(client)
end)
end
function ENT:SetMoney(value)
self.money = value
net.Start("ixVendorMoney")
net.WriteUInt(value and value or -1, 16)
net.Send(self.receivers)
end
function ENT:GiveMoney(value)
if (self.money) then
self:SetMoney(self:GetMoney() + value)
end
end
function ENT:TakeMoney(value)
if (self.money) then
self:GiveMoney(-value)
end
end
function ENT:SetStock(uniqueID, value)
if (!self.items[uniqueID][VENDOR_MAXSTOCK]) then
return
end
self.items[uniqueID] = self.items[uniqueID] or {}
self.items[uniqueID][VENDOR_STOCK] = math.min(value, self.items[uniqueID][VENDOR_MAXSTOCK])
net.Start("ixVendorStock")
net.WriteString(uniqueID)
net.WriteUInt(value, 16)
net.Send(self.receivers)
end
function ENT:AddStock(uniqueID, value)
if (!self.items[uniqueID][VENDOR_MAXSTOCK]) then
return
end
self:SetStock(uniqueID, self:GetStock(uniqueID) + (value or 1))
end
function ENT:TakeStock(uniqueID, value)
if (!self.items[uniqueID][VENDOR_MAXSTOCK]) then
return
end
self:AddStock(uniqueID, -(value or 1))
end
else
function ENT:CreateBubble()
self.bubble = ClientsideModel("models/extras/info_speech.mdl", RENDERGROUP_OPAQUE)
self.bubble:SetPos(self:GetPos() + Vector(0, 0, 84))
self.bubble:SetModelScale(0.6, 0)
end
function ENT:Draw()
local bubble = self.bubble
if (IsValid(bubble)) then
local realTime = RealTime()
bubble:SetRenderOrigin(self:GetPos() + Vector(0, 0, 84 + math.sin(realTime * 3) * 0.05))
bubble:SetRenderAngles(Angle(0, realTime * 100, 0))
end
self:DrawModel()
end
function ENT:Think()
local noBubble = self:GetNoBubble()
if (IsValid(self.bubble) and noBubble) then
self.bubble:Remove()
elseif (!IsValid(self.bubble) and !noBubble) then
self:CreateBubble()
end
if ((self.nextAnimCheck or 0) < CurTime()) then
self:SetAnim()
self.nextAnimCheck = CurTime() + 60
end
self:SetNextClientThink(CurTime() + 0.25)
return true
end
function ENT:OnRemove()
if (IsValid(self.bubble)) then
self.bubble:Remove()
end
end
ENT.PopulateEntityInfo = true
function ENT:OnPopulateEntityInfo(container)
local name = container:AddRow("name")
name:SetImportant()
name:SetText(self:GetDisplayName())
name:SizeToContents()
local descriptionText = self:GetDescription()
if (descriptionText != "") then
local description = container:AddRow("description")
description:SetText(self:GetDescription())
description:SizeToContents()
end
end
end
function ENT:GetMoney()
return self.money
end

View File

@@ -0,0 +1,825 @@
--[[
| 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/
--]]
-- luacheck: globals VENDOR_BUY VENDOR_SELL VENDOR_BOTH VENDOR_WELCOME VENDOR_LEAVE VENDOR_NOTRADE VENDOR_PRICE
-- luacheck: globals VENDOR_STOCK VENDOR_MODE VENDOR_MAXSTOCK VENDOR_SELLANDBUY VENDOR_SELLONLY VENDOR_BUYONLY VENDOR_TEXT
local PLUGIN = PLUGIN
PLUGIN.name = "Vendors"
PLUGIN.author = "Chessnut"
PLUGIN.description = "Adds NPC vendors that can sell things."
CAMI.RegisterPrivilege({
Name = "Helix - Manage Vendors",
MinAccess = "admin"
})
VENDOR_BUY = 1
VENDOR_SELL = 2
VENDOR_BOTH = 3
-- Keys for vendor messages.
VENDOR_WELCOME = 1
VENDOR_LEAVE = 2
VENDOR_NOTRADE = 3
-- Keys for item information.
VENDOR_PRICE = 1
VENDOR_STOCK = 2
VENDOR_MODE = 3
VENDOR_MAXSTOCK = 4
-- Sell and buy the item.
VENDOR_SELLANDBUY = 1
-- Only sell the item to the player.
VENDOR_SELLONLY = 2
-- Only buy the item from the player.
VENDOR_BUYONLY = 3
if (SERVER) then
util.AddNetworkString("ixVendorOpen")
util.AddNetworkString("ixVendorClose")
util.AddNetworkString("ixVendorTrade")
util.AddNetworkString("ixVendorEdit")
util.AddNetworkString("ixVendorEditFinish")
util.AddNetworkString("ixVendorEditor")
util.AddNetworkString("ixVendorMoney")
util.AddNetworkString("ixVendorStock")
util.AddNetworkString("ixVendorAddItem")
function PLUGIN:RegisterSaveEnts()
ix.saveEnts:RegisterEntity("ix_vendor", true, true, true, {
OnSave = function(entity, data) --OnSave
data.name = entity:GetDisplayName()
data.description = entity:GetDescription()
data.model = entity:GetModel()
data.items = entity.items
data.money = entity.money
data.maxStock = entity.maxStock
data.stashList = entity.stashList
data.motion = nil
data.bubble = entity:GetNoBubble()
data.factions = entity.factions
data.classes = entity.classes
data.scale = entity.scale
data.useCredits = entity:GetUseCredits()
end,
OnRestore = function(entity, data) --OnRestore
entity:SetModel(data.model)
entity:SetSolid(SOLID_BBOX)
entity:PhysicsInit(SOLID_BBOX)
local physObj = entity:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Sleep()
end
entity:SetDisplayName(data.name)
entity:SetDescription(data.description)
entity:SetNoBubble(data.bubble)
entity:SetUseCredits(data.useCredits or false)
local items = {}
for uniqueID, itemData in pairs(data.items) do
items[tostring(uniqueID)] = itemData
end
entity.items = items
entity.factions = data.factions or {}
entity.classes = data.classes or {}
entity.money = data.money
entity.scale = data.scale or 1
end,
})
end
function PLUGIN:SaveData()
local data = {}
for _, entity in ipairs(ents.FindByClass("ix_vendor")) do
local bodygroups = {}
for _, v in ipairs(entity:GetBodyGroups() or {}) do
bodygroups[v.id] = entity:GetBodygroup(v.id)
end
data[#data + 1] = {
name = entity:GetDisplayName(),
description = entity:GetDescription(),
pos = entity:GetPos(),
angles = entity:GetAngles(),
model = entity:GetModel(),
skin = entity:GetSkin(),
bodygroups = bodygroups,
bubble = entity:GetNoBubble(),
items = entity.items,
factions = entity.factions,
classes = entity.classes,
money = entity.money,
scale = entity.scale,
useCredits = entity:GetUseCredits()
}
end
self:SetData(data)
end
function PLUGIN:LoadData()
if (ix.saveEnts and !ix.config.Get("SaveEntsOldLoadingEnabled")) then return end
for _, v in ipairs(self:GetData() or {}) do
local entity = ents.Create("ix_vendor")
entity:SetPos(v.pos)
entity:SetAngles(v.angles)
entity:Spawn()
entity:SetModel(v.model)
entity:SetSkin(v.skin or 0)
entity:SetSolid(SOLID_BBOX)
entity:PhysicsInit(SOLID_BBOX)
local physObj = entity:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Sleep()
end
entity:SetNoBubble(v.bubble)
entity:SetDisplayName(v.name)
entity:SetDescription(v.description)
entity:SetUseCredits(v.useCredits or false)
for id, bodygroup in pairs(v.bodygroups or {}) do
entity:SetBodygroup(id, bodygroup)
end
local items = {}
for uniqueID, data in pairs(v.items) do
items[tostring(uniqueID)] = data
end
entity.items = items
entity.factions = v.factions or {}
entity.classes = v.classes or {}
entity.money = v.money
entity.scale = v.scale or 1
end
end
function PLUGIN:CanVendorSellItem(client, vendor, itemID)
local tradeData = vendor.items[itemID]
local char = client:GetCharacter()
if (!tradeData or !char) then
return false
end
if (!char:HasMoney(tradeData[1] or 0)) then
return false
end
return true
end
ix.log.AddType("vendorUse", function(client, ...)
local arg = {...}
return string.format("%s used the '%s' vendor.", client:Name(), arg[1])
end)
net.Receive("ixVendorClose", function(length, client)
local entity = client.ixVendor
if (IsValid(entity)) then
for k, v in ipairs(entity.receivers) do
if (v == client) then
table.remove(entity.receivers, k)
break
end
end
client.ixVendor = nil
end
end)
local function UpdateEditReceivers(receivers, key, value)
net.Start("ixVendorEdit")
net.WriteString(key)
net.WriteType(value)
net.Send(receivers)
end
net.Receive("ixVendorEdit", function(length, client)
if (!CAMI.PlayerHasAccess(client, "Helix - Manage Vendors", nil)) then
return
end
local entity = client.ixVendor
if (!IsValid(entity)) then
return
end
local key = net.ReadString()
local data = net.ReadType()
local feedback = true
if (key == "name") then
entity:SetDisplayName(data)
elseif (key == "description") then
entity:SetDescription(data)
elseif (key == "bubble") then
entity:SetNoBubble(data)
elseif (key == "mode") then
local uniqueID = data[1]
entity.items[uniqueID] = entity.items[uniqueID] or {}
entity.items[uniqueID][VENDOR_MODE] = data[2]
UpdateEditReceivers(entity.receivers, key, data)
elseif (key == "price") then
local uniqueID = data[1]
data[2] = tonumber(data[2])
if (data[2]) then
data[2] = math.Round(data[2])
end
entity.items[uniqueID] = entity.items[uniqueID] or {}
entity.items[uniqueID][VENDOR_PRICE] = data[2]
UpdateEditReceivers(entity.receivers, key, data)
data = uniqueID
elseif (key == "stockDisable") then
local uniqueID = data[1]
entity.items[data] = entity.items[uniqueID] or {}
entity.items[data][VENDOR_MAXSTOCK] = nil
UpdateEditReceivers(entity.receivers, key, data)
elseif (key == "stockMax") then
local uniqueID = data[1]
data[2] = math.max(math.Round(tonumber(data[2]) or 1), 1)
entity.items[uniqueID] = entity.items[uniqueID] or {}
entity.items[uniqueID][VENDOR_MAXSTOCK] = data[2]
entity.items[uniqueID][VENDOR_STOCK] = math.Clamp(entity.items[uniqueID][VENDOR_STOCK] or data[2], 1, data[2])
data[3] = entity.items[uniqueID][VENDOR_STOCK]
UpdateEditReceivers(entity.receivers, key, data)
data = uniqueID
elseif (key == "stock") then
local uniqueID = data[1]
entity.items[uniqueID] = entity.items[uniqueID] or {}
if (!entity.items[uniqueID][VENDOR_MAXSTOCK]) then
data[2] = math.max(math.Round(tonumber(data[2]) or 0), 0)
entity.items[uniqueID][VENDOR_MAXSTOCK] = data[2]
end
data[2] = math.Clamp(math.Round(tonumber(data[2]) or 0), 0, entity.items[uniqueID][VENDOR_MAXSTOCK])
entity.items[uniqueID][VENDOR_STOCK] = data[2]
UpdateEditReceivers(entity.receivers, key, data)
data = uniqueID
elseif (key == "faction") then
local faction = ix.faction.teams[data]
if (faction) then
entity.factions[data] = !entity.factions[data]
if (!entity.factions[data]) then
entity.factions[data] = nil
end
end
local uniqueID = data
data = {uniqueID, entity.factions[uniqueID]}
elseif (key == "class") then
local class
for _, v in ipairs(ix.class.list) do
if (v.uniqueID == data) then
class = v
break
end
end
if (class) then
entity.classes[data] = !entity.classes[data]
if (!entity.classes[data]) then
entity.classes[data] = nil
end
end
local uniqueID = data
data = {uniqueID, entity.classes[uniqueID]}
elseif (key == "model") then
entity:SetModel(data)
entity:SetSolid(SOLID_BBOX)
entity:PhysicsInit(SOLID_BBOX)
entity:SetAnim()
elseif (key == "useMoney") then
if (entity.money) then
entity:SetMoney()
else
entity:SetMoney(0)
end
elseif (key == "money") then
data = math.Round(math.abs(tonumber(data) or 0))
entity:SetMoney(data)
feedback = false
elseif (key == "scale") then
data = tonumber(data) or 0.5
entity.scale = data
UpdateEditReceivers(entity.receivers, key, data)
elseif (key == "useCredits") then
entity:SetUseCredits(data)
end
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(entity)
end
PLUGIN:SaveData()
if (feedback) then
local receivers = {}
for _, v in ipairs(entity.receivers) do
if (CAMI.PlayerHasAccess(v, "Helix - Manage Vendors", nil)) then
receivers[#receivers + 1] = v
end
end
net.Start("ixVendorEditFinish")
net.WriteString(key)
net.WriteType(data)
net.Send(receivers)
end
end)
net.Receive("ixVendorTrade", function(length, client)
if ((client.ixVendorTry or 0) < CurTime()) then
client.ixVendorTry = CurTime() + 0.33
else
return
end
local entity = client.ixVendor
if (!IsValid(entity) or client:GetPos():Distance(entity:GetPos()) > 192) then
return
end
local uniqueID = net.ReadString()
local isSellingToVendor = net.ReadBool()
if (entity.items[uniqueID] and
hook.Run("CanPlayerTradeWithVendor", client, entity, uniqueID, isSellingToVendor) != false) then
local price = entity:GetPrice(uniqueID, isSellingToVendor)
if (isSellingToVendor) then
local found = false
local name
if (!entity:HasMoney(price)) then
return client:NotifyLocalized("vendorNoMoney")
end
local stock, max = entity:GetStock(uniqueID)
if (stock and stock >= max) then
return client:NotifyLocalized("vendorMaxStock")
end
local invOkay = true
for _, v in pairs(client:GetCharacter():GetInventory():GetItems()) do
if (v.uniqueID == uniqueID and v:GetID() != 0 and ix.item.instances[v:GetID()] and v:GetData("equip", false) == false) then
invOkay = v:Remove()
found = true
name = L(v.name, client)
break
end
end
if (!found) then
return
end
if (!invOkay) then
client:GetCharacter():GetInventory():Sync(client, true)
return client:NotifyLocalized("tellAdmin", "trd!iid")
end
if (entity:GetUseCredits()) then
local card = client:GetCharacter():GetInventory():HasItem("id_card")
card:LoadOwnerGenericData(PLUGIN.GiveTakeCredits, nil, client, entity, price, uniqueID, false)
else
client:GetCharacter():GiveMoney(price)
end
client:NotifyLocalized("businessSell", name, !entity:GetUseCredits() and ix.currency.Get(price) or (price .. " Credits"))
entity:TakeMoney(price)
entity:AddStock(uniqueID)
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(entity)
end
PLUGIN:SaveData()
hook.Run("CharacterVendorTraded", client, entity, uniqueID, isSellingToVendor)
else
local stock = entity:GetStock(uniqueID)
if (stock and stock < 1) then
return client:NotifyLocalized("vendorNoStock")
end
local name = L(ix.item.list[uniqueID].name, client)
if (entity:GetUseCredits()) then
local card = client:GetCharacter():GetInventory():HasItem("id_card")
card:LoadOwnerGenericData(PLUGIN.GiveTakeCredits, nil, client, entity, price, uniqueID, true)
else
if (!client:GetCharacter():HasMoney(price)) then
return client:NotifyLocalized("canNotAfford")
end
client:GetCharacter():TakeMoney(price)
client:NotifyLocalized("businessPurchase", name, !entity:GetUseCredits()
and ix.currency.Get(price) or L("vendorNCredits", price))
entity:GiveMoney(price)
if (!client:GetCharacter():GetInventory():Add(uniqueID)) then
ix.item.Spawn(uniqueID, client)
else
net.Start("ixVendorAddItem")
net.WriteString(uniqueID)
net.Send(client)
end
entity:TakeStock(uniqueID)
end
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(entity)
end
PLUGIN:SaveData()
hook.Run("CharacterVendorTraded", client, entity, uniqueID, isSellingToVendor)
end
else
client:NotifyLocalized("vendorNoTrade")
end
end)
function PLUGIN.GiveTakeCredits(idCard, _, client, entity, price, itemID, isBuying)
if (isBuying) then
if (idCard:HasCredits(price)) then
local item = ix.item.Get(itemID)
local name = item and item.name or ""
idCard:TakeCredits(price, entity:GetDisplayName(), "\"" .. name .. "\" vendor purchase.")
client:NotifyLocalized("businessPurchase", name, price.." Credits")
entity:GiveMoney(price)
if (!client:GetCharacter():GetInventory():Add(itemID)) then
ix.item.Spawn(itemID, client)
else
net.Start("ixVendorAddItem")
net.WriteString(itemID)
net.Send(client)
end
entity:TakeStock(itemID)
else
return client:NotifyLocalized("canNotAfford")
end
else
idCard:GiveCredits(price, entity:GetDisplayName(),
"\"" .. ix.item.Get(itemID).name .. " " .. entity:GetDisplayName() .. "\" vendor sale.")
end
end
else
VENDOR_TEXT = {}
VENDOR_TEXT[VENDOR_SELLANDBUY] = "vendorBoth"
VENDOR_TEXT[VENDOR_BUYONLY] = "vendorBuy"
VENDOR_TEXT[VENDOR_SELLONLY] = "vendorSell"
net.Receive("ixVendorOpen", function()
local entity = net.ReadEntity()
if (!IsValid(entity)) then
return
end
entity.money = net.ReadUInt(16)
entity.items = net.ReadTable()
entity.scale = net.ReadFloat()
local usingCredits = net.ReadBool()
local credits = false
if (usingCredits) then
credits = net.ReadFloat()
end
ix.gui.vendor = vgui.Create("ixVendor")
ix.gui.vendor:SetReadOnly(false)
ix.gui.vendor:Populate(credits)
ix.gui.vendor:Setup(entity)
end)
net.Receive("ixVendorEditor", function()
local entity = net.ReadEntity()
if (!IsValid(entity) or !CAMI.PlayerHasAccess(LocalPlayer(), "Helix - Manage Vendors", nil)) then
return
end
entity.money = net.ReadUInt(16)
entity.items = net.ReadTable()
entity.scale = net.ReadFloat()
entity.messages = net.ReadTable()
entity.factions = net.ReadTable()
entity.classes = net.ReadTable()
ix.gui.vendor = vgui.Create("ixVendor")
ix.gui.vendor:SetReadOnly(true)
ix.gui.vendor:Populate()
ix.gui.vendor:Setup(entity)
ix.gui.vendorEditor = vgui.Create("ixVendorEditor")
end)
net.Receive("ixVendorEdit", function()
local panel = ix.gui.vendor
if (!IsValid(panel)) then
return
end
local entity = panel.entity
if (!IsValid(entity)) then
return
end
local key = net.ReadString()
local data = net.ReadType()
if (key == "mode") then
entity.items[data[1]] = entity.items[data[1]] or {}
entity.items[data[1]][VENDOR_MODE] = data[2]
if (!data[2]) then
panel:removeItem(data[1])
elseif (data[2] == VENDOR_SELLANDBUY) then
panel:addItem(data[1])
else
panel:addItem(data[1], data[2] == VENDOR_SELLONLY and "selling" or "buying")
panel:removeItem(data[1], data[2] == VENDOR_SELLONLY and "buying" or "selling")
end
elseif (key == "price") then
local uniqueID = data[1]
entity.items[uniqueID] = entity.items[uniqueID] or {}
entity.items[uniqueID][VENDOR_PRICE] = tonumber(data[2])
elseif (key == "stockDisable") then
if (entity.items[data]) then
entity.items[data][VENDOR_MAXSTOCK] = nil
end
elseif (key == "stockMax") then
local uniqueID = data[1]
local value = data[2]
local current = data[3]
entity.items[uniqueID] = entity.items[uniqueID] or {}
entity.items[uniqueID][VENDOR_MAXSTOCK] = value
entity.items[uniqueID][VENDOR_STOCK] = current
elseif (key == "stock") then
local uniqueID = data[1]
local value = data[2]
entity.items[uniqueID] = entity.items[uniqueID] or {}
if (!entity.items[uniqueID][VENDOR_MAXSTOCK]) then
entity.items[uniqueID][VENDOR_MAXSTOCK] = value
end
entity.items[uniqueID][VENDOR_STOCK] = value
elseif (key == "scale") then
entity.scale = data
end
end)
net.Receive("ixVendorEditFinish", function()
local panel = ix.gui.vendor
local editor = ix.gui.vendorEditor
if (!IsValid(panel) or !IsValid(editor)) then
return
end
local entity = panel.entity
if (!IsValid(entity)) then
return
end
local key = net.ReadString()
local data = net.ReadType()
if (key == "name") then
editor.name:SetText(data)
elseif (key == "description") then
editor.description:SetText(data)
elseif (key == "bubble") then
editor.bubble.noSend = true
editor.bubble:SetValue(data and 1 or 0)
elseif (key == "mode") then
if (data[2] == nil) then
editor.lines[data[1]]:SetValue(3, L"none")
else
editor.lines[data[1]]:SetValue(3, L(VENDOR_TEXT[data[2]]))
end
elseif (key == "price") then
editor.lines[data]:SetValue(4, entity:GetPrice(data))
elseif (key == "stockDisable") then
editor.lines[data]:SetValue(5, "-")
elseif (key == "stockMax" or key == "stock") then
local current, max = entity:GetStock(data)
editor.lines[data]:SetValue(5, current.."/"..max)
elseif (key == "faction") then
local uniqueID = data[1]
local state = data[2]
local editPanel = ix.gui.editorFaction
entity.factions[uniqueID] = state
if (IsValid(editPanel) and IsValid(editPanel.factions[uniqueID])) then
editPanel.factions[uniqueID]:SetChecked(state == true)
end
elseif (key == "class") then
local uniqueID = data[1]
local state = data[2]
local editPanel = ix.gui.editorFaction
entity.classes[uniqueID] = state
if (IsValid(editPanel) and IsValid(editPanel.classes[uniqueID])) then
editPanel.classes[uniqueID]:SetChecked(state == true)
end
elseif (key == "model") then
editor.model:SetText(entity:GetModel())
elseif (key == "scale") then
editor.sellScale.noSend = true
editor.sellScale:SetValue(data)
end
surface.PlaySound("buttons/button14.wav")
end)
net.Receive("ixVendorMoney", function()
local panel = ix.gui.vendor
if (!IsValid(panel)) then
return
end
local entity = panel.entity
if (!IsValid(entity)) then
return
end
local value = net.ReadUInt(16)
value = value != -1 and value or nil
entity.money = value
local editor = ix.gui.vendorEditor
if (IsValid(editor)) then
local useMoney = tonumber(value) != nil
editor.money:SetDisabled(!useMoney)
editor.money:SetEnabled(useMoney)
editor.money:SetText(useMoney and value or "")
end
end)
net.Receive("ixVendorStock", function()
local panel = ix.gui.vendor
if (!IsValid(panel)) then
return
end
local entity = panel.entity
if (!IsValid(entity)) then
return
end
local uniqueID = net.ReadString()
local amount = net.ReadUInt(16)
entity.items[uniqueID] = entity.items[uniqueID] or {}
entity.items[uniqueID][VENDOR_STOCK] = amount
local editor = ix.gui.vendorEditor
if (IsValid(editor)) then
local _, max = entity:GetStock(uniqueID)
editor.lines[uniqueID]:SetValue(4, amount .. "/" .. max)
end
end)
net.Receive("ixVendorAddItem", function()
local uniqueID = net.ReadString()
if (IsValid(ix.gui.vendor)) then
ix.gui.vendor:addItem(uniqueID, "buying")
end
end)
end
properties.Add("vendor_edit", {
MenuLabel = "Edit Vendor",
Order = 999,
MenuIcon = "icon16/user_edit.png",
Filter = function(self, entity, client)
if (!IsValid(entity)) then return false end
if (entity:GetClass() != "ix_vendor") then return false end
if (!gamemode.Call( "CanProperty", client, "vendor_edit", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Vendors", nil)
end,
Action = function(self, entity)
self:MsgStart()
net.WriteEntity(entity)
self:MsgEnd()
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
entity.receivers[#entity.receivers + 1] = client
local itemsTable = {}
for k, v in pairs(entity.items) do
if (!table.IsEmpty(v)) then
itemsTable[k] = v
end
end
client.ixVendor = entity
net.Start("ixVendorEditor")
net.WriteEntity(entity)
net.WriteUInt(entity.money or 0, 16)
net.WriteTable(itemsTable)
net.WriteFloat(entity.scale or 1)
net.WriteTable(entity.messages)
net.WriteTable(entity.factions)
net.WriteTable(entity.classes)
net.Send(client)
end
})