forked from VoxeLibre/VoxeLibre
Complete prototype of biome generated mobs
This commit is contained in:
parent
518252679f
commit
9d48549ec5
|
@ -89,7 +89,7 @@ local cod = {
|
||||||
y = lp.y - s.y,
|
y = lp.y - s.y,
|
||||||
z = lp.z - s.z
|
z = lp.z - s.z
|
||||||
}
|
}
|
||||||
if not object:is_player() and object:get_luaentity().name == "extra_mobs:cod" then
|
if object and not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "extra_mobs:cod" then
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
|
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
|
||||||
end
|
end
|
||||||
|
|
|
@ -88,7 +88,7 @@ local fox = {
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 8)) do
|
for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 8)) do
|
||||||
if not object:is_player() and object:get_luaentity().name == "extra_mobs:fox" and self.state ~= "attack" and math.random(1, 500) == 1 then
|
if object and not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "extra_mobs:fox" and self.state ~= "attack" and math.random(1, 500) == 1 then
|
||||||
self.horny = true
|
self.horny = true
|
||||||
end
|
end
|
||||||
local lp = object:get_pos()
|
local lp = object:get_pos()
|
||||||
|
@ -98,7 +98,7 @@ local fox = {
|
||||||
y = lp.y - s.y,
|
y = lp.y - s.y,
|
||||||
z = lp.z - s.z
|
z = lp.z - s.z
|
||||||
}
|
}
|
||||||
if object:is_player() and not object:get_player_control().sneak or not object:is_player() and object:get_luaentity().name == "mobs_mc:wolf" then
|
if object and object:is_player() and not object:get_player_control().sneak or not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mobs_mc:wolf" then
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
|
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
|
||||||
if self.reach > vector.distance(self.object:get_pos(), object:get_pos()) and self.timer > .9 then
|
if self.reach > vector.distance(self.object:get_pos(), object:get_pos()) and self.timer > .9 then
|
||||||
|
@ -154,6 +154,7 @@ mobs_mc.spawn_height.water,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mobs_mc.spawn_height.overworld_max)
|
||||||
|
|
||||||
--mobs:spawn_specific("extra_mobs:fox", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, 0, 500)
|
--mobs:spawn_specific("extra_mobs:fox", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, 0, 500)
|
||||||
|
--[[
|
||||||
mobs:spawn_specific(
|
mobs:spawn_specific(
|
||||||
"extra_mobs:artic_fox",
|
"extra_mobs:artic_fox",
|
||||||
"overworld",
|
"overworld",
|
||||||
|
@ -171,6 +172,6 @@ minetest.LIGHT_MAX+1,
|
||||||
3,
|
3,
|
||||||
mobs_mc.spawn_height.water,
|
mobs_mc.spawn_height.water,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mobs_mc.spawn_height.overworld_max)
|
||||||
|
]]--
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("extra_mobs:fox", S("Fox"), "extra_mobs_spawn_icon_fox.png", 0)
|
mobs:register_egg("extra_mobs:fox", S("Fox"), "extra_mobs_spawn_icon_fox.png", 0)
|
||||||
|
|
|
@ -1,29 +1,18 @@
|
||||||
|
--lua locals
|
||||||
|
local get_node = minetest.get_node
|
||||||
|
local get_item_group = minetest.get_item_group
|
||||||
|
local get_node_light = minetest.get_node_light
|
||||||
|
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
|
||||||
|
local new_vector = vector.new
|
||||||
|
local math_random = math.random
|
||||||
|
local get_biome_name = minetest.get_biome_name
|
||||||
--[[
|
--[[
|
||||||
|
|
||||||
THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
|
THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
|
||||||
|
|
||||||
underground:
|
underground:
|
||||||
"FlowerForest_underground",
|
"FlowerForest_underground",
|
||||||
"JungleEdge_underground",
|
"JungleEdge_underground",local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
|
||||||
"StoneBeach_underground",
|
|
||||||
"MesaBryce_underground",
|
|
||||||
"Mesa_underground",
|
|
||||||
"RoofedForest_underground",
|
|
||||||
"Jungle_underground",
|
|
||||||
"Swampland_underground",
|
|
||||||
"MushroomIsland_underground",
|
|
||||||
"BirchForest_underground",
|
|
||||||
"Plains_underground",
|
|
||||||
"MesaPlateauF_underground",
|
|
||||||
"ExtremeHills_underground",
|
|
||||||
"MegaSpruceTaiga_underground",
|
|
||||||
"BirchForestM_underground",
|
|
||||||
"SavannaM_underground",
|
|
||||||
"MesaPlateauFM_underground",
|
|
||||||
"Desert_underground",
|
|
||||||
"Savanna_underground",
|
|
||||||
"Forest_underground",
|
|
||||||
"SunflowerPlains_underground",
|
|
||||||
"ColdTaiga_underground",
|
"ColdTaiga_underground",
|
||||||
"IcePlains_underground",
|
"IcePlains_underground",
|
||||||
"IcePlainsSpikes_underground",
|
"IcePlainsSpikes_underground",
|
||||||
|
@ -433,59 +422,22 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh
|
||||||
|
|
||||||
|
|
||||||
--load information into the spawn dictionary
|
--load information into the spawn dictionary
|
||||||
|
local key = #spawn_dictionary + 1
|
||||||
|
spawn_dictionary[key] = {}
|
||||||
|
spawn_dictionary[key]["name"] = name
|
||||||
|
spawn_dictionary[key]["dimension"] = dimension
|
||||||
|
spawn_dictionary[key]["type_of_spawning"] = type_of_spawning
|
||||||
|
spawn_dictionary[key]["biomes"] = biomes
|
||||||
|
spawn_dictionary[key]["min_light"] = min_light
|
||||||
|
spawn_dictionary[key]["max_light"] = max_light
|
||||||
|
spawn_dictionary[key]["interval"] = interval
|
||||||
|
spawn_dictionary[key]["chance"] = chance
|
||||||
|
spawn_dictionary[key]["aoc"] = aoc
|
||||||
|
spawn_dictionary[key]["min_height"] = min_height
|
||||||
|
spawn_dictionary[key]["max_height"] = max_height
|
||||||
|
spawn_dictionary[key]["day_toggle"] = day_toggle
|
||||||
|
spawn_dictionary[key]["on_spawn"] = spawn_abm_action
|
||||||
|
|
||||||
--allow for new dimensions to be auto added
|
|
||||||
--this will take extra time, a whole few nanoseconds
|
|
||||||
--but will allow modularity
|
|
||||||
|
|
||||||
--build dimensions modularly
|
|
||||||
if not spawn_dictionary[dimension] then
|
|
||||||
spawn_dictionary[dimension] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
--build biome list modularly
|
|
||||||
for _,added_biome in pairs(biomes) do
|
|
||||||
if not spawn_dictionary[dimension][added_biome] then
|
|
||||||
spawn_dictionary[dimension][added_biome] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
--build type of spawning per biome modularly
|
|
||||||
if not spawn_dictionary[dimension][added_biome][type_of_spawning] then
|
|
||||||
spawn_dictionary[dimension][added_biome][type_of_spawning] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
--build light levels to spawn mob
|
|
||||||
for i = min_light,max_light do
|
|
||||||
if not spawn_dictionary[dimension][added_biome][type_of_spawning][i] then
|
|
||||||
spawn_dictionary[dimension][added_biome][type_of_spawning][i] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
for y = min_height, max_height do
|
|
||||||
--print(y)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
print("--")
|
|
||||||
print(min_height, max_height)
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
local key = #spawn_dictionary[dimension] + 1
|
|
||||||
|
|
||||||
spawn_dictionary[dimension][key] = {}
|
|
||||||
spawn_dictionary[dimension][key]["name"] = name
|
|
||||||
spawn_dictionary[dimension][key]["type"] = type_of_spawning
|
|
||||||
spawn_dictionary[dimension][key]["min_light"] = min_light
|
|
||||||
spawn_dictionary[dimension][key]["max_light"] = max_light
|
|
||||||
spawn_dictionary[dimension][key]["interval"] = interval
|
|
||||||
spawn_dictionary[dimension][key]["chance"] = chance
|
|
||||||
spawn_dictionary[dimension][key]["aoc"] = aoc
|
|
||||||
spawn_dictionary[dimension][key]["min_height"] = min_height
|
|
||||||
spawn_dictionary[dimension][key]["max_height"] = max_height
|
|
||||||
spawn_dictionary[dimension][key]["day_toggle"] = day_toggle
|
|
||||||
spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action
|
|
||||||
]]--
|
|
||||||
--[[
|
--[[
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = name .. " spawning",
|
label = name .. " spawning",
|
||||||
|
@ -499,7 +451,6 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh
|
||||||
]]--
|
]]--
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- compatibility with older mob registration
|
-- compatibility with older mob registration
|
||||||
-- we're going to forget about this for now -j4i
|
-- we're going to forget about this for now -j4i
|
||||||
--[[
|
--[[
|
||||||
|
@ -574,108 +525,119 @@ local function decypher_limits(posy)
|
||||||
posy = math.floor(posy)
|
posy = math.floor(posy)
|
||||||
return posy - 32, posy + 32
|
return posy - 32, posy + 32
|
||||||
end
|
end
|
||||||
--[[
|
|
||||||
minetest.register_on_mods_loaded(function()
|
--a simple helper function for mob_spawn
|
||||||
for _,data in pairs(minetest.registered_biomes) do
|
local function biome_check(biome_list, biome_goal)
|
||||||
print(data.name)
|
for _,data in ipairs(biome_list) do
|
||||||
|
if data == biome_goal then
|
||||||
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
print(dump(spawn_dictionary))
|
return false
|
||||||
end)
|
end
|
||||||
]]--
|
|
||||||
|
|
||||||
--todo mob limiting
|
--todo mob limiting
|
||||||
--MAIN LOOP
|
--MAIN LOOP
|
||||||
--[[
|
|
||||||
if mobs_spawn then
|
if mobs_spawn then
|
||||||
local timer = 15 --0
|
local timer = 15 --0
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
timer = timer + dtime
|
timer = timer + dtime
|
||||||
if timer >= 15 then
|
if timer >= 15 then
|
||||||
timer = 15--0
|
timer = 0--15--0
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
for i = 1,math.random(5) do
|
for i = 1,math.random(5) do
|
||||||
|
|
||||||
local player_pos = player:get_pos()
|
local player_pos = player:get_pos()
|
||||||
|
|
||||||
local _,dimension = mcl_worlds.y_to_layer(player_pos.y)
|
local _,dimension = mcl_worlds.y_to_layer(player_pos.y)
|
||||||
|
|
||||||
if dimension == "void" or dimension == "default" then
|
if dimension == "void" or dimension == "default" then
|
||||||
goto continue -- ignore void and unloaded area
|
goto continue -- ignore void and unloaded area
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local min,max = decypher_limits(player_pos.y)
|
local min,max = decypher_limits(player_pos.y)
|
||||||
|
|
||||||
local goal_pos = position_calculation(player_pos)
|
local goal_pos = position_calculation(player_pos)
|
||||||
|
|
||||||
local gotten_biome = minetest.get_biome_data(goal_pos)
|
local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"})
|
||||||
|
|
||||||
|
--couldn't find node
|
||||||
|
if #spawning_position_list <= 0 then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)]
|
||||||
|
|
||||||
|
--I have no idea why this would happen, but better to be safe
|
||||||
|
if not spawning_position then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local gotten_node = get_node(spawning_position).name
|
||||||
|
|
||||||
|
if not gotten_node or gotten_node == "air" then --skip air nodes
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local gotten_biome = minetest.get_biome_data(spawning_position)
|
||||||
|
|
||||||
if not gotten_biome then
|
if not gotten_biome then
|
||||||
goto continue --skip if in unloaded area
|
goto continue --skip if in unloaded area
|
||||||
end
|
end
|
||||||
|
|
||||||
print(minetest.get_biome_name(gotten_biome.biome))
|
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
|
||||||
|
|
||||||
local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])]
|
--grab random mob
|
||||||
|
local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)]
|
||||||
|
|
||||||
if not mob_def then --to catch a crazy error if it ever happens
|
if not mob_def then
|
||||||
minetest.log("error", "WARNING!! Attempted to spawn a mob that doesn't exist! Please notify developers!\nThe game will continue to run though.")
|
goto continue --skip if something ridiculous happens (nil mob def)
|
||||||
goto continue
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if mob_def.type == "ground" then
|
--skip if not correct dimension
|
||||||
|
if mob_def.dimension ~= dimension then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"})
|
--add this so mobs don't spawn inside nodes
|
||||||
|
spawning_position.y = spawning_position.y + 1
|
||||||
|
|
||||||
if #spawning_position_list <= 0 then
|
if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
|
|
||||||
|
|
||||||
spawning_position.y = spawning_position.y + 1
|
--only need to poll for node light if everything else worked
|
||||||
|
local gotten_light = get_node_light(spawning_position)
|
||||||
|
|
||||||
local gotten_light = minetest.get_node_light(spawning_position)
|
--don't spawn if not in light limits
|
||||||
|
if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then
|
local is_water = get_item_group(gotten_node, "water") ~= 0
|
||||||
minetest.add_entity(spawning_position, mob_def.name)
|
local is_lava = get_item_group(gotten_node, "lava") ~= 0
|
||||||
end
|
|
||||||
elseif mob_def.type == "air" then
|
|
||||||
local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"})
|
|
||||||
|
|
||||||
if #spawning_position_list <= 0 then
|
if mob_def.type_of_spawning == "ground" and is_water then
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
|
|
||||||
|
|
||||||
local gotten_light = minetest.get_node_light(spawning_position)
|
if mob_def.type_of_spawning == "ground" and is_lava then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then
|
--adjust the position for water and lava mobs
|
||||||
minetest.add_entity(spawning_position, mob_def.name)
|
if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then
|
||||||
end
|
spawning_position.y = spawning_position.y - 1
|
||||||
elseif mob_def.type == "water" then
|
end
|
||||||
local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"})
|
|
||||||
|
|
||||||
if #spawning_position_list <= 0 then
|
|
||||||
goto continue
|
|
||||||
end
|
|
||||||
|
|
||||||
local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
|
|
||||||
|
|
||||||
local gotten_light = minetest.get_node_light(spawning_position)
|
|
||||||
|
|
||||||
if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then
|
|
||||||
minetest.add_entity(spawning_position, mob_def.name)
|
|
||||||
end
|
|
||||||
--elseif mob_def.type == "lava" then
|
|
||||||
--implement later
|
|
||||||
end
|
|
||||||
--local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"})
|
|
||||||
|
|
||||||
|
--everything is correct, spawn mob
|
||||||
|
minetest.add_entity(spawning_position, mob_def.name)
|
||||||
::continue:: --this is a safety catch
|
::continue:: --this is a safety catch
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
]]--
|
|
|
@ -290,9 +290,9 @@ mobs_mc.spawn = {
|
||||||
mobs_mc.spawn_height = {
|
mobs_mc.spawn_height = {
|
||||||
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
||||||
|
|
||||||
-- Overworld boundaries (inclusive) --had to make this reasonable otherwise mob spawning would go nuts using data
|
-- Overworld boundaries (inclusive) --I adjusted this to be more reasonable
|
||||||
overworld_min = -64,-- -2999,
|
overworld_min = -64,-- -2999,
|
||||||
overworld_max = 256,-- 31000,
|
overworld_max = 31000,
|
||||||
|
|
||||||
-- Nether boundaries (inclusive)
|
-- Nether boundaries (inclusive)
|
||||||
nether_min = -29067,-- -3369,
|
nether_min = -29067,-- -3369,
|
||||||
|
|
Loading…
Reference in New Issue