exchange.lua 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. if not minetest.global_exists("exchange") then exchange = {} end
  2. exchange.modpath = minetest.get_modpath("easyvend")
  3. -- Note: exchange rate is doubled because only lumps are accepted now, not ingots.
  4. -- (Previously most folks would double their ingots before exchanging them.)
  5. -- Note: must not include infinitely-renewable commodities, like mese.
  6. --
  7. -- WARNING: do not include many exchange types. This makes certain kinds of
  8. -- exploits easier (e.g., abusing the exchange to simply transform one kind of
  9. -- item into another).
  10. exchange.types = {
  11. {name = "Gold", key = "gold", rate = 60, image = "default_gold_lump.png", item = "default:gold_lump", block = "default:goldblock"},
  12. {name = "Silver", key = "silver", rate = 50, image = "moreores_silver_lump.png", item = "moreores:silver_lump", block = "moreores:silver_block"},
  13. }
  14. for k, v in ipairs(exchange.types) do
  15. local function update_meta(pos)
  16. local meta = minetest.get_meta(pos)
  17. meta:set_string("infotext",
  18. v.name .. " Commodity Exchange\nPunch to exchange " .. v.key ..
  19. " for MG\nHold shift to get " .. v.key .. " (paying MG)\nSell 1 " .. v.key .. " lump for " .. v.rate .. " MG, buy 1 for " .. v.rate + 10 .. " MG" ..
  20. "\nHold 'E' to multiply x10")
  21. end
  22. exchange["on_punch_" .. v.key] = function(pos, node, puncher, pt)
  23. update_meta(pos)
  24. local pname = puncher:get_player_name()
  25. local inv = puncher:get_inventory()
  26. local altact = puncher:get_player_control().sneak
  27. local mult = puncher:get_player_control().aux1
  28. -- Must be in city and protected.
  29. if not (city_block:in_city(pos) and minetest.test_protection(pos, "")) then
  30. minetest.chat_send_player(pname, "# Server: You cannot exchange for minegeld outside any city or village.")
  31. return
  32. end
  33. local rate = v.rate
  34. -- If player is buying ore, the price is 10 units higher.
  35. -- The price-differential between buying and selling discourages abuse.
  36. if altact then
  37. rate = rate + 10
  38. end
  39. local item = ItemStack(v.item)
  40. item:set_count(1)
  41. if mult then
  42. rate = v.rate * 10
  43. item:set_count(10)
  44. end
  45. if altact then
  46. -- Take money, give player ore.
  47. local cash = currency.tell(pname)
  48. if cash >= rate then
  49. local safe = currency.safe_to_remove_cash(inv, "main", rate)
  50. local itemstack = ItemStack(item)
  51. if inv:room_for_item("main", itemstack) and safe then
  52. currency.remove(pname, rate)
  53. local leftover = inv:add_item("main", itemstack)
  54. local rem = currency.tell(pname)
  55. minetest.chat_send_player(pname, "# Server: Commodity exchanged: you receive " .. item:get_count() .. " " .. v.key .. " lump(s) for " .. rate .. " MG. You now have " .. rem .. " MG.")
  56. if leftover:get_count() > 0 then
  57. minetest.item_drop(leftover, puncher, puncher:get_pos())
  58. end
  59. easyvend.sound_vend(pos)
  60. else
  61. minetest.chat_send_player(pname, "# Server: Not enough room in your inventory to receive commodity.")
  62. end
  63. else
  64. minetest.chat_send_player(pname, "# Server: You don't have enough MG to exchange for a commodity.")
  65. end
  66. else
  67. -- Take ore, give player money.
  68. if inv:contains_item("main", item) then
  69. if currency.room(pname, rate) then
  70. currency.add(pname, rate)
  71. inv:remove_item("main", item)
  72. local cash = currency.tell(pname)
  73. minetest.chat_send_player(pname, "# Server: Commodity exchanged: you receive " .. rate .. " minegeld. You now have " .. cash .. " MG.")
  74. easyvend.sound_deposit(pos)
  75. else
  76. local cash = currency.tell(pname)
  77. minetest.chat_send_player(pname, "# Server: Not enough room in your inventory. You currently have " .. cash .. " MG.")
  78. end
  79. else
  80. local cash = currency.tell(pname)
  81. minetest.chat_send_player(pname, "# Server: You don't have enough unrefined " .. v.key .. ". You currently have " .. cash .. " MG.")
  82. end
  83. end
  84. end
  85. exchange["on_construct_" .. v.key] = function(pos, node, puncher, pt)
  86. update_meta(pos)
  87. end
  88. exchange["on_update_infotext_" .. v.key] = function(pos)
  89. update_meta(pos)
  90. end
  91. end
  92. if not exchange.run_once then
  93. minetest.register_alias("exchange:kiosk_mese", "exchange:kiosk_gold")
  94. minetest.register_alias("exchange:kiosk_copper", "exchange:kiosk_gold")
  95. minetest.register_alias("exchange:kiosk_iron", "exchange:kiosk_gold")
  96. minetest.register_alias("exchange:kiosk_coal", "exchange:kiosk_gold")
  97. minetest.register_alias("exchange:kiosk_pearl", "exchange:kiosk_gold")
  98. minetest.register_alias("exchange:kiosk_rack", "exchange:kiosk_gold")
  99. for k, v in ipairs(exchange.types) do
  100. minetest.register_node(":exchange:kiosk_" .. v.key, {
  101. description = v.name .. " Commodity Exchange\n\nPunch to obtain MG in exchange for commodities.\nShift-punch to redeem commodities for money.\nHold 'E' to multiply exchange by 10.",
  102. tiles = {
  103. "easyvend_vendor_side.png^" .. v.image,
  104. "easyvend_vendor_side.png",
  105. "easyvend_ad_booth.png",
  106. "easyvend_ad_booth.png",
  107. "easyvend_ad_booth.png",
  108. "easyvend_ad_booth.png",
  109. },
  110. paramtype2 = "facedir",
  111. groups = utility.dig_groups("furniture", {flammable = 2}),
  112. sounds = default.node_sound_wood_defaults(),
  113. on_construct = function(pos, node, puncher, pt)
  114. (exchange["on_construct_" .. v.key])(pos, node, puncher, pt)
  115. end,
  116. on_punch = function(pos, node, puncher, pt)
  117. (exchange["on_punch_" .. v.key])(pos, node, puncher, pt)
  118. end,
  119. _on_update_infotext = function(pos, node, puncher, pt)
  120. (exchange["on_update_infotext_" .. v.key])(pos)
  121. end,
  122. })
  123. end
  124. for k, v in ipairs(exchange.types) do
  125. minetest.register_craft({
  126. output = "exchange:kiosk_" .. v.key,
  127. recipe = {
  128. {'', 'passport:passport_adv', ''},
  129. {"market:booth", "voidchest:voidchest_closed", v.block},
  130. {'', v.block, ''},
  131. },
  132. })
  133. end
  134. local c = "exchange:core"
  135. local f = exchange.modpath .. "/exchange.lua"
  136. reload.register_file(c, f, false)
  137. exchange.run_once = true
  138. end