From 7bcd2bcf4a344be02f2f8465b2564ac1ce9a62c6 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sat, 13 Dec 2014 03:37:46 +0100 Subject: [PATCH] changed village_sizes to village_type_data as preparation for code cleanup --- buildings.lua | 146 ++++++++++++++++++++++++++++++++--------------- map_of_world.lua | 10 ++-- name_gen.lua | 21 +------ villages.lua | 18 +++--- 4 files changed, 118 insertions(+), 77 deletions(-) diff --git a/buildings.lua b/buildings.lua index 1649979..73a4ae5 100644 --- a/buildings.lua +++ b/buildings.lua @@ -1,21 +1,84 @@ ---village_types = { 'nore', 'logcabin', 'grasshut', 'medieval', 'charachoal', 'taoki'}; +-- DOCUMENTATION: mg_villages.village_type_data has entries in the following form: +-- key = { data values } with key beeing the name of the village type +-- meaning of the data values: +-- min, max: the village size will be choosen randomly between these two values; +-- the actual village will have a radius about twice as big (including sourrounding area) +-- space_between_buildings=2 How much space is there between the buildings. 1 or 2 are good values. +-- The higher, the further the buildings are spread apart. +-- mods = {'homedecor','moreblocks'} List of mods that are required for the buildings of this village type. +-- List all the mods the blocks used by your buildings which are not in default. +-- texture = 'wool_white.png' Texture used to show the location of the village when using the +-- vmap command. +-- name_prefix = 'Village ', +-- name_postfix = '' When creating village names for single houses which are spawned outside +-- of villages, the village name will consist of name_prefix..village_name..name_postfix -mg_villages.village_sizes = { - nore = { min = 20, max = 40, space_between_buildings=1, texture = 'default_stone_brick.png'}, - taoki = { min = 30, max = 70, space_between_buildings=1, texture = 'default_brick.png' }, - medieval = { min = 25, max = 60, space_between_buildings=2, texture = 'cottages_darkage_straw.png'}, -- they often have straw roofs - charachoal = { min = 10, max = 15, space_between_buildings=1, texture = 'default_coal_block.png'}, - lumberjack = { min = 10, max = 30, space_between_buildings=1, texture = 'default_tree.png'}, - claytrader = { min = 10, max = 20, space_between_buildings=1, texture = 'default_clay.png'}, - logcabin = { min = 15, max = 30, space_between_buildings=1, texture = 'default_wood.png'}, - canadian = { min = 40, max = 110, space_between_buildings=1, texture = 'wool_white.png'}, - grasshut = { min = 10, max = 40, space_between_buildings=1, texture = 'dryplants_reed.png'}, - tent = { min = 5, max = 20, space_between_buildings=2, texture = 'wool_white.png'}, - tower = { min = 2, max = 6, space_between_buildings=1, texture = 'default_mese.png'}, - chateau = { min = 50, max = 80, space_between_buildings=1, texture = 'default_gold_block.png'}, + +mg_villages.village_type_data = { + nore = { min = 20, max = 40, space_between_buildings=1, mods={}, texture = 'default_stone_brick.png'}, + taoki = { min = 30, max = 70, space_between_buildings=1, mods={}, texture = 'default_brick.png' }, + medieval = { min = 25, max = 60, space_between_buildings=2, mods={'cottages'}, texture = 'cottages_darkage_straw.png'}, -- they often have straw roofs + charachoal = { min = 10, max = 15, space_between_buildings=1, mods={'cottages'}, texture = 'default_coal_block.png'}, + lumberjack = { min = 10, max = 30, space_between_buildings=1, mods={'cottages'}, texture = 'default_tree.png', name_prefix = 'Camp '}, + claytrader = { min = 10, max = 20, space_between_buildings=1, mods={'cottages'}, texture = 'default_clay.png'}, + logcabin = { min = 15, max = 30, space_between_buildings=1, mods={'cottages'}, texture = 'default_wood.png'}, + canadian = { min = 40, max = 110, space_between_buildings=1, mods={'hdb','nbu'}, texture = 'wool_white.png'}, + grasshut = { min = 10, max = 40, space_between_buildings=1, mods={'dryplants'}, texture = 'dryplants_reed.png'}, + tent = { min = 5, max = 20, space_between_buildings=2, mods={'cottages'}, texture = 'wool_white.png', name_preifx = 'Tent at'}, + + -- these sub-types may occour as single houses placed far from villages + tower = { only_single = 1, name_prefix = 'Tower at ', mods={'cottages'}, texture = 'default_mese.png'}, + chateau = { only_single = 1, name_prefix = 'Chateau ', texture = 'default_gold_block.png'}, + forge = { only_single = 1, name_prefix = 'Forge at '}, + tavern = { only_single = 1, name_prefix = 'Inn at '}, + well = { only_single = 1, name_prefix = 'Well at '}, + trader = { only_single = 1, name_prefix = 'Trading post ' }, + sawmill = { only_single = 1, name_prefix = 'Sawmill at ' }, + farm_tiny = { only_single = 1, name_prefix = 'House '}, + farm_full = { only_single = 1, name_prefix = 'Farm '}, + single = { only_single = 1, name_prefix = 'House '}, -- fallback } + +-- list of village types supported by the mods installed +-- (some villages require special mods as building material for their houses) +mg_villages.village_types = {}; +for k,v in pairs( mg_villages.village_type_data ) do + local found = true; + if( not( v.mods )) then + v.mods = {}; + end + for _,m in ipairs( v.mods ) do + if( not( minetest.get_modpath( m ))) then + found = false; + end + end + if( found ) then + if( not( v.only_single )) then + table.insert( mg_villages.village_types, k ); + end + -- this village type is supported by the mods installed and may be used + v.supported = 1; + end +end + +print('[mg_villages] Will create villages of the following types: '..minetest.serialize( mg_villages.village_types )); + + + + +-- the schematics for buildings of type 'farm_tiny' grow cotton; the farming_plus fruits would be far more fitting +mg_villages.fruit_list = {'carrot','potatoe','orange','rhubarb','strawberry','tomato','cotton'}; +-- is farming_plus available? If not, we can't use this +if( not( minetest.get_modpath("farming_plus"))) then + mg_villages.fruit_list = nil; +end + + + + + -- if set to true, the outer buildings in medieval villages will be fields; this is not very convincing yet mg_villages.medieval_subtype = false; @@ -266,33 +329,6 @@ mg_villages.BUILDINGS = { } --- the schematics for buildings of type 'farm_tiny' grow cotton; the farming_plus fruits would be far more fitting -mg_villages.fruit_list = {'carrot','potatoe','orange','rhubarb','strawberry','tomato','cotton'}; --- is farming_plus available? If not, we can't use this -if( not( minetest.get_modpath("farming_plus"))) then - mg_villages.fruit_list = nil; -end - --- 'nore' and 'taoki' do not require any other mods; thus, they can be used in all worlds -mg_villages.village_types = { 'nore', 'taoki'}; - -if( minetest.get_modpath("cottages")) then - table.insert( mg_villages.village_types, 'medieval' ); - table.insert( mg_villages.village_types, 'charachoal' ); - table.insert( mg_villages.village_types, 'lumberjack' ); - table.insert( mg_villages.village_types, 'claytrader' ); - table.insert( mg_villages.village_types, 'logcabin' ); - table.insert( mg_villages.village_types, 'tent' ); -end - -if( minetest.get_modpath( 'hdb' ) and minetest.get_modpath( 'nbu' )) then - table.insert( mg_villages.village_types, 'canadian' ); -end - -if( minetest.get_modpath( 'dryplants' )) then - table.insert( mg_villages.village_types, 'grasshut' ); -end - -- read the data files and fill in information like size and nodes that need on_construct to be called after placing @@ -303,14 +339,11 @@ mg_villages.buildings_init = function() for i,v in ipairs( mg_villages.BUILDINGS ) do local is_used = false; - for _,t in ipairs( mg_villages.village_types ) do - if( t and v and v.weight and v.weight[ t ] ) then + for typ,weight in pairs( v.weight ) do + if( typ and weight and weight>0 and mg_villages.village_type_data[ typ ] and mg_villages.village_type_data[ typ ].supported ) then is_used = true; end end - if( v.weight and (v.weight.fields or v.weight.tower or v.weight.single)) then - is_used = true; - end local res = nil; if( is_used ) then @@ -320,11 +353,31 @@ mg_villages.buildings_init = function() if( not( res )) then res = mg_villages.import_scm( mg_villages.BUILDINGS[ i ].scm ); end + + -- create lists for all village types containing the buildings which may be used for that village + for typ, data in pairs( mg_villages.village_type_data ) do + local total_weight = 0; + if( not( data.building_list ) or not( data.max_weight_list )) then + data.building_list = {}; + data.max_weight_list = {}; + elseif( #data.max_weight_list > 0 ) then + -- get the last entry - that one will determine the current total_weight + total_weight = data.max_weight_list[ #data.max_weight_list ]; + end + + if( v.weight and v.weight[ typ ] and v.weight[ typ ] > 0 ) then + local index = #data.building_list+1; + data.building_list[ index ] = i; + data.max_weight_list[ index ] = total_weight + v.weight[ typ ]; + end + end end if( not( is_used )) then -- do nothing; skip this file print('SKIPPING '..tostring( mg_villages.BUILDINGS[ i ].scm )..' due to village type not supported.'); + -- building cannot be used + v.not_available = 1; -- provided the file could be analyzed successfully elseif( res and res.size and res.size.x ) then -- the file has to be placed with minetest.place_schematic(...) @@ -438,7 +491,6 @@ mg_villages.BUILDINGS["wall"] = {yoff = 1, ysize = 6, scm = wall} -print('[mg_villages] Will create villages of the following types: '..minetest.serialize( mg_villages.village_types )); mg_villages.village_types[ #mg_villages.village_types+1 ] = 'single'; mg_villages.village_types[ #mg_villages.village_types+1 ] = 'fields'; mg_villages.village_types[ #mg_villages.village_types+1 ] = 'tower'; diff --git a/map_of_world.lua b/map_of_world.lua index 143cbb9..cd8705c 100644 --- a/map_of_world.lua +++ b/map_of_world.lua @@ -97,8 +97,8 @@ mg_villages.map_of_world = function( pname ) -- show only villages which are at max mg_villages.MAP_RANGE away from player if( x and z - and mg_villages.village_sizes[ data.village_type ] - and mg_villages.village_sizes[ data.village_type ].texture + and mg_villages.village_type_data[ data.village_type ] + and mg_villages.village_type_data[ data.village_type ].texture and math.abs( x ) < r and math.abs( z ) < r ) then @@ -115,7 +115,7 @@ mg_villages.map_of_world = function( pname ) z = f1 * ( (2*r) -(z+r)); formspec = formspec.. - "label["..x..",".. z ..";"..tostring( data.nr ).."]"..mg_villages.draw_tile( nil, mg_villages.village_sizes[ data.village_type ].texture, x, z, dx, dz ); + "label["..x..",".. z ..";"..tostring( data.nr ).."]"..mg_villages.draw_tile( nil, mg_villages.village_type_data[ data.village_type ].texture, x, z, dx, dz ); shown_villages[ #shown_villages+1 ] = tostring( data.nr )..". "..tostring( v.name or 'unknown' ).."]"; end @@ -154,9 +154,9 @@ mg_villages.map_of_world = function( pname ) local i = 0.05; formspec = formspec.."label[10,-0.4;Village types:]"; -- explain the meaning of the textures - for typ,data in pairs(mg_villages.village_sizes) do + for _,typ in ipairs(mg_villages.village_types) do formspec = formspec.."label[10.5,"..tostring(i)..";"..tostring( typ ).."]".. - "image[10.0,"..tostring(i+0.1)..";0.4,0.4;"..tostring( data.texture ).."]"; + "image[10.0,"..tostring(i+0.1)..";0.4,0.4;"..tostring( mg_villages.village_type_data[ typ ].texture ).."]"; i = i+0.45; end diff --git a/name_gen.lua b/name_gen.lua index 0302488..4ef81bb 100644 --- a/name_gen.lua +++ b/name_gen.lua @@ -75,24 +75,9 @@ namegen.generate_village_name_with_prefix = function( pr, village ) -- if a village consists of a single house, it gets a prefix depending on the house type if( village.is_single_house and village.to_add_data and village.to_add_data.bpos ) then local btyp = mg_villages.BUILDINGS[ village.to_add_data.bpos[1].btype].typ; - if( btyp == 'forge' ) then - name = 'Forge at '..name; - elseif( btyp == 'tower' ) then - name = 'Tower at '..name; - elseif( btyp == 'tavern' ) then - name = 'Inn at '..name; - elseif( btyp == 'well' ) then - name = 'Well at '..name; - elseif( btyp == 'lumberjack' ) then - name = 'Camp '..name; - elseif( btyp == 'sawmill' ) then - name = 'Sawmill at '..name; - elseif( btyp == 'trader' ) then - name = 'Trading post '..name; - elseif( btyp == 'tent' ) then - name = 'Tent at '..name; - elseif( btyp == 'chateau' ) then - name = 'Chateau '..name; + local bdata = mg_villages.village_type_data[ btyp ]; + if( bdata and (bdata.name_prefix or bdata.name_postfix )) then + name = (bdata.name_prefix or '')..name..(bdata.name_postfix or ''); else name = 'House '..name; end diff --git a/villages.lua b/villages.lua index 80c6915..d6f1464 100644 --- a/villages.lua +++ b/villages.lua @@ -41,10 +41,10 @@ mg_villages.villages_at_point = function(minp, noise1) village_type = mg_villages.village_types[ pr:next(1, #mg_villages.village_types )]; -- select a random type end - if( not( mg_villages.village_sizes[ village_type ] )) then - mg_villages.village_sizes[ village_type ] = { min = mg_villages.VILLAGE_MIN_SIZE, max = mg_villages.VILLAGE_MAX_SIZE }; + if( not( mg_villages.village_type_data[ village_type ] )) then + mg_villages.village_type_data[ village_type ] = { min = mg_villages.VILLAGE_MIN_SIZE, max = mg_villages.VILLAGE_MAX_SIZE }; end - local size = pr:next(mg_villages.village_sizes[ village_type ].min, mg_villages.village_sizes[ village_type ].max) + local size = pr:next(mg_villages.village_type_data[ village_type ].min, mg_villages.village_type_data[ village_type ].max) -- local height = pr:next(5, 20) local height = pr:next(1, 5) -- villages of a size >= 40 are always placed at a height of 1 @@ -78,8 +78,12 @@ local function choose_building(l, pr, village_type) local btype while true do local p = pr:next(1, 3000) - for b, i in ipairs(mg_villages.BUILDINGS) do - if i.weight[ village_type ] and i.weight[ village_type ] > 0 and i.max_weight and i.max_weight[ village_type ] and i.max_weight[ village_type ] >= p then + + for _, b in ipairs( mg_villages.village_type_data[ village_type ][ 'building_list'] ) do + if mg_villages.BUILDINGS[ b ].max_weight[ village_type ] >= p then + +-- for b, i in ipairs(mg_villages.BUILDINGS) do +-- if i.weight[ village_type ] and i.weight[ village_type ] > 0 and i.max_weight and i.max_weight[ village_type ] and i.max_weight[ village_type ] >= p then btype = b break end @@ -596,8 +600,8 @@ mg_villages.generate_village = function(village, vnoise) -- in the case of medieval villages, we later on want to add wheat fields with dirt roads; 1 wide dirt roads look odd local space_between_buildings = 1; - if( mg_villages.village_sizes[ village_type ]) then - space_between_buildings = mg_villages.village_sizes[ village_type ].space_between_buildings; + if( mg_villages.village_type_data[ village_type ] and mg_villages.village_type_data[ village_type ].space_between_buildings) then + space_between_buildings = mg_villages.village_type_data[ village_type ].space_between_buildings; end local bpos = {};