Schedules: Allow to set trade list as a schedule property.

Trade: Trading list now supports setting maximum sell count, buy count and how much to keep (in case of sell).
Add price for empty bucket.
This commit is contained in:
Hector Franqui 2017-09-21 18:53:43 -04:00
parent c94edbc649
commit d55ffd06fc
3 changed files with 597 additions and 561 deletions

53
npc.lua
View File

@ -420,11 +420,7 @@ function npc.initialize(entity, pos, is_lua_entity, npc_stats, occupation_name)
-- 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 = {
sell = {},
buy = {},
both = {}
},
trade_list = {},
-- Custom trade allows to specify more than one payment
-- and a custom prompt (instead of the usual buy or sell prompts)
custom_trades = {}
@ -521,21 +517,21 @@ function npc.initialize(entity, pos, is_lua_entity, npc_stats, occupation_name)
-- TODO: Remove this - do inside occupation
-- Dedicated trade test
ent.trader_data.trade_list.both = {
["default:tree"] = {},
["default:cobble"] = {},
["default:wood"] = {},
["default:diamond"] = {},
["default:mese_crystal"] = {},
["flowers:rose"] = {},
["advanced_npc:marriage_ring"] = {},
["flowers:geranium"] = {},
["mobs:meat"] = {},
["mobs:leather"] = {},
["default:sword_stone"] = {},
["default:shovel_stone"] = {},
["default:axe_stone"] = {}
}
-- ent.trader_data.trade_list = {
-- ["default:tree"] = {},
-- ["default:cobble"] = {},
-- ["default:wood"] = {},
-- ["default:diamond"] = {},
-- ["default:mese_crystal"] = {},
-- ["flowers:rose"] = {},
-- ["advanced_npc:marriage_ring"] = {},
-- ["flowers:geranium"] = {},
-- ["mobs:meat"] = {},
-- ["mobs:leather"] = {},
-- ["default:sword_stone"] = {},
-- ["default:shovel_stone"] = {},
-- ["default:axe_stone"] = {}
-- }
-- Generate trade offers
npc.trade.generate_trade_offers_by_status(ent)
@ -564,10 +560,11 @@ function npc.generate_trade_list_from_inventory(self)
for i = 1, #self.inventory do
list[npc.get_item_name(self.inventory[i])] = {}
end
self.trader_data.trade_list.both = list
self.trader_data.trade_list = list
end
function npc.set_trading_status(self, status)
minetest.log("Trader_data: "..dump(self.trader_data))
-- Set status
self.trader_data.trader_status = status
-- Re-generate trade offers
@ -879,7 +876,8 @@ npc.schedule_properties = {
trader_status = "trader_status",
can_receive_gifts = "can_receive_gifts",
flag = "flag",
enable_gift_items_hints = "enable_gift_items_hints"
enable_gift_items_hints = "enable_gift_items_hints",
set_trade_list = "set_trade_list"
}
local function get_time_in_hours()
@ -1048,6 +1046,17 @@ function npc.schedule_change_property(self, property, args)
end
elseif property == npc.schedule_properties.enable_gift_item_hints then
self.gift_data.enable_gift_items_hints = args.value
elseif property == npc.schedule_properties.set_trade_list then
-- Insert items
for i = 1, #args.items do
-- Insert entry into trade list
self.trader_data.trade_list[args.items[i].name] = {
max_item_buy_count = args.items[i].buy,
max_item_sell_count = args.items[i].sell,
amount_to_keep = args.items[i].keep
}
end
end
end

View File

@ -37,6 +37,7 @@ npc.trade.prices.table["default:shovel_stone"] = {tier = npc.trade.prices.curre
npc.trade.prices.table["default:axe_stone"] = {tier = npc.trade.prices.currency.tier3.string, count = 6}
npc.trade.prices.table["default:hoe_stone"] = {tier = npc.trade.prices.currency.tier3.string, count = 6}
npc.trade.prices.table["default:pick_stone"] = {tier = npc.trade.prices.currency.tier3.string, count = 7}
npc.trade.prices.table["bucket:bucket_empty"] = {tier = npc.trade.prices.currency.tier3.string, count = 10}
npc.trade.prices.table["farming:cotton"] = {tier = npc.trade.prices.currency.tier3.string, count = 15}
npc.trade.prices.table["farming:bread"] = {tier = npc.trade.prices.currency.tier3.string, count = 20}

View File

@ -438,7 +438,9 @@ function npc.trade.get_dedicated_trade_offers(self)
buy = {}
}
local trade_list = self.trader_data.trade_list.both
local trade_list = self.trader_data.trade_list
npc.log("INFO", "NPC Inventory: "..dump(self.inventory))
for item_name, trade_info in pairs(trade_list) do
-- Abort if more than 12 buy or sell offers are made
@ -449,8 +451,17 @@ function npc.trade.get_dedicated_trade_offers(self)
-- If it is, create a sell offer, else create a buy offer if possible.
-- Also, avoid creating sell offers immediately if the item was just bought
local item = npc.inventory_contains(self, item_name)
minetest.log("Searched item: "..dump(item_name))
minetest.log("Found: "..dump(item))
if item ~= nil and trade_info.last_offer_type ~= npc.trade.OFFER_BUY then
-- Check if item can be sold
if trade_info.item_sold_count == nil
or (trade_info.item_sold_count ~= nil
and (trade_info.max_item_sell_count
and trade_info.item_sold_count < trade_info.max_item_sell_count)) then
-- This check makes sure that the NPC will keep max_item_sell_count at any time.
if trade_info.amount_to_keep == nil or (trade_info.amount_to_keep ~= nil
and trade_info.amount_to_keep < ItemStack(item.item_string):get_count()) then
-- Create sell offer for this item. Currently, traders will offer to sell only
-- one 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
@ -464,6 +475,11 @@ function npc.trade.get_dedicated_trade_offers(self)
)
-- Set last offer type
trade_info.last_offer_type = npc.trade.OFFER_SELL
end
else
-- Clear the trade info for this item
trade_info.item_sold_count = 0
end
else
-- Avoid flipping an item to the buy side if the stock was just depleted
@ -484,12 +500,10 @@ function npc.trade.get_dedicated_trade_offers(self)
-- 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.
--minetest.log("Item: "..item_name)
--minetest.log("Trade info: "..dump(trade_info))
--minetest.log("Logic: "..dump(trade_info.item_bought_count == nil
-- or (trade_info.item_bought_count ~= nil and trade_info.item_bought_count <= npc.trade.DEDICATED_MAX_BUY_AMOUNT)))
if trade_info.item_bought_count == nil
or (trade_info.item_bought_count ~= nil and trade_info.item_bought_count <= npc.trade.DEDICATED_MAX_BUY_AMOUNT) then
or (trade_info.item_bought_count ~= nil
and (trade_info.max_item_buy_count and trade_info.item_bought_count <= trade_info.max_item_buy_count
or trade_info.item_bought_count <= npc.trade.DEDICATED_MAX_BUY_AMOUNT)) then
-- Create trade offer for this item
table.insert(offers.buy, npc.trade.create_offer(
npc.trade.OFFER_BUY,
@ -697,15 +711,27 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
-- Increase the item bought count
local offer_item_name = npc.get_item_name(trade_offers[i].item)
--minetest.log("Bought item name: "..dump(offer_item_name))
--minetest.log(dump(player_response.npc.trader_data.trade_list.both[offer_item_name]))
--minetest.log(dump(player_response.npc.trader_data.trade_list[offer_item_name]))
-- Check if this item has been bought before
if player_response.npc.trader_data.trade_list.both[offer_item_name].item_bought_count == nil then
if player_response.npc.trader_data.trade_list[offer_item_name].item_bought_count == nil then
-- Set first count to 1
player_response.npc.trader_data.trade_list.both[offer_item_name].item_bought_count = 1
player_response.npc.trader_data.trade_list[offer_item_name].item_bought_count = 1
else
-- Increase count
player_response.npc.trader_data.trade_list.both[offer_item_name].item_bought_count
= player_response.npc.trader_data.trade_list.both[offer_item_name].item_bought_count + 1
player_response.npc.trader_data.trade_list[offer_item_name].item_bought_count
= player_response.npc.trader_data.trade_list[offer_item_name].item_bought_count + 1
end
else
-- Also count how many items are sold
local offer_item_name = npc.get_item_name(trade_offers[i].item)
-- Check if this item has been sold before
if player_response.npc.trader_data.trade_list[offer_item_name].item_sold_count == nil then
-- Set first count to 1
player_response.npc.trader_data.trade_list[offer_item_name].item_sold_count = 1
else
-- Increase count
player_response.npc.trader_data.trade_list[offer_item_name].item_sold_count
= player_response.npc.trader_data.trade_list[offer_item_name].item_sold_count + 1
end
end
-- Re-generate trade offers