added option to plotmarker for changing village replacements etc

This commit is contained in:
Sokomine 2016-06-23 04:51:06 +02:00
parent 3e2a55a308
commit 0ac703ef88

View File

@ -33,6 +33,26 @@ mg_villages.get_town_id_at_pos = function( pos )
end
-- search the trader (who is supposed to be at the given position) and
-- spawn a new one in case he went missing
mg_villages.plotmarker_search_trader = function( trader, height )
local obj_list = minetest.get_objects_inside_radius({x=trader.x, y=height, z=trader.z}, 10 );
for i,obj in ipairs( obj_list ) do
local e = obj:get_luaentity();
if( e and e.object ) then
local p = e.object:getpos();
if( p and p.x and math.abs(p.x-trader.x)<1.5
and p.z and math.abs(p.z-trader.z)<1.5
and e.name and e.name=="mobf_trader:trader"
and e.trader_typ and e.trader_typ==trader.typ) then
-- minetest.chat_send_player( "singleplayer", "FOUND trader "..tostring( e.trader_typ)); --TODO
end
end
end
end
-- checks if the plot marker is still present; places a new one if needed
-- p: plot data (position, size, orientation, owner, ..)
mg_villages.check_plot_marker = function( p, plot_nr, village_id )
@ -167,16 +187,214 @@ mg_villages.plotmarker_formspec = function( pos, formname, fields, player )
or not( mg_villages.all_villages )
or not( mg_villages.all_villages[ village_id ] )
or not( plot_nr )
or not( mg_villages.all_villages[ village_id ].to_add_data )
or not( mg_villages.all_villages[ village_id ].to_add_data.bpos )
or not( mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ] )) then
minetest.chat_send_player( pname, 'Error. This plot marker is not configured correctly.'..minetest.serialize({village_id,plot_nr }));
return;
end
local owner = mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].owner;
local btype = mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ].btype;
local village = mg_villages.all_villages[ village_id ];
local plot = mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ];
local owner_name = plot.owner;
if( not( owner_name ) or owner_name == "" ) then
if( plot.btype=="road" ) then
owner_name = "- the village community -";
else
owner_name = "- for sale -";
end
end
local building_name = mg_villages.BUILDINGS[ plot.btype ].mts_path..mg_villages.BUILDINGS[ plot.btype ].scm;
-- show coordinates of the village center to the player
local village_pos = minetest.pos_to_string( {x=village.vx, y=village.vh, z=village.vz});
-- distance from village center
local distance = math.floor( math.sqrt( (village.vx - pos.x ) * (village.vx - pos.x )
+ (village.vh - pos.y ) * (village.vh - pos.y )
+ (village.vz - pos.z ) * (village.vz - pos.z ) ));
-- create the header
local formspec = "size[13,10]"..
"label[3.3,0.0;Plot No.: "..tostring( plot_nr )..", with "..tostring( mg_villages.BUILDINGS[ plot.btype ].scm ).."]"..
"label[0.3,0.4;Located at:]" .."label[3.3,0.4;"..(minetest.pos_to_string( pos ) or '?')..", which is "..tostring( distance ).." m away]"
.."label[7.3,0.4;from the village center]"..
"label[0.3,0.8;Part of village:]" .."label[3.3,0.8;"..(village.name or "- name unknown -").."]"
.."label[7.3,0.8;located at "..(village_pos).."]"..
"label[0.3,1.2;Owned by:]" .."label[3.3,1.2;"..(owner_name).."]"..
"label[3.3,1.6;Click on a menu entry to select it:]"..
"field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]";
build_chest.show_size_data( building_name );
if( plot and plot.traders ) then
if( #plot.traders > 1 ) then
formspec = formspec.."label[0.3,7.0;Some traders live here. One works as a "..tostring(plot.traders[1].typ)..".]";
for i=2,#plot.traders do
formspec = formspec.."label[0.3,"..(6.0+i)..";Another trader works as a "..tostring(plot.traders[i].typ)..".]";
end
elseif( plot.traders[1] and plot.traders[1].typ) then
formspec = formspec..
"label[0.3,7.0;A trader lives here. He works as a "..tostring( plot.traders[1].typ )..".]";
else
formspec = formspec..
"label[0.3,7.0;No trader currently works at this place.]";
end
-- add buttons for visiting (teleport to trader), calling (teleporting trader to plot) and firing the trader
for i,trader in ipairs(plot.traders) do
local trader_entity = mg_villages.plotmarker_search_trader( trader, village.vh );
formspec = formspec..
"button[6.0,"..(6.0+i)..";1.2,0.5;visit_trader_"..i..";visit]"..
"button[7.4,"..(6.0+i)..";1.2,0.5;call_trader_"..i..";call]"..
"button[8.8,"..(6.0+i)..";1.2,0.5;fire_trader_"..i..";fire]";
if( fields[ "visit_trader_"..i ] ) then
player:moveto( {x=trader.x, y=(village.vh+1), z=trader.z} );
minetest.chat_send_player( pname, "You are visiting the "..tostring( trader.typ )..
" trader, who is supposed to be somewhere here. He might also be on a floor above you.");
return;
end
if( fields[ "visit_call_"..i ] ) then
-- TODO: spawning: mob_basics.spawn_mob( {x=v.x, y=v.y, z=v.z}, v.typ, nil, nil, nil, nil, true );
end
-- TODO: fire mob
end
formspec = formspec.."button[3.75,"..(7.0+math.max(1,#plot.traders))..";3.5,0.5;hire_trader;Hire a new random trader]";
-- TODO: hire mob
end
local replace_row = -1;
-- the player selected a material which ought to be replaced
if( fields.build_chest_replacements ) then
local event = minetest.explode_table_event( fields.build_chest_replacements );
if( event and event.row and event.row > 0 ) then
replace_row = event.row;
fields.show_materials = "show_materials";
end
-- the player provided the name of the material for the replacement of the currently selected
elseif( fields.store_replacement and fields.store_repalcement ~= ""
and fields.replace_row_with and fields.replace_row_with ~= ""
and fields.replace_row_material and fields.replace_row_material ~= "") then
build_chest.replacements_apply( pos, meta, fields.replace_row_material, fields.replace_row_with, village_id );
fields.show_materials = "show_materials";
-- group selections for easily changing several nodes at once
elseif( fields.wood_selection ) then
build_chest.replacements_apply_for_group( pos, meta, 'wood', fields.wood_selection, fields.set_wood, village_id );
fields.set_wood = nil;
fields.show_materials = "show_materials";
elseif( fields.farming_selection ) then
build_chest.replacements_apply_for_group( pos, meta, 'farming', fields.farming_selection, fields.set_farming, village_id );
fields.set_farming = nil;
fields.show_materials = "show_materials";
elseif( fields.roof_selection ) then
build_chest.replacements_apply_for_group( pos, meta, 'roof', fields.roof_selection, fields.set_roof, village_id );
fields.set_roof = nil;
fields.show_materials = "show_materials";
-- actually store the new group replacement
elseif( (fields.set_wood and fields.set_wood ~= "")
or (fields.set_farming and fields.set_farming ~= "" )
or (fields.set_roof and fields.set_roof ~= "" )) then
minetest.show_formspec( pname, "mg_villages:plotmarker",
handle_schematics.get_formspec_group_replacement( pos, fields, formspec ));
return;
end
-- show which materials (and replacements!) where used for the building
if( (fields.show_materials and fields.show_materials ~= "" )
or (fields.replace_row_with and fields.replace_row_with ~= "")
or (fields.replace_row_material and fields.replace_row_material ~= "")) then
formspec = formspec.."button[9.9,0.4;2,0.5;info;Back]";
if( not( minetest.check_player_privs( pname, {protection_bypass=true}))) then
-- do not allow any changes; just show the materials and their replacements
minetest.show_formspec( pname, "mg_villages:plotmarker",
formspec..build_chest.replacements_get_list_formspec( pos, nil, 0, meta, village_id, building_name, replace_row ));
else
minetest.show_formspec( pname, "mg_villages:plotmarker",
formspec..build_chest.replacements_get_list_formspec( pos, nil, 1, nil, village_id, building_name, replace_row ));
end
return;
-- place the building again
elseif( (fields.reset_building and fields.reset_building ~= "")
or (fields.remove_building and fields.remove_building ~= "")) then
formspec = formspec.."button[9.9,0.4;2,0.5;back;Back]";
if( not( minetest.check_player_privs( pname, {protection_bypass=true}))) then
minetest.show_formspec( pname, "mg_villages:plotmarker", formspec..
"label[3,3;You need the protection_bypass priv in order to use this functin.]" );
return;
end
local selected_building = build_chest.building[ building_name ];
local start_pos = {x=plot.x, y=plot.y, z=plot.z, brotate=plot.brotate};
if( selected_building.yoff ) then
start_pos.y = start_pos.y + selected_building.yoff;
end
local end_pos = {x=plot.x+plot.bsizex-1,
y=plot.y+selected_building.yoff-1+selected_building.ysize,
z=plot.z+plot.bsizez-1};
local replacements = build_chest.replacements_get_current( meta, village_id );
if( fields.remove_building and fields.remove_building ~= "" ) then
-- clear the space above ground, put dirt below ground, but keep the
-- surface intact
handle_schematics.clear_area( start_pos, end_pos, pos.y-1);
-- also clear the meta data to avoid strange effects
handle_schematics.clear_meta( start_pos, end_pos );
formspec = formspec.."label[3,3;The plot has been cleared.]";
else
-- actually place it (disregarding mirroring)
local error_msg = handle_schematics.place_building_from_file(
start_pos,
end_pos,
building_name,
replacements,
plot.o,
build_chest.building[ building_name ].axis, plot.mirror, 1, true );
formspec = formspec.."label[3,3;The building has been reset.]";
if( error_msg ) then
formspec = formspec..'label[4,3;Error: '..tostring( fields.error_msg ).."]";
end
end
minetest.show_formspec( pname, "mg_villages:plotmarker", formspec );
return;
elseif( fields.info and fields.info ~= "" ) then
local show_material_text = "Change materials used";
if( not( minetest.check_player_privs( pname, {protection_bypass=true}))) then
show_material_text = "Show materials used";
end
minetest.show_formspec( pname, "mg_villages:plotmarker",
formspec..
"button[9.9,0.4;2,0.5;back;Back]"..
"button[3,3;5,0.5;create_backup;Create backup of current stage]"..
"button[4,4;3,0.5;show_materials;"..show_material_text.."]"..
"button[4,5;3,0.5;reset_building;Reset building]"..
"button[4,6;3,0.5;remove_building;Remove building]");
return;
end
local owner = plot.owner;
local btype = plot.btype;
--minetest.chat_send_player( player:get_player_name(),'DATA FOR '..tostring(plot_nr)..': '..minetest.serialize( mg_villages.all_villages[ village_id ].to_add_data.bpos[ plot_nr ] ));
local original_formspec = "size[8,3]"..
"button[7.0,0.0;1.0,0.5;info;Info]"..
"label[1.0,0.5;Plot No.: "..tostring( plot_nr ).."]"..
"label[2.5,0.5;Building:]"..
"label[3.5,0.5;"..tostring( mg_villages.BUILDINGS[btype].scm ).."]"..