Spawner: Adds ABM for replacement for when LBM fails.
This commit is contained in:
parent
f5fbda142e
commit
3649d5bc6a
@ -8,34 +8,57 @@
|
|||||||
-- to know where the farm they work is located, or where the bed they sleep is.
|
-- to know where the farm they work is located, or where the bed they sleep is.
|
||||||
-- Other mods have to be supported for this to work correctly, as there are
|
-- Other mods have to be supported for this to work correctly, as there are
|
||||||
-- many sitting nodes, many beds, many tables, chests, etc. For now, by default,
|
-- many sitting nodes, many beds, many tables, chests, etc. For now, by default,
|
||||||
-- support for default and cottages is going to be provided.
|
-- support for default MTG games and cottages mod is going to be provided.
|
||||||
|
|
||||||
npc.places = {}
|
npc.places = {}
|
||||||
|
|
||||||
npc.places.nodes = {
|
npc.places.nodes = {
|
||||||
BEDS = {
|
BED_TYPE = {
|
||||||
"beds:bed_bottom",
|
"beds:bed_bottom",
|
||||||
"beds:fancy_bed_bottom"
|
"beds:fancy_bed_bottom",
|
||||||
},
|
"cottages:bed_foot",
|
||||||
SITTABLE = {
|
"cottages:straw_mat",
|
||||||
|
"cottages:sleeping_mat"
|
||||||
|
},
|
||||||
|
SITTABLE_TYPE = {
|
||||||
"cottages:bench",
|
"cottages:bench",
|
||||||
-- TODO: Register all stairs node that are supported for sitting
|
-- TODO: Register other stair types
|
||||||
-- Hint: wood
|
|
||||||
"stairs:stair_wood"
|
"stairs:stair_wood"
|
||||||
},
|
},
|
||||||
CHESTS = {
|
STORAGE_TYPE = {
|
||||||
"default:chest",
|
"default:chest",
|
||||||
"default:chest_locked"
|
"default:chest_locked",
|
||||||
|
"cottages:shelf"
|
||||||
|
},
|
||||||
|
FURNACE_TYPE = {
|
||||||
|
"default:furnace",
|
||||||
|
"default:furnace_active"
|
||||||
|
},
|
||||||
|
OPENABLE_TYPE = {
|
||||||
|
-- TODO: Register fences
|
||||||
|
"doors:door_glass_a",
|
||||||
|
"doors:door_glass_b",
|
||||||
|
"doors:door_obsidian_a",
|
||||||
|
"doors:door_obsidian_b",
|
||||||
|
"doors:door_steel_a",
|
||||||
|
"doors:door_steel_b",
|
||||||
|
"doors:door_wood_a",
|
||||||
|
"doors:door_wood_b",
|
||||||
|
"cottages:gate_open",
|
||||||
|
"cottages:gate_closed",
|
||||||
|
"cottages:half_door"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
npc.places.PLACE_TYPE = {
|
npc.places.PLACE_TYPE = {
|
||||||
"OWN_BED",
|
NPC_HOUSE = {
|
||||||
"OWN_CHEST",
|
"OWN_BED",
|
||||||
"HOUSE_CHAIR",
|
"OWN_ROOM_DOOR",
|
||||||
"HOUSE_TABLE",
|
"OWN_STORAGE",
|
||||||
"HOUSE_FURNACE",
|
"SHARED_FURNACE",
|
||||||
"HOUSE_ENTRANCE"
|
"SHARED_SITTABLE",
|
||||||
|
"ENTRANCE_DOOR"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
240
spawner.lua
240
spawner.lua
@ -37,9 +37,14 @@
|
|||||||
-- such as scanning upper floors, spawning families of NPCs and creating relationships
|
-- such as scanning upper floors, spawning families of NPCs and creating relationships
|
||||||
-- among them, etc. will be for other versions.
|
-- among them, etc. will be for other versions.
|
||||||
|
|
||||||
|
-- Public API
|
||||||
|
npc.spawner = {}
|
||||||
|
-- Private API
|
||||||
|
local spawner = {}
|
||||||
|
|
||||||
-- This is the official list of support building types
|
-- This is the official list of support building types
|
||||||
-- from the mg_villages mod
|
-- from the mg_villages mod
|
||||||
local mg_villages_supported_building_types = {
|
npc.spawner.mg_villages_supported_building_types = {
|
||||||
"house",
|
"house",
|
||||||
"farm_full",
|
"farm_full",
|
||||||
"farm_tiny",
|
"farm_tiny",
|
||||||
@ -47,13 +52,112 @@ local mg_villages_supported_building_types = {
|
|||||||
"lumberjack"
|
"lumberjack"
|
||||||
}
|
}
|
||||||
|
|
||||||
local replace_activated = true
|
npc.spawner.replace_activated = true
|
||||||
local max_replace_count = 1
|
-- npc.spawner.max_replace_count = 1
|
||||||
local replace_count = 0
|
-- spawner.replace_count = 0
|
||||||
|
|
||||||
-- Node registration
|
---------------------------------------------------------------------------------------
|
||||||
-- This node is currently a slightly modified mg_villages:plotmarker
|
-- Scanning functions
|
||||||
minetest.register_node("advanced_npc:auto_spawner", {
|
---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Scans an area for the supported nodes: beds, benches,
|
||||||
|
-- furnaces, storage (e.g. chests) and openable (e.g. doors).
|
||||||
|
-- Returns a table with these classifications
|
||||||
|
function spawner.scan_area(start_pos, end_pos)
|
||||||
|
minetest.log("Scanning area for nodes...")
|
||||||
|
minetest.log("Start pos: "..dump(start_pos))
|
||||||
|
minetest.log("End pos: "..dump(end_pos))
|
||||||
|
local result = {
|
||||||
|
bed_type = {},
|
||||||
|
sittable_type = {},
|
||||||
|
furnace_type = {},
|
||||||
|
storage_type = {},
|
||||||
|
openable_type = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.bed_type = npc.places.find_node_in_area(start_pos, end_pos, npc.places.nodes.BED_TYPE)
|
||||||
|
result.sittable_type = npc.places.find_node_in_area(start_pos, end_pos, npc.places.nodes.SITTABLE_TYPE)
|
||||||
|
result.furnace_type = npc.places.find_node_in_area(start_pos, end_pos, npc.places.nodes.FURNACE_TYPE)
|
||||||
|
result.storage_type = npc.places.find_node_in_area(start_pos, end_pos, npc.places.nodes.STORAGE_TYPE)
|
||||||
|
result.openable_type = npc.places.find_node_in_area(start_pos, end_pos, npc.places.nodes.OPENABLE_TYPE)
|
||||||
|
|
||||||
|
minetest.log("Found nodes inside area: "..dump(result))
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- This function takes care of calculating how many NPCs will be spawn
|
||||||
|
function spawner.calculate_npc_spawning(pos)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------
|
||||||
|
-- Support code for mg_villages mods
|
||||||
|
---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- This function creates a table of the scannable nodes inside
|
||||||
|
-- a mg_villages building. It needs the plotmarker position for a start
|
||||||
|
-- point and the building_data to get the x, y and z-coordinate size
|
||||||
|
-- of the building schematic
|
||||||
|
function spawner.scan_mg_villages_building(pos, building_data)
|
||||||
|
-- Get area of the building
|
||||||
|
local x_size = building_data.sizex
|
||||||
|
local y_size = building_data.ysize
|
||||||
|
local z_size = building_data.sizez
|
||||||
|
local start_pos = {x=pos.x, y=pos.y, z=pos.z}
|
||||||
|
local end_pos = {x=pos.x + x_size, y=pos.y + y_size, z=pos.z + z_size}
|
||||||
|
|
||||||
|
return spawner.scan_area(start_pos, end_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This function replaces an existent mg_villages:plotmarker with
|
||||||
|
-- and advanced_npc:auto_spawner. The existing metadata will be kept,
|
||||||
|
-- to allow compatibility. A new formspec will appear on right-click,
|
||||||
|
-- however it will as well allow to buy or manage the plot.
|
||||||
|
-- Also, the building is scanned for NPC-usable nodes and the amount
|
||||||
|
-- of NPCs to spawn and the interval is calculated.
|
||||||
|
function spawner.replace_mg_villages_plotmarker(pos)
|
||||||
|
-- Get the meta at the current position
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local village_id = meta:get_string("village_id")
|
||||||
|
local plot_nr = meta:get_int("plot_nr")
|
||||||
|
local infotext = meta:get_string("infotext")
|
||||||
|
-- Following line from mg_villages mod, protection.lua
|
||||||
|
local btype = mg_villages.all_villages[village_id].to_add_data.bpos[plot_nr].btype
|
||||||
|
local building_data = mg_villages.BUILDINGS[btype]
|
||||||
|
local building_type = building_data.typ
|
||||||
|
-- Check if the building is of the support types
|
||||||
|
for _,value in pairs(npc.spawner.mg_villages_supported_building_types) do
|
||||||
|
|
||||||
|
if building_type == value then
|
||||||
|
|
||||||
|
minetest.log("Replacing mg_villages:plotmarker at "..dump(pos))
|
||||||
|
-- Replace the plotmarker for auto-spawner
|
||||||
|
minetest.set_node(pos, {name="advanced_npc:plotmarker_auto_spawner"})
|
||||||
|
-- Store old plotmarker metadata again
|
||||||
|
meta:set_string("village_id", village_id)
|
||||||
|
meta:set_int("plot_nr", plot_nr)
|
||||||
|
meta:set_string("infotext", infotext)
|
||||||
|
-- Store building type in metadata
|
||||||
|
meta:set_string("building_type", building_type)
|
||||||
|
-- Scan building for nodes
|
||||||
|
local nodedata = spawner.scan_mg_villages_building(pos, building_data)
|
||||||
|
-- Store nodedata into the spawner's metadata
|
||||||
|
meta:set_string("nodedata", minetest.serialize(nodedata))
|
||||||
|
-- Stop searching for building type
|
||||||
|
break
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Only register the node, the ABM and the LBM if mg_villages mod
|
||||||
|
-- is present
|
||||||
|
if minetest.get_modpath("mg_villages") ~= nil then
|
||||||
|
-- Node registration
|
||||||
|
-- This node is currently a slightly modified mg_villages:plotmarker
|
||||||
|
minetest.register_node("advanced_npc:plotmarker_auto_spawner", {
|
||||||
description = "Automatic NPC Spawner",
|
description = "Automatic NPC Spawner",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
tiles = {"default_stone.png"},
|
tiles = {"default_stone.png"},
|
||||||
@ -68,97 +172,53 @@ minetest.register_node("advanced_npc:auto_spawner", {
|
|||||||
groups = {cracky=3,stone=2},
|
groups = {cracky=3,stone=2},
|
||||||
|
|
||||||
on_rightclick = function( pos, node, clicker, itemstack, pointed_thing)
|
on_rightclick = function( pos, node, clicker, itemstack, pointed_thing)
|
||||||
return mg_villages.plotmarker_formspec( pos, nil, {}, clicker )
|
return mg_villages.plotmarker_formspec( pos, nil, {}, clicker )
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
return mg_villages.plotmarker_formspec( pos, formname, fields, sender );
|
return mg_villages.plotmarker_formspec( pos, formname, fields, sender );
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- protect against digging
|
-- protect against digging
|
||||||
can_dig = function(pos, player)
|
can_dig = function(pos, player)
|
||||||
local meta = minetest.get_meta(pos);
|
local meta = minetest.get_meta(pos);
|
||||||
if (meta and meta:get_string("village_id") ~= "" and meta:get_int("plot_nr") and meta:get_int("plot_nr") > 0 ) then
|
if (meta and meta:get_string("village_id") ~= "" and meta:get_int("plot_nr") and meta:get_int("plot_nr") > 0 ) then
|
||||||
return false;
|
return false;
|
||||||
end
|
end
|
||||||
return true;
|
return true;
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Scans an area for the supported nodes: beds, benches,
|
-- LBM Registration
|
||||||
-- furnaces, storage (e.g. chests) and openable (e.g. doors).
|
-- Used to modify plotmarkers and replace them with advanced_npc:plotmarker_auto_spawner
|
||||||
-- Returns a table with these classifications
|
minetest.register_lbm({
|
||||||
local function scan_area(start_pos, end_pos)
|
label = "Replace mg_villages:plotmarker with Advanced NPC auto spawners",
|
||||||
local result = {
|
name = "advanced_npc:mg_villages_plotmarker_replacer",
|
||||||
bed_type = {},
|
nodenames = {"mg_villages:plotmarker"},
|
||||||
sittable_type = {},
|
run_at_every_load = true,
|
||||||
furnace_type = {},
|
action = function(pos, node)
|
||||||
storage_type = {},
|
-- Check if replacement is activated
|
||||||
openable_type = {}
|
if npc.spawner.replace_activated then
|
||||||
}
|
-- Replace mg_villages:plotmarker
|
||||||
|
spawner.replace_mg_villages_plotmarker(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- ABM Registration... for when LBM fails.
|
||||||
|
minetest.register_abm({
|
||||||
|
label = "Replace mg_villages:plotmarker with Advanced NPC auto spawners",
|
||||||
|
nodenames = {"mg_villages:plotmarker"},
|
||||||
|
interval = 1.0,
|
||||||
|
chance = 1,
|
||||||
|
catch_up = true,
|
||||||
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
-- Check if replacement is activated
|
||||||
|
if npc.spawner.replace_activated then
|
||||||
|
-- Replace mg_villages:plotmarker
|
||||||
|
spawner.replace_mg_villages_plotmarker(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This function creates a table of the scannable nodes inside
|
|
||||||
-- a mg_villages building. It needs the plotmarker position for a start
|
|
||||||
-- point and the building_data to get the x, y and z-coordinate size
|
|
||||||
-- of the building schematic
|
|
||||||
local function scan_mg_villages_building(pos, building_data)
|
|
||||||
-- Get area of the building
|
|
||||||
local x_size = building_data.sizex
|
|
||||||
local y_size = building_data.ysize
|
|
||||||
local z_size = building_data.sizez
|
|
||||||
local start_pos = {x=pos.x, y=pos.y, z=pos.z}
|
|
||||||
local end_pos = {x=pos.x + x_size, y=pos.y + y_size, z=pos.z + z_size}
|
|
||||||
|
|
||||||
return scan_area(start_pos, end_pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if minetest.get_modpath("mg_villages") ~= nil then
|
|
||||||
-- LBM Registration
|
|
||||||
-- Used to modify plotmarkers and replace them with advanced_npc:auto_spawner
|
|
||||||
minetest.register_lbm({
|
|
||||||
label = "Replace mg_villages:plotmarker with Advanced NPC auto spawners",
|
|
||||||
name = "advanced_npc:mg_villages_plotmarker_replacer",
|
|
||||||
nodenames = {"mg_villages:plotmarker"},
|
|
||||||
run_at_every_load = true,
|
|
||||||
action = function(pos, node)
|
|
||||||
-- Check if replacement is activated
|
|
||||||
if replace_activated then
|
|
||||||
-- Check if limit has been reached
|
|
||||||
if replace_count < max_replace_count then
|
|
||||||
-- Get the meta at the current position
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local village_id = meta:get_string("village_id")
|
|
||||||
local plot_nr = meta:get_int("plot_nr")
|
|
||||||
local infotext = meta:get_string("infotext")
|
|
||||||
-- Following line from mg_villages mod, protection.lua
|
|
||||||
local btype = mg_villages.all_villages[village_id].to_add_data.bpos[plot_nr].btype
|
|
||||||
minetest.log("All info: "..dump(mg_villages.BUILDINGS[btype]))
|
|
||||||
local building_data = mg_villages.BUILDINGS[btype]
|
|
||||||
local building_type = building_data.typ
|
|
||||||
-- Check if the building is of the support types
|
|
||||||
for _,value in pairs(mg_villages_supported_building_types) do
|
|
||||||
minetest.log("Current value: "..dump(value))
|
|
||||||
if building_type == value then
|
|
||||||
-- Replace the plotmarker for auto-spawner
|
|
||||||
minetest.set_node(pos, {name="advanced_npc:auto_spawner"})
|
|
||||||
-- Set the old plotmarker meta again
|
|
||||||
meta:set_string("village_id", village_id)
|
|
||||||
meta:set_int("plot_nr", plot_nr)
|
|
||||||
meta:set_string("infotext", infotext)
|
|
||||||
|
|
||||||
|
|
||||||
-- Increase count of modified nodes
|
|
||||||
replace_count = replace_count + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user