diff --git a/api/player_inv_class.lua b/api/player_inv_class.lua index 18f694e..069469f 100644 --- a/api/player_inv_class.lua +++ b/api/player_inv_class.lua @@ -16,24 +16,6 @@ function player_inv_class:_init(player) inv_class._init(self, player:get_inventory()) end -function smartshop.api.get_player_inv(player) - return player_inv_class(player) -end - --------------------- - -function player_inv_class:contains_item(stack) - return inv_class.contains_item(self, stack, true) -end - -function player_inv_class:remove_item(stack) - return inv_class.remove_item(self, stack, true) -end - -function player_inv_class:get_count(stack, kind) - return inv_class.get_count(self, stack, true) -end - -function player_inv_class:get_all_counts() - return inv_class.get_all_counts(self, true) +function smartshop.api.get_player_inv(player, strict_meta) + return player_inv_class(player, strict_meta) end diff --git a/api/purchase_mechanics.lua b/api/purchase_mechanics.lua index 555d164..7f0c9ee 100644 --- a/api/purchase_mechanics.lua +++ b/api/purchase_mechanics.lua @@ -88,8 +88,9 @@ function api.get_purchase_fail_reason(player, shop, i) local player_inv = api.get_player_inv(player) local pay_stack = shop:get_pay_stack(i) local give_stack = shop:get_give_stack(i) + local strict_meta = shop:is_strict_meta() - if not player_inv:contains_item(pay_stack) then + if not player_inv:contains_item(pay_stack, strict_meta) then return "You lack appropriate payment" elseif not shop:contains_item(give_stack, "give") then return "Shop is sold out" @@ -109,6 +110,7 @@ api.register_purchase_mechanic({ local player_inv = api.get_player_inv(player) local pay_stack = shop:get_pay_stack(i) local give_stack = shop:get_give_stack(i) + local strict_meta = shop:is_strict_meta() local tmp_shop_inv = shop:get_tmp_inv() local tmp_player_inv = player_inv:get_tmp_inv() @@ -118,13 +120,13 @@ api.register_purchase_mechanic({ local success = count_to_remove == shop_removed:get_count() count_to_remove = pay_stack:get_count() - local player_removed = tmp_player_inv:remove_item(pay_stack, "pay") + local player_removed = tmp_player_inv:remove_item(pay_stack, strict_meta) success = success and (count_to_remove == player_removed:get_count()) local leftover = tmp_shop_inv:add_item(player_removed, "pay") success = success and (leftover:get_count() == 0) - leftover = tmp_player_inv:add_item(shop_removed, "give") + leftover = tmp_player_inv:add_item(shop_removed) success = success and (leftover:get_count() == 0) shop:destroy_tmp_inv(tmp_shop_inv) @@ -136,9 +138,10 @@ api.register_purchase_mechanic({ local player_inv = api.get_player_inv(player) local pay_stack = shop:get_pay_stack(i) local give_stack = shop:get_give_stack(i) + local strict_meta = shop:is_strict_meta() local shop_removed = shop:remove_item(give_stack, "give") - local player_removed = player_inv:remove_item(pay_stack) + local player_removed = player_inv:remove_item(pay_stack, strict_meta) shop_removed, player_removed = api.do_transaction_transforms(player, shop, i, shop_removed, player_removed) diff --git a/compat/currency.lua b/compat/currency.lua index 0684ab9..feaa839 100644 --- a/compat/currency.lua +++ b/compat/currency.lua @@ -190,17 +190,17 @@ api.register_purchase_mechanic({ name = "smartshop:currency", description = S("currency exchange"), allow_purchase = function(player, shop, i) - local player_inv = api.get_player_inv(player) - local pay_stack = shop:get_pay_stack(i) local give_stack = shop:get_give_stack(i) + local strict_meta = shop:is_strict_meta() if not (currency.is_currency(pay_stack) or currency.is_currency(give_stack)) then return end - local tmp_shop_inv = shop:get_tmp_inv() + local player_inv = api.get_player_inv(player) local tmp_player_inv = player_inv:get_tmp_inv() + local tmp_shop_inv = shop:get_tmp_inv() local success = true local player_removed, shop_removed @@ -210,7 +210,7 @@ api.register_purchase_mechanic({ success = success and not player_removed:is_empty() else local count = pay_stack:get_count() - player_removed = tmp_player_inv:remove_item(pay_stack, "pay") + player_removed = tmp_player_inv:remove_item(pay_stack, strict_meta) success = success and (count == player_removed:get_count()) end @@ -244,7 +244,7 @@ api.register_purchase_mechanic({ return false end - local player_remaining = tmp_player_inv:add_item(shop_removed, "give") + local player_remaining = tmp_player_inv:add_item(shop_removed) success = success and player_remaining:is_empty() shop:destroy_tmp_inv(tmp_shop_inv) @@ -257,6 +257,7 @@ api.register_purchase_mechanic({ local pay_stack = shop:get_pay_stack(i) local give_stack = shop:get_give_stack(i) + local strict_meta = shop:is_strict_meta() local shop_removed local shop_remaining @@ -266,7 +267,7 @@ api.register_purchase_mechanic({ if currency.is_currency(pay_stack) then player_removed = currency.remove_item(player_inv, pay_stack, "pay") else - player_removed = player_inv:remove_item(pay_stack, "pay") + player_removed = player_inv:remove_item(pay_stack, strict_meta) end if currency.is_currency(give_stack) then @@ -278,7 +279,7 @@ api.register_purchase_mechanic({ shop_removed, player_removed = api.do_transaction_transforms(player, shop, i, shop_removed, player_removed) shop_remaining = shop:add_item(player_removed, "pay") - player_remaining = player_inv:add_item(shop_removed, "give") + player_remaining = player_inv:add_item(shop_removed) check_shop_removed(shop, shop_removed, give_stack) check_player_removed(player_inv, shop, player_removed, pay_stack) diff --git a/init.lua b/init.lua index 5b9621b..c0d7fe7 100644 --- a/init.lua +++ b/init.lua @@ -12,3 +12,7 @@ smartshop.dofile("compat", "init") smartshop.dofile("crafting") smartshop.dofile("aliases") + +if smartshop.settings.enable_tests then + smartshop.dofile("tests", "init") +end diff --git a/tests/strict_meta.lua b/tests/strict_meta.lua index 15a234a..e5bdc98 100644 --- a/tests/strict_meta.lua +++ b/tests/strict_meta.lua @@ -2,7 +2,7 @@ local inv_count = smartshop.tests.inv_count local put_in_shop = smartshop.tests.put_in_shop smartshop.tests.register_test({ - name = "item with metadata in a normal shop can be purchased", + name = "item with metadata in a non-strict shop can be purchased", func = function(player, state) local under = state.place_shop_against local shop_at = vector.subtract(state.place_shop_against, vector.new(0, 0, 1)) @@ -84,15 +84,14 @@ smartshop.tests.register_test({ local shop = smartshop.api.get_object(shop_at) shop:receive_fields(player, { strict_meta = "true" }) - shop.inv:set_stack("pay3", 1, "smartshop:gold") - local metatool = ItemStack("smartshop:tool") local tool_meta = metatool:get_meta() tool_meta:set_string("description", "Hey I'm a Tool") put_in_shop(shop, "smartshop:tool", player) put_in_shop(shop, metatool, player) - shop:update_appearance() + shop.inv:set_stack("pay3", 1, "smartshop:gold") shop.inv:set_stack("give3", 1, metatool) + shop:update_appearance() local player_inv = player:get_inventory() player_inv:set_list("main", { "smartshop:gold" }) @@ -110,3 +109,41 @@ smartshop.tests.register_test({ assert(tool_meta:get_string("description") == "Hey I'm a Tool", "purchased tool has meta") end, }) + +smartshop.tests.register_test({ + name = "shop is lax, allow payment with mismatched meta", + func = function(player, state) + local under = state.place_shop_against + local shop_at = vector.subtract(state.place_shop_against, vector.new(0, 0, 1)) + + minetest.remove_node(shop_at) + minetest.item_place_node(ItemStack("smartshop:shop"), player, { type = "node", under = under, above = shop_at }) + + local shop = smartshop.api.get_object(shop_at) + shop:receive_fields(player, { strict_meta = "false" }) + local metatool = ItemStack("smartshop:tool") + local tool_meta = metatool:get_meta() + tool_meta:set_string("description", "Hey I'm a Tool") + shop.inv:set_stack("give3", 1, "smartshop:gold") + shop.inv:set_stack("pay3", 1, metatool) + put_in_shop(shop, "smartshop:gold", player) + shop:update_appearance() + + tool_meta:set_string("description", "Hey I'm a different Tool") + + local player_inv = player:get_inventory() + player_inv:set_list("main", { metatool }) + + shop:receive_fields(player, { buy3a = true }) + + assert(inv_count(player_inv, "main", "smartshop:gold") == 1, "received gold") + assert(inv_count(player_inv, "main", "smartshop:tool") == 0, "tool in shop") + + assert(inv_count(shop.inv, "main", "smartshop:tool") == 1, "correct amount was received") + assert(inv_count(shop.inv, "main", "smartshop:gold") == 0, "correct amount were removed") + + local should_have_meta = shop.inv:remove_item("main", "smartshop:tool") + tool_meta = should_have_meta:get_meta() + assert(tool_meta:get_string("description") == "Hey I'm a different Tool", "spent tool has meta") + end, +})