1 -- TODO: Improve mod compability
4 local S
= minetest
.get_translator("easyvend")
5 local F
= minetest
.formspec_escape
7 local traversable_node_types
= {
8 ["easyvend:vendor"] = true,
9 ["easyvend:depositor"] = true,
10 ["easyvend:vendor_on"] = true,
11 ["easyvend:depositor_on"] = true,
13 local registered_chests
= {}
14 local cost_stack_max
= minetest
.registered_items
[easyvend
.currency
].stack_max
15 local maxcost
= cost_stack_max
* slots_max
17 local joketimer_start
= 3
19 local active_item_selection
= {}
21 -- Allow for other mods to register custom chests
22 easyvend
.register_chest
= function(node_name
, inv_list
, meta_owner
)
23 registered_chests
[node_name
] = { inv_list
= inv_list
, meta_owner
= meta_owner
}
24 traversable_node_types
[node_name
] = true
27 if minetest
.get_modpath("select_item") then
28 -- When player selects item via "select item" dialog, switch the
29 -- machine's selected item and update the formspec.
30 select_item
.register_on_select_item(function(playername
, dialogname
, itemstring
)
31 if dialogname
== "easyvend:trade_item" then
32 local player
= minetest
.get_player_by_name(playername
)
36 local pos
= active_item_selection
[playername
]
38 local node
= minetest
.get_node(pos
)
39 if not easyvend
.is_machine(node
.name
) then
42 local meta
= minetest
.get_meta(pos
)
43 local owner
= meta
:get_string("owner")
44 if playername
== owner
then
45 local inv
= meta
:get_inventory()
46 local stack
= ItemStack(itemstring
)
48 inv
:set_stack( "item", 1, nil )
50 inv
:set_stack( "item", 1, stack
)
51 meta
:set_string("itemname", itemstring
)
52 easyvend
.set_formspec(pos
, player
)
56 active_item_selection
[playername
] = nil
61 -- Partly a wrapper around contains_item, but does special treatment if the item
62 -- is a tool. Basically checks whether the items exist in the supplied inventory
63 -- list. If check_wear is true, only counts items without wear.
64 easyvend
.check_and_get_items
= function(inventory
, listname
, itemtable
, check_wear
)
65 local itemstring
= itemtable
.name
66 local minimum
= itemtable
.count
67 if check_wear
== nil then check_wear
= false end
70 if minetest
.registered_tools
[itemstring
] ~= nil then
72 for i
=1,inventory
:get_size(listname
) do
73 local stack
= inventory
:get_stack(listname
, i
)
74 if stack
:get_name() == itemstring
then
75 if not check_wear
or stack
:get_wear() == 0 then
77 table.insert(get_items
, {id
=i
, item
=stack
})
78 if count
>= minimum
then
79 return true, get_items
86 -- Normal Minetest check
87 return inventory
:contains_item(listname
, ItemStack(itemtable
))
92 if minetest
.get_modpath("default") ~= nil then
93 easyvend
.register_chest("default:chest_locked", "main", "owner")
96 easyvend
.free_slots
= function(inv
, listname
)
97 local size
= inv
:get_size(listname
)
100 local stack
= inv
:get_stack(listname
, i
)
101 if stack
:is_empty() then
108 easyvend
.buysell
= function(nodename
)
110 if ( nodename
== "easyvend:depositor" or nodename
== "easyvend:depositor_on" ) then
112 elseif ( nodename
== "easyvend:vendor" or nodename
== "easyvend:vendor_on" ) then
118 easyvend
.is_machine
= function(nodename
)
119 return ( nodename
== "easyvend:depositor_on" or nodename
== "easyvend:vendor_on" or nodename
== "easyvend:depositor" or nodename
== "easyvend:vendor" )
122 easyvend
.is_active
= function(nodename
)
123 if ( nodename
== "easyvend:depositor_on" or nodename
== "easyvend:vendor_on" ) then
125 elseif ( nodename
== "easyvend:depositor" or nodename
== "easyvend:vendor" ) then
132 easyvend
.set_formspec
= function(pos
, player
)
133 local meta
= minetest
.get_meta(pos
)
134 local node
= minetest
.get_node(pos
)
136 local description
= minetest
.registered_nodes
[node
.name
].description
;
137 local number = meta
:get_int("number")
138 local cost
= meta
:get_int("cost")
139 local itemname
= meta
:get_string("itemname")
141 local configmode
= meta
:get_int("configmode") == 1
142 -- Support legacy background from default mod (MT<=0.4.17)
143 if minetest
.get_modpath("default") and default
.gui_bg
then
144 bg
= default
.gui_bg
.. default
.gui_bg_img
.. default
.gui_slots
147 local numbertext
, costtext
, buysellbuttontext
148 local itemcounttooltip
= S("Item count (append āsā to multiply with maximum stack size)")
149 local buysell
= easyvend
.buysell(node
.name
)
150 if buysell
== "sell" then
151 numbertext
= S("Offered item")
152 costtext
= S("Price")
153 buysellbuttontext
= S("Buy")
154 elseif buysell
== "buy" then
155 numbertext
= S("Requested item")
156 costtext
= S("Payment")
157 buysellbuttontext
= S("Sell")
161 local status
= meta
:get_string("status")
162 if status
== "" then status
= S("Unknown.") end
163 local message
= meta
:get_string("message")
164 if message
== "" then message
= S("No message.") end
166 if node
.name
== "easyvend:vendor_on" or node
.name
== "easyvend:depositor_on" then
167 status_image
= "easyvend_status_on.png"
169 status_image
= "easyvend_status_off.png"
172 -- TODO: Expose number of items in stock
174 local formspec
= "size[8,7.3;]"
176 .."label[3,-0.2;" .. F(description
) .. "]"
178 .."image[7.5,0.2;0.5,1;" .. status_image
.. "]"
179 .."textarea[2.8,0.2;5.1,1.45;;"..F(S("Status: @1", status
)) .. ";]"
180 .."textarea[2.8,1.3;5.6,1.45;;"..F(S("Message: @1", message
)) .. ";]"
182 .."label[0,-0.15;"..F(numbertext
).."]"
183 .."label[0,1.2;"..F(costtext
).."]"
184 .."list[current_player;main;0,3.5;8,4;]"
188 if meta
:get_int("wear") == 1 then wear
= "true" end
189 local desc
= ItemStack(easyvend
.currency
):get_description()
191 .."item_image[0,1.65;1,1;"..easyvend
.currency
.."]"
192 .."tooltip[0,1.65;0.8,0.8;"..F(desc
).."]"
193 .."list[current_name;item;0,0.35;1,1;]"
194 .."listring[current_player;main]"
195 .."listring[current_name;item]"
196 .."field[1.3,0.65;1.5,1;number;;" .. number .. "]"
197 .."tooltip[number;"..F(itemcounttooltip
).."]"
198 .."field[1.3,1.95;1.5,1;cost;;" .. F(cost
) .. "]"
199 .."tooltip[cost;"..F(itemcounttooltip
).."]"
200 .."button[6,2.8;2,0.5;save;"..F(S("Confirm")).."]"
201 .."tooltip[save;"..F(S("Confirm configuration and activate machine (only for owner)")).."]"
202 if minetest
.get_modpath("select_item") then
203 formspec
= formspec
.. "button[0,2.8;2,0.5;select_item;"..F(S("Select item")).."]"
205 local weartext
, weartooltip
206 if buysell
== "buy" then
207 weartext
= S("Buy worn tools")
208 weartooltip
= S("If disabled, only tools in perfect condition will be bought from sellers (only settable by owner)")
210 weartext
= S("Sell worn tools")
211 weartooltip
= S("If disabled, only tools in perfect condition will be sold (only settable by owner)")
213 if minetest
.registered_tools
[itemname
] ~= nil then
214 formspec
= formspec
.."checkbox[2,2.4;wear;"..F(weartext
)..";"..wear
.."]"
215 .."tooltip[wear;"..F(weartooltip
).."]"
218 local desc_c
= ItemStack(easyvend
.currency
):get_description()
220 if minetest
.registered_items
[itemname
] then
221 local desc_i
= ItemStack(itemname
):get_description()
222 tt_i
= "tooltip[0,0.35;0.8,0.8;"..F(desc_i
).."]"
225 .."item_image[0,1.65;1,1;"..easyvend
.currency
.."]"
226 .."tooltip[0,1.65;0.8,0.8;"..F(desc_c
).."]"
227 .."item_image[0,0.35;1,1;"..itemname
.."]"
229 .."label[1,1.85;Ć" .. cost
.. "]"
230 .."label[1,0.55;Ć" .. number .. "]"
231 .."button[6,2.8;2,0.5;config;"..F(S("Configure")).."]"
232 if buysell
== "sell" then
233 formspec
= formspec
.. "tooltip[config;"..F(S("Configure offered items and price (only for owner)")).."]"
235 formspec
= formspec
.. "tooltip[config;"..F(S("Configure requested items and payment (only for owner)")).."]"
237 formspec
= formspec
.."button[0,2.8;2,0.5;buysell;"..F(buysellbuttontext
).."]"
238 if minetest
.registered_tools
[itemname
] ~= nil then
240 if meta
:get_int("wear") == 0 then
241 if buysell
== "buy" then
242 weartext
= S("Only intact tools are bought.")
244 weartext
= S("Only intact tools are sold.")
247 if buysell
== "sell" then
248 weartext
= S("Note: Might sell worn tools.")
250 weartext
= S("Accepts worn tools.")
253 if weartext
~= nil then
254 formspec
= formspec
.."textarea[2.3,2.6;4,1;;"..F(weartext
)..";]"
259 meta
:set_string("formspec", formspec
)
262 easyvend
.machine_disable
= function(pos
, node
, playername
)
263 if node
.name
== "easyvend:vendor_on" then
264 easyvend
.sound_disable(pos
)
265 minetest
.swap_node(pos
, {name
="easyvend:vendor", param2
= node
.param2
})
267 elseif node
.name
== "easyvend:depositor_on" then
268 easyvend
.sound_disable(pos
)
269 minetest
.swap_node(pos
, {name
="easyvend:depositor", param2
= node
.param2
})
272 if playername
~= nil then
273 easyvend
.sound_error(playername
)
279 easyvend
.machine_enable
= function(pos
, node
)
280 if node
.name
== "easyvend:vendor" then
281 easyvend
.sound_setup(pos
)
282 minetest
.swap_node(pos
, {name
="easyvend:vendor_on", param2
= node
.param2
})
284 elseif node
.name
== "easyvend:depositor" then
285 easyvend
.sound_setup(pos
)
286 minetest
.swap_node(pos
, {name
="easyvend:depositor_on", param2
= node
.param2
})
293 easyvend
.machine_check
= function(pos
, node
)
295 local status
= S("Ready.")
297 local meta
= minetest
.get_meta(pos
)
299 local machine_owner
= meta
:get_string("owner")
300 local number = meta
:get_int("number")
301 local cost
= meta
:get_int("cost")
302 local itemname
= meta
:get_string("itemname")
303 local check_wear
= meta
:get_int("wear") == 0
304 local inv
= meta
:get_inventory()
305 local itemstack
= inv
:get_stack("item",1)
306 local buysell
= easyvend
.buysell(node
.name
)
308 local chest_pos_remove
, chest_error_remove
, chest_pos_add
, chest_error_add
309 if buysell
== "sell" then
310 chest_pos_remove
, chest_error_remove
= easyvend
.find_connected_chest(machine_owner
, pos
, itemname
, check_wear
, number, true)
311 chest_pos_add
, chest_error_add
= easyvend
.find_connected_chest(machine_owner
, pos
, easyvend
.currency
, check_wear
, cost
, false)
313 chest_pos_remove
, chest_error_remove
= easyvend
.find_connected_chest(machine_owner
, pos
, easyvend
.currency
, check_wear
, cost
, true)
314 chest_pos_add
, chest_error_add
= easyvend
.find_connected_chest(machine_owner
, pos
, itemname
, check_wear
, number, false)
316 if chest_pos_remove
and chest_pos_add
then
317 local rchest
, rchestdef
, rchest_meta
, rchest_inv
318 rchest
= minetest
.get_node(chest_pos_remove
)
319 rchestdef
= registered_chests
[rchest
.name
]
320 rchest_meta
= minetest
.get_meta(chest_pos_remove
)
321 rchest_inv
= rchest_meta
:get_inventory()
323 local checkstack
, checkitem
324 if buysell
== "buy" then
325 checkitem
= easyvend
.currency
331 -- FIXME: Ignore tools with bad wear level
332 for i
=1,rchest_inv
:get_size(rchestdef
.inv_list
) do
333 checkstack
= rchest_inv
:get_stack(rchestdef
.inv_list
, i
)
334 if checkstack
:get_name() == checkitem
then
335 stock
= stock
+ checkstack
:get_count()
338 meta
:set_int("stock", stock
)
340 if not itemstack
:is_empty() then
341 local number_stack_max
= itemstack
:get_stack_max()
342 local maxnumber
= number_stack_max
* slots_max
343 if not(number >= 1 and number <= maxnumber
and cost
>= 1 and cost
<= maxcost
) then
345 if buysell
== "sell" then
346 status
= S("Invalid item count or price.")
348 status
= S("Invalid item count or payment.")
353 status
= S("Awaiting configuration by owner.")
357 meta
:set_int("stock", 0)
358 if chest_error_remove
== "no_chest" and chest_error_add
== "no_chest" then
359 status
= S("No storage; machine needs to be connected with a locked chest.")
360 elseif chest_error_remove
== "not_owned" or chest_error_add
== "not_owned" then
361 status
= S("Storage canāt be accessed because it is owned by a different person!")
362 elseif chest_error_remove
== "no_stock" then
363 if buysell
== "sell" then
364 status
= S("The vending machine has insufficient materials!")
366 status
= S("The depositing machine is out of money!")
368 elseif chest_error_add
== "no_space" then
369 status
= S("No room in the machineās storage!")
371 status
= S("Unknown error!")
374 if meta
:get_int("configmode") == 1 then
376 status
= S("Awaiting configuration by owner.")
379 if itemname
== easyvend
.currency
and number == cost
and active
then
380 local jt
= meta
:get_int("joketimer")
385 if buysell
== "sell" then
386 meta
:set_string("message", S("Item bought."))
388 meta
:set_string("message", S("Item sold."))
392 meta
:set_int("joketimer", jt
)
394 meta
:set_string("status", status
)
396 meta
:set_string("infotext", easyvend
.make_infotext(node
.name
, machine_owner
, cost
, number, itemname
))
397 itemname
=itemstack
:get_name()
398 meta
:set_string("itemname", itemname
)
400 if minetest
.get_modpath("awards") and buysell
== "sell" then
401 if minetest
.get_player_by_name(machine_owner
) then
402 local earnings
= meta
:get_int("earnings")
403 if earnings
>= 1 then
404 awards
.unlock(machine_owner
, "easyvend_seller")
406 if earnings
>= easyvend
.powerseller
then
407 awards
.unlock(machine_owner
, "easyvend_powerseller")
413 if node
.name
== "easyvend:vendor" or node
.name
== "easyvend:depositor" then
414 if active
then change
= easyvend
.machine_enable(pos
, node
) end
415 elseif node
.name
== "easyvend:vendor_on" or node
.name
== "easyvend:depositor_on" then
416 if not active
then change
= easyvend
.machine_disable(pos
, node
) end
418 easyvend
.set_formspec(pos
)
422 easyvend
.on_receive_fields_config
= function(pos
, formname
, fields
, sender
)
423 local node
= minetest
.get_node(pos
)
424 local meta
= minetest
.get_meta(pos
)
425 local inv_self
= meta
:get_inventory()
426 local itemstack
= inv_self
:get_stack("item",1)
427 local buysell
= easyvend
.buysell(node
.name
)
429 if fields
.config
then
430 meta
:set_int("configmode", 1)
431 local was_active
= easyvend
.is_active(node
.name
)
433 meta
:set_string("message", S("Configuration mode activated; machine disabled."))
435 meta
:set_string("message", S("Configuration mode activated."))
437 easyvend
.machine_check(pos
, node
)
441 if not fields
.save
then
445 local number = fields
.number
446 local cost
= fields
.cost
448 --[[ Convenience function:
449 When appending āsā or āSā to the number, it is multiplied
450 by the maximum stack size. ]]
451 local number_stack_max
= itemstack
:get_stack_max()
452 local ss
= string.sub(number, #number, #number)
453 if ss
== "s" or ss
== "S" then
454 local n
= tonumber(string.sub(number, 1, #number-1))
455 if string.len(number) == 1 then n
= 1 end
457 number = n
* number_stack_max
460 ss
= string.sub(cost
, #cost
, #cost
)
461 if ss
== "s" or ss
== "S" then
462 local n
= tonumber(string.sub(cost
, 1, #cost
-1))
463 if string.len(cost
) == 1 then n
= 1 end
465 cost
= n
* cost_stack_max
468 number = tonumber(number)
469 cost
= tonumber(cost
)
473 local oldnumber
= meta
:get_int("number")
474 local oldcost
= meta
:get_int("cost")
475 local maxnumber
= number_stack_max
* slots_max
477 if ( itemstack
== nil or itemstack
:is_empty() ) then
478 meta
:set_string("status", S("Awaiting configuration by owner."))
479 meta
:set_string("message", S("No item specified."))
480 easyvend
.sound_error(sender
:get_player_name())
481 easyvend
.set_formspec(pos
, sender
)
483 elseif ( not itemstack
:is_known() ) then
484 meta
:set_string("status", S("Awaiting configuration by owner."))
485 meta
:set_string("message", S("Unknown item specified."))
486 easyvend
.sound_error(sender
:get_player_name())
487 easyvend
.set_formspec(pos
, sender
)
489 elseif ( number == nil or number < 1 or number > maxnumber
) then
490 if maxnumber
> 1 then
491 meta
:set_string("message", S("Invalid item count; must be between 1 and @1!", maxnumber
))
493 meta
:set_string("message", S("Invalid item count; must be exactly 1!"))
495 meta
:set_int("number", oldnumber
)
496 easyvend
.sound_error(sender
:get_player_name())
497 easyvend
.set_formspec(pos
, sender
)
499 elseif ( cost
== nil or cost
< 1 or cost
> maxcost
) then
501 meta
:set_string("message", S("Invalid cost; must be between 1 and @1!", maxcost
))
503 meta
:set_string("message", S("Invalid cost; must be exactly 1!"))
505 meta
:set_int("cost", oldcost
)
506 easyvend
.sound_error(sender
:get_player_name())
507 easyvend
.set_formspec(pos
, sender
)
510 meta
:set_int("number", number)
511 meta
:set_int("cost", cost
)
512 itemname
=itemstack
:get_name()
513 meta
:set_string("itemname", itemname
)
514 meta
:set_int("configmode", 0)
516 if itemname
== easyvend
.currency
and number == cost
and cost
<= cost_stack_max
then
517 meta
:set_string("message", S("Configuration successful. I am feeling funny."))
518 meta
:set_int("joketimer", joketimer_start
)
519 meta
:set_int("joke_id", easyvend
.assign_joke(buysell
))
521 meta
:set_string("message", S("Configuration successful."))
524 local change
= easyvend
.machine_check(pos
, node
)
527 if (node
.name
== "easyvend:vendor_on" or node
.name
== "easyvend:depositor_on") then
528 easyvend
.sound_setup(pos
)
530 easyvend
.sound_disable(pos
)
535 easyvend
.make_infotext
= function(nodename
, owner
, cost
, number, itemstring
)
537 if itemstring
== nil or itemstring
== "" or number == 0 or cost
== 0 then
538 if easyvend
.buysell(nodename
) == "sell" then
539 d
= S("Inactive vending machine (owned by @1)", owner
)
541 d
= S("Inactive depositing machine (owned by @1)", owner
)
546 if minetest
.registered_items
[itemstring
] then
547 iname
= minetest
.registered_items
[itemstring
].description
549 iname
= S("Unknown Item (@1)", itemstring
)
551 if iname
== nil then iname
= itemstring
end
552 local printitem
, printcost
556 printitem
= S("@1Ć@2", number, iname
)
559 printcost
= easyvend
.currency_desc
561 printcost
= S("@1Ć@2", cost
, easyvend
.currency_desc
)
563 if nodename
== "easyvend:vendor_on" then
564 d
= S("Vending machine (owned by @1)", owner
).."\n"..S("Selling: @1", printitem
).."\n"..S("Price: @1", printcost
)
565 elseif nodename
== "easyvend:vendor" then
566 d
= S("Inactive vending machine (owned by @1)", owner
).."\n"..S("Selling: @1", printitem
).."\n"..S("Price: @1", printcost
)
567 elseif nodename
== "easyvend:depositor_on" then
568 d
= S("Depositing machine (owned by @1)", owner
).."\n"..S("Buying: @1", printitem
).."\n"..S("Payment: @1", printcost
)
569 elseif nodename
== "easyvend:depositor" then
570 d
= S("Inactive depositing machine (owned by @1)", owner
).."\n"..S("Buying: @1", printitem
).."\n"..S("Payment: @1", printcost
)
575 if minetest
.get_modpath("awards") then
576 awards
.register_achievement("easyvend_seller",{
577 title
= S("First Sale"),
578 description
= S("Sell something with a vending machine."),
579 icon
= "easyvend_vendor_front_on.png^awards_level1.png",
581 local desc_powerseller
582 if easyvend
.currency
== "default:gold_ingot" then
583 desc_powerseller
= S("Earn @1 gold ingots by selling goods with a single vending machine.", easyvend
.powerseller
)
585 desc_powerseller
= S("Earn @1 currency items by selling goods with a single vending machine.", easyvend
.powerseller
)
587 awards
.register_achievement("easyvend_powerseller",{
588 title
= S("Power Seller"),
589 description
= desc_powerseller
,
590 icon
= "easyvend_vendor_front_on.png^awards_level2.png",
594 easyvend
.check_earnings
= function(buyername
, nodemeta
)
595 local owner
= nodemeta
:get_string("owner")
596 if buyername
~= owner
then
597 local cost
= nodemeta
:get_int("cost")
598 local itemname
= nodemeta
:get_string("itemname")
600 if minetest
.get_modpath("awards") and minetest
.get_player_by_name(owner
) ~= nil then
601 awards
.unlock(owner
, "easyvend_seller")
603 if itemname
~= easyvend
.currency
then
604 local newearnings
= nodemeta
:get_int("earnings") + cost
605 if newearnings
>= easyvend
.powerseller
and minetest
.get_modpath("awards") then
606 if minetest
.get_player_by_name(owner
) ~= nil then
607 awards
.unlock(owner
, "easyvend_powerseller")
610 nodemeta
:set_int("earnings", newearnings
)
615 easyvend
.on_receive_fields_buysell
= function(pos
, formname
, fields
, sender
)
616 local sendername
= sender
:get_player_name()
617 local meta
= minetest
.get_meta(pos
)
619 if not fields
.buysell
then
623 local node
= minetest
.get_node(pos
)
624 local number = meta
:get_int("number")
625 local cost
= meta
:get_int("cost")
626 local itemname
=meta
:get_string("itemname")
627 local item
=meta
:get_inventory():get_stack("item", 1)
628 local check_wear
= meta
:get_int("wear") == 0 and minetest
.registered_tools
[itemname
] ~= nil
629 local machine_owner
= meta
:get_string("owner")
631 local buysell
= easyvend
.buysell(node
.name
)
633 local number_stack_max
= item
:get_stack_max()
634 local maxnumber
= number_stack_max
* slots_max
636 if ( number == nil or number < 1 or number > maxnumber
) or
637 ( cost
== nil or cost
< 1 or cost
> maxcost
) or
638 ( itemname
== nil or itemname
=="") then
639 meta
:set_string("status", S("Invalid item count or price!"))
640 easyvend
.machine_disable(pos
, node
, sendername
)
644 local chest_pos_remove
, chest_error_remove
, chest_pos_add
, chest_error_add
645 if buysell
== "sell" then
646 chest_pos_remove
, chest_error_remove
= easyvend
.find_connected_chest(machine_owner
, pos
, itemname
, check_wear
, number, true)
647 chest_pos_add
, chest_error_add
= easyvend
.find_connected_chest(machine_owner
, pos
, easyvend
.currency
, check_wear
, cost
, false)
649 chest_pos_remove
, chest_error_remove
= easyvend
.find_connected_chest(machine_owner
, pos
, easyvend
.currency
, check_wear
, cost
, true)
650 chest_pos_add
, chest_error_add
= easyvend
.find_connected_chest(machine_owner
, pos
, itemname
, check_wear
, number, false)
653 if chest_pos_remove
~= nil and chest_pos_add
~= nil and sender
and sender
:is_player() then
654 local rchest
= minetest
.get_node(chest_pos_remove
)
655 local rchestdef
= registered_chests
[rchest
.name
]
656 local rchest_meta
= minetest
.get_meta(chest_pos_remove
)
657 local rchest_inv
= rchest_meta
:get_inventory()
658 local achest
= minetest
.get_node(chest_pos_add
)
659 local achestdef
= registered_chests
[achest
.name
]
660 local achest_meta
= minetest
.get_meta(chest_pos_add
)
661 local achest_inv
= achest_meta
:get_inventory()
663 local player_inv
= sender
:get_inventory()
665 local stack
= {name
=itemname
, count
=number, wear
=0, metadata
=""}
666 local price
= {name
=easyvend
.currency
, count
=cost
, wear
=0, metadata
=""}
667 local chest_has
, player_has
, chest_free
, player_free
, chest_out
, player_out
669 if buysell
== "sell" then
670 chest_has
, chest_out
= easyvend
.check_and_get_items(rchest_inv
, rchestdef
.inv_list
, stack
, check_wear
)
671 player_has
, player_out
= easyvend
.check_and_get_items(player_inv
, "main", price
, check_wear
)
672 chest_free
= achest_inv
:room_for_item(achestdef
.inv_list
, price
)
673 player_free
= player_inv
:room_for_item("main", stack
)
674 if chest_has
and player_has
and chest_free
and player_free
then
675 if cost
<= cost_stack_max
and number <= number_stack_max
then
676 easyvend
.machine_enable(pos
, node
)
677 player_inv
:remove_item("main", price
)
679 rchest_inv
:set_stack(rchestdef
.inv_list
, chest_out
[1].id
, "")
680 player_inv
:add_item("main", chest_out
[1].item
)
682 stack
= rchest_inv
:remove_item(rchestdef
.inv_list
, stack
)
683 player_inv
:add_item("main", stack
)
685 achest_inv
:add_item(achestdef
.inv_list
, price
)
686 if itemname
== easyvend
.currency
and number == cost
and cost
<= cost_stack_max
then
687 meta
:set_string("message", easyvend
.get_joke(buysell
, meta
:get_int("joke_id")))
688 meta
:set_int("joketimer", joketimer_start
)
690 meta
:set_string("message", S("Item bought."))
692 easyvend
.check_earnings(sendername
, meta
)
693 easyvend
.sound_vend(pos
)
694 easyvend
.machine_check(pos
, node
)
696 -- Large item counts (multiple stacks)
697 local coststacks
= math
.modf(cost
/ cost_stack_max
)
698 local costremainder
= math
.fmod(cost
, cost_stack_max
)
699 local numberstacks
= math
.modf(number / number_stack_max
)
700 local numberremainder
= math
.fmod(number, number_stack_max
)
701 local numberfree
= numberstacks
702 local costfree
= coststacks
703 if numberremainder
> 0 then numberfree
= numberfree
+ 1 end
704 if costremainder
> 0 then costfree
= costfree
+ 1 end
705 if not player_free
and easyvend
.free_slots(player_inv
, "main") < numberfree
then
706 if numberfree
> 1 then
707 msg
= S("No room in your inventory (@1 empty slots required)!", numberfree
)
709 msg
= S("No room in your inventory!")
711 meta
:set_string("message", msg
)
712 elseif not chest_free
and easyvend
.free_slots(achest_inv
, achestdef
.inv_list
) < costfree
then
713 meta
:set_string("status", S("No room in the machineās storage!"))
714 easyvend
.machine_disable(pos
, node
, sendername
)
716 -- Remember items for transfer
717 local cheststacks
= {}
718 easyvend
.machine_enable(pos
, node
)
719 for i
=1, coststacks
do
720 price
.count
= cost_stack_max
721 player_inv
:remove_item("main", price
)
723 if costremainder
> 0 then
724 price
.count
= costremainder
725 player_inv
:remove_item("main", price
)
728 for o
=1,#chest_out
do
729 rchest_inv
:set_stack(rchestdef
.inv_list
, chest_out
[o
].id
, "")
732 for i
=1, numberstacks
do
733 stack
.count
= number_stack_max
734 table.insert(cheststacks
, rchest_inv
:remove_item(rchestdef
.inv_list
, stack
))
737 if numberremainder
> 0 then
738 stack
.count
= numberremainder
739 table.insert(cheststacks
, rchest_inv
:remove_item(rchestdef
.inv_list
, stack
))
741 for i
=1, coststacks
do
742 price
.count
= cost_stack_max
743 achest_inv
:add_item(achestdef
.inv_list
, price
)
745 if costremainder
> 0 then
746 price
.count
= costremainder
747 achest_inv
:add_item(achestdef
.inv_list
, price
)
750 for o
=1,#chest_out
do
751 player_inv
:add_item("main", chest_out
[o
].item
)
754 for i
=1,#cheststacks
do
755 player_inv
:add_item("main", cheststacks
[i
])
758 meta
:set_string("message", S("Item bought."))
759 easyvend
.check_earnings(sendername
, meta
)
760 easyvend
.sound_vend(pos
)
761 easyvend
.machine_check(pos
, node
)
764 elseif chest_has
and player_has
then
765 if not player_free
then
766 msg
= S("No room in your inventory!")
767 meta
:set_string("message", msg
)
768 easyvend
.sound_error(sendername
)
769 elseif not chest_free
then
770 msg
= S("No room in the machineās storage!")
771 meta
:set_string("status", msg
)
772 easyvend
.machine_disable(pos
, node
, sendername
)
775 if not chest_has
then
776 msg
= S("The vending machine has insufficient materials!")
777 meta
:set_string("status", msg
)
778 easyvend
.machine_disable(pos
, node
, sendername
)
779 elseif not player_has
then
780 msg
= S("You canāt afford this item!")
781 meta
:set_string("message", msg
)
782 easyvend
.sound_error(sendername
)
786 chest_has
, chest_out
= easyvend
.check_and_get_items(rchest_inv
, rchestdef
.inv_list
, price
, check_wear
)
787 player_has
, player_out
= easyvend
.check_and_get_items(player_inv
, "main", stack
, check_wear
)
788 chest_free
= achest_inv
:room_for_item(achestdef
.inv_list
, stack
)
789 player_free
= player_inv
:room_for_item("main", price
)
790 if chest_has
and player_has
and chest_free
and player_free
then
791 if cost
<= cost_stack_max
and number <= number_stack_max
then
792 easyvend
.machine_enable(pos
, node
)
794 player_inv
:set_stack("main", player_out
[1].id
, "")
795 achest_inv
:add_item(achestdef
.inv_list
, player_out
[1].item
)
797 stack
= player_inv
:remove_item("main", stack
)
798 achest_inv
:add_item(achestdef
.inv_list
, stack
)
800 rchest_inv
:remove_item(rchestdef
.inv_list
, price
)
801 player_inv
:add_item("main", price
)
802 meta
:set_string("status", S("Ready."))
803 if itemname
== easyvend
.currency
and number == cost
and cost
<= cost_stack_max
then
804 meta
:set_string("message", easyvend
.get_joke(buysell
, meta
:get_int("joke_id")))
805 meta
:set_int("joketimer", joketimer_start
)
807 meta
:set_string("message", S("Item sold."))
809 easyvend
.sound_deposit(pos
)
810 easyvend
.machine_check(pos
, node
)
812 -- Large item counts (multiple stacks)
813 local coststacks
= math
.modf(cost
/ cost_stack_max
)
814 local costremainder
= math
.fmod(cost
, cost_stack_max
)
815 local numberstacks
= math
.modf(number / number_stack_max
)
816 local numberremainder
= math
.fmod(number, number_stack_max
)
817 local numberfree
= numberstacks
818 local costfree
= coststacks
819 if numberremainder
> 0 then numberfree
= numberfree
+ 1 end
820 if costremainder
> 0 then costfree
= costfree
+ 1 end
821 if not player_free
and easyvend
.free_slots(player_inv
, "main") < costfree
then
823 msg
= S("No room in your inventory (@1 empty slots required)!", costfree
)
825 msg
= S("No room in your inventory!")
827 meta
:set_string("message", msg
)
828 easyvend
.sound_error(sendername
)
829 elseif not chest_free
and easyvend
.free_slots(achest_inv
, achestdef
.inv_list
) < numberfree
then
830 meta
:set_string("status", S("No room in the machineās storage!"))
831 easyvend
.machine_disable(pos
, node
, sendername
)
833 easyvend
.machine_enable(pos
, node
)
834 -- Remember removed items for transfer
835 local playerstacks
= {}
836 for i
=1, coststacks
do
837 price
.count
= cost_stack_max
838 rchest_inv
:remove_item(rchestdef
.inv_list
, price
)
840 if costremainder
> 0 then
841 price
.count
= costremainder
842 rchest_inv
:remove_item(rchestdef
.inv_list
, price
)
845 for o
=1,#player_out
do
846 player_inv
:set_stack("main", player_out
[o
].id
, "")
849 for i
=1, numberstacks
do
850 stack
.count
= number_stack_max
851 table.insert(playerstacks
, player_inv
:remove_item("main", stack
))
854 if numberremainder
> 0 then
855 stack
.count
= numberremainder
856 table.insert(playerstacks
, player_inv
:remove_item("main", stack
))
858 for i
=1, coststacks
do
859 price
.count
= cost_stack_max
860 player_inv
:add_item("main", price
)
862 if costremainder
> 0 then
863 price
.count
= costremainder
864 player_inv
:add_item("main", price
)
867 for o
=1,#player_out
do
868 achest_inv
:add_item(achestdef
.inv_list
, player_out
[o
].item
)
871 for i
=1,#playerstacks
do
872 achest_inv
:add_item(achestdef
.inv_list
, playerstacks
[i
])
875 meta
:set_string("message", S("Item sold."))
876 easyvend
.sound_deposit(pos
)
877 easyvend
.machine_check(pos
, node
)
880 elseif chest_has
and player_has
then
881 if not player_free
then
882 msg
= S("No room in your inventory!")
883 meta
:set_string("message", msg
)
884 easyvend
.sound_error(sendername
)
885 elseif not chest_free
then
886 msg
= S("No room in the machineās storage!")
887 meta
:set_string("status", msg
)
888 easyvend
.machine_disable(pos
, node
, sendername
)
891 if not player_has
then
892 msg
= S("You have insufficient materials!")
893 meta
:set_string("message", msg
)
894 easyvend
.sound_error(sendername
)
895 elseif not chest_has
then
896 msg
= S("The depositing machine is out of money!")
897 meta
:set_string("status", msg
)
898 easyvend
.machine_disable(pos
, node
, sendername
)
904 meta
:set_int("stock", 0)
905 if chest_error_remove
== "no_chest" and chest_error_add
== "no_chest" then
906 status
= S("No storage; machine needs to be connected with a locked chest.")
907 elseif chest_error_remove
== "not_owned" or chest_error_add
== "not_owned" then
908 status
= S("Storage canāt be accessed because it is owned by a different person!")
909 elseif chest_error_remove
== "no_stock" then
910 if buysell
== "sell" then
911 status
= S("The vending machine has insufficient materials!")
913 status
= S("The depositing machine is out of money!")
915 elseif chest_error_add
== "no_space" then
916 status
= S("No room in the machineās storage!")
918 status
= S("Unknown error!")
920 meta
:set_string("status", status
)
921 easyvend
.sound_error(sendername
)
924 easyvend
.set_formspec(pos
, sender
)
928 easyvend
.after_place_node
= function(pos
, placer
)
929 local node
= minetest
.get_node(pos
)
930 local meta
= minetest
.get_meta(pos
)
931 local inv
= meta
:get_inventory()
932 local player_name
= placer
:get_player_name()
933 inv
:set_size("item", 1)
934 inv
:set_size("gold", 1)
936 inv
:set_stack( "gold", 1, easyvend
.currency
)
939 if node
.name
== "easyvend:vendor" then
940 d
= S("Inactive vending machine (owned by @1)", player_name
)
941 meta
:set_int("wear", 1)
942 -- Total number of currency items earned for the machine's life time (excluding currency-currency trading)
943 meta
:set_int("earnings", 0)
944 elseif node
.name
== "easyvend:depositor" then
945 d
= S("Inactive depositing machine (owned by @1)", player_name
)
946 meta
:set_int("wear", 0)
948 meta
:set_string("infotext", d
)
949 meta
:set_string("status", S("Awaiting configuration by owner."))
950 meta
:set_string("message", S("Please select an item and amount, then confirm."))
951 meta
:set_int("number", 1)
952 meta
:set_int("cost", 1)
953 meta
:set_int("stock", -1)
954 meta
:set_int("configmode", 1)
955 meta
:set_int("joketimer", -1)
956 meta
:set_int("joke_id", 1)
957 meta
:set_string("itemname", "")
959 meta
:set_string("owner", player_name
or "")
961 easyvend
.set_formspec(pos
, placer
)
964 easyvend
.can_dig
= function(pos
, player
)
965 local meta
= minetest
.get_meta(pos
)
966 local name
= player
:get_player_name()
967 local owner
= meta
:get_string("owner")
968 -- Owner can always dig shop
969 if owner
== name
then
972 local chest_pos
= easyvend
.find_connected_chest(owner
, pos
)
973 local chest
, meta_chest
975 chest
= minetest
.get_node(chest_pos
)
976 meta_chest
= minetest
.get_meta(chest_pos
)
978 return true --if no chest, enyone can dig this shop
980 if registered_chests
[chest
.name
] then
981 if player
and player
:is_player() then
982 local owner_chest
= meta_chest
:get_string(registered_chests
[chest
.name
].meta_owner
)
983 if name
== owner_chest
then
984 return true --chest owner can also dig shop
989 return true --if no chest, enyone can dig this shop
993 easyvend
.on_receive_fields
= function(pos
, formname
, fields
, sender
)
994 local meta
= minetest
.get_meta(pos
)
995 local node
= minetest
.get_node(pos
)
996 local owner
= meta
:get_string("owner")
997 local sendername
= sender
:get_player_name()
1000 if minetest
.get_modpath("doc") and minetest
.get_modpath("doc_items") then
1001 if easyvend
.buysell(node
.name
) == "buy" then
1002 doc
.show_entry(sendername
, "nodes", "easyvend:depositor", true)
1004 doc
.show_entry(sendername
, "nodes", "easyvend:vendor", true)
1007 elseif fields
.config
or fields
.save
or fields
.usermode
then
1008 if sendername
== owner
then
1009 easyvend
.on_receive_fields_config(pos
, formname
, fields
, sender
)
1011 meta
:set_string("message", S("Only the owner may change the configuration."))
1012 easyvend
.sound_error(sendername
)
1013 easyvend
.set_formspec(pos
, sender
)
1016 elseif fields
.select_item
then
1017 if minetest
.get_modpath("select_item") then
1018 if sendername
== owner
then
1019 active_item_selection
[sendername
] = pos
1020 select_item
.show_dialog(sendername
, "easyvend:trade_item", select_item
.filters
.creative
)
1022 meta
:set_string("message", S("Only the owner may change the configuration."))
1023 easyvend
.sound_error(sendername
)
1024 easyvend
.set_formspec(pos
, sender
)
1028 elseif fields
.wear
~= nil then
1029 if sender
:get_player_name() == owner
then
1030 if fields
.wear
== "true" then
1031 if easyvend
.buysell(node
.name
) == "buy" then
1032 meta
:set_string("message", S("Used tools are now accepted."))
1034 meta
:set_string("message", S("Used tools are now for sale."))
1036 meta
:set_int("wear", 1)
1037 elseif fields
.wear
== "false" then
1038 if easyvend
.buysell(node
.name
) == "buy" then
1039 meta
:set_string("message", S("Used tools are now rejected."))
1041 meta
:set_string("message", S("Used tools wonāt be sold anymore."))
1043 meta
:set_int("wear", 0)
1045 easyvend
.set_formspec(pos
, sender
)
1048 meta
:set_string("message", S("Only the owner may change the configuration."))
1049 easyvend
.sound_error(sendername
)
1050 easyvend
.set_formspec(pos
, sender
)
1053 elseif fields
.buysell
then
1054 easyvend
.on_receive_fields_buysell(pos
, formname
, fields
, sender
)
1058 -- Jokes: Appear when machine exchanges currency for currency at equal rate
1061 local jokes_vendor
= {
1062 S("Thank you. You have made a vending machine very happy."),
1063 S("Humans have a strange sense of humor."),
1064 S("Letās get this over with ā¦"),
1065 S("Item āboughtā."),
1067 S("Do you realize what youāve just bought?"),
1070 local jokes_depositor
= {
1071 S("Thank you, the money started to smell inside."),
1072 S("Money doesnāt grow on trees, you know?"),
1074 S("Well, that was an awkward exchange."),
1075 S("Are you having fun?"),
1076 S("Is this really trading?"),
1079 easyvend
.assign_joke
= function(buysell
)
1081 if buysell
== "sell" then
1082 jokes
= jokes_vendor
1083 elseif buysell
== "buy" then
1084 jokes
= jokes_depositor
1086 local r
= math
.random(1,#jokes
)
1090 easyvend
.get_joke
= function(buysell
, id
)
1092 if buysell
== nil or id
== nil then
1093 -- Fallback message (should never happen)
1094 return S("Items exchanged.")
1096 if buysell
== "sell" then
1097 joke
= jokes_vendor
[id
]
1098 if joke
== nil then joke
= jokes_vendor
[1] end
1099 elseif buysell
== "buy" then
1100 joke
= jokes_depositor
[id
]
1101 if joke
== nil then joke
= jokes_depositor
[1] end
1106 easyvend
.sound_error
= function(playername
)
1107 minetest
.sound_play("easyvend_error", {to_player
= playername
, gain
= 0.25}, true)
1110 easyvend
.sound_setup
= function(pos
)
1111 minetest
.sound_play("easyvend_activate", {pos
= pos
, gain
= 0.5, max_hear_distance
= 12,}, true)
1114 easyvend
.sound_disable
= function(pos
)
1115 minetest
.sound_play("easyvend_disable", {pos
= pos
, gain
= 0.9, max_hear_distance
= 12,}, true)
1118 easyvend
.sound_vend
= function(pos
)
1119 minetest
.sound_play("easyvend_vend", {pos
= pos
, gain
= 0.4, max_hear_distance
= 5,}, true)
1122 easyvend
.sound_deposit
= function(pos
)
1123 minetest
.sound_play("easyvend_deposit", {pos
= pos
, gain
= 0.4, max_hear_distance
= 5,}, true)
1126 --[[ Tower building ]]
1128 easyvend
.is_traversable
= function(pos
)
1129 local node
= minetest
.get_node_or_nil(pos
)
1130 if (node
== nil) then
1133 return traversable_node_types
[node
.name
] == true
1136 easyvend
.neighboring_nodes
= function(pos
)
1138 {x
=pos
.x
, y
=pos
.y
-1, z
=pos
.z
},
1139 {x
=pos
.x
, y
=pos
.y
+1, z
=pos
.z
},
1143 if easyvend
.is_traversable(check
[i
]) then
1144 table.insert(trav
, check
[i
])
1150 easyvend
.find_connected_chest
= function(owner
, pos
, nodename
, check_wear
, amount
, removing
)
1151 local nodes
= easyvend
.neighboring_nodes(pos
)
1153 if (#nodes
< 1 or #nodes
> 2) then
1154 return nil, "no_chest"
1157 -- Find the stack direction
1161 if ( first
== nil ) then
1168 local chest_pos
, chest_internal
1170 if (first
~= nil and second
~= nil) then
1171 local dy
= (first
.y
- second
.y
)/2
1172 chest_pos
, chest_internal
= easyvend
.find_chest(owner
, pos
, dy
, nodename
, check_wear
, amount
, removing
)
1173 if ( chest_pos
== nil ) then
1174 chest_pos
, chest_internal
= easyvend
.find_chest(owner
, pos
, -dy
, nodename
, check_wear
, amount
, removing
, chest_internal
)
1177 local dy
= first
.y
- pos
.y
1178 chest_pos
, chest_internal
= easyvend
.find_chest(owner
, pos
, dy
, nodename
, check_wear
, amount
, removing
)
1181 if chest_internal
.chests
== 0 then
1182 return nil, "no_chest"
1183 elseif chest_internal
.chests
== chest_internal
.other_chests
then
1184 return nil, "not_owned"
1185 elseif removing
and chest_internal
.stock
< 1 then
1186 return nil, "no_stock"
1187 elseif not removing
and chest_internal
.space
< 1 then
1188 return nil, "no_space"
1189 elseif chest_pos
~= nil then
1192 return nil, "unknown"
1196 easyvend
.find_chest
= function(owner
, pos
, dy
, itemname
, check_wear
, amount
, removing
, internal
)
1197 pos
= {x
=pos
.x
, y
=pos
.y
+ dy
, z
=pos
.z
}
1199 if internal
== nil then
1202 internal
.other_chests
= 0
1207 local node
= minetest
.get_node_or_nil(pos
)
1208 if ( node
== nil ) then
1209 return nil, internal
1211 local chestdef
= registered_chests
[node
.name
]
1212 if (chestdef
~= nil) then
1213 internal
.chests
= internal
.chests
+ 1
1214 local meta
= minetest
.get_meta(pos
)
1215 if (owner
~= meta
:get_string(chestdef
.meta_owner
)) then
1216 internal
.other_chests
= internal
.other_chests
+ 1
1217 return nil, internal
1219 local inv
= meta
:get_inventory()
1220 if (inv
~= nil) then
1221 if (itemname
~= nil and minetest
.registered_items
[itemname
] and amount
~= nil and removing
~= nil and check_wear
~= nil) then
1222 local chest_has
, chest_free
1223 local stack
= {name
=itemname
, count
=amount
, wear
=0, metadata
=""}
1224 local stack_max
= minetest
.registered_items
[itemname
].stack_max
1226 local stacks
= math
.modf(amount
/ stack_max
)
1227 local stacksremainder
= math
.fmod(amount
, stack_max
)
1229 if stacksremainder
> 0 then free
= free
+ 1 end
1231 chest_has
= easyvend
.check_and_get_items(inv
, chestdef
.inv_list
, stack
, check_wear
)
1233 internal
.stock
= internal
.stock
+ 1
1235 chest_free
= inv
:room_for_item(chestdef
.inv_list
, stack
) and easyvend
.free_slots(inv
, chestdef
.inv_list
) >= free
1237 internal
.space
= internal
.space
+ 1
1240 if (removing
and internal
.stock
== 0) or (not removing
and internal
.space
== 0) then
1241 return easyvend
.find_chest(owner
, pos
, dy
, itemname
, check_wear
, amount
, removing
, internal
)
1243 return pos
, internal
1246 return nil, internal
1249 return nil, internal
1251 elseif not easyvend
.is_machine(node
.name
) then
1252 return nil, internal
1255 return easyvend
.find_chest(owner
, pos
, dy
, itemname
, check_wear
, amount
, removing
, internal
)
1258 -- Pseudo-inventory handling
1259 easyvend
.allow_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
1260 if listname
=="item" then
1261 local meta
= minetest
.get_meta(pos
);
1262 local owner
= meta
:get_string("owner")
1263 local name
= player
:get_player_name()
1264 if name
== owner
then
1265 local inv
= meta
:get_inventory()
1266 if stack
== nil then
1267 inv
:set_stack( "item", 1, nil )
1269 inv
:set_stack( "item", 1, stack
:get_name() )
1270 meta
:set_string("itemname", stack
:get_name())
1271 easyvend
.set_formspec(pos
, player
)
1278 easyvend
.allow_metadata_inventory_take
= function(pos
, listname
, index
, stack
, player
)
1282 easyvend
.allow_metadata_inventory_move
= function(pos
, from_list
, from_index
, to_list
, to_index
, count
, player
)
1286 minetest
.register_abm({
1287 nodenames
= {"easyvend:vendor", "easyvend:vendor_on", "easyvend:depositor", "easyvend:depositor_on"},
1291 action
= function(pos
, node
, active_object_count
, active_object_count_wider
)
1292 easyvend
.machine_check(pos
, node
)
1296 -- Legacy support for vendor mod:
1297 -- Transform the world and items to use the easyvend nodes/items
1299 -- For safety reasons, only do this when player requested so
1300 if minetest
.settings
:get_bool("easyvend_convert_vendor") == true then
1301 -- Replace vendor nodes
1302 minetest
.register_lbm({
1303 name
= "easyvend:replace_vendor",
1304 nodenames
= { "vendor:vendor", "vendor:depositor" },
1305 run_at_every_load
= true,
1306 action
= function(pos
, node
)
1309 if node
.name
== "vendor:vendor" then
1310 newnodename
= "easyvend:vendor"
1311 elseif node
.name
== "vendor:depositor" then
1312 newnodename
= "easyvend:depositor"
1314 -- Remove axis rotation; only allow 4 facedirs
1315 local p2
= math
.fmod(node
.param2
, 4)
1316 minetest
.swap_node(pos
, { name
= newnodename
, param2
= p2
})
1318 -- Initialize metadata
1319 local meta
= minetest
.get_meta(pos
)
1320 if node
.name
== "vendor:vendor" then
1321 meta
:set_int("earnings", 0)
1323 meta
:set_int("stock", -1)
1324 meta
:set_int("joketimer", -1)
1325 meta
:set_int("joke_id", 1)
1326 local inv
= meta
:get_inventory()
1327 inv
:set_size("item", 1)
1328 inv
:set_size("gold", 1)
1329 inv
:set_stack("gold", 1, easyvend
.currency
)
1331 -- In vendor, all machines accepted worn tools
1332 meta
:set_int("wear", 1)
1335 local itemname
= meta
:get_string("itemname")
1336 if itemname
== "" or itemname
== nil then
1337 itemname
= meta
:get_string("itemtype")
1339 if itemname
~= "" and itemname
~= nil then
1340 inv
:set_stack("item", 1, itemname
)
1341 meta
:set_string("itemname", itemname
)
1344 -- Check for valid item, item count and price
1345 local configmode
= 1
1346 if itemname
~= "" and itemname
~= nil then
1347 local itemstack
= inv
:get_stack("item", 1)
1348 local number_stack_max
= itemstack
:get_stack_max()
1349 local maxnumber
= number_stack_max
* slots_max
1350 local cost
= meta
:get_int("cost")
1351 local number = meta
:get_int("number")
1352 if number >= 1 and number <= maxnumber
and cost
>= 1 and cost
<= maxcost
then
1353 -- Everything's OK, get out of config mode!
1358 -- Final initialization stuff
1359 meta
:set_int("configmode", configmode
)
1361 local owner
= meta
:get_string("owner")
1362 if easyvend
.buysell(newnodename
) == "sell" then
1363 meta
:set_string("infotext", S("Vending machine (owned by @1)", owner
))
1365 meta
:set_string("infotext", S("Depositing machine (owned by @1)", owner
))
1369 meta
:set_string("status", S("Initializing ā¦"))
1370 meta
:set_string("message", S("Upgrade successful."))
1371 easyvend
.machine_check(pos
, node
)