From 75d0f49027402835a3546e3f1036c47bc1976fa5 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Fri, 28 Jul 2017 16:41:52 +0200 Subject: [PATCH] added new command: village_mob_repopulate --- chat_commands.lua | 40 ++++++++++++++++++++++++++++++++++++++++ inhabitants.lua | 35 +++++++++++++++++++++++++++++++++-- mapgen.lua | 9 ++++++--- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/chat_commands.lua b/chat_commands.lua index 0fc3188..0ef4172 100644 --- a/chat_commands.lua +++ b/chat_commands.lua @@ -234,3 +234,43 @@ minetest.register_chatcommand( 'visit', { minetest.chat_send_player( name, "There is no village with the number "..tostring( param ).." (yet?)."); end }); + +minetest.register_chatcommand( 'village_mob_repopulate', { + description = "Discards old mob data and assigns beds and workplaces anew. Mobs get new names.", + params = "", + privs = {}, + func = function(name, param) + + + if( not( minetest.check_player_privs( name, {protection_bypass=true}))) then + minetest.chat_send_player( name, "You need the 'protection_bypass' priv in order to delete all the old mob data of a village and to recalculate it anew."); + return; + end + + if( not( param ) or param == "" ) then + minetest.chat_send_player( name, "Which village do you want to repopulate? Please provide the village number!"); + return; + end + + local nr = tonumber( param ); + for id, v in pairs( mg_villages.all_villages ) do + -- we have found the village + if( v and v.nr == nr ) then + + minetest.chat_send_player( name, "Deleting information about workplaces and beds. Recalculating. Assigning new data for village no. "..tostring( v.nr )..", called "..( tostring( v.name or 'unknown')).."."); + -- move the player to the center of the village he just changed + local player = minetest.get_player_by_name( name ); + player:moveto( { x=v.vx, y=(v.vh+1), z=v.vz }, false); + + local village_id = tostring( v.vx )..':'..tostring( v.vz ); + -- actually do the reassigning + mg_villages.inhabitants.assign_mobs( v, village_id, true); + -- save the modified data + save_restore.save_data( 'mg_all_villages.data', mg_villages.all_villages ); + return; + end + end + -- no village found + minetest.chat_send_player( name, "There is no village with the number "..tostring( param ).." (yet?)."); + end +}); diff --git a/inhabitants.lua b/inhabitants.lua index ce0afaf..8c48a78 100644 --- a/inhabitants.lua +++ b/inhabitants.lua @@ -1160,8 +1160,30 @@ mg_villages.inhabitants.spawn_mobs_for_one_house = function( bpos, minp, maxp, v end --- spawn mobs in villages -mg_villages.inhabitants.part_of_village_spawned = function( village, minp, maxp, data, param2_data, a, cid ) +-- calculate which mob works and lives where +mg_villages.inhabitants.assign_mobs = function( village, village_id, force_repopulate ) + -- make sure mobs get assigned only once (no point in doing this every time + -- when part of a village spawned) + if( village.mob_data_version and not(force_repopulate)) then + return; + end + + -- if force_repopulate is true: recalculate road network, discard all worker- and + -- bed data and create new mobs + if( force_repopulate ) then + for plot_nr,bpos in ipairs(village.to_add_data.bpos) do + -- delete information about who works here + bpos.worker = nil; + -- delete information about who lives here + bpos.beds = nil; + -- delete information about the interconnection of the road network + bpos.xdir = nil; + bpos.parent_road_plot = nil; + end + end + + -- analyze the road network + mg_villages.get_road_list( village_id, true ); -- some types of buildings require special workers village.to_add_data.bpos = mg_villages.inhabitants.assign_jobs_to_houses( village.to_add_data.bpos ); @@ -1171,7 +1193,16 @@ mg_villages.inhabitants.part_of_village_spawned = function( village, minp, maxp, -- each bed gets a mob assigned bpos = mg_villages.inhabitants.assign_mobs_to_beds( bpos, plot_nr, village.to_add_data.bpos, village ); + end + -- later versions may become incompatible + village.mob_data_version = 1; +end + +-- spawn mobs in villages +mg_villages.inhabitants.part_of_village_spawned = function( village, minp, maxp, data, param2_data, a, cid ) + -- for each building in the village + for plot_nr,bpos in ipairs(village.to_add_data.bpos) do -- actually spawn the mobs local village_id = tostring( village.vx )..':'..tostring( village.vz ); mg_villages.inhabitants.spawn_mobs_for_one_house( bpos, minp, maxp, village_id, plot_nr ); diff --git a/mapgen.lua b/mapgen.lua index 1c7c1f8..547574c 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -1235,11 +1235,14 @@ mg_villages.place_villages_via_voxelmanip = function( villages, minp, maxp, vm, t1 = time_elapsed( t1, 'do fill chests' ); -- TODO: extra_calls.signs - -- set up workplace markers so that they know for which mob they are responsible + -- set up mob data and workplace markers so that they know for which mob they are responsible for _, village in ipairs(villages) do local village_id = tostring( village.vx )..':'..tostring( village.vz ); - -- this is a good time to analyze the road network as well - mg_villages.get_road_list( village_id, true ); + -- analyze road network, assign workers to buildings, assign mobs to beds + mg_villages.inhabitants.assign_mobs( village, village_id, false ); + -- TODO: set up workplace markers based on what was assigned in the function above + -- TODO: also label beds? + -- set up the workplace markers for building_nr_in_bpos,pos in ipairs( village.to_add_data.bpos ) do if( pos.workplaces and #pos.workplaces>0) then for workplace_nr, wp in ipairs( pos.workplaces ) do