Trade: Add function to store trade offers on NPC data based on the trading status.
Add support to avoid flipping sold items out of stock to buy immediately.
This commit is contained in:
parent
b3b9bf393f
commit
d8b90d95c3
48
npc.lua
48
npc.lua
@ -381,16 +381,16 @@ local function choose_spawn_items(self)
|
||||
minetest.log("Initial inventory: "..dump(self.inventory))
|
||||
end
|
||||
|
||||
-- Creates new single buy and sell offers for NPCs that
|
||||
-- trade casually.
|
||||
local function select_casual_trade_offers(self)
|
||||
self.trader_data.buy_offers = {
|
||||
[1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_BUY)
|
||||
}
|
||||
self.trader_data.sell_offers = {
|
||||
[1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_SELL)
|
||||
}
|
||||
end
|
||||
-- -- Creates new single buy and sell offers for NPCs that
|
||||
-- -- trade casually.
|
||||
-- local function select_casual_trade_offers(self)
|
||||
-- self.trader_data.buy_offers = {
|
||||
-- [1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_BUY)
|
||||
-- }
|
||||
-- self.trader_data.sell_offers = {
|
||||
-- [1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_SELL)
|
||||
-- }
|
||||
-- end
|
||||
|
||||
-- Spawn function. Initializes all variables that the
|
||||
-- NPC will have and choose random, starting values
|
||||
@ -464,13 +464,18 @@ local function npc_spawn(self, pos)
|
||||
-- It is mostly related to its occupation.
|
||||
-- If empty, the NPC will revert to casual trading
|
||||
-- If not, it will try to sell those that it have, and buy the ones it not.
|
||||
trade_list = {}
|
||||
trade_list = {
|
||||
sell = {},
|
||||
buy = {},
|
||||
both = {}
|
||||
}
|
||||
}
|
||||
|
||||
-- Initialize trading offers if NPC is casual trader
|
||||
if ent.trader_data.trader_status == npc.trade.CASUAL then
|
||||
select_casual_trade_offers(ent)
|
||||
end
|
||||
-- Initialize trading offers for NPC
|
||||
--npc.trade.generate_trade_offers_by_status(ent)
|
||||
-- if ent.trader_data.trader_status == npc.trade.CASUAL then
|
||||
-- select_casual_trade_offers(ent)
|
||||
-- end
|
||||
|
||||
-- Actions data
|
||||
ent.actions = {
|
||||
@ -526,14 +531,13 @@ local function npc_spawn(self, pos)
|
||||
end
|
||||
|
||||
-- Dedicated trade test
|
||||
ent.trader_data.trade_list = {
|
||||
"default:tree",
|
||||
"default:cobble",
|
||||
"default:wood"
|
||||
ent.trader_data.trade_list.both = {
|
||||
["default:tree"] = {},
|
||||
["default:cobble"] = {},
|
||||
["default:wood"] = {}
|
||||
}
|
||||
|
||||
local trade_offers = npc.trade.get_trade_offers_for_dedicated_trader(ent)
|
||||
minetest.log("Trade offers: "..dump(trade_offers))
|
||||
|
||||
npc.trade.generate_trade_offers_by_status(ent)
|
||||
|
||||
-- npc.add_action(ent, npc.action.stand, {self = ent})
|
||||
-- npc.add_action(ent, npc.action.stand, {self = ent})
|
||||
|
104
trade/trade.lua
104
trade/trade.lua
@ -22,7 +22,7 @@ npc.trade.CASUAL_TRADE_BUY_DIALOGUE = {
|
||||
casual_trade_type = npc.trade.OFFER_BUY,
|
||||
responses = {
|
||||
[1] = {
|
||||
text = "Yes, let's see what you are looking for",
|
||||
text = "Sell",
|
||||
action_type = "function",
|
||||
response_id = 1,
|
||||
action = function(self, player)
|
||||
@ -38,7 +38,7 @@ npc.trade.CASUAL_TRADE_SELL_DIALOGUE = {
|
||||
casual_trade_type = npc.trade.OFFER_SELL,
|
||||
responses = {
|
||||
[1] = {
|
||||
text = "Yes, let's see what you have",
|
||||
text = "Buy",
|
||||
action_type = "function",
|
||||
response_id = 1,
|
||||
action = function(self, player)
|
||||
@ -122,6 +122,38 @@ function npc.trade.get_random_trade_status()
|
||||
end
|
||||
end
|
||||
|
||||
-- This function generates and stores on the NPC data trade
|
||||
-- offers depending on the trader status.
|
||||
function npc.trade.generate_trade_offers_by_status(self)
|
||||
-- Get trader status
|
||||
local status = self.trader_data.trader_status
|
||||
-- Check what is the trader status
|
||||
if status == npc.trade.NONE then
|
||||
-- For none, clear all offers
|
||||
self.trader_data.buy_offers = {}
|
||||
self.trader_data.sell_offers = {}
|
||||
elseif status == npc.trade.CASUAL then
|
||||
-- For casual, generate one buy and one sell offer
|
||||
self.trader_data.buy_offers = {
|
||||
[1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_BUY)
|
||||
}
|
||||
self.trader_data.sell_offers = {
|
||||
[1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_SELL)
|
||||
}
|
||||
elseif status == npc.trade.TRADER then
|
||||
-- Get trade offers for a dedicated trader
|
||||
local offers = npc.trade.get_dedicated_trade_offers(self)
|
||||
-- Store buy offers
|
||||
for i = 1, #offers.buy do
|
||||
table.insert(self.trader_data.buy_offers, offers.buy[i])
|
||||
end
|
||||
-- Store sell offers
|
||||
for i = 1, #offers.sell do
|
||||
table.insert(self.trader_data.sell_offers, offers.sell[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Convenience method that retrieves all the currency
|
||||
-- items that a NPC has on his/her inventory
|
||||
function npc.trade.get_currencies_in_inventory(self)
|
||||
@ -198,43 +230,59 @@ end
|
||||
-- based on the trader list and the source of items. Initially, it will only
|
||||
-- be NPC inventories. In the future, it should support both NPC and chest
|
||||
-- inventories,
|
||||
function npc.trade.get_trade_offers_for_dedicated_trader(self)
|
||||
function npc.trade.get_dedicated_trade_offers(self)
|
||||
local offers = {
|
||||
for_sell = {},
|
||||
to_buy = {}
|
||||
sell = {},
|
||||
buy = {}
|
||||
}
|
||||
|
||||
for i = 1, #self.trader_data.trade_list do
|
||||
local trade_list = self.trader_data.trade_list.both
|
||||
|
||||
for item_name, trade_info in pairs(trade_list) do
|
||||
-- For each item on the trader list, check if it is in the NPC inventory.
|
||||
-- If it is, create a sell offer, else create a buy offer if possible.
|
||||
local item = npc.inventory_contains(self, self.trader_data.trade_list[i])
|
||||
local item = npc.inventory_contains(self, item_name)
|
||||
if item ~= nil then
|
||||
-- Create sell offer for this item. Currently, traders will offer to sell only
|
||||
-- of their items to allow the fine control for players to buy what they want.
|
||||
-- This requires, however, that the trade offers are re-generated everytime a
|
||||
-- sell is made.
|
||||
table.insert(offers.for_sell, npc.trade.create_offer(npc.trade.OFFER_SELL, self.trader_data.trade_list[i], nil, nil, 1))
|
||||
table.insert(offers.sell, npc.trade.create_offer(
|
||||
npc.trade.OFFER_SELL,
|
||||
item_name,
|
||||
nil,
|
||||
nil,
|
||||
1)
|
||||
)
|
||||
-- Set last offer type
|
||||
trade_info.last_offer_type = npc.trade.OFFER_SELL
|
||||
else
|
||||
-- Create buy offer for this item
|
||||
-- Only do if the NPC can actually afford the items.
|
||||
local currencies = npc.trade.get_currencies_in_inventory(self)
|
||||
-- Choose a random currency
|
||||
local chosen_tier = currencies[math.random(#currencies)]
|
||||
-- Get items for this currency
|
||||
local buyable_items =
|
||||
npc.trade.prices.get_items_for_currency_count(chosen_tier.name, chosen_tier.count, 0.5)
|
||||
-- Check if the item from trader list is present in the buyable items list
|
||||
for buyable_item, price_info in pairs(buyable_items) do
|
||||
if buyable_item == self.trader_data.trade_list[i] then
|
||||
-- If item found, create a buy offer for this item
|
||||
-- Again, offers are created for one item only. Buy offers should be removed
|
||||
-- after the NPC has bought a certain quantity, say, 5 items.
|
||||
table.insert(offers.to_buy, npc.trade.create_offer(
|
||||
npc.trade.OFFER_BUY,
|
||||
self.trader_data.trade_list[i],
|
||||
price_info.price,
|
||||
price_info.min_buyable_item_price,
|
||||
1))
|
||||
-- Avoid flipping an item to the buy side if the stock was just depleted
|
||||
if trade_info.last_offer_type ~= npc.trade.OFFER_SELL then
|
||||
-- Create buy offer for this item
|
||||
-- Only do if the NPC can actually afford the items.
|
||||
local currencies = npc.trade.get_currencies_in_inventory(self)
|
||||
-- Choose a random currency
|
||||
local chosen_tier = currencies[math.random(#currencies)]
|
||||
-- Get items for this currency
|
||||
local buyable_items =
|
||||
npc.trade.prices.get_items_for_currency_count(chosen_tier.name, chosen_tier.count, 0.5)
|
||||
-- Check if the item from trader list is present in the buyable items list
|
||||
for buyable_item, price_info in pairs(buyable_items) do
|
||||
if buyable_item == item_name then
|
||||
-- If item found, create a buy offer for this item
|
||||
-- Again, offers are created for one item only. Buy offers should be removed
|
||||
-- after the NPC has bought a certain quantity, say, 5 items.
|
||||
table.insert(offers.buy, npc.trade.create_offer(
|
||||
npc.trade.OFFER_BUY,
|
||||
item_name,
|
||||
price_info.price,
|
||||
price_info.min_buyable_item_price,
|
||||
price_info.min_buyable_item_count)
|
||||
)
|
||||
-- Set last offer type
|
||||
trade_info.last_offer_type = npc.trade.OFFER_BUY
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user