mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
396
gamemodes/helix/plugins/vendor/entities/entities/ix_vendor.lua
vendored
Normal file
396
gamemodes/helix/plugins/vendor/entities/entities/ix_vendor.lua
vendored
Normal 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
|
||||
Reference in New Issue
Block a user