Skip to content

Commit

Permalink
allow non-strict-meta shops to accept items w/ meta as payment
Browse files Browse the repository at this point in the history
  • Loading branch information
fluxionary committed Nov 6, 2023
1 parent b602b23 commit 8f7e2e8
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 35 deletions.
22 changes: 2 additions & 20 deletions api/player_inv_class.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 7 additions & 4 deletions api/purchase_mechanics.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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()
Expand All @@ -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)
Expand All @@ -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)

Expand Down
15 changes: 8 additions & 7 deletions compat/currency.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
45 changes: 41 additions & 4 deletions tests/strict_meta.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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" })
Expand All @@ -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,
})

0 comments on commit 8f7e2e8

Please sign in to comment.