Trade: Working buy/sell trade mechanism.
Various cleanups and modularizations for supporting dedicated traders. Data: Added more favorite items for phase 1.
This commit is contained in:
parent
376c6e1df0
commit
f717c3f1e5
@ -34,7 +34,7 @@ function npc.dialogue.show_options_dialogue(self,
|
||||
for i = 1, #responses do
|
||||
local y = 0.8;
|
||||
if i > 1 then
|
||||
y = (0.7 * i)
|
||||
y = (0.75 * i)
|
||||
end
|
||||
formspec = formspec.."button_exit[0.5,"
|
||||
..(y - 0.5)..";6,0.5;opt"..tostring(i)..";"..responses[i].text.."]"
|
||||
|
13
npc.lua
13
npc.lua
@ -39,12 +39,14 @@ end
|
||||
|
||||
-- Utility function to get item name from a string
|
||||
local function get_item_name(item_string)
|
||||
return item_string.sub(item_string, 1, string.find(item_string, " "))
|
||||
local i,j = string.find(item_string, " ")
|
||||
return item_string.sub(item_string, 1, i-1)
|
||||
end
|
||||
|
||||
-- Utility function to get item count from a string
|
||||
local function get_item_count(item_string)
|
||||
return tonumber(item_string.sub(item_string, string.find(item_string, " ")))
|
||||
local i,j = string.find(item_string, " ")
|
||||
return tonumber(item_string.sub(item_string, i+1))
|
||||
end
|
||||
|
||||
local function initialize_inventory()
|
||||
@ -98,6 +100,13 @@ function npc.add_item_to_inventory(self, item_name, count)
|
||||
end
|
||||
end
|
||||
|
||||
-- Same add method but with itemstring for convenience
|
||||
function npc.add_item_to_inventory_itemstring(self, item_string)
|
||||
local item_name = get_item_name(item_string)
|
||||
local item_count = get_item_count(item_string)
|
||||
npc.add_item_to_inventory(self, item_name, item_count)
|
||||
end
|
||||
|
||||
-- Checks if an item is contained in the inventory. Returns
|
||||
-- the item string or nil if not found
|
||||
function npc.inventory_contains(self, item_name)
|
||||
|
@ -276,7 +276,31 @@ npc.FAVORITE_ITEMS.female["phase1"] = {
|
||||
hint = "I could really do with an apple..."},
|
||||
{item = "farming:bread",
|
||||
response = "Thanks, you didn't have to, but thanks...",
|
||||
hint = "Some fresh bread would be good!"}
|
||||
hint = "Some fresh bread would be good!"},
|
||||
{item = "farming:seed_cotton",
|
||||
response = "Thank you, I will plant this really soon",
|
||||
hint = "I would like to have some cotton plants around"},
|
||||
{item = "farming:seed_wheat",
|
||||
response = "Thank you! These seeds will make a good wheat plant!",
|
||||
hint = "I've been thinking I should get wheat seeds"},
|
||||
{item = "flowers:rose",
|
||||
response = "Thanks...",
|
||||
hint = "Red roses make a nice gift!"},
|
||||
{item = "flowers:geranium",
|
||||
response = "Oh, for me? Thank you!",
|
||||
hint = "Blue geraniums are so beautiful"},
|
||||
{item = "default:clay_lump",
|
||||
response = "Thanks! Now, what can I do with this...",
|
||||
hint = "If I had some clay lump, I may do some pottery"},
|
||||
{item = "mobs:meat_raw",
|
||||
response = "This will be great for tonight! Thanks",
|
||||
hint = "A good dinner always have meat"},
|
||||
{item = "mobs:leather",
|
||||
response = "Thank you! I needed this leather!",
|
||||
hint = "If only I could get some leather"},
|
||||
{item = "default:sapling",
|
||||
response = "Now I can plant that tree...",
|
||||
hint = "I really would like an apple tree close by."}
|
||||
}
|
||||
npc.FAVORITE_ITEMS.female["phase2"] = {
|
||||
{item = "farming:cotton",
|
||||
@ -320,12 +344,36 @@ npc.FAVORITE_ITEMS.female["phase6"] = {
|
||||
}
|
||||
-- Male
|
||||
npc.FAVORITE_ITEMS.male["phase1"] = {
|
||||
{item = "default:apple",
|
||||
{item = "default:apple",
|
||||
response = "Hey, I really wanted an apple, thank you!",
|
||||
hint = "I could really do with an apple..."},
|
||||
{item = "farming:bread",
|
||||
response = "Thanks, you didn't have to, but thanks...",
|
||||
hint = "Some fresh bread would be good!"}
|
||||
hint = "Some fresh bread would be good!"},
|
||||
{item = "farming:seed_cotton",
|
||||
response = "Thank you, I will plant this really soon",
|
||||
hint = "I would like to have some cotton plants around"},
|
||||
{item = "farming:seed_wheat",
|
||||
response = "Thank you! These seeds will make a good wheat plant!",
|
||||
hint = "I've been thinking I should get wheat seeds"},
|
||||
{item = "default:wood",
|
||||
response = "Thanks, I needed this.",
|
||||
hint = "Some wood without having to cut a tree would be good."},
|
||||
{item = "default:tree",
|
||||
response = "Excellent to get that furnace going!",
|
||||
hint = "I need logs, do you have some?"},
|
||||
{item = "default:clay_lump",
|
||||
response = "Thanks! Now, what can I do with this...",
|
||||
hint = "I wish I had some clay"},
|
||||
{item = "mobs:meat_raw",
|
||||
response = "This makes a great meal. Thank you",
|
||||
hint = "Meat is always great"},
|
||||
{item = "mobs:leather",
|
||||
response = "Time to tan some leathers!",
|
||||
hint = "I have been needing leather these days"},
|
||||
{item = "default:sapling",
|
||||
response = "Thanks, I will plant this right now",
|
||||
hint = "I really would like an apple tree close by."}
|
||||
}
|
||||
npc.FAVORITE_ITEMS.male["phase2"] = {
|
||||
{item = "farming:cotton",
|
||||
|
@ -36,7 +36,7 @@ npc.relationships.RELATIONSHIP_PHASE["phase2"] = {limit = 25}
|
||||
npc.relationships.RELATIONSHIP_PHASE["phase3"] = {limit = 45}
|
||||
npc.relationships.RELATIONSHIP_PHASE["phase4"] = {limit = 70}
|
||||
npc.relationships.RELATIONSHIP_PHASE["phase5"] = {limit = 100}
|
||||
|
||||
|
||||
-- Married NPC dialogue definition
|
||||
npc.relationships.MARRIED_NPC_DIALOGUE = {
|
||||
text = "Hi darling!",
|
||||
|
@ -11,8 +11,8 @@ npc.trade.OFFER_SELL = "sell"
|
||||
|
||||
-- This table holds all responses for trades
|
||||
npc.trade.results = {
|
||||
casual = {},
|
||||
formal = {}
|
||||
single_trade_offer = {},
|
||||
trade_offers = {}
|
||||
}
|
||||
|
||||
-- Casual trader NPC dialogues definition
|
||||
@ -26,7 +26,7 @@ npc.trade.CASUAL_TRADE_BUY_DIALOGUE = {
|
||||
action_type = "function",
|
||||
response_id = 1,
|
||||
action = function(self, player)
|
||||
npc.trade.show_casual_trade_formspec(self, player, npc.trade.OFFER_BUY)
|
||||
npc.trade.show_trade_offer_formspec(self, player, npc.trade.OFFER_BUY)
|
||||
end
|
||||
}
|
||||
}
|
||||
@ -42,13 +42,13 @@ npc.trade.CASUAL_TRADE_SELL_DIALOGUE = {
|
||||
action_type = "function",
|
||||
response_id = 1,
|
||||
action = function(self, player)
|
||||
npc.trade.show_casual_trade_formspec(self, player, npc.trade.OFFER_SELL)
|
||||
npc.trade.show_trade_offer_formspec(self, player, npc.trade.OFFER_SELL)
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function npc.trade.show_casual_trade_formspec(self, player, offer_type)
|
||||
function npc.trade.show_trade_offer_formspec(self, player, offer_type)
|
||||
|
||||
-- Strings for formspec, to include international support later
|
||||
local prompt_string = " offers to buy from you"
|
||||
@ -76,11 +76,12 @@ function npc.trade.show_casual_trade_formspec(self, player, offer_type)
|
||||
"button_exit[4.1,3.3;2.9,0.5;no_option;"..npc.dialogue.NEGATIVE_ANSWER_LABEL.."]"
|
||||
|
||||
-- Create entry into results table
|
||||
npc.trade.results.casual[player:get_player_name()] = {
|
||||
trade_offer = trade_offer
|
||||
npc.trade.results.single_trade_offer[player:get_player_name()] = {
|
||||
trade_offer = trade_offer,
|
||||
npc = self
|
||||
}
|
||||
-- Show formspec to player
|
||||
minetest.show_formspec(player:get_player_name(), "advanced_npc:casual_trade", formspec)
|
||||
minetest.show_formspec(player:get_player_name(), "advanced_npc:trade_offer", formspec)
|
||||
end
|
||||
|
||||
function npc.trade.get_random_trade_status()
|
||||
@ -114,32 +115,70 @@ function npc.trade.get_casual_trade_offer(self, offer_type)
|
||||
}
|
||||
end
|
||||
|
||||
function npc.trade.perform_trade(self, player_name, offer)
|
||||
|
||||
local item_stack = ItemStack(offer.item)
|
||||
local price_stack = ItemStack(offer.price)
|
||||
local inv = minetest.get_inventory({type = "player", name = player_name})
|
||||
|
||||
-- Check if offer is a buy or sell
|
||||
if offer.offer_type == npc.trade.OFFER_BUY then
|
||||
-- If NPC is buying from player, then player loses item, gets price
|
||||
-- Check player has the item being buyed
|
||||
if inv:contains_item("main", item_stack) then
|
||||
-- Check if there is enough room to add the price item to player
|
||||
if inv:room_for_item("main", price_stack) then
|
||||
-- Remove item from player
|
||||
inv:remove_item("main", item_stack)
|
||||
-- Add item to NPC's inventory
|
||||
npc.add_item_to_inventory_itemstring(self, offer.item)
|
||||
-- Add price items to player
|
||||
inv:add_item("main", price_stack)
|
||||
-- Send message to player
|
||||
minetest.chat_send_player(player_name, "Thank you!")
|
||||
else
|
||||
minetest.chat_send_player(player_name,
|
||||
"Looks like you can't what I'm giving you for payment!")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player_name, "Looks like you don't have what I want to buy...")
|
||||
end
|
||||
else
|
||||
-- If NPC is selling to the player, then player gives price and gets
|
||||
-- item, NPC loses item and gets price
|
||||
-- Check NPC has the required item to pay
|
||||
if inv:contains_item("main", price_stack) then
|
||||
-- Check if there is enough room to add the item to player
|
||||
if inv:room_for_item("main", item_stack) then
|
||||
-- Remove item from player
|
||||
inv:remove_item("main", price_stack)
|
||||
-- Add item to NPC's inventory
|
||||
npc.add_item_to_inventory_itemstring(self, offer.price)
|
||||
-- Add price items to player
|
||||
inv:add_item("main", item_stack)
|
||||
-- Send message to player
|
||||
minetest.chat_send_player(player_name, "Thank you!")
|
||||
else
|
||||
minetest.chat_send_player(player_name, "Looks like you can't carry anything else...")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player_name, "Looks like you don't have what I'm asking for!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Handler for chat formspec
|
||||
minetest.register_on_player_receive_fields(function (player, formname, fields)
|
||||
-- Additional checks for other forms should be handled here
|
||||
-- Handle yes/no dialogue
|
||||
if formname == "advanced_npc:casual_trade" then
|
||||
if formname == "advanced_npc:trade_offer" then
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
if fields then
|
||||
local player_response = npc.trade.results.casual[player_name]
|
||||
local player_response = npc.trade.results.single_trade_offer[player_name]
|
||||
if fields.yes_option then
|
||||
-- Check if offer is a buy or sell
|
||||
if player_response.trade_offer.offer_type == npc.trade.OFFER_BUY then
|
||||
-- If NPC is buying from player, then player loses item, gets price
|
||||
local inv = minetest.get_inventory({type = "player", name = player_name})
|
||||
-- Check NPC has the item being buyed
|
||||
if inv:contains_item("main", ItemStack(player_response.trade_offer.item)) then
|
||||
-- Remove item from player
|
||||
inv:remove_item("main", ItemStack(player_response.trade_offer.item))
|
||||
-- TODO: Add to NPC
|
||||
-- Add price items to player
|
||||
inv:add_item("main", ItemStack(player_response.trade_offer.price))
|
||||
end
|
||||
else
|
||||
|
||||
end
|
||||
npc.trade.perform_trade(player_response.npc, player_name, player_response.trade_offer)
|
||||
elseif fields.no_option then
|
||||
minetest.chat_send_player(player_name, "Talk to me if you change your mind!")
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user