commoditymarket-cd2025/default_markets.lua
2019-07-30 19:09:08 -06:00

376 lines
17 KiB
Lua

local default_modpath = minetest.get_modpath("default")
if not default_modpath then return end
local gold_coins_required = false
local default_items = {"default:axe_bronze","default:axe_diamond","default:axe_mese","default:axe_steel","default:axe_steel","default:axe_stone","default:axe_wood","default:pick_bronze","default:pick_diamond","default:pick_mese","default:pick_steel","default:pick_stone","default:pick_wood","default:shovel_bronze","default:shovel_diamond","default:shovel_mese","default:shovel_steel","default:shovel_stone","default:shovel_wood","default:sword_bronze","default:sword_diamond","default:sword_mese","default:sword_steel","default:sword_stone","default:sword_wood", "default:blueberries", "default:book", "default:bronze_ingot", "default:clay_brick", "default:clay_lump", "default:coal_lump", "default:copper_ingot", "default:copper_lump", "default:diamond", "default:flint", "default:gold_ingot", "default:gold_lump", "default:iron_lump", "default:mese_crystal", "default:mese_crystal_fragment", "default:obsidian_shard", "default:paper", "default:steel_ingot", "default:stick", "default:tin_ingot", "default:tin_lump", "default:acacia_tree", "default:acacia_wood", "default:apple", "default:aspen_tree", "default:aspen_wood", "default:blueberry_bush_sapling", "default:bookshelf", "default:brick", "default:bronzeblock", "default:bush_sapling", "default:cactus", "default:clay", "default:coalblock", "default:cobble", "default:copperblock", "default:desert_cobble", "default:desert_sand", "default:desert_sandstone", "default:desert_sandstone_block", "default:desert_sandstone_brick", "default:desert_stone", "default:desert_stone_block", "default:desert_stonebrick", "default:diamondblock", "default:dirt", "default:glass", "default:goldblock", "default:gravel", "default:ice", "default:junglegrass", "default:junglesapling", "default:jungletree", "default:junglewood", "default:ladder_steel", "default:ladder_wood", "default:large_cactus_seedling", "default:mese", "default:mese_post_light", "default:meselamp", "default:mossycobble", "default:obsidian", "default:obsidian_block", "default:obsidian_glass", "default:obsidianbrick", "default:papyrus", "default:pine_sapling", "default:pine_tree", "default:pine_wood", "default:sand", "default:sandstone", "default:sandstone_block", "default:sandstonebrick", "default:sapling", "default:silver_sand", "default:silver_sandstone", "default:silver_sandstone_block", "default:silver_sandstone_brick", "default:snow", "default:snowblock", "default:steelblock", "default:stone", "default:stone_block", "default:stonebrick", "default:tinblock", "default:tree", "default:wood",}
------------------------------------------------------------------------------
-- King's Market
if minetest.settings:get_bool("commoditymarket_enable_kings_market") then
local kings_def = {
description = "King's Market",
long_description = "The largest and most accessible market for the common man, the King's Market uses gold coins as its medium of exchange (or the equivalent in gold ingots - 1000 coins to the ingot). However, as a respectable institution of the surface world, the King's Market operates only during the hours of daylight. The purchase and sale of swords and explosives is prohibited in the King's Market.",
currency = {
["default:gold_ingot"] = 1000,
["commoditymarket:gold_coins"] = 1
},
currency_symbol = "\u{263C}", -- Alchemical symbol for gold
allow_item = function(item)
if item:sub(1,13) == "default:sword" or item:sub(1,4) == "tnt:" then
return false
end
return true
end,
inventory_limit = 100000,
--sell_limit =, -- no sell limit for the King's Market
initial_items = default_items,
}
gold_coins_required = true
commoditymarket.register_market("kings", kings_def)
minetest.register_node("commoditymarket:kings_market", {
description = "King's Market",
_doc_items_longdesc = "",
tiles = {"default_chest_top.png","default_chest_top.png",
"default_chest_side.png","default_chest_side.png",
"commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_crown.png",},
paramtype2 = "facedir",
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
sounds = default.node_sound_wood_defaults(),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local timeofday = minetest.get_timeofday()
if timeofday > 0.2 and timeofday < 0.8 then
commoditymarket.show_market("kings", clicker:get_player_name())
else
minetest.chat_send_player(clicker:get_player_name(), "At this time of day the King's Market is closed.")
end
end,
can_dig = function(pos, player)
if player and minetest.check_player_privs(player, "server") then
return true
end
return false
end,
})
end
-------------------------------------------------------------------------------
-- Night Market
if minetest.settings:get_bool("commoditymarket_enable_night_market") then
local night_def = {
description = "Night Market",
long_description = "When the sun sets and the stalls of the King's Market close, other vendors are just waking up to share their wares. The Night Market is not as voluminous as the King's Market but accepts a wider range of wares. It accepts the same gold coinage of the realm.",
currency = {
["default:gold_ingot"] = 1000,
["commoditymarket:gold_coins"] = 1
},
currency_symbol = "\u{263C}",
inventory_limit = 10000,
--sell_limit =, -- no sell limit for the Night Market
initial_items = default_items,
}
gold_coins_required = true
commoditymarket.register_market("night", night_def)
minetest.register_node("commoditymarket:night_market", {
description = night_def.description,
_doc_items_longdesc = night_def.long_description,
tiles = {"default_chest_top.png","default_chest_top.png",
"default_chest_side.png","default_chest_side.png",
"commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_moon.png",},
paramtype2 = "facedir",
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
sounds = default.node_sound_wood_defaults(),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local timeofday = minetest.get_timeofday()
if timeofday < 0.2 or timeofday > 0.8 then
commoditymarket.show_market("night", clicker:get_player_name())
else
minetest.chat_send_player(clicker:get_player_name(), "At this time of day the Night Market is closed.")
end
end,
can_dig = function(pos, player)
if player and minetest.check_player_privs(player, "server") then
return true
end
return false
end,
})
end
-------------------------------------------------------------------------------
if minetest.settings:get_bool("commoditymarket_enable_caravan_market", true) then
-- "Trader's Caravan" - small-capacity market that players can summon
local time_until_caravan = 120 -- caravan arrives in two minutes
local dwell_time = 600 -- caravan leaves ten minutes after last usage
local caravan_def = {
description = "Trader's Caravan",
long_description = "Unlike most markets that have well-known fixed locations that travelers congregate to, the network of Trader's Caravans is fluid and dynamic in their locations. A Trader's Caravan can show up anywhere, make modest trades, and then be gone the next time you visit them. These caravans accept gold and gold coins as a currency.",
currency = {
["default:gold_ingot"] = 1000,
["commoditymarket:gold_coins"] = 1
},
currency_symbol = "\u{263C}",
inventory_limit = 1000,
sell_limit = 1000,
initial_items = default_items,
}
gold_coins_required = true
minetest.register_craft({
output = "commoditymarket:caravan_post",
recipe = {
{'group:wood', 'group:wood', ''},
{'group:wood', "default:gold_ingot", ''},
{'group:wood', "default:chest_locked", ''},
}
})
commoditymarket.register_market("caravan", caravan_def)
minetest.register_node("commoditymarket:caravan_market", {
description = "Trader's Caravan",
_doc_items_longdesc = caravan_def.long_description,
tiles = {"default_chest_top.png","default_chest_top.png",
"default_chest_side.png^commoditymarket_caravan.png","default_chest_side.png^commoditymarket_caravan.png",
"commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_trade.png",},
paramtype2 = "facedir",
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_wood_defaults(),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
commoditymarket.show_market("caravan", clicker:get_player_name())
local timer = minetest.get_node_timer(pos)
timer:start(dwell_time)
end,
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
local facedir = node.param2
local dir = minetest.facedir_to_dir(facedir)
local target = vector.add(pos, vector.multiply(dir,-2))
local target_node = minetest.get_node(target)
if target_node.name == "commoditymarket:caravan_post" then
local meta = minetest.get_meta(target)
meta:set_string("infotext", "Right-click to summon another caravan")
end
minetest.set_node(pos, {name="air"})
minetest.sound_play("commoditymarket_register_closed", {
pos = pos,
gain = 1.0, -- default
max_hear_distance = 32, -- default, uses an euclidean metric
})
end,
})
-- This one doesn't delete itself, server admins can place a permanent instance of it that way. Maybe inside towns next to bigger stationary markets.
minetest.register_node("commoditymarket:caravan_market_permanent", {
description = "Trader's Caravan",
_doc_items_longdesc = caravan_def.long_description,
tiles = {"default_chest_top.png","default_chest_top.png",
"default_chest_side.png^commoditymarket_caravan.png","default_chest_side.png^commoditymarket_caravan.png",
"commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_trade.png",},
paramtype2 = "facedir",
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
sounds = default.node_sound_wood_defaults(),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
commoditymarket.show_market("caravan", clicker:get_player_name())
end,
})
-- is a 3x3 area centered around pos clear of obstruction and has usable ground?
local is_suitable_caravan_space = function(pos)
-- walkable ground?
for x = pos.x - 1, pos.x + 1, 1 do
for z = pos.z - 1, pos.z + 1, 1 do
local node = minetest.get_node({x=x, y=pos.y-1, z=z})
local node_def = minetest.registered_nodes[node.name]
if node_def == nil or node_def.walkable ~= true then return false end
end
end
-- air in the rest?
for y = pos.y, pos.y+2, 1 do
for x = pos.x - 1, pos.x + 1, 1 do
for z = pos.z - 1, pos.z + 1, 1 do
local node = minetest.get_node({x=x, y=y, z=z})
if node.name ~= "air" then return false end
end
end
end
return true
end
minetest.register_node("commoditymarket:caravan_post", {
description = "Trading Post",
_long_items_longdesc = "This post signals passing caravan traders that customers can be found here, and signals to customers that caravan traders can be found here. If no caravan is present, right-click to summon one.",
tiles = {"commoditymarket_sign.png^[transformR90", "commoditymarket_sign.png^[transformR270",
"commoditymarket_sign.png^commoditymarket_caravan_sign.png", "commoditymarket_sign.png^commoditymarket_caravan_sign.png^[transformFX",
"commoditymarket_sign_post.png", "commoditymarket_sign_post.png"},
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
sounds = default.node_sound_wood_defaults(),
paramtype= "light",
paramtype2 = "facedir",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-0.125,-0.5,-0.5,0.125,2.0625,-0.25},
{-0.0625,1.4375,-0.25,0.0625,2.0,0.5},
},
},
on_construct = function(pos)
local timer = minetest.get_node_timer(pos)
timer:start(1.0)
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local timer = minetest.get_node_timer(pos)
timer:start(1.0)
end,
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
if node.name ~= "commoditymarket:caravan_post" then
return -- the node was removed
end
local facedir = node.param2
local dir = minetest.facedir_to_dir(facedir)
local target = vector.add(pos, vector.multiply(dir,2))
local target_node = minetest.get_node(target)
if target_node.name == "commoditymarket:caravan_market" then
-- It's already here somehow, shut down timer.
meta:set_string("infotext", "")
meta:set_float("wait_time", 0)
return
end
local is_suitable_space = is_suitable_caravan_space(target)
if not is_suitable_space then
meta:set_string("infotext", "Indicated parking area isn't suitable.\nA 3x3 open space with solid ground\nis required for a caravan.")
meta:set_float("wait_time", 0)
local timer = minetest.get_node_timer(pos)
timer:start(1.0)
return
end
local wait_time = (meta:get_float("wait_time") or 0) + elapsed
meta:set_float("wait_time", wait_time)
if wait_time < time_until_caravan then
meta:set_string("infotext", "Caravan summoned\nETA: " .. math.floor(time_until_caravan - wait_time) .. " seconds.")
local timer = minetest.get_node_timer(pos)
timer:start(1.0)
return
end
-- spawn the caravan. We've already established that the target pos is clear.
minetest.set_node(target, {name="commoditymarket:caravan_market", param2=facedir})
minetest.sound_play("commoditymarket_register_opened", {
pos = target,
gain = 1.0, -- default
max_hear_distance = 32, -- default, uses an euclidean metric
})
local timer = minetest.get_node_timer(target)
timer:start(dwell_time)
meta:set_string("infotext", "")
meta:set_float("wait_time", 0)
end,
})
end
-------------------------------------------------------------------------------
-- "Goblin Exchange"
if minetest.settings:get_bool("commoditymarket_enable_goblin_market") then
local goblin_def = {
description = "Goblin Exchange",
long_description = "One does not usually associate Goblins with the sort of sophistication that running a market requires. Usually one just associates Goblins with savagery and violence. But they understand the principle of tit-for-tat exchange, and if approached correctly they actually respect the concepts of ownership and debt. However, for some peculiar reason they understand this concept in the context of coal lumps. Goblins deal in the standard coal lump as their form of currency, conceptually divided into 100 coal centilumps (though Goblin brokers prefer to \"keep the change\" when giving back actual coal lumps).",
currency = {
["default:coal_lump"] = 100
},
currency_symbol = "\u{00A2}",
inventory_limit = 1000,
--sell_limit =, -- no sell limit
}
commoditymarket.register_market("goblin", goblin_def)
minetest.register_node("commoditymarket:goblin_market", {
description = goblin_def.description,
_doc_items_longdesc = goblin_def.long_description,
tiles = {"default_chest_top.png","default_chest_top.png",
"default_chest_side.png","default_chest_side.png",
"commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_goblin.png",},
paramtype2 = "facedir",
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
sounds = default.node_sound_wood_defaults(),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
commoditymarket.show_market("goblin", clicker:get_player_name())
end,
can_dig = function(pos, player)
if player and minetest.check_player_privs(player, "server") then
return true
end
return false
end,
})
end
--------------------------------------------------------------------------------
if minetest.settings:get_bool("commoditymarket_enable_under_market") then
local undermarket_def = {
description = "Undermarket",
long_description = "Deep in the bowels of the world, below even the goblin-infested warrens and ancient delvings of the dwarves, dark and mysterious beings once dwelled. A few still linger to this day, and facilitate barter for those brave souls willing to travel in their lost realms. The Undermarket uses Mese chips as a currency - twenty chips to the Mese fragment. Though traders are loathe to physically break Mese crystals up into units that small, as it renders it useless for other purposes.",
currency = {
["default:mese"] = 9*9*20,
["default:mese_crystal"] = 9*20,
["default:mese_crystal_fragment"] = 20
},
currency_symbol = "\u{20A5}",
inventory_limit = 10000,
--sell_limit =, -- no sell limit
}
commoditymarket.register_market("under", undermarket_def)
minetest.register_node("commoditymarket:under_market", {
description = undermarket_def.description,
_doc_items_longdesc = undermarket_def.long_description,
tiles = {"commoditymarket_under_top.png","commoditymarket_under_top.png",
"commoditymarket_under.png","commoditymarket_under.png","commoditymarket_under.png","commoditymarket_under.png"},
paramtype2 = "facedir",
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
sounds = default.node_sound_stone_defaults(),
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
commoditymarket.show_market("under", clicker:get_player_name())
end,
can_dig = function(pos, player)
if player and minetest.check_player_privs(player, "server") then
return true
end
return false
end,
})
end
------------------------------------------------------------------
if gold_coins_required then
minetest.register_craftitem("commoditymarket:gold_coins", {
description = "Gold Coins",
inventory_image = "commoditymarket_gold_coins.png",
stack_max = 1000,
})
end