303 lines
11 KiB
Lua
303 lines
11 KiB
Lua
quests.treasure = {}
|
|
|
|
local quest_file = minetest.get_worldpath().."/quests-treasure"
|
|
|
|
local ground_nodes = {"default:dirt",
|
|
"default:dirt_with_grass",
|
|
"default:sand",
|
|
"default:desert_sand",
|
|
"mg:dirt_with_dry_grass",
|
|
"default:dirt_with_snow",
|
|
"default:snow",
|
|
"default:gravel",
|
|
"deafult:river_gravel",
|
|
|
|
}
|
|
|
|
local treasure_markers = { [0] = "default:stonebrick",
|
|
[1] = "default:cobble",
|
|
[2] = "default:bronzeblock",
|
|
[3] = "default:bookshelf",
|
|
[4] = "wool:yellow",
|
|
[5] = "wool:violet",
|
|
[6] = "moretrees:pine_planks",
|
|
}
|
|
|
|
local treasures = {
|
|
[1] = {
|
|
{ item = "default:sword_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:helmet_steel", max=1, chance=80, },
|
|
{ item = "3d_armor:chestplate_steel", max=1, chance=80, },
|
|
{ item = "3d_armor:leggings_steel", max=1, chance=80, },
|
|
{ item = "3d_armor:boots_steel", max=1, chance=80, },
|
|
{ item = "default:gold_ingot",max=18, chance=89, },
|
|
{ item = "potions:fly1",max=2, chance=70, },
|
|
{ item = "default:pick_steel",max=1, chance=80, },
|
|
{ item = "default:diamond",max=6, chance=60, },
|
|
{ item = "potions:bones",max=2,chance=75, },
|
|
},
|
|
[2] = {
|
|
{ item = "default:sword_mese", max=1, chance=80, },
|
|
{ item = "3d_armor:helmet_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:chestplate_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:leggings_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:boots_steel", max=1, chance=90, },
|
|
{ item = "default:gold_ingot",max=36, chance=89, },
|
|
{ item = "potions:fly2",max=2, chance=75, },
|
|
{ item = "default:pick_mese",max=1, chance=80, },
|
|
{ item = "default:diamond",max=12, chance=65, },
|
|
{ item = "potions:bones",max=4,chance=80, },
|
|
},
|
|
[3] = {
|
|
{ item = "default:sword_mese", max=1, chance=80, },
|
|
{ item = "3d_armor:helmet_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:chestplate_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:leggings_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:boots_steel", max=1, chance=90, },
|
|
{ item = "default:gold_ingot",max=36, chance=89, },
|
|
{ item = "potions:fly2",max=2, chance=75, },
|
|
{ item = "default:pick_mese",max=1, chance=80, },
|
|
{ item = "default:diamond",max=12, chance=65, },
|
|
{ item = "potions:bones",max=4,chance=80, },
|
|
},
|
|
[4] = {
|
|
{ item = "default:sword_mese", max=1, chance=80, },
|
|
{ item = "3d_armor:helmet_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:chestplate_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:leggings_steel", max=1, chance=90, },
|
|
{ item = "3d_armor:boots_steel", max=1, chance=90, },
|
|
{ item = "default:gold_ingot",max=36, chance=89, },
|
|
{ item = "potions:fly2",max=2, chance=75, },
|
|
{ item = "default:pick_mese",max=1, chance=80, },
|
|
{ item = "default:diamond",max=12, chance=65, },
|
|
{ item = "potions:bones",max=4,chance=80, },
|
|
},
|
|
}
|
|
|
|
local max_exp = 1000
|
|
|
|
quests.treasure.generateQuest = function()
|
|
quests.treasure.data.quest_start = os.time()
|
|
quests.treasure.data.quest_end = nil
|
|
quests.treasure.data.completed = false
|
|
quests.treasure.data.completed_by = nil
|
|
quests.treasure.data.pos = nil
|
|
quests.treasure.data.do_on_generate = false
|
|
|
|
-- find an area to place the treasure box
|
|
local tx = math.random(-20000,20000)
|
|
local tz = math.random(-20000,20000)
|
|
quests.treasure.data.marker = treasure_markers[math.random(0,(#treasure_markers-1))]
|
|
|
|
local minp = {x= tx-32, y=-32, z=tz-32}
|
|
local maxp = {x= tx+32, y=32, z=tz+32}
|
|
|
|
local c_air = minetest.get_content_id("air")
|
|
local c_ignore = minetest.get_content_id("ignore")
|
|
local vm = VoxelManip()
|
|
local e1, e2 = vm:read_from_map(minp, maxp)
|
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
|
local data = vm:get_data()
|
|
|
|
local allair = true
|
|
for _,d in pairs(data) do
|
|
if d ~= c_air and d ~= c_ignore then
|
|
allair = false
|
|
end
|
|
end
|
|
|
|
quests.treasure.data.pos = {x=tx,y=0,z=tz}
|
|
default.serialize_to_file(quest_file,quests.treasure.data)
|
|
|
|
if allair == true then
|
|
quests.treasure.data.do_on_generate = true
|
|
default.serialize_to_file(quest_file,quests.treasure.data)
|
|
return
|
|
end
|
|
quests.treasure.place_treasure({x=tx,y=0,z=tz},vm,e1,e2)
|
|
end
|
|
|
|
quests.treasure.tell_story = function(pos)
|
|
|
|
if quests.treasure.data.completed == false and quests.treasure.data.pos ~= nil then
|
|
local directions = "The old explorer says, 'If you search about "
|
|
local diff = math.floor(pos.x - quests.treasure.data.pos.x)
|
|
diff = diff - ( diff % 5 )
|
|
directions = directions .. tostring(math.abs(diff)) .. " meters "
|
|
if pos.x < quests.treasure.data.pos.x then
|
|
directions = directions .. "east"
|
|
else
|
|
directions = directions .. "west"
|
|
end
|
|
|
|
diff = math.floor(pos.z - quests.treasure.data.pos.z)
|
|
diff = diff - ( diff % 5 )
|
|
directions = directions .. " and about " .. tostring(math.abs(diff)) .. " meters "
|
|
if pos.z > quests.treasure.data.pos.z then
|
|
directions = directions .. "south"
|
|
else
|
|
directions = directions .. "north"
|
|
end
|
|
|
|
directions = directions .. "'"
|
|
chat.local_chat(pos,"The old explorer says, 'I hear there are treasures buried in these lands...'",12)
|
|
minetest.after(4,chat.local_chat,pos,directions,12)
|
|
minetest.after(8,chat.local_chat,pos,"The old explorer says, 'You should find the treasure buried under a "..minetest.registered_nodes[quests.treasure.data.marker].description.."'",12)
|
|
else
|
|
chat.local_chat(pos,"The old explorer says, 'I hear "..tostring(quests.treasure.data.completed_by).." recently found some treasure'")
|
|
minetest.after(4,chat.local_chat,pos,"The old explorer says, 'Come talk to me later and I will let you know if I hear of any more treasure'")
|
|
end
|
|
end
|
|
|
|
-- LOAD DATA FROM PREVIOUS SESSION
|
|
quests.treasure.data = default.deserialize_from_file(quest_file)
|
|
|
|
-- If data is an emtpy table then generateQuest
|
|
if next(quests.treasure.data) == nil then
|
|
minetest.after(1,quests.treasure.generateQuest)
|
|
else
|
|
if quests.treasure.data.completed == true then
|
|
minetest.after(60,quests.treasure.generateQuest)
|
|
end
|
|
end
|
|
|
|
function is_ground_node(nodeid)
|
|
for _,n in pairs(ground_nodes) do
|
|
if minetest.get_content_id(n) == nodeid then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
quests.treasure.place_treasure = function (pos,minp,maxp)
|
|
local c_air = minetest.get_content_id("air")
|
|
local c_water = minetest.get_content_id("default:water_source")
|
|
local prevnode = nil
|
|
|
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
|
|
local e1, e2 = vm:read_from_map(minp, maxp)
|
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
|
local data = vm:get_data()
|
|
|
|
-- find ground level
|
|
for tz = minp.z, maxp.z,1 do
|
|
for tx=minp.x, maxp.x,1 do
|
|
for ty=32,-32,-1 do
|
|
if data[area:index(tx, ty, tz)] ~= c_air then
|
|
--if is_ground_node(data[area:index(tx, ty, tz)]) then
|
|
if prevnode == c_air or prevnode == c_water then
|
|
quests.treasure.data.pos = {x=tx,y=ty-2,z=tz}
|
|
quests.treasure.data.do_on_generate = false
|
|
data[area:index(tx, ty+1, tz)] = minetest.get_content_id(quests.treasure.data.marker)
|
|
local depth = math.random(2,6)
|
|
data[area:index(tx,ty-depth,tz)] = minetest.get_content_id("quests:treasure_chest")
|
|
vm:set_data(data)
|
|
vm:write_to_map(data)
|
|
vm:update_map()
|
|
quests.treasure.set_inventory({x=tx,y=ty-depth,z=tz})
|
|
default.serialize_to_file(quest_file,quests.treasure.data)
|
|
return
|
|
end
|
|
--end
|
|
end
|
|
prevnode = data[area:index(tx, ty, tz)]
|
|
end
|
|
prevnode = nil
|
|
end
|
|
end
|
|
-- placing treasure failed
|
|
minetest.after(60,quests.treasure.generateQuest)
|
|
--quests.treasure.data.do_on_generate = true
|
|
end
|
|
|
|
quests.treasure.set_inventory = function (pos)
|
|
local distance = default.get_distance(game_origin,{x=pos.x,y=0,z=pos.z})
|
|
local treasure_level = math.floor( distance / 5000 )
|
|
if treasure_level == 0 then treasure_level = 1 end
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("formspec",default.chest_formspec)
|
|
meta:set_string("infotext", "Treasure Chest")
|
|
|
|
local treasure_set = treasures[treasure_level]
|
|
if treasure_set ~= nil then
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("main", 8*4)
|
|
for _,item in pairs(treasure_set) do
|
|
if math.random(1,100) < item.chance then
|
|
local qty = math.random(1,item.max)
|
|
inv:add_item("main",item.item.." "..tostring(qty))
|
|
end
|
|
end
|
|
|
|
-- add experience to the chest
|
|
local exp = max_exp * ( distance / 30000 )
|
|
local exp_items = experience.exp_to_items(exp)
|
|
for _,e in pairs(exp_items) do
|
|
inv:add_item("main",e)
|
|
end
|
|
end
|
|
end
|
|
|
|
quests.treasure.end_quest = function (player)
|
|
local name = player:get_player_name()
|
|
quests.treasure.data.quest_end = os.time()
|
|
quests.treasure.data.completed = true
|
|
quests.treasure.data.completed_by = name
|
|
minetest.after(120,quests.treasure.generateQuest)
|
|
default.serialize_to_file(quest_file,quests.treasure.data)
|
|
end
|
|
|
|
--[[minetest.register_on_generated(function(minp, maxp, seed)
|
|
|
|
end)]]
|
|
|
|
-- called from mg mod
|
|
quests.treasure.on_generated = function (minp,maxp)
|
|
if quests.treasure.data.do_on_generate == true then
|
|
if quests.treasure.data.pos.x > minp.x and quests.treasure.data.pos.x < maxp.x and quests.treasure.data.pos.z > minp.z and quests.treasure.data.pos.z < maxp.z then
|
|
--local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
quests.treasure.place_treasure(quests.treasure.data.pos,minp,maxp)
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_node("quests:treasure_chest", {
|
|
description = "Treasure Chest",
|
|
tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
|
|
"default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
|
|
paramtype2 = "facedir",
|
|
groups = {choppy=2,oddly_breakable_by_hand=2},
|
|
legacy_facedir_simple = true,
|
|
is_ground_content = false,
|
|
sounds = default.node_sound_wood_defaults(),
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("formspec",default.chest_formspec)
|
|
meta:set_string("infotext", "Treasure Chest")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("main", 8*4)
|
|
end,
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
quests.treasure.end_quest(digger)
|
|
local meta = minetest:get_meta(pos)
|
|
meta:from_table(oldmetadata)
|
|
local inv = meta:get_inventory()
|
|
default.dump_inv(pos,"main",inv)
|
|
end,
|
|
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
|
minetest.log("action", player:get_player_name()..
|
|
" moves stuff in chest at "..minetest.pos_to_string(pos))
|
|
end,
|
|
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
minetest.log("action", player:get_player_name()..
|
|
" moves stuff to chest at "..minetest.pos_to_string(pos))
|
|
end,
|
|
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
quests.treasure.end_quest(player)
|
|
minetest.log("action", player:get_player_name()..
|
|
" takes stuff from chest at "..minetest.pos_to_string(pos))
|
|
end,
|
|
})
|