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,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