Trading: Allow to sell compass

This commit is contained in:
Wuzzy 2018-06-06 19:37:31 +02:00
parent 3823a6ba11
commit 4d4374730e
1 changed files with 97 additions and 12 deletions

View File

@ -6,6 +6,7 @@
-- TODO: Per-player trading inventories -- TODO: Per-player trading inventories
-- TODO: Particles -- TODO: Particles
-- TODO: 4s Regeneration I after trade unlock -- TODO: 4s Regeneration I after trade unlock
-- FIXME: Possible to lock all trades
-- intllib -- intllib
local MP = minetest.get_modpath(minetest.get_current_modname()) local MP = minetest.get_modpath(minetest.get_current_modname())
@ -21,6 +22,20 @@ local player_trading_with = {}
--################### --###################
-- LIST OF VILLAGER PROFESSIONS AND TRADES -- LIST OF VILLAGER PROFESSIONS AND TRADES
-- TECHNICAL RESTRICTIONS (FIXME):
-- * You can't use a clock as requested item
-- * You can't use a compass as requested item if its stack size > 1
-- * You can't use a compass in the second requested slot
-- This is a problem in the mcl_compass and mcl_clock mods,
-- these items should be implemented as single items, then everything
-- will be much easier.
local COMPASS = "mcl_compass:compass"
if minetest.registered_aliases[COMPASS] then
COMPASS = minetest.registered_aliases[COMPASS]
end
local E1 = { "mcl_core:emerald", 1, 1 } -- one emerald local E1 = { "mcl_core:emerald", 1, 1 } -- one emerald
local professions = { local professions = {
farmer = { farmer = {
@ -143,11 +158,10 @@ local professions = {
{ { "mcl_core:paper", 24, 36 }, E1 }, { { "mcl_core:paper", 24, 36 }, E1 },
}, },
-- { {
-- TODO: compass -- subject to special checks
-- the difficulty lies in supporting the compass group, not the concrete item { { "mcl_compass:compass", 1, 1 }, E1 },
-- { { "mcl_compass:compass", 1, 1 }, E1 }, },
-- },
{ {
-- TODO: replace with empty map -- TODO: replace with empty map
@ -446,9 +460,47 @@ local update_offer = function(inv, player, sound)
if not trade then if not trade then
return false return false
end end
if inv:contains_item("input", inv:get_stack("wanted", 1)) and local wanted1, wanted2 = inv:get_stack("wanted", 1), inv:get_stack("wanted", 2)
(inv:get_stack("wanted", 2):is_empty() or inv:contains_item("input", inv:get_stack("wanted", 2))) and local input1, input2 = inv:get_stack("input", 1), inv:get_stack("input", 2)
(trade.locked == false) then
-- BEGIN OF SPECIAL HANDLING OF COMPASS
-- These 2 functions are a complicated check to check if the input contains a
-- special item which we cannot check directly against their name, like
-- compass.
-- TODO: Remove these check functions when compass and clock are implemented
-- as single items.
local check_special = function(special_item, group, wanted1, wanted2, input1, input2)
if minetest.registered_aliases[special_item] then
special_item = minetest.registered_aliases[special_item]
end
if wanted1:get_name() == special_item then
local check_input = function(input, wanted, group)
return minetest.get_item_group(input:get_name(), group) ~= 0 and input:get_count() >= wanted:get_count()
end
if check_input(input1, wanted1, group) then
return true
elseif check_input(input2, wanted1, group) then
return true
else
return false
end
end
return false
end
-- Apply above function to all items which we consider special.
-- This function succeeds if ANY item check succeeds.
local check_specials = function(wanted1, wanted2, input1, input2)
return check_special(COMPASS, "compass", wanted1, wanted2, input1, input2)
end
-- END OF SPECIAL HANDLING OF COMPASS
if (
((inv:contains_item("input", wanted1) and
(wanted2:is_empty() or inv:contains_item("input", wanted2))) or
-- BEGIN OF SPECIAL HANDLING OF COMPASS
check_specials(wanted1, wanted2, input1, input2)) and
-- END OF SPECIAL HANDLING OF COMPASS
(trade.locked == false)) then
inv:set_stack("output", 1, inv:get_stack("offered", 1)) inv:set_stack("output", 1, inv:get_stack("offered", 1))
if sound then if sound then
minetest.sound_play("mobs_mc_villager_accept", {to_player = name}) minetest.sound_play("mobs_mc_villager_accept", {to_player = name})
@ -558,10 +610,30 @@ mobs:register_mob("mobs_mc:villager", {
-- enough items in input after the trade -- enough items in input after the trade
local wanted1 = inv:get_stack("wanted", 1) local wanted1 = inv:get_stack("wanted", 1)
local wanted2 = inv:get_stack("wanted", 2) local wanted2 = inv:get_stack("wanted", 2)
local input1 = inv:get_stack("input", 1)
local input2 = inv:get_stack("input", 2)
wanted1:set_count(wanted1:get_count()*2) wanted1:set_count(wanted1:get_count()*2)
wanted2:set_count(wanted2:get_count()*2) wanted2:set_count(wanted2:get_count()*2)
if inv:contains_item("input", wanted1) and -- BEGIN OF SPECIAL HANDLING FOR COMPASS
(wanted2:is_empty() or inv:contains_item("input", wanted2)) then local special_checks = function(wanted1, input1, input2)
if wanted1:get_name() == COMPASS then
local compasses = 0
if (minetest.get_item_group(input1:get_name(), "compass") ~= 0) then
compasses = compasses + input1:get_count()
end
if (minetest.get_item_group(input2:get_name(), "compass") ~= 0) then
compasses = compasses + input2:get_count()
end
return compasses >= wanted1:get_count()
end
return false
end
-- END OF SPECIAL HANDLING FOR COMPASS
if (inv:contains_item("input", wanted1) and
(wanted2:is_empty() or inv:contains_item("input", wanted2)))
-- BEGIN OF SPECIAL HANDLING FOR COMPASS
or special_checks(wanted1, input1, input2) then
-- END OF SPECIAL HANDLING FOR COMPASS
return -1 return -1
else else
-- If less than double the wanted items, -- If less than double the wanted items,
@ -612,11 +684,24 @@ mobs:register_mob("mobs_mc:villager", {
local accept local accept
local name = player:get_player_name() local name = player:get_player_name()
if listname == "output" then if listname == "output" then
inv:remove_item("input", inv:get_stack("wanted", 1)) local wanted1 = inv:get_stack("wanted", 1)
inv:remove_item("input", wanted1)
local wanted2 = inv:get_stack("wanted", 2) local wanted2 = inv:get_stack("wanted", 2)
if not wanted2:is_empty() then if not wanted2:is_empty() then
inv:remove_item("input", inv:get_stack("wanted", 2)) inv:remove_item("input", inv:get_stack("wanted", 2))
end end
-- BEGIN OF SPECIAL HANDLING FOR COMPASS
if wanted1:get_name() == COMPASS then
for n=1, 2 do
local input = inv:get_stack("input", n)
if minetest.get_item_group(input:get_name(), "compass") ~= 0 then
input:set_count(input:get_count() - wanted1:get_count())
inv:set_stack("input", n, input)
break
end
end
end
-- END OF SPECIAL HANDLING FOR COMPASS
local trader = player_trading_with[name] local trader = player_trading_with[name]
local tradenum = player_tradenum[name] local tradenum = player_tradenum[name]
local trades local trades
@ -649,7 +734,7 @@ mobs:register_mob("mobs_mc:villager", {
if trade.trade_counter >= 12 then if trade.trade_counter >= 12 then
trade.locked = true trade.locked = true
elseif trade.trade_counter >= 2 then elseif trade.trade_counter >= 2 then
local r = math.random(1, math.random(1, 9)) local r = math.random(1, math.random(4, 10))
if r == 1 then if r == 1 then
trade.locked = true trade.locked = true
end end