adventuretest/mods/quests/treasure.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,
})