added function for filling chests and shelves with random materials

master
Sokomine 2014-09-28 03:56:24 +02:00
parent 6481e288fa
commit d36e830d97
4 changed files with 155 additions and 9 deletions

138
fill_chest.lua Normal file
View File

@ -0,0 +1,138 @@
-- TODO: refill chest after some time?
-- TODO: alert NPC that something was taken
mg_villages.random_chest_content = {};
-- things that can be found in private, not locked chests belonging to npc
-- contains tables of the following structure: { node_name, probability (in percent, 100=always, 0=never), max_amount, repeat (for more than one stack) }
mg_villages.random_chest_content = {
{"default:pick_stone", 10, 1, 3 },
{"default:pick_steel", 5, 1, 2 },
{"default:pick_mese", 2, 1, 2 },
{"default:shovel_stone", 5, 1, 3 },
{"default:shovel_steel", 5, 1, 2 },
{"default:axe_stone", 5, 1, 3 },
{"default:axe_steel", 5, 1, 2 },
{"default:sword_stone", 1, 1, 3 },
{"default:sword_steel", 1, 1, 3 },
{"default:stick", 20, 40, 2 },
{"default:torch", 50, 10, 4 },
{"default:book", 60, 1, 2 },
{"default:paper", 60, 6, 4 },
{"default:apple", 50, 10, 2 },
{"default:ladder", 20, 1, 2 },
{"default:coal_lump", 80, 30, 1 },
{"default:steel_ingot", 30, 4, 2 },
{"default:mese_crystal_fragment", 10, 3, 1 },
{"bucket:bucket_empty", 10, 3, 2 },
{"bucket:bucket_water", 5, 3, 2 },
{"bucket:bucket_lava", 3, 3, 2 },
{"vessels:glass_bottle", 10, 10, 2 },
{"vessels:drinking_glass", 20, 2, 1 },
{"vessels:steel_bottle", 10, 1, 1 },
{"wool:white", 60, 8, 2 },
}
-- that someone will hide valuable ingots in chests that are not locked is fairly unrealistic; thus, those items are rare
if( minetest.get_modpath("moreores") ~= nil ) then
table.insert( mg_villages.random_chest_content, {"moreores:gold_ingot", 1, 2, 1 } );
table.insert( mg_villages.random_chest_content, {"moreores:silver_ingot", 1, 2, 1 } );
table.insert( mg_villages.random_chest_content, {"moreores:copper_ingot", 30, 10, 1 } );
table.insert( mg_villages.random_chest_content, {"moreores:tin_ingot", 1, 5, 1 } );
table.insert( mg_villages.random_chest_content, {"moreores:bronze_ingot", 1, 1, 1 } );
table.insert( mg_villages.random_chest_content, {"moreores:mithril_ingot", 1, 1, 1 } );
end
-- candles are a very likely content of chests
if( minetest.get_modpath("candles") ~= nil ) then
table.insert( mg_villages.random_chest_content, {"candles:candle", 80, 12, 2 } );
table.insert( mg_villages.random_chest_content, {"candles:candelabra_steel", 1, 1, 1 } );
table.insert( mg_villages.random_chest_content, {"candles:candelabra_copper", 1, 1, 1 } );
table.insert( mg_villages.random_chest_content, {"candles:honey", 50, 2, 1 } );
end
-- our NPC have to spend their free time somehow...also adds food variety
if( minetest.get_modpath("fishing") ~= nil ) then
table.insert( mg_villages.random_chest_content, {"fishing:pole", 60, 1, 1 } );
end
-- ropes are always useful
if( minetest.get_modpath("ropes") ~= nil ) then
table.insert( mg_villages.random_chest_content, {"ropes:rope", 60, 5, 2 } );
elseif( minetest.get_modpath("farming") ~= nil ) then
table.insert( mg_villages.random_chest_content, {"farming:string", 60, 5, 2 } );
elseif( minetest.get_modpath("moreblocks") ~= nil ) then
table.insert( mg_villages.random_chest_content, {"moreblocks:rope", 60, 5, 2 } );
end
-- TODO: food mod
-- get some random content for a chest
mg_villages.fill_chest_random = function( pos, pr, building_nr, building_typ )
local meta = minetest.env:get_meta( pos );
local inv = meta:get_inventory();
local count = 0;
local inv_size = inv:get_size('main');
for i,v in ipairs( mg_villages.random_chest_content ) do
-- repeat this many times
for count=1, v[ 4 ] do
-- to avoid too many things inside a chest, lower probability
if( count<30 -- make sure it does not get too much and there is still room for a new stack
and inv_size and inv_size > 0 and v[ 2 ] > pr:next( 1, 200 )) then
--inv:add_item('main', v[ 1 ].." "..tostring( math.random( 1, tonumber(v[ 3 ]) )));
-- add itemstack at a random position in the chests inventory
inv:set_stack( 'main', pr:next( 1, inv:get_size( 'main' )), v[ 1 ].." "..tostring( pr:next( 1, tonumber(v[ 3 ]) )) );
count = count+1;
end
end
end
end
--[[ -- TODO
for _, n in pairs(village.to_add_data.extranodes) do
-- minetest.set_node(n.pos, n.node)
if n.meta ~= nil then
meta = minetest.get_meta(n.pos)
meta:from_table(n.meta)
if n.node.name == "default:chest" then
local inv = meta:get_inventory()
local items = inv:get_list("main")
for i=1, inv:get_size("main") do
inv:set_stack("main", i, ItemStack(""))
end
local numitems = pr:next(3, 20)
for i=1,numitems do
local ii = pr:next(1, #items)
local prob = items[ii]:get_count() % 2 ^ 8
local stacksz = math.floor(items[ii]:get_count() / 2 ^ 8)
if pr:next(0, prob) == 0 and stacksz>0 then
stk = ItemStack({name=items[ii]:get_name(), count=pr:next(1, stacksz), wear=items[ii]:get_wear(), metadata=items[ii]:get_metadata()})
local ind = pr:next(1, inv:get_size("main"))
while not inv:get_stack("main",ind):is_empty() do
ind = pr:next(1, inv:get_size("main"))
end
inv:set_stack("main", ind, stk)
end
end
end
end
end
--]]

View File

@ -40,6 +40,8 @@ dofile(mg_villages.modpath.."/protection.lua")
-- create and show a map of the world
dofile(mg_villages.modpath.."/map_of_world.lua")
dofile(mg_villages.modpath.."/fill_chest.lua")
-- the interface for the mapgen;
-- also takes care of spawning the player
dofile(mg_villages.modpath.."/mapgen.lua")

View File

@ -811,16 +811,22 @@ t1 = time_elapsed( t1, 'vm data written' );
if( minetest.registered_nodes[ node_name ].on_construct ) then
for _, pos in ipairs(v) do
minetest.registered_nodes[ node_name ].on_construct( pos );
print('calling on_construct for '..minetest.pos_to_string( pos )..' for '..tostring( node_name ));
end
end
end
end
-- TODO: extra_calls.chests, extra_calls.signs
local pr = PseudoRandom(mg_villages.get_bseed(minp));
for _, village in ipairs(villages) do
for _,v in ipairs( village.to_add_data.extra_calls.chests ) do
local building_nr = village.to_add_data.bpos[ v.bpos_i ];
local building_typ = mg_villages.BUILDINGS[ building_nr.btype ].scm;
mg_villages.fill_chest_random( v, pr, building_nr, building_typ );
end
end
-- TODO: extra_calls.signs
-- initialize the pseudo random generator so that the chests will be filled in a reproducable pattern
local pr = PseudoRandom(mg_villages.get_bseed(minp));
local meta
for _, village in ipairs(villages) do
for _, n in pairs(village.to_add_data.extranodes) do

View File

@ -698,7 +698,7 @@ end
local function generate_building(pos, minp, maxp, data, param2_data, a, pr, extranodes, replacements, cid, extra_calls)
local function generate_building(pos, minp, maxp, data, param2_data, a, pr, extranodes, replacements, cid, extra_calls, building_nr_in_bpos)
local binfo = mg_villages.BUILDINGS[pos.btype]
local scm
@ -860,20 +860,20 @@ local function generate_building(pos, minp, maxp, data, param2_data, a, pr, extr
or new_content == cid.c_chest_locked
or new_content == cid.c_chest_shelf ) then
-- we're dealing with a chest that might need filling
table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content});
table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content, bpos_i=building_nr_in_bpos});
elseif( new_content == cid.c_chest_private
or new_content == cid.c_chest_work
or new_content == cid.c_chest_storage ) then
-- we're dealing with a chest that might need filling
table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content});
table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content, bpos_i=building_nr_in_bpos});
-- TODO: perhaps use a locked chest owned by the mob living there?
-- place a normal chest here
data[a:index(ax, ay, az)] = cid.c_chest;
elseif( new_content == cid.c_sign ) then
-- the sign may require some text to be written on it
table.insert( extra_calls.signs, {x=ax, y=ay, z=az, typ=new_content});
table.insert( extra_calls.signs, {x=ax, y=ay, z=az, typ=new_content, bpos_i=building_nr_in_bpos});
end
end
end
@ -1198,9 +1198,9 @@ print('REPLACEMENTS: '..minetest.serialize( replacements.table )..' CHEST: '..to
local extranodes = {}
local extra_calls = { on_constr = {}, trees = {}, chests = {}, signs = {} };
for _, pos in ipairs(bpos) do
for i, pos in ipairs(bpos) do
-- replacements are in table format for mapgen-based building spawning
generate_building(pos, minp, maxp, data, param2_data, a, pr_village, extranodes, replacements, cid, extra_calls )
generate_building(pos, minp, maxp, data, param2_data, a, pr_village, extranodes, replacements, cid, extra_calls, i )
end
-- replacements are in list format for minetest.place_schematic(..) type spawning