227 lines
6.3 KiB
Lua
227 lines
6.3 KiB
Lua
local foodRequests = {
|
||
{ 700, L.omelet },
|
||
{ 800, L.hotdog },
|
||
{ 950, L.ceasar },
|
||
{ 1280, L.mushroom_soup },
|
||
{ 1350, L.bolognese },
|
||
{ 1500, L.zitti },
|
||
{ 1550, L.wrap },
|
||
{ 1750, L.borsch },
|
||
{ 1900, L.pizza_pepperoni },
|
||
{ 1900, L.pizza_margarita },
|
||
{ 2250, L.pizza_volcano },
|
||
{ 2350, L.lasagna },
|
||
{ 3200, 'Запеченный окунь' },
|
||
{ 3200, 'Запеченный карп' },
|
||
{ 3200, 'Форель под медом' },
|
||
{ 3200, 'Щука в сливочном соусе' },
|
||
|
||
{ 700, L.tea },
|
||
{ 700, L.cacao },
|
||
{ 800, L.cappuccino },
|
||
{ 900, L.espresso },
|
||
}
|
||
|
||
local function getBoxData(volume)
|
||
if volume <= 10 then
|
||
return 10, 'models/props/cs_office/cardboard_box02.mdl'
|
||
elseif volume <= 50 then
|
||
return 50, 'models/props/cs_office/cardboard_box03.mdl'
|
||
else
|
||
return math.ceil(volume / 10) * 10, 'models/props/cs_office/cardboard_box01.mdl'
|
||
end
|
||
end
|
||
|
||
local orderTypes = {
|
||
{
|
||
-- name = 'Продукты на дом',
|
||
-- icon = octolib.icons.silk32('apple'),
|
||
-- getOrderData = function()
|
||
-- if not foodShopItems then
|
||
-- foodShopItems = octolib.table.map(octoinv.shopItems, function(item)
|
||
-- if item.cat == 'ings' then return item end
|
||
-- end)
|
||
-- end
|
||
|
||
-- local totalPrice = 0
|
||
-- local totalVolume = 0
|
||
-- local items = {}
|
||
-- local kindsAmount = math.random(2, 10)
|
||
-- for _ = 1, kindsAmount do
|
||
-- local itemData, itemID = table.Random(foodShopItems)
|
||
-- local amount = math.random(1, 10)
|
||
-- items[itemID] = (items[itemID] or 0) + amount
|
||
-- totalPrice = totalPrice + itemData.price * amount
|
||
-- totalVolume = totalVolume + octoinv.getItemData('volume', itemID) * amount
|
||
-- end
|
||
|
||
-- local bonusMoney = math.ceil(totalPrice * 0.05) * 10 -- 50% rounded up to 10s
|
||
|
||
-- return {
|
||
-- timeout = octolib.time.toSeconds(15, 'minutes'),
|
||
-- reward = DarkRP.formatMoney(bonusMoney),
|
||
-- money = totalPrice + bonusMoney,
|
||
-- text = table.concat(octolib.table.mapSequential(items, function(amount, itemID)
|
||
-- return '— ' .. amount .. 'х ' .. octoinv.getItemData('name', itemID)
|
||
-- end), '\n') .. '\nСтоимость продуктов будет компенсирована',
|
||
-- volume = totalVolume,
|
||
-- queries = octolib.table.mapSequential(items, function(amount, itemID)
|
||
-- return { class = itemID, amount = { _gte = amount }}
|
||
-- end),
|
||
-- }
|
||
-- end,
|
||
-- }, {
|
||
name = 'Доставка еды',
|
||
icon = octolib.icons.silk32('hamburger'),
|
||
getOrderData = function()
|
||
local totalMoney = 0
|
||
local queries = {}
|
||
local amount = math.random(1, 4)
|
||
for _, item in RandomPairs(foodRequests) do
|
||
local price, name = unpack(item)
|
||
totalMoney = totalMoney + price
|
||
queries[#queries + 1] = { class = 'food', name = name, part = { _exists = false }}
|
||
|
||
if #queries >= amount then break end
|
||
end
|
||
|
||
return {
|
||
timeout = octolib.time.toSeconds(20, 'minutes'),
|
||
reward = DarkRP.formatMoney(totalMoney),
|
||
money = totalMoney,
|
||
text = table.concat(octolib.table.mapSequential(queries, function(item)
|
||
return '— ' .. item.name
|
||
end), '\n'),
|
||
volume = 20,
|
||
queries = queries,
|
||
}
|
||
end,
|
||
},
|
||
}
|
||
|
||
local job = {}
|
||
|
||
function job.publish()
|
||
local orderType = table.Random(orderTypes)
|
||
if not orderType then return end
|
||
|
||
local orderData = orderType.getOrderData()
|
||
if not orderData or #orderData.queries < 1 then return end
|
||
|
||
local mapConfig = dbgJobs.mapConfig and dbgJobs.mapConfig.home
|
||
if not mapConfig then return end
|
||
|
||
local existingContainersPositions = octolib.table.mapSequential(ents.FindByClass('dbg_jobs_container'), function(ent)
|
||
return ent:GetPos()
|
||
end)
|
||
|
||
local spawnPos
|
||
for _, pos in RandomPairs(mapConfig) do
|
||
-- we don't want any other containers near spawn
|
||
local ok = true
|
||
for _, theirPos in ipairs(existingContainersPositions) do
|
||
if theirPos:DistToSqr(pos) < 40000 then
|
||
ok = false
|
||
break
|
||
end
|
||
end
|
||
|
||
if ok then
|
||
spawnPos = pos
|
||
break
|
||
end
|
||
end
|
||
if not spawnPos then return end
|
||
|
||
local volume, model = getBoxData(orderData.volume)
|
||
local cont = ents.Create 'dbg_jobs_container'
|
||
cont:SetModel(model)
|
||
cont:SetPos(spawnPos)
|
||
cont:SetAngles(Angle(0, math.random() * 360, 0))
|
||
cont:Spawn()
|
||
cont:Activate()
|
||
|
||
local phys = cont:GetPhysicsObject()
|
||
if IsValid(phys) then
|
||
phys:Wake()
|
||
timer.Simple(3, function()
|
||
if not IsValid(phys) then return end
|
||
phys:EnableMotion(false)
|
||
end)
|
||
end
|
||
|
||
local estateTo = dbgEstates.getNearest(spawnPos)
|
||
local addressTo = estateTo and estateTo.name or '???'
|
||
|
||
local desc = ('Требуется доставить к %s:\n%s'):format(addressTo, orderData.text)
|
||
|
||
return {
|
||
name = orderType.name,
|
||
icon = orderType.icon,
|
||
desc = desc,
|
||
reward = orderData.reward,
|
||
deposit = math.floor(orderData.money / 40) * 10,
|
||
timeout = orderData.timeout,
|
||
|
||
money = orderData.money,
|
||
cont = cont,
|
||
volume = volume,
|
||
queries = orderData.queries,
|
||
}
|
||
end
|
||
|
||
function job.cancel(publishData)
|
||
local cont = publishData.cont
|
||
if IsValid(cont) then cont:Remove() end
|
||
end
|
||
|
||
function job.start(ply, publishData)
|
||
if not IsValid(publishData.cont) then
|
||
ply:Notify('Что-то случилось с контейнером, задание отменено')
|
||
dbgJobs.removeAvailable(publishData.id, true)
|
||
return
|
||
end
|
||
|
||
local cont = publishData.cont
|
||
ply:AddMarker({
|
||
id = 'job:' .. publishData.id,
|
||
txt = 'Получатель',
|
||
pos = cont:WorldSpaceCenter(),
|
||
col = Color(255,92,38),
|
||
des = {'time', { octolib.time.toSeconds(2, 'hours') }},
|
||
icon = octolib.icons.silk16('arrow_down'),
|
||
})
|
||
cont:SetDeliveryData(publishData.id, publishData.volume, function(cont)
|
||
for _, query in ipairs(publishData.queries) do
|
||
if not cont:FindItem(query) then return end
|
||
end
|
||
|
||
return true
|
||
end)
|
||
|
||
return {}
|
||
end
|
||
|
||
function job.finish(startData, isSuccessful)
|
||
local cont = startData.publishData.cont
|
||
if IsValid(cont) then cont:Remove() end
|
||
|
||
local ply = startData.ply
|
||
if not IsValid(ply) then return end
|
||
|
||
ply:ClearMarkers('job:' .. startData.publishData.id)
|
||
|
||
if isSuccessful then
|
||
local totalReward = startData.publishData.money + startData.publishData.deposit
|
||
|
||
ply:Notify(('Задание "%s" выполнено! На твой счет перечислено %s'):format(
|
||
startData.publishData.name,
|
||
DarkRP.formatMoney(totalReward)
|
||
))
|
||
ply:BankAdd(totalReward)
|
||
else
|
||
ply:Notify('warning', ('Задание "%s" провалено'):format(startData.publishData.name))
|
||
end
|
||
end
|
||
|
||
dbgJobs.registerType('home', job)
|