294 lines
12 KiB
Lua
294 lines
12 KiB
Lua
if not minetest.settings:get_bool("commoditymarket_enable_caravan_market", true) then
|
|
return
|
|
end
|
|
|
|
local S = commoditymarket_fantasy.S
|
|
local coins_per_ingot = commoditymarket_fantasy.coins_per_ingot
|
|
local default_items = commoditymarket_fantasy.default_items
|
|
local gold_ingot = commoditymarket_fantasy.gold_ingot
|
|
local gold_currency = commoditymarket_fantasy.gold_currency
|
|
local chest_locked = commoditymarket_fantasy.chest_locked
|
|
local wood_sounds = commoditymarket_fantasy.wood_sounds
|
|
local usage_help = commoditymarket_fantasy.usage_help
|
|
|
|
commoditymarket_fantasy.register_gold_coins()
|
|
|
|
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 = S("Trader's Caravan"),
|
|
long_description = S("Unlike most markets that have well-known fixed locations that travellers 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 (one gold ingot to @1 gold coins exchange rate). Any reasonably-wealthy person can create a signpost marking a location where Trader's Caravans will make a stop.", coins_per_ingot),
|
|
currency = gold_currency,
|
|
currency_symbol = "☼", --"\u{263C}"
|
|
inventory_limit = 1000,
|
|
sell_limit = 1000,
|
|
initial_items = default_items,
|
|
}
|
|
|
|
minetest.register_craft({
|
|
output = "commoditymarket_fantasy:caravan_post",
|
|
recipe = {
|
|
{'group:wood', 'group:wood', ''},
|
|
{'group:wood', gold_ingot, ''},
|
|
{'group:wood', chest_locked, ''},
|
|
}
|
|
})
|
|
|
|
commoditymarket.register_market("caravan", caravan_def)
|
|
|
|
local caravan_nodebox = {
|
|
type = "fixed",
|
|
fixed = {
|
|
-- Note: this nodebox should have a height of 1.5, but using 95/64 as a workaround for
|
|
-- https://github.com/minetest/minetest/issues/9322
|
|
{-0.75, -0.5, -1.25, 0.75, 95/64, 1.25},
|
|
},
|
|
}
|
|
|
|
|
|
local create_caravan_def = function(override_table)
|
|
local def = {
|
|
description = caravan_def.description,
|
|
_doc_items_longdesc = caravan_def.long_description,
|
|
_doc_items_usagehelp = usage_help,
|
|
drawtype = "mesh",
|
|
mesh = "commoditymarket_wagon.obj",
|
|
tiles = {
|
|
{ name = "commoditymarket_door_wood.png", backface_culling = true }, -- door
|
|
{ name = "default_wood.png", backface_culling = true }, -- base wood
|
|
{ name = "commoditymarket_default_fence_rail_wood.png", backface_culling = true }, -- wheel sides
|
|
{ name = "default_coal_block.png", backface_culling = true }, -- wheel tyre
|
|
{ name = "commoditymarket_shingles_wood.png", backface_culling = true }, -- roof
|
|
{ name = "default_junglewood.png", backface_culling = true }, -- corner wood
|
|
},
|
|
collision_box = caravan_nodebox,
|
|
selection_box = caravan_nodebox,
|
|
|
|
paramtype2 = "facedir",
|
|
drop = "",
|
|
groups = {choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1},
|
|
sounds = wood_sounds,
|
|
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,
|
|
after_destruct = function(pos, oldnode)
|
|
local facedir = oldnode.param2
|
|
local dir = minetest.facedir_to_dir(facedir)
|
|
local target = vector.add(pos, vector.multiply(dir,-3))
|
|
local target_node = minetest.get_node(target)
|
|
if target_node.name == "commoditymarket_fantasy:caravan_post" then
|
|
local meta = minetest.get_meta(target)
|
|
meta:set_string("infotext", S("Right-click to summon a trader's caravan"))
|
|
end
|
|
end,
|
|
on_timer = function(pos, elapsed)
|
|
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,
|
|
}
|
|
if override_table then
|
|
for k, v in pairs(override_table) do
|
|
def[k] = v
|
|
end
|
|
end
|
|
return def
|
|
end
|
|
|
|
-- Create five caravans with different textures, randomly pick which one shows up.
|
|
minetest.register_node("commoditymarket_fantasy:caravan_market_1", create_caravan_def())
|
|
minetest.register_node("commoditymarket_fantasy:caravan_market_2", create_caravan_def({
|
|
tiles = {
|
|
{ name = "commoditymarket_door_wood.png^[multiply:#CCCCFF", backface_culling = true }, -- door
|
|
{ name = "default_acacia_wood.png", backface_culling = true }, -- base wood
|
|
{ name = "commoditymarket_default_fence_rail_wood.png", backface_culling = true }, -- wheel sides
|
|
{ name = "commoditymarket_default_copper_block.png", backface_culling = true }, -- wheel tyre
|
|
{ name = "commoditymarket_shingles_wood.png^[multiply:#CC8888", backface_culling = true }, -- roof
|
|
{ name = "default_wood.png", backface_culling = true }, -- corner wood
|
|
}
|
|
}))
|
|
minetest.register_node("commoditymarket_fantasy:caravan_market_3", create_caravan_def({
|
|
tiles = {
|
|
{ name = "commoditymarket_door_wood.png", backface_culling = true }, -- door
|
|
{ name = "commoditymarket_default_aspen_wood.png", backface_culling = true }, -- base wood
|
|
{ name = "commoditymarket_default_fence_aspen_wood.png", backface_culling = true }, -- wheel sides
|
|
{ name = "default_cobble.png", backface_culling = true }, -- wheel tyre
|
|
{ name = "default_stone_brick.png", backface_culling = true }, -- roof
|
|
{ name = "commoditymarket_default_pine_tree.png", backface_culling = true }, -- corner wood
|
|
}
|
|
}))
|
|
minetest.register_node("commoditymarket_fantasy:caravan_market_4", create_caravan_def({
|
|
tiles = {
|
|
{ name = "commoditymarket_door_wood.png", backface_culling = true }, -- door
|
|
{ name = "default_junglewood.png", backface_culling = true }, -- base wood
|
|
{ name = "commoditymarket_default_fence_rail_junglewood.png", backface_culling = true }, -- wheel sides
|
|
{ name = "default_obsidian.png", backface_culling = true }, -- wheel tyre
|
|
{ name = "commoditymarket_shingles_wood.png^[multiply:#88FF88", backface_culling = true }, -- roof
|
|
{ name = "default_tree.png", backface_culling = true }, -- corner wood
|
|
}
|
|
}))
|
|
minetest.register_node("commoditymarket_fantasy:caravan_market_5", create_caravan_def({
|
|
tiles = {
|
|
{ name = "commoditymarket_door_wood.png", backface_culling = true }, -- door
|
|
{ name = "commoditymarket_default_pine_wood.png", backface_culling = true }, -- base wood
|
|
{ name = "commoditymarket_default_chest_lock.png", backface_culling = true }, -- wheel sides
|
|
{ name = "commoditymarket_default_chest_top.png", backface_culling = true }, -- wheel tyre
|
|
{ name = "default_furnace_top.png", backface_culling = true }, -- roof
|
|
{ name = "default_wood.png", backface_culling = true }, -- corner wood
|
|
}
|
|
}))
|
|
|
|
local caravan_protect = minetest.settings:get_bool("commoditymarket_protect_caravan_market", true)
|
|
local on_blast
|
|
if caravan_protect then
|
|
on_blast = function() end
|
|
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_fantasy:caravan_market_permanent", {
|
|
description = caravan_def.description,
|
|
_doc_items_longdesc = caravan_def.long_description,
|
|
_doc_items_usagehelp = usage_help,
|
|
drawtype = "mesh",
|
|
mesh = "commoditymarket_wagon.obj",
|
|
tiles = {
|
|
{ name = "commoditymarket_door_wood.png", backface_culling = true }, -- door
|
|
{ name = "default_wood.png", backface_culling = true }, -- base wood
|
|
{ name = "commoditymarket_default_fence_rail_wood.png", backface_culling = true }, -- wheel sides
|
|
{ name = "default_coal_block.png", backface_culling = true }, -- wheel tyre
|
|
{ name = "commoditymarket_shingles_wood.png", backface_culling = true }, -- roof
|
|
{ name = "default_junglewood.png", backface_culling = true }, -- corner wood
|
|
},
|
|
collision_box = caravan_nodebox,
|
|
selection_box = caravan_nodebox,
|
|
|
|
paramtype2 = "facedir",
|
|
is_ground_content = false,
|
|
groups = {choppy = 2, oddly_breakable_by_hand = 1,},
|
|
sounds = wood_sounds,
|
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
commoditymarket.show_market("caravan", clicker:get_player_name())
|
|
end,
|
|
can_dig = function(pos, player)
|
|
return not caravan_protect or minetest.check_player_privs(player, "protection_bypass")
|
|
end,
|
|
on_blast = on_blast,
|
|
})
|
|
|
|
-- is a 5x3 area centered around pos clear of obstruction and has usable ground?
|
|
local is_suitable_caravan_space = function(pos, facedir)
|
|
local x_dim = 2
|
|
local z_dim = 2
|
|
local dir = minetest.facedir_to_dir(facedir)
|
|
if dir.x ~= 0 then
|
|
z_dim = 1
|
|
elseif dir.z ~= 0 then
|
|
x_dim = 1
|
|
end
|
|
|
|
-- walkable ground?
|
|
for x = pos.x - x_dim, pos.x + x_dim, 1 do
|
|
for z = pos.z - z_dim, pos.z + z_dim, 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
|
|
-- buildable_to in the rest?
|
|
for y = pos.y, pos.y+2, 1 do
|
|
for x = pos.x - x_dim, pos.x + x_dim, 1 do
|
|
for z = pos.z - z_dim, pos.z + z_dim, 1 do
|
|
local node = minetest.get_node({x=x, y=y, z=z})
|
|
local node_def = minetest.registered_nodes[node.name]
|
|
if node_def == nil or node_def.buildable_to ~= true then return false end
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
minetest.register_node("commoditymarket_fantasy:caravan_post", {
|
|
description = S("Trading Post"),
|
|
_long_items_longdesc = S("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."),
|
|
_doc_items_usagehelp = S("The trader's caravan requires a suitable open space next to the trading post for it to arrive, and takes some time to arrive after being summoned. The post gives a countdown to the caravan's arrival when moused over."),
|
|
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 = wood_sounds,
|
|
inventory_image = "commoditymarket_caravan_sign_inventory.png",
|
|
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_fantasy: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,3))
|
|
|
|
local target_node = minetest.get_node(target)
|
|
|
|
if target_node.name:sub(1,string.len("commoditymarket_fantasy:caravan_market")) == "commoditymarket_fantasy: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, facedir)
|
|
|
|
if not is_suitable_space then
|
|
meta:set_string("infotext", S("Indicated parking area isn't suitable.\nA 5x3 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", S("Caravan summoned\nETA: @1 seconds.", math.floor(time_until_caravan - wait_time)))
|
|
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_fantasy:caravan_market_"..math.random(1,5), 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,
|
|
}) |