Files
wnsrc/gamemodes/ixhl2rp/plugins/smuggler/sh_plugin.lua
lifestorm ba1fc01b16 Upload
2024-08-04 23:12:27 +03:00

386 lines
15 KiB
Lua

--[[
| 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 SMUGGLER_BUY SMUGGLER_SELL SMUGGLER_BOTH SMUGGLER_WELCOME SMUGGLER_LEAVE SMUGGLER_NOTRADE SMUGGLER_PRICE
-- luacheck: globals SMUGGLER_STOCK SMUGGLER_MODE SMUGGLER_MAXSTOCK SMUGGLER_SELLANDBUY SMUGGLER_SELLONLY SMUGGLER_BUYONLY
local PLUGIN = PLUGIN
PLUGIN.name = "Smugglers"
PLUGIN.author = "Chessnut & Gr4Ss"
PLUGIN.description = "Adds NPC smugglers that can sell things. Heavily based on Chessnut's vendor plugin."
CAMI.RegisterPrivilege({
Name = "Helix - Manage Smugglers",
MinAccess = "superadmin"
})
PLUGIN.cacheIDList = PLUGIN.cacheIDList or {}
SMUGGLER_BUY = 1
SMUGGLER_SELL = 2
SMUGGLER_BOTH = 3
-- Keys for smuggler messages.
SMUGGLER_WELCOME = 1
SMUGGLER_LEAVE = 2
SMUGGLER_NOTRADE = 3
-- Keys for item information.
SMUGGLER_PRICE = 1
SMUGGLER_STOCK = 2
SMUGGLER_MODE = 3
SMUGGLER_MAXSTOCK = 4
-- Sell and buy the item.
SMUGGLER_SELLANDBUY = 1
-- Only sell the item to the player.
SMUGGLER_SELLONLY = 2
-- Only buy the item from the player.
SMUGGLER_BUYONLY = 3
ix.util.Include("cl_plugin.lua")
ix.util.Include("cl_hooks.lua")
ix.util.Include("sh_items.lua")
ix.util.Include("sh_properties.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_plugin.lua")
ix.config.Add("SmugglerMoveInterval", 2, "The amount of hours in between the smuggler moving.", nil, {
data = {min = 0.1, max = 8, decimals = 1},
category = "Smuggler"
})
ix.config.Add("SmugglerDefaultMoney", 800, "The amount of money a smuggler spawns with by default.", nil, {
data = {min = 0, max = 2000},
category = "Smuggler"
})
ix.config.Add("SmugglerPickupDelay", 45, "The amount of minutes until items are available for pickup.", nil, {
data = {min = 1, max = 300},
category = "Smuggler"
})
ix.config.Add("SmugglingSellExpScale", 1, "The scale smuggling experience for selling items based on the price of the item.", nil, {
data = {min = 0.1, max = 10, decimals = 2},
category = "Smuggler"
})
ix.config.Add("SmugglingBuyExpScale", 1, "The scale smuggling experience for buying items based on the price of the item.", nil, {
data = {min = 0.1, max = 10, decimals = 2},
category = "Smuggler"
})
ix.config.Add("SmugglingShowWaypoints", true, "Should player see exact location of the smuggling stashes?", nil, {
category = "Smuggler"
})
ix.lang.AddTable("english", {
smugglerNoSellItems = "Nie ma żadnych przedmiotów na sprzedaż.",
smugglerNoBuyItems = "Nie ma żadnych przedmiotów do zakupu.",
smugglerSettings = "Ustawienia przemytnika",
smugglerUseMoney = "Przemytnik powinien użyć pieniędzy?",
smugglerBoth = "Kupno i sprzedaż",
smugglerBuy = "Tylko kupno",
smugglerSell = "Tylko sprzedaż",
smugglerWelcome = "Witaj w moim sklepie, co mogę Ci dziś zaoferować?",
smugglerBye = "Wpadnijcie jeszcze kiedyś!",
smugglerEditor = "Edytor przemytnika",
smugglerEditCurStock = "Edytuj bieżące zapasy",
smugglerStockReq = "Wprowadź maksymalną ilość przedmiotu, jaką przemytnik może kupić za każdym razem, gdy się pojawi.",
smugglerStockCurReq = "Wprowadź liczbę przedmiotów dostępnych do kupienia obecnie lub następnym razem, gdy pojawi się ten przemytnik.",
smugglerNoTrade = "Ten przemytnik odmawia handlu z tobą!",
smugglerNoTrust = "Ten przemytnik nie ufa ci na tyle, by handlować tym przedmiotem!",
smugglerNoMoney = "Tego przemytnika nie stać na ten przedmiot!",
smugglerNoStock = "Ten przemytnik nie ma tego przedmiotu w zapasie. Zamiast tego zamów go z dostawą!",
smugglerNoItems = "Ten przemytnik nie chce sprzedać Ci żadnych przedmiotów.",
smugglerMaxStock = "Ten przemytnik nie może dźwigać więcej tego przedmiotu!",
smugglerSelectPickupItem = "Wybierz przedmiot do odebrania:",
smugglerPickupItem = "Odebrałeś %s.",
smugglerPickupNoSpace = "Nie masz wystarczającej ilości miejsca na %s!",
smugglerNoPickupItems = "W tym miejscu nie ma żadnych przedmiotów dostępnych do odbioru!",
smugglerSelectDelivery = "Wybierz lokalizację dostawy",
smugglerDeliverTo = "Kup i dostarcz do %s",
smugglerPrepMove = "Ten przemytnik przygotowuje się do przemieszczenia, nie będzie już rozpoczynał nowych transakcji.",
smugglerAvailableDelivery = "Dostępne tylko na zamówienie",
smugglerAvailable = "Dostępne do kupienia: %d",
smugglerStock = "Przemytnik może kupić: %d\nPosiadasz: %d",
smugglerItemsDelivery = "Twoje przedmioty zostaną dostarczone do punktu odbioru za %d minut.",
smugglerUniqueIDExists = "Skrzynka odbiorcza o tym unikalnym identyfikatorze już istnieje!",
smugglerStackSize = "Sprzedawane w partiach %d.",
smugglerDeliveryNotify = "Masz kilka przedmiotów do odebrania! Znajdź oznaczoną skrytkę.",
smugglerNeedAtLeast = "Do sprzedaży potrzeba co najmniej %d tego przedmiotu."
})
ix.lang.AddTable("spanish", {
smugglerBye = "¡Vuelve pronto!",
smugglerMaxStock = "¡El contrabandista no puede llevar más de ese objeto!",
smugglerNoMoney = "¡El contrabandista no puede permitirse ese objeto!",
smugglerPrepMove = "El contrabandista se está preparando para trasladarse, ya no iniciará nuevos intercambios.",
smugglerEditCurStock = "Editar Actual Stock",
smugglerStockCurReq = "Introduce cuántos objetos están disponibles para su compra al momento o la próxima vez que aparezca este contrabandista.",
smugglerNoPickupItems = "¡No hay artículos disponibles que recoger aquí!",
smugglerPickupItem = "Has recogido un %s.",
smugglerNoTrust = "¡El contrabandista aún no confía lo suficiente en ti como para intercambiar este objeto!",
smugglerWelcome = "Bienvenido a mi tienda, ¿qué puedo ofrecerte hoy?",
smugglerBuy = "Solo Compra",
smugglerNoTrade = "¡El contrabandista se niega a comerciar contigo!",
smugglerStock = "Contrabandista puede comprar: %d\nTienes: %d",
smugglerAvailable = "Disponible para comprar: %d",
smugglerNoItems = "El contrabandista no está dispuesto a venderte ningún objeto.",
smugglerSelectPickupItem = "Elige un objeto a recuperar:",
smugglerDeliverTo = "Comprar y enviar a %s",
smugglerNoSellItems = "No hay objetos para vender.",
smugglerBoth = "Compra y Venta",
smugglerUseMoney = "¿Debería el contrabandista usar dinero?",
smugglerUniqueIDExists = "¡Ya existe un alijo de recogida con este ID único!",
smugglerItemsDelivery = "Tus objetos serán entregados en el punto de recogida en %d minutos.",
smugglerNoStock = "El contrabandista no tiene ese artículo en stock. ¡Pídelo para que te lo envíen!",
smugglerPickupNoSpace = "¡No tienes espacio suficiente para %s!",
smugglerSell = "Solo Venta",
smugglerAvailableDelivery = "Disponible solo por pedido para su entrega",
smugglerStockReq = "Introduce la cantidad máxima del objeto que el contrabandista puede comprar cada vez que aparezca.",
smugglerNoBuyItems = "No hay objetos para comprar.",
smugglerDeliveryNotify = "¡Tienes objetos que recoger! Encuentra el alijo marcado",
smugglerStackSize = "Se vende en lotes de %d.",
smugglerNeedAtLeast = "Necesitas al menos %d de este objeto para venderlo.",
smugglerSelectDelivery = "Selecciona el lugar de entrega",
smugglerEditor = "Editor del Contrabandista",
smugglerSettings = "Configuración del contrabandista"
})
ix.lang.AddTable("polish", {
smugglerNoSellItems = "Nie ma żadnych przedmiotów na sprzedaż.",
smugglerNoBuyItems = "Nie ma żadnych przedmiotów do zakupu.",
smugglerSettings = "Ustawienia przemytnika",
smugglerUseMoney = "Przemytnik powinien użyć pieniędzy?",
smugglerBoth = "Kupno i sprzedaż",
smugglerBuy = "Tylko kupno",
smugglerSell = "Tylko sprzedaż",
smugglerWelcome = "Witaj w moim sklepie, co mogę Ci dziś zaoferować?",
smugglerBye = "Wpadnijcie jeszcze kiedyś!",
smugglerEditor = "Edytor przemytnika",
smugglerEditCurStock = "Edytuj bieżące zapasy",
smugglerStockReq = "Wprowadź maksymalną ilość przedmiotu, jaką przemytnik może kupić za każdym razem, gdy się pojawi.",
smugglerStockCurReq = "Wprowadź liczbę przedmiotów dostępnych do kupienia obecnie lub następnym razem, gdy pojawi się ten przemytnik.",
smugglerNoTrade = "Ten przemytnik odmawia handlu z tobą!",
smugglerNoTrust = "Ten przemytnik nie ufa ci na tyle, by handlować tym przedmiotem!",
smugglerNoMoney = "Tego przemytnika nie stać na ten przedmiot!",
smugglerNoStock = "Ten przemytnik nie ma tego przedmiotu w zapasie. Zamiast tego zamów go z dostawą!",
smugglerNoItems = "Ten przemytnik nie chce sprzedać Ci żadnych przedmiotów.",
smugglerMaxStock = "Ten przemytnik nie może dźwigać więcej tego przedmiotu!",
smugglerSelectPickupItem = "Wybierz przedmiot do odebrania:",
smugglerPickupItem = "Odebrałeś %s.",
smugglerPickupNoSpace = "Nie masz wystarczającej ilości miejsca na %s!",
smugglerNoPickupItems = "W tym miejscu nie ma żadnych przedmiotów dostępnych do odbioru!",
smugglerSelectDelivery = "Wybierz lokalizację dostawy",
smugglerDeliverTo = "Kup i dostarcz do %s",
smugglerPrepMove = "Ten przemytnik przygotowuje się do przemieszczenia, nie będzie już rozpoczynał nowych transakcji.",
smugglerAvailableDelivery = "Dostępne tylko na zamówienie",
smugglerAvailable = "Dostępne do kupienia: %d",
smugglerStock = "Przemytnik może kupić: %d\nPosiadasz: %d",
smugglerItemsDelivery = "Twoje przedmioty zostaną dostarczone do punktu odbioru za %d minut.",
smugglerUniqueIDExists = "Skrzynka odbiorcza o tym unikalnym identyfikatorze już istnieje!",
smugglerStackSize = "Sprzedawane w partiach %d.",
smugglerDeliveryNotify = "Masz kilka przedmiotów do odebrania! Znajdź oznaczoną skrytkę.",
smugglerNeedAtLeast = "Do sprzedaży potrzeba co najmniej %d tego przedmiotu."
})
ix.char.RegisterVar("smugglingPickupItems", {
default = {},
bNoDisplay = true,
field = "smugglingPickup",
fieldType = ix.type.text,
bNoNetworking = true,
OnSet = function(character, itemID, locationID, amount)
if (!itemID or !ix.item.list[itemID]) then
return false
end
local items = character:GetSmugglingPickupItems()
local location = items[locationID] or {}
if (amount) then
location[itemID] = math.max((location[itemID] or 0) + amount, 0)
if (location[itemID] == 0) then
location[itemID] = nil
end
else
if (location[itemID] > 0) then
location[itemID] = location[itemID] - 1
if (location[itemID] == 0) then
location[itemID] = nil
end
else
return false
end
end
if (!table.IsEmpty(location)) then
items[locationID] = location
else
items[locationID] = nil
end
character.vars.smugglingPickupItems = items
end,
OnGet = function(character)
return character.vars.smugglingPickupItems or {}
end
})
ix.char.RegisterVar("smugglingPickupDelay", {
default = {},
bNoDisplay = true,
field = "smugglingPickupDelay",
fieldType = ix.type.text,
bNoNetworking = true,
OnSet = function(character, itemID, locationID, offset)
if (!itemID or !ix.item.list[itemID]) then
return
end
local items = character:GetSmugglingPickupDelay()
local time = os.time() + ix.config.Get("SmugglerPickupDelay") * 60 * offset
items[#items + 1] = {time, itemID, locationID}
character.vars.smugglingPickupDelay = items
character:SetSmugglingNextPickup(time)
end,
OnGet = function(character)
return character.vars.smugglingPickupDelay or {}
end
})
ix.char.RegisterVar("smugglingNextPickup", {
default = 0,
bNoDisplay = true,
isLocal = true
})
ix.command.Add("SmugglerForceRotate", {
description = "Forcefully rotates the current smuggler to a new one.",
superAdminOnly = true,
OnRun = function(self, client)
PLUGIN:RotateActiveSmuggler()
end
})
ix.command.Add("CheckPlayerSmugglerPickupItems", {
description = "Prints out data about smuggler items for specific player.",
adminOnly = true,
arguments = {
ix.type.character,
},
OnRun = function(self, client, character)
client:ChatPrint(character:GetName() .. "'s Pickup Items:")
for k, v in pairs(character:GetSmugglingPickupItems()) do
for key, val in pairs(v) do
client:ChatPrint(character:GetName() .. ": [" .. key .. "] - with amount of " .. val .. " is stored in crate with ID: " .. k)
end
end
client:ChatPrint(character:GetName() .. "'s Pickup Delay:")
for k, v in ipairs(character:GetSmugglingPickupDelay()) do
local delay = v[1] - os.time()
delay = math.Round(delay / 60)
if (delay % 5 != 0) then
delay = delay - (delay % 5) + 5
end
client:ChatPrint(character:GetName() .. ": ".. "Item["..v[2].."] - ".. delay .. " minutes until arriving to cache with ID: " .. v[3])
end
end
})
function PLUGIN:PhysgunPickup(client, entity)
if (entity:GetClass() == "ix_smuggler" or entity:GetClass() == "ix_pickupcache") then
return CAMI.PlayerHasAccess(client, "Helix - Manage Smugglers")
end
end
function PLUGIN:InitializedPlugins()
for uniqueID, data in pairs(self.itemList) do
local item = ix.item.list[uniqueID]
if (!item) then
ErrorNoHalt("[SMUGGLER] Attempted to add unknown item '"..uniqueID.."'.")
self.itemList[uniqueID] = nil
continue
end
if (!data.buy and !data.sell) then
ErrorNoHalt("[SMUGGLER] Attempted to add item '"..uniqueID.."' without buy or sell price.")
self.itemList[uniqueID] = nil
continue
end
ix.action:RegisterSkillAction("smuggling", "recipe_smuggling_"..uniqueID, {
name = item.name,
data = data,
itemID = uniqueID,
bNoLog = true,
description = "Allows you to buy and sell the '"..item.name.."' item via the smuggling network.",
CanDo = data.level or 0,
DoResult = function(action, character, skillLevel, bIsSelling)
if (skillLevel < action.CanDo) then return 0 end
-- set to selling if not specified to use sell exp as default exp
if (bIsSelling == nil) then bIsSelling = self.itemList[action.itemID].sell != nil end
local exp
if (bIsSelling != false and self.itemList[action.itemID]) then
exp = self.itemList[action.itemID].sellExp or self.itemList[action.itemID].sell
elseif (bIsSelling == false and self.itemList[action.itemID]) then
exp = self.itemList[action.itemID].buyExp or self.itemList[action.itemID].buy
end
if (!exp) then return 0 end
if (bIsSelling != false) then
exp = exp * ix.config.Get("SmugglingSellExpScale")
else
exp = exp * ix.config.Get("SmugglingBuyExpScale")
end
return exp
end}
)
local RECIPE = ix.recipe:New()
RECIPE.uniqueID = "smuggling_"..uniqueID
RECIPE.name = item.name
RECIPE.description = "Umożliwia kupowanie i sprzedawanie '"..item.name.."' za pośrednictwem sieci przemytniczej.."
RECIPE.model = item.model
RECIPE.category = data.cat or item.category
RECIPE.hidden = false
RECIPE.skill = "smuggling"
RECIPE.level = data.level or 0
RECIPE.cost = data.sell or "N/A"
RECIPE.buyPrice = data.buy or "N/A"
RECIPE.result = {[uniqueID] = 1}
RECIPE.bNoAction = true
RECIPE.costIcon = "willardnetworks/tabmenu/charmenu/chips.png"
RECIPE:Register()
end
if (SERVER) then
timer.Create("ixSmugglerRotation", 300, 0, function()
if (!self.nextRotation) then return end
if (self.nextRotation < os.time()) then
self:RotateActiveSmuggler()
elseif (self.nextRotation < os.time() + 300) then
self:PreRotateActiveSmuggler()
end
end)
end
end