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))
|
minetest.log("Initial inventory: "..dump(self.inventory))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Creates new single buy and sell offers for NPCs that
|
-- -- Creates new single buy and sell offers for NPCs that
|
||||||
-- trade casually.
|
-- -- trade casually.
|
||||||
local function select_casual_trade_offers(self)
|
-- local function select_casual_trade_offers(self)
|
||||||
self.trader_data.buy_offers = {
|
-- self.trader_data.buy_offers = {
|
||||||
[1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_BUY)
|
-- [1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_BUY)
|
||||||
}
|
-- }
|
||||||
self.trader_data.sell_offers = {
|
-- self.trader_data.sell_offers = {
|
||||||
[1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_SELL)
|
-- [1] = npc.trade.get_casual_trade_offer(self, npc.trade.OFFER_SELL)
|
||||||
}
|
-- }
|
||||||
end
|
-- end
|
||||||
|
|
||||||
-- Spawn function. Initializes all variables that the
|
-- Spawn function. Initializes all variables that the
|
||||||
-- NPC will have and choose random, starting values
|
-- 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.
|
-- It is mostly related to its occupation.
|
||||||
-- If empty, the NPC will revert to casual trading
|
-- 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.
|
-- 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
|
-- Initialize trading offers for NPC
|
||||||
if ent.trader_data.trader_status == npc.trade.CASUAL then
|
--npc.trade.generate_trade_offers_by_status(ent)
|
||||||
select_casual_trade_offers(ent)
|
-- if ent.trader_data.trader_status == npc.trade.CASUAL then
|
||||||
end
|
-- select_casual_trade_offers(ent)
|
||||||
|
-- end
|
||||||
|
|
||||||
-- Actions data
|
-- Actions data
|
||||||
ent.actions = {
|
ent.actions = {
|
||||||
@ -526,14 +531,13 @@ local function npc_spawn(self, pos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Dedicated trade test
|
-- Dedicated trade test
|
||||||
ent.trader_data.trade_list = {
|
ent.trader_data.trade_list.both = {
|
||||||
"default:tree",
|
["default:tree"] = {},
|
||||||
"default:cobble",
|
["default:cobble"] = {},
|
||||||
"default:wood"
|
["default:wood"] = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
local trade_offers = npc.trade.get_trade_offers_for_dedicated_trader(ent)
|
npc.trade.generate_trade_offers_by_status(ent)
|
||||||
minetest.log("Trade offers: "..dump(trade_offers))
|
|
||||||
|
|
||||||
-- npc.add_action(ent, npc.action.stand, {self = ent})
|
-- npc.add_action(ent, npc.action.stand, {self = 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,
|
casual_trade_type = npc.trade.OFFER_BUY,
|
||||||
responses = {
|
responses = {
|
||||||
[1] = {
|
[1] = {
|
||||||
text = "Yes, let's see what you are looking for",
|
text = "Sell",
|
||||||
action_type = "function",
|
action_type = "function",
|
||||||
response_id = 1,
|
response_id = 1,
|
||||||
action = function(self, player)
|
action = function(self, player)
|
||||||
@ -38,7 +38,7 @@ npc.trade.CASUAL_TRADE_SELL_DIALOGUE = {
|
|||||||
casual_trade_type = npc.trade.OFFER_SELL,
|
casual_trade_type = npc.trade.OFFER_SELL,
|
||||||
responses = {
|
responses = {
|
||||||
[1] = {
|
[1] = {
|
||||||
text = "Yes, let's see what you have",
|
text = "Buy",
|
||||||
action_type = "function",
|
action_type = "function",
|
||||||
response_id = 1,
|
response_id = 1,
|
||||||
action = function(self, player)
|
action = function(self, player)
|
||||||
@ -122,6 +122,38 @@ function npc.trade.get_random_trade_status()
|
|||||||
end
|
end
|
||||||
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
|
-- Convenience method that retrieves all the currency
|
||||||
-- items that a NPC has on his/her inventory
|
-- items that a NPC has on his/her inventory
|
||||||
function npc.trade.get_currencies_in_inventory(self)
|
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
|
-- 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
|
-- be NPC inventories. In the future, it should support both NPC and chest
|
||||||
-- inventories,
|
-- inventories,
|
||||||
function npc.trade.get_trade_offers_for_dedicated_trader(self)
|
function npc.trade.get_dedicated_trade_offers(self)
|
||||||
local offers = {
|
local offers = {
|
||||||
for_sell = {},
|
sell = {},
|
||||||
to_buy = {}
|
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.
|
-- 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.
|
-- 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
|
if item ~= nil then
|
||||||
-- Create sell offer for this item. Currently, traders will offer to sell only
|
-- 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.
|
-- 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
|
-- This requires, however, that the trade offers are re-generated everytime a
|
||||||
-- sell is made.
|
-- 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
|
else
|
||||||
-- Create buy offer for this item
|
-- Avoid flipping an item to the buy side if the stock was just depleted
|
||||||
-- Only do if the NPC can actually afford the items.
|
if trade_info.last_offer_type ~= npc.trade.OFFER_SELL then
|
||||||
local currencies = npc.trade.get_currencies_in_inventory(self)
|
-- Create buy offer for this item
|
||||||
-- Choose a random currency
|
-- Only do if the NPC can actually afford the items.
|
||||||
local chosen_tier = currencies[math.random(#currencies)]
|
local currencies = npc.trade.get_currencies_in_inventory(self)
|
||||||
-- Get items for this currency
|
-- Choose a random currency
|
||||||
local buyable_items =
|
local chosen_tier = currencies[math.random(#currencies)]
|
||||||
npc.trade.prices.get_items_for_currency_count(chosen_tier.name, chosen_tier.count, 0.5)
|
-- Get items for this currency
|
||||||
-- Check if the item from trader list is present in the buyable items list
|
local buyable_items =
|
||||||
for buyable_item, price_info in pairs(buyable_items) do
|
npc.trade.prices.get_items_for_currency_count(chosen_tier.name, chosen_tier.count, 0.5)
|
||||||
if buyable_item == self.trader_data.trade_list[i] then
|
-- Check if the item from trader list is present in the buyable items list
|
||||||
-- If item found, create a buy offer for this item
|
for buyable_item, price_info in pairs(buyable_items) do
|
||||||
-- Again, offers are created for one item only. Buy offers should be removed
|
if buyable_item == item_name then
|
||||||
-- after the NPC has bought a certain quantity, say, 5 items.
|
-- If item found, create a buy offer for this item
|
||||||
table.insert(offers.to_buy, npc.trade.create_offer(
|
-- Again, offers are created for one item only. Buy offers should be removed
|
||||||
npc.trade.OFFER_BUY,
|
-- after the NPC has bought a certain quantity, say, 5 items.
|
||||||
self.trader_data.trade_list[i],
|
table.insert(offers.buy, npc.trade.create_offer(
|
||||||
price_info.price,
|
npc.trade.OFFER_BUY,
|
||||||
price_info.min_buyable_item_price,
|
item_name,
|
||||||
1))
|
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
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user