This commit is contained in:
Elias Fleckenstein 2021-04-10 20:05:09 +02:00
commit 2116b2b9d0
53 changed files with 2937 additions and 456 deletions

View file

@ -61,8 +61,6 @@ end
-- Load settings -- Load settings
local damage_enabled = minetest.settings:get_bool("enable_damage") local damage_enabled = minetest.settings:get_bool("enable_damage")
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local disable_blood = minetest.settings:get_bool("mobs_disable_blood") local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
@ -84,11 +82,6 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then
end) end)
end end
-- calculate aoc range for mob count
local aosrb = tonumber(minetest.settings:get("active_object_send_range_blocks"))
local abr = tonumber(minetest.settings:get("active_block_range"))
local aoc_range = max(aosrb, abr) * 16
-- pathfinding settings -- pathfinding settings
local enable_pathfinding = true local enable_pathfinding = true
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
@ -866,10 +859,12 @@ local check_for_death = function(self, cause, cmi_cause)
remove_texture_mod(self, "^[colorize:#FF000040") remove_texture_mod(self, "^[colorize:#FF000040")
remove_texture_mod(self, "^[brighten") remove_texture_mod(self, "^[brighten")
self.passive = true self.passive = true
self.object:set_properties({ self.object:set_properties({
pointable = false, pointable = false,
collide_with_objects = false, collide_with_objects = false,
}) })
set_velocity(self, 0) set_velocity(self, 0)
local acc = self.object:get_acceleration() local acc = self.object:get_acceleration()
acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0 acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0
@ -3418,7 +3413,6 @@ local mob_activate = function(self, staticdata, def, dtime)
self.timer = 0 self.timer = 0
self.blinktimer = 0 self.blinktimer = 0
self.blinkstatus = false self.blinkstatus = false
self.collide_with_objects = false
-- check existing nametag -- check existing nametag
if not self.nametag then if not self.nametag then
@ -3562,7 +3556,7 @@ local mob_step = function(self, dtime)
end end
-- mob plays random sound at times -- mob plays random sound at times
if random(1, 100) == 1 then if random(1, 70) == 1 then
mob_sound(self, "random", true) mob_sound(self, "random", true)
end end
@ -3907,6 +3901,12 @@ minetest.register_entity(name, {
on_detach_child = mob_detach_child, on_detach_child = mob_detach_child,
on_activate = function(self, staticdata, dtime) on_activate = function(self, staticdata, dtime)
--this is a temporary hack so mobs stop
--glitching and acting really weird with the
--default built in engine collision detection
self.object:set_properties({
collide_with_objects = false,
})
return mob_activate(self, staticdata, def, dtime) return mob_activate(self, staticdata, def, dtime)
end, end,
@ -3925,289 +3925,6 @@ end
end -- END mobs:register_mob function end -- END mobs:register_mob function
-- count how many mobs of one type are inside an area
local count_mobs = function(pos, mobtype)
local num = 0
local objs = minetest.get_objects_inside_radius(pos, aoc_range)
for n = 1, #objs do
local obj = objs[n]:get_luaentity()
if obj and obj.name and obj._cmi_is_mob then
-- count passive mobs only
if mobtype == "!passive" then
if obj.spawn_class == "passive" then
num = num + 1
end
-- count hostile mobs only
elseif mobtype == "!hostile" then
if obj.spawn_class == "hostile" then
num = num + 1
end
-- count ambient mobs only
elseif mobtype == "!ambient" then
if obj.spawn_class == "ambient" then
num = num + 1
end
-- count water mobs only
elseif mobtype == "!water" then
if obj.spawn_class == "water" then
num = num + 1
end
-- count mob type
elseif mobtype and obj.name == mobtype then
num = num + 1
-- count total mobs
elseif not mobtype then
num = num + 1
end
end
end
return num
end
-- global functions
function mobs:spawn_abm_check(pos, node, name)
-- global function to add additional spawn checks
-- return true to stop spawning mob
end
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
-- Do mobs spawn at all?
if not mobs_spawn then
return
end
-- chance/spawn number override in minetest.conf for registered mob
local numbers = minetest.settings:get(name)
if numbers then
numbers = numbers:split(",")
chance = tonumber(numbers[1]) or chance
aoc = tonumber(numbers[2]) or aoc
if chance == 0 then
minetest.log("warning", string.format("[mobs] %s has spawning disabled", name))
return
end
minetest.log("action",
string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
local spawn_action
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
local orig_pos = table.copy(pos)
-- is mob actually registered?
if not mobs.spawning_mobs[name]
or not minetest.registered_entities[name] then
minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!")
return
end
-- additional custom checks for spawning mob
if mobs:spawn_abm_check(pos, node, name) == true then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!")
return
end
-- count nearby mobs in same spawn class
local entdef = minetest.registered_entities[name]
local spawn_class = entdef and entdef.spawn_class
if not spawn_class then
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
end
local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class]
-- do not spawn if too many of same mob in area
if active_object_count_wider >= max_per_block -- large-range mob cap
or (not in_class_cap) -- spawn class mob cap
or count_mobs(pos, name) >= aoc then -- per-mob mob cap
-- too many entities
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!")
return
end
-- if toggle set to nil then ignore day/night check
if day_toggle ~= nil then
local tod = (minetest.get_timeofday() or 0) * 24000
if tod > 4500 and tod < 19500 then
-- daylight, but mob wants night
if day_toggle == false then
-- mob needs night
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!")
return
end
else
-- night time but mob wants day
if day_toggle == true then
-- mob needs day
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!")
return
end
end
end
-- spawn above node
pos.y = pos.y + 1
-- only spawn away from player
local objs = minetest.get_objects_inside_radius(pos, 24)
for n = 1, #objs do
if objs[n]:is_player() then
-- player too close
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!")
return
end
end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!")
return
end
-- are we spawning within height limits?
if pos.y > max_height
or pos.y < min_height then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!")
return
end
-- are light levels ok?
local light = minetest.get_node_light(pos)
if not light
or light > max_light
or light < min_light then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!")
return
end
-- do we have enough space to spawn mob?
local ent = minetest.registered_entities[name]
local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1]))
local min_x, max_x
if width_x % 2 == 0 then
max_x = math.floor(width_x/2)
min_x = -(max_x-1)
else
max_x = math.floor(width_x/2)
min_x = -max_x
end
local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z
if width_z % 2 == 0 then
max_z = math.floor(width_z/2)
min_z = -(max_z-1)
else
max_z = math.floor(width_z/2)
min_z = -max_z
end
local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do
for x = min_x, max_x do
for z = min_z, max_z do
local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
-- inside block
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!")
if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative)
spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative)
end
return
end
end
end
end
-- tweak X/Y/Z spawn pos
if width_x % 2 == 0 then
pos.x = pos.x + 0.5
end
if width_z % 2 == 0 then
pos.z = pos.z + 0.5
end
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, name)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
if on_spawn then
local ent = mob:get_luaentity()
on_spawn(ent, pos)
end
end
local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider)
spawn_action(pos, node, active_object_count, active_object_count_wider, name)
end
minetest.register_abm({
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = floor(max(1, chance * mobs_spawn_chance)),
catch_up = false,
action = spawn_abm_action,
})
end
-- compatibility with older mob registration
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
chance, active_object_count, -31000, max_height, day_toggle)
end
-- MarkBu's spawn function
function mobs:spawn(def)
local name = def.name
local nodes = def.nodes or {"group:soil", "group:stone"}
local neighbors = def.neighbors or {"air"}
local min_light = def.min_light or 0
local max_light = def.max_light or 15
local interval = def.interval or 30
local chance = def.chance or 5000
local active_object_count = def.active_object_count or 1
local min_height = def.min_height or -31000
local max_height = def.max_height or 31000
local day_toggle = def.day_toggle
local on_spawn = def.on_spawn
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
end
-- register arrow for shoot attack -- register arrow for shoot attack
function mobs:register_arrow(name, def) function mobs:register_arrow(name, def)

View file

@ -4,6 +4,9 @@ local path = minetest.get_modpath(minetest.get_current_modname())
-- Mob API -- Mob API
dofile(path .. "/api.lua") dofile(path .. "/api.lua")
-- Spawning Algorithm
dofile(path .. "/spawning.lua")
-- Rideable Mobs -- Rideable Mobs
dofile(path .. "/mount.lua") dofile(path .. "/mount.lua")

View file

@ -0,0 +1,648 @@
--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
local max = math.max
local get_objects_inside_radius = minetest.get_objects_inside_radius
local vector_distance = vector.distance
-- range for mob count
local aoc_range = 32
--[[
THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
underground:
"FlowerForest_underground",
"JungleEdge_underground",local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)]
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
ocean:
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
water or beach?
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
beach:
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
dimension biome:
"Nether",
"End",
Overworld regular:
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
]]--
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
-- count how many mobs of one type are inside an area
local count_mobs = function(pos,mobtype)
print(mobtype)
local num = 0
local objs = get_objects_inside_radius(pos, aoc_range)
for n = 1, #objs do
local obj = objs[n]:get_luaentity()
if obj and obj.name and obj._cmi_is_mob then
-- count hostile mobs only
if mobtype == "hostile" then
if obj.spawn_class == "hostile" then
num = num + 1
end
-- count passive mobs only
else
num = num + 1
end
end
end
return num
end
-- global functions
function mobs:spawn_abm_check(pos, node, name)
-- global function to add additional spawn checks
-- return true to stop spawning mob
end
--[[
Custom elements changed:
name:
the mobs name
dimension:
"overworld"
"nether"
"end"
types of spawning:
"water"
"ground"
"lava"
biomes: tells the spawner to allow certain mobs to spawn in certain biomes
{"this", "that", "grasslands", "whatever"}
what is aoc??? objects in area
WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua??
]]--
--this is where all of the spawning information is kept
local spawn_dictionary = {}
function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
--print(dump(biomes))
-- Do mobs spawn at all?
if not mobs_spawn then
return
end
-- chance/spawn number override in minetest.conf for registered mob
local numbers = minetest.settings:get(name)
if numbers then
numbers = numbers:split(",")
chance = tonumber(numbers[1]) or chance
aoc = tonumber(numbers[2]) or aoc
if chance == 0 then
minetest.log("warning", string.format("[mobs] %s has spawning disabled", name))
return
end
minetest.log("action",
string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
--[[
local spawn_action
spawn_action = function(pos, node, active_object_count, active_object_count_wider, name)
local orig_pos = table.copy(pos)
-- is mob actually registered?
if not mobs.spawning_mobs[name]
or not minetest.registered_entities[name] then
minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!")
return
end
-- additional custom checks for spawning mob
if mobs:spawn_abm_check(pos, node, name) == true then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!")
return
end
-- count nearby mobs in same spawn class
local entdef = minetest.registered_entities[name]
local spawn_class = entdef and entdef.spawn_class
if not spawn_class then
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
end
local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class]
-- do not spawn if too many of same mob in area
if active_object_count_wider >= max_per_block -- large-range mob cap
or (not in_class_cap) -- spawn class mob cap
or count_mobs(pos, name) >= aoc then -- per-mob mob cap
-- too many entities
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!")
return
end
-- if toggle set to nil then ignore day/night check
if day_toggle ~= nil then
local tod = (minetest.get_timeofday() or 0) * 24000
if tod > 4500 and tod < 19500 then
-- daylight, but mob wants night
if day_toggle == false then
-- mob needs night
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!")
return
end
else
-- night time but mob wants day
if day_toggle == true then
-- mob needs day
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!")
return
end
end
end
-- spawn above node
pos.y = pos.y + 1
-- only spawn away from player
local objs = minetest.get_objects_inside_radius(pos, 24)
for n = 1, #objs do
if objs[n]:is_player() then
-- player too close
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!")
return
end
end
-- mobs cannot spawn in protected areas when enabled
if not spawn_protected
and minetest.is_protected(pos, "") then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!")
return
end
-- are we spawning within height limits?
if pos.y > max_height
or pos.y < min_height then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!")
return
end
-- are light levels ok?
local light = minetest.get_node_light(pos)
if not light
or light > max_light
or light < min_light then
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!")
return
end
-- do we have enough space to spawn mob?
local ent = minetest.registered_entities[name]
local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1]))
local min_x, max_x
if width_x % 2 == 0 then
max_x = math.floor(width_x/2)
min_x = -(max_x-1)
else
max_x = math.floor(width_x/2)
min_x = -max_x
end
local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z
if width_z % 2 == 0 then
max_z = math.floor(width_z/2)
min_z = -(max_z-1)
else
max_z = math.floor(width_z/2)
min_z = -max_z
end
local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do
for x = min_x, max_x do
for z = min_z, max_z do
local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
-- inside block
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!")
if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative)
spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative)
end
return
end
end
end
end
-- tweak X/Y/Z spawn pos
if width_x % 2 == 0 then
pos.x = pos.x + 0.5
end
if width_z % 2 == 0 then
pos.z = pos.z + 0.5
end
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, name)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
if on_spawn then
local ent = mob:get_luaentity()
on_spawn(ent, pos)
end
end
local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider)
spawn_action(pos, node, active_object_count, active_object_count_wider, name)
end
]]--
local entdef = minetest.registered_entities[name]
local spawn_class
if entdef.type == "monster" then
spawn_class = "hostile"
else
spawn_class = "passive"
end
--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
spawn_dictionary[key]["spawn_class"] = spawn_class
--[[
minetest.register_abm({
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = floor(max(1, chance * mobs_spawn_chance)),
catch_up = false,
action = spawn_abm_action,
})
]]--
end
-- compatibility with older mob registration
-- we're going to forget about this for now -j4i
--[[
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
chance, active_object_count, -31000, max_height, day_toggle)
end
]]--
--Don't disable this yet-j4i
-- MarkBu's spawn function
function mobs:spawn(def)
--does nothing for now
--[[
local name = def.name
local nodes = def.nodes or {"group:soil", "group:stone"}
local neighbors = def.neighbors or {"air"}
local min_light = def.min_light or 0
local max_light = def.max_light or 15
local interval = def.interval or 30
local chance = def.chance or 5000
local active_object_count = def.active_object_count or 1
local min_height = def.min_height or -31000
local max_height = def.max_height or 31000
local day_toggle = def.day_toggle
local on_spawn = def.on_spawn
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
]]--
end
local axis
--inner and outer part of square donut radius
local inner = 1
local outer = 65
local int = {-1,1}
local position_calculation = function(pos)
pos = vector.floor(pos)
--this is used to determine the axis buffer from the player
axis = math.random(0,1)
--cast towards the direction
if axis == 0 then --x
pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)]
pos.z = pos.z + math.random(-outer,outer)
else --z
pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)]
pos.x = pos.x + math.random(-outer,outer)
end
return(pos)
end
--[[
local decypher_limits_dictionary = {
["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max},
["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max},
["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max}
}
]]--
local function decypher_limits(posy)
--local min_max_table = decypher_limits_dictionary[dimension]
--return min_max_table[1],min_max_table[2]
posy = math.floor(posy)
return posy - 32, posy + 32
end
--a simple helper function for mob_spawn
local function biome_check(biome_list, biome_goal)
for _,data in ipairs(biome_list) do
if data == biome_goal then
return true
end
end
return false
end
--todo mob limiting
--MAIN LOOP
if mobs_spawn then
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer >= 8 then
timer = 0
for _,player in ipairs(minetest.get_connected_players()) do
for i = 1,math.random(3,8) do
local player_pos = player:get_pos()
local _,dimension = mcl_worlds.y_to_layer(player_pos.y)
if dimension == "void" or dimension == "default" then
goto continue -- ignore void and unloaded area
end
local min,max = decypher_limits(player_pos.y)
local goal_pos = position_calculation(player_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)]
--Prevent strange behavior/too close to player
if not spawning_position or vector_distance(player_pos, spawning_position) < 15 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
goto continue --skip if in unloaded area
end
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
--grab random mob
local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)]
if not mob_def then
goto continue --skip if something ridiculous happens (nil mob def)
end
--skip if not correct dimension
if mob_def.dimension ~= dimension then
goto continue
end
--skip if not in correct biome
if not biome_check(mob_def.biomes, gotten_biome) then
goto continue
end
--add this so mobs don't spawn inside nodes
spawning_position.y = spawning_position.y + 1
if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then
goto continue
end
--only need to poll for node light if everything else worked
local gotten_light = 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
local is_water = get_item_group(gotten_node, "water") ~= 0
local is_lava = get_item_group(gotten_node, "lava") ~= 0
if mob_def.type_of_spawning == "ground" and is_water then
goto continue
end
if mob_def.type_of_spawning == "ground" and is_lava then
goto continue
end
--finally do the heavy check (for now) of mobs in area
if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then
goto continue
end
--adjust the position for water and lava mobs
if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then
spawning_position.y = spawning_position.y - 1
end
--everything is correct, spawn mob
minetest.add_entity(spawning_position, mob_def.name)
::continue:: --this is a safety catch
end
end
end
end)
end

View file

@ -290,13 +290,13 @@ 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) -- Overworld boundaries (inclusive) --I adjusted this to be more reasonable
overworld_min = -2999, overworld_min = -64,-- -2999,
overworld_max = 31000, overworld_max = 31000,
-- Nether boundaries (inclusive) -- Nether boundaries (inclusive)
nether_min = -3369, nether_min = -29067,-- -3369,
nether_max = -3000, nether_max = -28939,-- -3000,
-- End boundaries (inclusive) -- End boundaries (inclusive)
end_min = -6200, end_min = -6200,

View file

@ -1,5 +1,5 @@
--################### --###################
--################### AGENT --################### AGENT - seemingly unused
--################### --###################
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator("mobs_mc")

View file

@ -64,7 +64,81 @@ else
end end
-- Spawn on solid blocks at or below Sea level and the selected light level -- Spawn on solid blocks at or below Sea level and the selected light level
mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) mobs:spawn_specific(
"mobs_mc:bat",
"overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
},
0,
maxlight,
20,
5000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.water-1)
-- spawn eggs -- spawn eggs

View file

@ -1,6 +1,6 @@
-- daufinsyd -- daufinsyd
-- My work is under the LGPL terms -- My work is under the LGPL terms
-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez
-- blaze.lua partial copy of mobs_mc/ghast.lua -- blaze.lua partial copy of mobs_mc/ghast.lua
local S = minetest.get_translator("mobs_mc") local S = minetest.get_translator("mobs_mc")
@ -128,7 +128,18 @@ mobs:register_mob("mobs_mc:blaze", {
end, end,
}) })
mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:blaze",
"nether",
"ground",
{"Nether"},
0,
minetest.LIGHT_MAX+1,
30,
5000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- Blaze fireball -- Blaze fireball
mobs:register_arrow("mobs_mc:blaze_fireball", { mobs:register_arrow("mobs_mc:blaze_fireball", {

View file

@ -100,7 +100,34 @@ mobs:register_mob("mobs_mc:chicken", {
}) })
--spawn --spawn
mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:chicken",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30, 17000,
3,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0)

View file

@ -145,8 +145,53 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
-- Spawning -- Spawning
mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) "mobs_mc:cow",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30,
17000,
10,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:mooshroom",
"overworld",
"ground",
{
"MushroomIslandShore",
"MushroomIsland"
},
9,
minetest.LIGHT_MAX+1,
30,
17000,
5,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn egg -- spawn egg
mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)

View file

@ -39,6 +39,8 @@ mobs:register_mob("mobs_mc:creeper", {
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
attack_type = "explode", attack_type = "explode",
--hssssssssssss
explosion_strength = 3, explosion_strength = 3,
explosion_radius = 3.5, explosion_radius = 3.5,
explosion_damage_radius = 3.5, explosion_damage_radius = 3.5,
@ -138,6 +140,9 @@ mobs:register_mob("mobs_mc:creeper_charged", {
pathfinding = 1, pathfinding = 1,
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_creeper.b3d", mesh = "mobs_mc_creeper.b3d",
--BOOM
textures = { textures = {
{"mobs_mc_creeper.png", {"mobs_mc_creeper.png",
"mobs_mc_creeper_charge.png"}, "mobs_mc_creeper_charge.png"},
@ -248,7 +253,158 @@ mobs:register_mob("mobs_mc:creeper_charged", {
glow = 3, glow = 3,
}) })
mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:creeper",
"overworld",
"ground",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
20,
16500,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)

View file

@ -0,0 +1 @@
mcl_mobs

View file

@ -562,11 +562,189 @@ mobs:register_mob("mobs_mc:enderman", {
-- End spawn -- End spawn
mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) mobs:spawn_specific(
"mobs_mc:enderman",
"end",
"ground",
{
"End"
},
0,
minetest.LIGHT_MAX+1,
30,
3000,
12,
mobs_mc.spawn_height.end_min,
mobs_mc.spawn_height.end_max)
-- Overworld spawn -- Overworld spawn
mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:enderman",
"overworld",
"ground",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
30,
19000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Nether spawn (rare) -- Nether spawn (rare)
mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:enderman",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
27500,
4,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)

View file

@ -75,7 +75,20 @@ mobs:register_mob("mobs_mc:ghast", {
}) })
mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:ghast",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
18000,
2,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- fireball (projectile) -- fireball (projectile)
mobs:register_arrow("mobs_mc:fireball", { mobs:register_arrow("mobs_mc:fireball", {

View file

@ -106,7 +106,7 @@ mobs:register_mob("mobs_mc:guardian_elder", {
view_range = 16, view_range = 16,
}) })
-- Spawning disabled due to size issues -- Spawning disabled due to size issues <- what do you mean? -j4i
-- TODO: Re-enable spawning -- TODO: Re-enable spawning
-- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18) -- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18)

View file

@ -510,8 +510,56 @@ mobs:register_mob("mobs_mc:mule", mule)
--=========================== --===========================
--Spawn Function --Spawn Function
mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) "mobs_mc:horse",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:donkey",
"overworld",
"ground",
{
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)

View file

@ -217,7 +217,25 @@ mobs:register_mob("mobs_mc:llama", {
}) })
--spawn --spawn
mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:llama",
"overworld",
"ground",
{
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
5,
mobs_mc.spawn_height.water+15,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0)

View file

@ -152,6 +152,25 @@ mobs:register_mob("mobs_mc:cat", cat)
local base_spawn_chance = 5000 local base_spawn_chance = 5000
-- Spawn ocelot -- Spawn ocelot
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i
mobs:spawn_specific(
"mobs_mc:ocelot",
"overworld",
"ground",
{
"Jungle",
"JungleEdgeM",
"JungleM",
"JungleEdge",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
5,
mobs_mc.spawn_height.water+15,
mobs_mc.spawn_height.overworld_max)
--[[
mobs:spawn({ mobs:spawn({
name = "mobs_mc:ocelot", name = "mobs_mc:ocelot",
nodes = mobs_mc.spawn.jungle, nodes = mobs_mc.spawn.jungle,
@ -163,8 +182,8 @@ mobs:spawn({
min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level
max_height = mobs_mc.spawn_height.overworld_max, max_height = mobs_mc.spawn_height.overworld_max,
on_spawn = function(self, pos) on_spawn = function(self, pos)
--[[ Note: Minecraft has a 1/3 spawn failure rate. Note: Minecraft has a 1/3 spawn failure rate.
In this mod it is emulated by reducing the spawn rate accordingly (see above). ]] In this mod it is emulated by reducing the spawn rate accordingly (see above).
-- 1/7 chance to spawn 2 ocelot kittens -- 1/7 chance to spawn 2 ocelot kittens
if pr:next(1,7) == 1 then if pr:next(1,7) == 1 then
@ -207,6 +226,7 @@ mobs:spawn({
end end
end, end,
}) })
]]--
-- spawn eggs -- spawn eggs
-- FIXME: The spawn icon shows a cat texture, not an ocelot texture -- FIXME: The spawn icon shows a cat texture, not an ocelot texture

View file

@ -90,8 +90,24 @@ mobs:register_mob("mobs_mc:parrot", {
}) })
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* -- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
mobs:spawn_specific("mobs_mc:parrot", {"mcl_core:jungletree", "mcl_core:jungleleaves"}, {"air"}, 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:parrot",
"overworld",
"ground",
{
"Jungle",
"JungleEdgeM",
"JungleM",
"JungleEdge",
},
0,
minetest.LIGHT_MAX+1,
7,
30000,
1,
mobs_mc.spawn_height.water+7,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)

View file

@ -182,7 +182,35 @@ mobs:register_mob("mobs_mc:pig", {
end, end,
}) })
mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:pig",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30,
15000,
8,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0)

View file

@ -67,7 +67,23 @@ mobs:register_mob("mobs_mc:polar_bear", {
}) })
mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:polar_bear",
"overworld",
"ground",
{
"ColdTaiga",
"IcePlainsSpikes",
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
minetest.LIGHT_MAX+1,
30,
7000,
3,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn egg -- spawn egg
mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0)

View file

@ -107,8 +107,39 @@ end
mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) mobs:register_mob("mobs_mc:killer_bunny", killer_bunny)
-- Mob spawning rules. -- Mob spawning rules.
-- Different skins depending on spawn location -- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out
mobs:spawn_specific(
"mobs_mc:rabbit",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
9,
minetest.LIGHT_MAX+1,
30,
15000,
8,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
--[[
local spawn = { local spawn = {
name = "mobs_mc:rabbit", name = "mobs_mc:rabbit",
neighbors = {"air"}, neighbors = {"air"},
@ -165,6 +196,7 @@ spawn_grass.on_spawn = function(self, pos)
self.object:set_properties({textures = self.base_texture}) self.object:set_properties({textures = self.base_texture})
end end
mobs:spawn(spawn_grass) mobs:spawn(spawn_grass)
]]--
-- Spawn egg -- Spawn egg
mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0)

View file

@ -303,7 +303,35 @@ mobs:register_mob("mobs_mc:sheep", {
end end
end, end,
}) })
mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:sheep",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
3,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0)

View file

@ -81,4 +81,17 @@ mobs:register_arrow("mobs_mc:shulkerbullet", {
mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0)
mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) mobs:spawn_specific(
"mobs_mc:shulker",
"end",
"ground",
{
"End"
},
0,
minetest.LIGHT_MAX+1,
30,
5000,
2,
mobs_mc.spawn_height.end_min,
mobs_mc.spawn_height.end_max)

View file

@ -139,13 +139,195 @@ table.insert(stray.drops, {
mobs:register_mob("mobs_mc:stray", stray) mobs:register_mob("mobs_mc:stray", stray)
-- Overworld spawn -- Overworld spawn
mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:skeleton",
"overworld",
"ground",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
20,
17000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Nether spawn -- Nether spawn
mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:skeleton",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
10000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- Stray spawn -- Stray spawn
-- TODO: Spawn directly under the sky -- TODO: Spawn directly under the sky
mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:stray",
"overworld",
"ground",
{
"ColdTaiga",
"IcePlainsSpikes",
"IcePlains",
"ExtremeHills+_snowtop",
},
0,
7,
20,
19000,
2,
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs

View file

@ -94,7 +94,20 @@ mobs:register_mob("mobs_mc:witherskeleton", {
}) })
--spawn --spawn
mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:witherskeleton",
"nether",
"ground",
{
"Nether"
},
0,
7,
30,
5000,
5,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)

View file

@ -157,9 +157,137 @@ mobs:register_mob("mobs_mc:slime_tiny", slime_tiny)
local smin = mobs_mc.spawn_height.overworld_min local smin = mobs_mc.spawn_height.overworld_min
local smax = mobs_mc.spawn_height.water - 23 local smax = mobs_mc.spawn_height.water - 23
mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) "mobs_mc:slime_tiny",
mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) "overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
12000,
4,
smin,
smax)
mobs:spawn_specific(
"mobs_mc:slime_small",
"overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
8500,
4,
smin,
smax)
mobs:spawn_specific(
"mobs_mc:slime_big",
"overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
10000,
4,
smin,
smax)
-- Magma cube -- Magma cube
local magma_cube_big = { local magma_cube_big = {
@ -272,13 +400,55 @@ mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny)
local mmin = mobs_mc.spawn_height.nether_min local mmin = mobs_mc.spawn_height.nether_min
local mmax = mobs_mc.spawn_height.nether_max local mmax = mobs_mc.spawn_height.nether_max
mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) "mobs_mc:magma_cube_tiny",
mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) "nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mmin,
mmax)
mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) "mobs_mc:magma_cube_small",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
15500,
4,
mmin,
mmax)
mobs:spawn_specific(
"mobs_mc:magma_cube_big",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
16000,
4,
mmin,
mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
--mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
-- spawn eggs -- spawn eggs

View file

@ -87,7 +87,158 @@ cave_spider.sounds.base_pitch = 1.25
mobs:register_mob("mobs_mc:cave_spider", cave_spider) mobs:register_mob("mobs_mc:cave_spider", cave_spider)
mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:spider",
"overworld",
"ground",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
7,
30,
17000,
2,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0)

View file

@ -62,7 +62,158 @@ mobs:register_mob("mobs_mc:squid", {
local water = mobs_mc.spawn_height.water local water = mobs_mc.spawn_height.water
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) mobs:spawn_specific(
"mobs_mc:squid",
"overworld",
"water",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
5500,
3,
water-16,
water+1)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0)

View file

@ -1074,7 +1074,35 @@ mobs:register_mob("mobs_mc:villager", {
mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:villager",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
20,
4,
mobs_mc.spawn_height.water+1,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0)

View file

@ -146,8 +146,99 @@ mobs:register_mob("mobs_mc:villager_zombie", {
harmed_by_heal = true, harmed_by_heal = true,
}) })
mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) "mobs_mc:villager_zombie",
"overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
30,
4090,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
--mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0)

View file

@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:potion_arrow", {
end end
}) })
-- TODO: Spawn when witch works properly -- TODO: Spawn when witch works properly <- eventually -j4i
--mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max) --mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs

View file

@ -232,6 +232,34 @@ end
mobs:register_mob("mobs_mc:dog", dog) mobs:register_mob("mobs_mc:dog", dog)
-- Spawn -- Spawn
mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:wolf",
"overworld",
"ground",
{
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"ColdTaiga",
"SunflowerPlains",
"RoofedForest",
"MesaPlateauFM_grasstop",
"ExtremeHillsM",
"BirchForestM",
},
0,
minetest.LIGHT_MAX+1,
30,
9000,
7,
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0)

View file

@ -135,11 +135,227 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk)
-- Spawning -- Spawning
mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
"mobs_mc:zombie",
"overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
30,
6000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Baby zombie is 20 times less likely than regular zombies -- Baby zombie is 20 times less likely than regular zombies
mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific(
mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) "mobs_mc:baby_zombie",
mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) "overworld",
"ground",
{
"FlowerForest_underground",
"JungleEdge_underground",
"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",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
30,
60000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:husk",
"overworld",
"ground",
{
"Desert",
"SavannaM",
"Savanna",
"Savanna_beach",
},
0,
7,
30,
6500,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific(
"mobs_mc:baby_husk",
"overworld",
"ground",
{
"Desert",
"SavannaM",
"Savanna",
"Savanna_beach",
},
0,
7,
30,
65000,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Spawn eggs -- Spawn eggs
mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0)

View file

@ -111,12 +111,38 @@ baby_pigman.child = 1
mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) mobs:register_mob("mobs_mc:baby_pigman", baby_pigman)
-- Regular spawning in the Nether -- Regular spawning in the Nether
mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:pigman",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
6000,
3,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- Baby zombie is 20 times less likely than regular zombies -- Baby zombie is 20 times less likely than regular zombies
mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) mobs:spawn_specific(
"mobs_mc:baby_pigman",
"nether",
"ground",
{
"Nether"
},
0,
minetest.LIGHT_MAX+1,
30,
100000,
4,
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- Spawning in Nether portals in the Overworld -- Spawning in Nether portals in the Overworld
mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) --mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0) mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0)

View file

@ -47,28 +47,34 @@
-- mesecon.rotate_rules_down(rules) -- mesecon.rotate_rules_down(rules)
-- These functions return rules that have been rotated in the specific direction -- These functions return rules that have been rotated in the specific direction
local equals = vector.equals
local get_node_force = mesecon.get_node_force
local invertRule = mesecon.invertRule
local copy, insert = table.copy, table.insert
local registered_nodes = minetest.registered_nodes
-- General -- General
function mesecon.get_effector(nodename) function mesecon.get_effector(nodename)
if minetest.registered_nodes[nodename] if registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons and registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.effector then and registered_nodes[nodename].mesecons.effector then
return minetest.registered_nodes[nodename].mesecons.effector return registered_nodes[nodename].mesecons.effector
end end
end end
function mesecon.get_receptor(nodename) function mesecon.get_receptor(nodename)
if minetest.registered_nodes[nodename] if registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons and registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.receptor then and registered_nodes[nodename].mesecons.receptor then
return minetest.registered_nodes[nodename].mesecons.receptor return registered_nodes[nodename].mesecons.receptor
end end
end end
function mesecon.get_conductor(nodename) function mesecon.get_conductor(nodename)
if minetest.registered_nodes[nodename] if registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons and registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.conductor then and registered_nodes[nodename].mesecons.conductor then
return minetest.registered_nodes[nodename].mesecons.conductor return registered_nodes[nodename].mesecons.conductor
end end
end end
@ -103,13 +109,14 @@ end
-- Receptors -- Receptors
-- Nodes that can power mesecons -- Nodes that can power mesecons
function mesecon.is_receptor_on(nodename) local function is_receptor_on(nodename)
local receptor = mesecon.get_receptor(nodename) local receptor = mesecon.get_receptor(nodename)
if receptor and receptor.state == mesecon.state.on then if receptor and receptor.state == mesecon.state.on then
return true return true
end end
return false return false
end end
mesecon.is_receptor_on = is_receptor_on
function mesecon.is_receptor_off(nodename) function mesecon.is_receptor_off(nodename)
local receptor = mesecon.get_receptor(nodename) local receptor = mesecon.get_receptor(nodename)
@ -127,7 +134,7 @@ function mesecon.is_receptor(nodename)
return false return false
end end
function mesecon.receptor_get_rules(node) local function receptor_get_rules(node)
local receptor = mesecon.get_receptor(node.name) local receptor = mesecon.get_receptor(node.name)
if receptor then if receptor then
local rules = receptor.rules local rules = receptor.rules
@ -140,6 +147,7 @@ function mesecon.receptor_get_rules(node)
return mesecon.rules.default return mesecon.rules.default
end end
mesecon.receptor_get_rules = receptor_get_rules
-- Effectors -- Effectors
-- Nodes that can be powered by mesecons -- Nodes that can be powered by mesecons
@ -186,7 +194,7 @@ end
-- Activation: -- Activation:
mesecon.queue:add_function("activate", function (pos, rulename) mesecon.queue:add_function("activate", function (pos, rulename)
local node = mesecon.get_node_force(pos) local node = get_node_force(pos)
if not node then return end if not node then return end
local effector = mesecon.get_effector(node.name) local effector = mesecon.get_effector(node.name)
@ -198,7 +206,7 @@ end)
function mesecon.activate(pos, node, rulename, depth) function mesecon.activate(pos, node, rulename, depth)
if rulename == nil then if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do for _,rule in pairs(mesecon.effector_get_rules(node)) do
mesecon.activate(pos, node, rule, depth + 1) mesecon.activate(pos, node, rule, depth + 1)
end end
return return
@ -209,7 +217,7 @@ end
-- Deactivation -- Deactivation
mesecon.queue:add_function("deactivate", function (pos, rulename) mesecon.queue:add_function("deactivate", function (pos, rulename)
local node = mesecon.get_node_force(pos) local node = get_node_force(pos)
if not node then return end if not node then return end
local effector = mesecon.get_effector(node.name) local effector = mesecon.get_effector(node.name)
@ -221,7 +229,7 @@ end)
function mesecon.deactivate(pos, node, rulename, depth) function mesecon.deactivate(pos, node, rulename, depth)
if rulename == nil then if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do for _,rule in pairs(mesecon.effector_get_rules(node)) do
mesecon.deactivate(pos, node, rule, depth + 1) mesecon.deactivate(pos, node, rule, depth + 1)
end end
return return
@ -232,7 +240,7 @@ end
-- Change -- Change
mesecon.queue:add_function("change", function (pos, rulename, changetype) mesecon.queue:add_function("change", function (pos, rulename, changetype)
local node = mesecon.get_node_force(pos) local node = get_node_force(pos)
if not node then return end if not node then return end
local effector = mesecon.get_effector(node.name) local effector = mesecon.get_effector(node.name)
@ -244,7 +252,7 @@ end)
function mesecon.changesignal(pos, node, rulename, newstate, depth) function mesecon.changesignal(pos, node, rulename, newstate, depth)
if rulename == nil then if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do for _,rule in pairs(mesecon.effector_get_rules(node)) do
mesecon.changesignal(pos, node, rule, newstate, depth + 1) mesecon.changesignal(pos, node, rule, newstate, depth + 1)
end end
return return
@ -356,15 +364,15 @@ end
-- some more general high-level stuff -- some more general high-level stuff
function mesecon.is_power_on(pos, rulename) function mesecon.is_power_on(pos, rulename)
local node = mesecon.get_node_force(pos) local node = get_node_force(pos)
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then
return true return true
end end
return false return false
end end
function mesecon.is_power_off(pos, rulename) function mesecon.is_power_off(pos, rulename)
local node = mesecon.get_node_force(pos) local node = get_node_force(pos)
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
return true return true
end end
@ -381,7 +389,7 @@ function mesecon.turnon(pos, link)
local depth = 1 local depth = 1
while frontiers[1] do while frontiers[1] do
local f = table.remove(frontiers, 1) local f = table.remove(frontiers, 1)
local node = mesecon.get_node_force(f.pos) local node = get_node_force(f.pos)
if not node then if not node then
-- Area does not exist; do nothing -- Area does not exist; do nothing
@ -389,10 +397,10 @@ function mesecon.turnon(pos, link)
local rules = mesecon.conductor_get_rules(node) local rules = mesecon.conductor_get_rules(node)
-- Call turnon on neighbors -- Call turnon on neighbors
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r) local np = vector.add(f.pos, r)
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
table.insert(frontiers, {pos = np, link = l}) insert(frontiers, {pos = np, link = l})
end end
end end
@ -406,12 +414,12 @@ function mesecon.turnon(pos, link)
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
-- Call turnon on neighbors -- Call turnon on neighbors
-- Warning: A LOT of nodes need to be looked at for this to work -- Warning: A LOT of nodes need to be looked at for this to work
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local np = vector.add(f.pos, r) local np = vector.add(f.pos, r)
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
local nlink = table.copy(l) local nlink = copy(l)
nlink.spread = false nlink.spread = false
table.insert(frontiers, {pos = np, link = nlink}) insert(frontiers, {pos = np, link = nlink})
end end
end end
end end
@ -443,33 +451,33 @@ function mesecon.turnoff(pos, link)
local depth = 1 local depth = 1
while frontiers[1] do while frontiers[1] do
local f = table.remove(frontiers, 1) local f = table.remove(frontiers, 1)
local node = mesecon.get_node_force(f.pos) local node = get_node_force(f.pos)
if not node then if not node then
-- No-op -- No-op
elseif mesecon.is_conductor_on(node, f.link) then elseif mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node) local rules = mesecon.conductor_get_rules(node)
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r) local np = vector.add(f.pos, r)
-- Check if an onstate receptor is connected. If that is the case, -- Check if an onstate receptor is connected. If that is the case,
-- abort this turnoff process by returning false. `receptor_off` will -- abort this turnoff process by returning false. `receptor_off` will
-- discard all the changes that we made in the voxelmanip: -- discard all the changes that we made in the voxelmanip:
for _, l in ipairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
if mesecon.is_receptor_on(mesecon.get_node_force(np).name) then if is_receptor_on(get_node_force(np).name) then
return false return false
end end
end end
-- Call turnoff on neighbors -- Call turnoff on neighbors
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
table.insert(frontiers, {pos = np, link = l}) insert(frontiers, {pos = np, link = l})
end end
end end
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link)) mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
elseif mesecon.is_effector(node.name) then elseif mesecon.is_effector(node.name) then
table.insert(signals, { insert(signals, {
pos = f.pos, pos = f.pos,
node = node, node = node,
link = f.link, link = f.link,
@ -480,21 +488,22 @@ function mesecon.turnoff(pos, link)
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
-- Call turnoff on neighbors -- Call turnoff on neighbors
-- Warning: A LOT of nodes need to be looked at for this to work -- Warning: A LOT of nodes need to be looked at for this to work
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local fpos = f.pos
local np = vector.add(f.pos, r) for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local n = mesecon.get_node_force(np) local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z}
if mesecon.is_receptor_on(n.name) then local n = get_node_force(np)
local receptorrules = mesecon.receptor_get_rules(n) if n and is_receptor_on(n.name) then
local receptorrules = receptor_get_rules(n)
for _, rr in pairs(receptorrules) do for _, rr in pairs(receptorrules) do
if rr.spread and vector.equals(mesecon.invertRule(rr), r) then if rr.spread and equals(invertRule(rr), r) then
return false return false
end end
end end
end end
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do
local nlink = table.copy(l) local nlink = copy(l)
nlink.spread = false nlink.spread = false
table.insert(frontiers, {pos = np, link = nlink}) insert(frontiers, {pos = np, link = nlink})
end end
end end
end end
@ -502,7 +511,7 @@ function mesecon.turnoff(pos, link)
depth = depth + 1 depth = depth + 1
end end
for _, sig in ipairs(signals) do for _, sig in pairs(signals) do
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth) mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth) mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
@ -516,19 +525,19 @@ end
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule` -- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
function mesecon.rules_link_rule_all(output, rule) function mesecon.rules_link_rule_all(output, rule)
local input = vector.add(output, rule) local input = vector.add(output, rule)
local inputnode = mesecon.get_node_force(input) local inputnode = get_node_force(input)
local inputrules = mesecon.get_any_inputrules(inputnode) local inputrules = mesecon.get_any_inputrules(inputnode)
if not inputrules then if not inputrules then
return {} return {}
end end
local rules = {} local rules = {}
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do for _, inputrule in pairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output -- Check if input accepts from output
if vector.equals(vector.add(input, inputrule), output) then if equals(vector.add(input, inputrule), output) then
local newrule = table.copy(inputrule) local newrule = copy(inputrule)
newrule.spread = rule.spread newrule.spread = rule.spread
table.insert(rules, newrule) insert(rules, newrule)
end end
end end
@ -539,19 +548,19 @@ end
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule` -- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
function mesecon.rules_link_rule_all_inverted(input, rule) function mesecon.rules_link_rule_all_inverted(input, rule)
local output = vector.add(input, rule) local output = vector.add(input, rule)
local outputnode = mesecon.get_node_force(output) local outputnode = get_node_force(output)
local outputrules = mesecon.get_any_outputrules(outputnode) local outputrules = mesecon.get_any_outputrules(outputnode)
if not outputrules then if not outputrules then
return {} return {}
end end
local rules = {} local rules = {}
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do for _, outputrule in pairs(mesecon.flattenrules(outputrules)) do
if vector.equals(vector.add(output, outputrule), input) then if equals(vector.add(output, outputrule), input) then
local newrule = table.copy(outputrule) local newrule = copy(outputrule)
newrule = mesecon.invertRule(newrule) newrule = invertRule(newrule)
newrule.spread = rule.spread newrule.spread = rule.spread
table.insert(rules, newrule) insert(rules, newrule)
end end
end end
return rules return rules
@ -562,7 +571,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
if depth > 1 then if depth > 1 then
return false, false return false, false
end end
local node = mesecon.get_node_force(pos) local node = get_node_force(pos)
local rules = mesecon.get_any_inputrules(node) local rules = mesecon.get_any_inputrules(node)
if not rules then if not rules then
return false, false return false, false
@ -578,23 +587,23 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth) local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
local spread = false local spread = false
for _, rname in ipairs(rulenames) do for _, rname in pairs(rulenames) do
local np = vector.add(pos, rname) local np = vector.add(pos, rname)
local nn = mesecon.get_node_force(np) local nn = get_node_force(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) if (mesecon.is_conductor_on (nn, invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then or is_receptor_on (nn.name)) then
if not vector.equals(home_pos, np) then if not equals(home_pos, np) then
local rulez = mesecon.get_any_outputrules(nn) local rulez = mesecon.get_any_outputrules(nn)
local spread_tmp = false local spread_tmp = false
for r=1, #rulez do for r=1, #rulez do
if vector.equals(mesecon.invertRule(rname), rulez[r]) then if equals(invertRule(rname), rulez[r]) then
if rulez[r].spread then if rulez[r].spread then
spread_tmp = true spread_tmp = true
end end
end end
end end
if depth == 0 or spread_tmp then if depth == 0 or spread_tmp then
table.insert(sourcepos, np) insert(sourcepos, np)
if spread_tmp then if spread_tmp then
spread = true spread = true
end end
@ -612,7 +621,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
local spread = false local spread = false
if not rule then if not rule then
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in pairs(mesecon.flattenrules(rules)) do
local spread_temp local spread_temp
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth) sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)

View file

@ -46,6 +46,56 @@ minetest.register_craft({
} }
}) })
-- Stripped Bark
minetest.register_craft({
output = "mcl_core:stripped_oak_bark 3",
recipe = {
{ "mcl_core:stripped_oak", "mcl_core:stripped_oak" },
{ "mcl_core:stripped_oak", "mcl_core:stripped_oak" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_acacia_bark 3",
recipe = {
{ "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" },
{ "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_dark_oak_bark 3",
recipe = {
{ "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" },
{ "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_birch_bark 3",
recipe = {
{ "mcl_core:stripped_birch", "mcl_core:stripped_birch" },
{ "mcl_core:stripped_birch", "mcl_core:stripped_birch" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_spruce_bark 3",
recipe = {
{ "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" },
{ "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_jungle_bark 3",
recipe = {
{ "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" },
{ "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" },
}
})
minetest.register_craft({ minetest.register_craft({
type = 'shapeless', type = 'shapeless',
output = 'mcl_core:mossycobble', output = 'mcl_core:mossycobble',

View file

@ -1,4 +1,4 @@
-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves -- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood
local S = minetest.get_translator("mcl_core") local S = minetest.get_translator("mcl_core")
local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil
@ -48,6 +48,166 @@ local register_tree_trunk = function(subname, description_trunk, description_bar
}) })
end end
-- Register stripped trunk
minetest.register_node("mcl_core:stripped_oak", {
description = "Stripped Oak Log",
_doc_items_longdesc = "Stripped Oak Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_acacia", {
description = "Stripped Acacia Log",
_doc_items_longdesc = "Stripped Acacia Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_dark_oak", {
description = "Stripped Dark Oak Log",
_doc_items_longdesc = "Stripped Dark Oak Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_birch", {
description = "Stripped Birch Log",
_doc_items_longdesc = "Stripped Birch Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_spruce", {
description = "Stripped Spruce Log",
_doc_items_longdesc = "Stripped Spruce Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_jungle", {
description = "Stripped Jungle Log",
_doc_items_longdesc = "Stripped Jungle Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
-- Register stripped bark
minetest.register_node("mcl_core:stripped_oak_bark", {
description = "Stripped Oak Bark",
_doc_items_longdesc = "Stripped Oak Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_acacia_bark", {
description = "Stripped Acacia Bark",
_doc_items_longdesc = "Stripped Acacia Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_acacia_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_dark_oak_bark", {
description = "Stripped Dark Oak Bark",
_doc_items_longdesc = "Stripped Dark Oak Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_dark_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_birch_bark", {
description = "Stripped Birch Bark",
_doc_items_longdesc = "Stripped Birch Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_birch_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_spruce_bark", {
description = "Stripped Spruce Bark",
_doc_items_longdesc = "Stripped Spruce Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_spruce_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_jungle_bark", {
description = "Stripped Jungle Bark",
_doc_items_longdesc = "Stripped Jungles Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_jungle_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
local register_wooden_planks = function(subname, description, tiles) local register_wooden_planks = function(subname, description, tiles)
minetest.register_node("mcl_core:"..subname, { minetest.register_node("mcl_core:"..subname, {
description = description, description = description,

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

View file

@ -1,6 +1,9 @@
-- TODO: whenever it becomes possible to fully implement kelp without the -- TODO: whenever it becomes possible to fully implement kelp without the
-- plantlike_rooted limitation, please update accordingly. -- plantlike_rooted limitation, please update accordingly.
-- --
-- TODO: whenever it becomes possible to make kelp grow infinitely without
-- resorting to making intermediate kelp stem node, please update accordingly.
--
-- TODO: In MC, you can't actually destroy kelp by bucket'ing water in the middle. -- TODO: In MC, you can't actually destroy kelp by bucket'ing water in the middle.
-- However, because of the plantlike_rooted hack, we'll just allow it for now. -- However, because of the plantlike_rooted hack, we'll just allow it for now.
@ -191,17 +194,18 @@ end
-- Converts param2 to kelp height. -- Converts param2 to kelp height.
-- For the special case where the max param2 is reached, interpret that as the
-- 16th kelp stem.
function kelp.get_height(param2) function kelp.get_height(param2)
return math_floor(param2 / 16) return math_floor(param2 / 16) + math_floor(param2 % 16 / 8)
end end
-- Obtain pos and node of the tip of kelp. -- Obtain pos and node of the tip of kelp.
function kelp.get_tip(pos, param2) function kelp.get_tip(pos, height)
-- Optional params: param2 -- Optional params: height
local height = kelp.get_height(param2 or mt_get_node(pos).param2) local height = height or kelp.get_height(mt_get_node(pos).param2)
local pos_tip = {x=pos.x, y=pos.y, z=pos.z} local pos_tip = {x=pos.x, y=pos.y+height+1, z=pos.z}
pos_tip.y = pos_tip.y + height + 1
return pos_tip, mt_get_node(pos_tip), height return pos_tip, mt_get_node(pos_tip), height
end end
@ -210,7 +214,7 @@ end
function kelp.find_unsubmerged(pos, node, height) function kelp.find_unsubmerged(pos, node, height)
-- Optional params: node, height -- Optional params: node, height
local node = node or mt_get_node(pos) local node = node or mt_get_node(pos)
local height = height or kelp.get_height(node.param2) local height = height or ((node.param2 >= 0 and node.param2 < 16) and 1) or kelp.get_height(node.param2)
local walk_pos = {x=pos.x, z=pos.z} local walk_pos = {x=pos.x, z=pos.z}
local y = pos.y local y = pos.y
@ -227,7 +231,8 @@ end
-- Obtain next param2. -- Obtain next param2.
function kelp.next_param2(param2) function kelp.next_param2(param2)
return param2+16 - param2 % 16 -- param2 max value is 255, so adding to 256 causes overflow.
return math_min(param2+16 - param2 % 16, 255);
end end
@ -311,7 +316,7 @@ function kelp.init_timer(pos, pos_hash)
end end
-- Apply next kelp height. -- Apply next kelp height. The surface is swapped. so on_construct is skipped.
function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing) function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing)
-- Modified params: node -- Modified params: node
-- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing -- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing
@ -367,9 +372,9 @@ end
-- Drops the items for detached kelps. -- Drops the items for detached kelps.
function kelp.detach_drop(pos, param2) function kelp.detach_drop(pos, height)
-- Optional params: param2 -- Optional params: height
local height = kelp.get_height(param2 or mt_get_node(pos).param2) local height = height or kelp.get_height(mt_get_node(pos).param2)
local y = pos.y local y = pos.y
local walk_pos = {x=pos.x, z=pos.z} local walk_pos = {x=pos.x, z=pos.z}
for i=1,height do for i=1,height do
@ -384,17 +389,18 @@ end
-- Synonymous to digging the kelp. -- Synonymous to digging the kelp.
-- NOTE: this is intended for whenever kelp truly becomes segmented plants -- NOTE: this is intended for whenever kelp truly becomes segmented plants
-- instead of rooted to the floor. Don't try to remove dig_pos. -- instead of rooted to the floor. Don't try to remove dig_pos.
function kelp.detach_dig(dig_pos, pos, node, drop) function kelp.detach_dig(dig_pos, pos, drop, node, height)
-- Optional params: drop -- Optional params: drop, node, height
local param2 = node.param2 local node = node or mt_get_node(pos)
local height = height or kelp.get_height(node.param2)
-- pos.y points to the surface, offset needed to point to the first kelp. -- pos.y points to the surface, offset needed to point to the first kelp.
local new_height = dig_pos.y - (pos.y+1) local new_height = dig_pos.y - (pos.y+1)
-- Digs the entire kelp. -- Digs the entire kelp.
if new_height <= 0 then if new_height <= 0 then
if drop then if drop then
kelp.detach_drop(dig_pos, param2) kelp.detach_drop(dig_pos, height)
end end
mt_set_node(pos, { mt_set_node(pos, {
name=mt_registered_nodes[node.name].node_dig_prediction, name=mt_registered_nodes[node.name].node_dig_prediction,
@ -404,7 +410,7 @@ function kelp.detach_dig(dig_pos, pos, node, drop)
-- Digs the kelp beginning at a height. -- Digs the kelp beginning at a height.
else else
if drop then if drop then
kelp.detach_drop(dig_pos, param2 - new_height) kelp.detach_drop(dig_pos, height - new_height)
end end
mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height}) mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height})
end end
@ -416,7 +422,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function kelp.surface_on_dig(pos, node, digger) function kelp.surface_on_dig(pos, node, digger)
kelp.detach_dig(pos, pos, node, true) kelp.detach_dig(pos, pos, true, node)
end end
@ -430,11 +436,11 @@ function kelp.surface_on_timer(pos)
local pos_hash local pos_hash
-- Update detahed kelps -- Update detahed kelps
local dig_pos = kelp.find_unsubmerged(pos, node) local dig_pos,_, height = kelp.find_unsubmerged(pos, node)
if dig_pos then if dig_pos then
pos_hash = mt_hash_node_position(pos) pos_hash = mt_hash_node_position(pos)
mt_sound_play(mt_registered_nodes[node.name].sounds.dug, { gain = 0.5, pos = dig_pos }, true) mt_sound_play(mt_registered_nodes[node.name].sounds.dug, { gain = 0.5, pos = dig_pos }, true)
kelp.detach_dig(dig_pos, pos, node, true) kelp.detach_dig(dig_pos, pos, true, node, height)
kelp.store_age(kelp.roll_init_age(), pos, pos_hash) kelp.store_age(kelp.roll_init_age(), pos, pos_hash)
end end
@ -463,7 +469,7 @@ function kelp.surface_on_destruct(pos)
-- on_falling callback. Activated by pistons for falling nodes too. -- on_falling callback. Activated by pistons for falling nodes too.
if kelp.is_falling(pos, node) then if kelp.is_falling(pos, node) then
kelp.detach_drop(pos, node.param2) kelp.detach_drop(pos, kelp.get_height(node.param2))
end end
-- Removes position from queue -- Removes position from queue
@ -474,7 +480,7 @@ end
function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta) function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta)
-- Pistons moving falling nodes will have already activated on_falling callback. -- Pistons moving falling nodes will have already activated on_falling callback.
kelp.detach_dig(pos, pos, node, mt_get_item_group(node.name, "falling_node") ~= 1) kelp.detach_dig(pos, pos, mt_get_item_group(node.name, "falling_node") ~= 1, node)
end end
@ -518,7 +524,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
end end
local pos_tip, node_tip, def_tip, new_kelp local pos_tip, node_tip, def_tip, new_surface, height
-- Kelp must also be placed on the top/tip side of the surface/kelp -- Kelp must also be placed on the top/tip side of the surface/kelp
if pos_under.y >= pos_above.y then if pos_under.y >= pos_above.y then
return itemstack return itemstack
@ -526,31 +532,33 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
-- When placed on kelp. -- When placed on kelp.
if mt_get_item_group(nu_name, "kelp") == 1 then if mt_get_item_group(nu_name, "kelp") == 1 then
pos_tip,node_tip = kelp.get_tip(pos_under, node_under.param2) height = kelp.get_height(node_under.param2)
pos_tip,node_tip = kelp.get_tip(pos_under, height)
def_tip = mt_registered_nodes[node_tip.name] def_tip = mt_registered_nodes[node_tip.name]
-- When placed on surface. -- When placed on surface.
else else
new_kelp = false new_surface = false
for _,surface in pairs(kelp.surfaces) do for _,surface in pairs(kelp.surfaces) do
if nu_name == surface.nodename then if nu_name == surface.nodename then
node_under.name = "mcl_ocean:kelp_" ..surface.name node_under.name = "mcl_ocean:kelp_" ..surface.name
node_under.param2 = 0 node_under.param2 = 0
new_kelp = true new_surface = true
break break
end end
end end
-- Surface must support kelp -- Surface must support kelp
if not new_kelp then if not new_surface then
return itemstack return itemstack
end end
pos_tip = pos_above pos_tip = pos_above
node_tip = mt_get_node(pos_above) node_tip = mt_get_node(pos_above)
def_tip = mt_registered_nodes[node_tip.name] def_tip = mt_registered_nodes[node_tip.name]
height = 0
end end
-- New kelp must also be submerged in water. -- Next kelp must also be submerged in water.
local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip) local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip)
local submerged = kelp.is_submerged(node_tip) local submerged = kelp.is_submerged(node_tip)
if not submerged then if not submerged then
@ -562,14 +570,19 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing)
if def_node.sounds then if def_node.sounds then
mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true)
end end
kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing) -- TODO: get rid of rooted plantlike hack
if height < 16 then
kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing)
else
mt_add_item(pos_tip, "mcl_ocean:kelp")
end
if not mt_is_creative_enabled(player_name) then if not mt_is_creative_enabled(player_name) then
itemstack:take_item() itemstack:take_item()
end end
-- Initialize age and timer when it's a new kelp -- Initialize age and timer when it's planted on a new surface.
local pos_hash = mt_hash_node_position(pos_under) local pos_hash = mt_hash_node_position(pos_under)
if new_kelp then if new_surface then
kelp.init_age(pos_under, nil, pos_hash) kelp.init_age(pos_under, nil, pos_hash)
kelp.init_timer(pos_under, pos_hash) kelp.init_timer(pos_under, pos_hash)
else else

View file

@ -490,10 +490,12 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
end end
if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then
local pos1, pos2, pos = param.next_chunk_1, param.next_chunk_2, param.next_pos local pos1, pos2, p = param.next_chunk_1, param.next_chunk_2, param.next_pos
log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(pos)) if p.x >= pos1.x and p.x <= pos2.x and p.y >= pos1.y and p.y <= pos2.y and p.z >= pos1.z and p.z <= pos2.z then
minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = pos, pos1 = pos1, pos2 = pos2, name=name, obj=obj}) log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(p))
return minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = p, pos1 = pos1, pos2 = pos2, name=name, obj=obj})
return
end
end end
log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal") log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal")
@ -536,7 +538,7 @@ local function create_portal(pos, limit1, limit2, name, obj)
-- Basically the copy of code above, with minor additions to continue the search in single additional chunk below: -- Basically the copy of code above, with minor additions to continue the search in single additional chunk below:
local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z} local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z}
local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1) local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1)
local next_pos = {x = pos.x, y=next_chunk_2.y, z = pos.z} local next_pos = {x = pos.x, y=max(next_chunk_2.y, limit1.y), z = pos.z}
if limit1 and limit1.x and limit1.y and limit1.z then if limit1 and limit1.x and limit1.y and limit1.z then
pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)}
next_chunk_1 = {x = max(min(limit1.x, next_pos.x), next_chunk_1.x), y = max(min(limit1.y, next_pos.y), next_chunk_1.y), z = max(min(limit1.z, next_pos.z), next_chunk_1.z)} next_chunk_1 = {x = max(min(limit1.x, next_pos.x), next_chunk_1.x), y = max(min(limit1.y, next_pos.y), next_chunk_1.y), z = max(min(limit1.z, next_pos.z), next_chunk_1.z)}

View file

@ -352,6 +352,56 @@ minetest.register_tool("mcl_tools:shovel_diamond", {
}) })
-- Axes -- Axes
local make_stripped_trunk = function(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
local pos = minetest.get_pointed_thing_position(pointed_thing)
local node = minetest.get_node(pos)
local node_name = node.name
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].on_rightclick then
return minetest.registered_nodes[node_name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
end
end
if minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
return itemstack
end
if not minetest.is_creative_enabled(placer:get_player_name()) then
-- Add wear (as if digging a axey node)
local toolname = itemstack:get_name()
local wear = mcl_autogroup.get_wear(toolname, "axey")
itemstack:add_wear(wear)
end
if node_name == "mcl_core:tree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak"})
elseif node_name == "mcl_core:darktree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak"})
elseif node_name == "mcl_core:acaciatree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia"})
elseif node_name == "mcl_core:birchtree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch"})
elseif node_name == "mcl_core:sprucetree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce"})
elseif node_name == "mcl_core:jungletree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle"})
elseif node_name == "mcl_core:tree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak_bark"})
elseif node_name == "mcl_core:darktree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak_bark"})
elseif node_name == "mcl_core:acaciatree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia_bark"})
elseif node_name == "mcl_core:birchtree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch_bark"})
elseif node_name == "mcl_core:sprucetree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce_bark"})
elseif node_name == "mcl_core:jungletree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle_bark"})
end
end
return itemstack
end
minetest.register_tool("mcl_tools:axe_wood", { minetest.register_tool("mcl_tools:axe_wood", {
description = S("Wooden Axe"), description = S("Wooden Axe"),
_doc_items_longdesc = axe_longdesc, _doc_items_longdesc = axe_longdesc,
@ -365,6 +415,7 @@ minetest.register_tool("mcl_tools:axe_wood", {
damage_groups = {fleshy=7}, damage_groups = {fleshy=7},
punch_attack_uses = 30, punch_attack_uses = 30,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "group:wood", _repair_material = "group:wood",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -384,6 +435,7 @@ minetest.register_tool("mcl_tools:axe_stone", {
damage_groups = {fleshy=9}, damage_groups = {fleshy=9},
punch_attack_uses = 66, punch_attack_uses = 66,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:cobble", _repair_material = "mcl_core:cobble",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -404,6 +456,7 @@ minetest.register_tool("mcl_tools:axe_iron", {
damage_groups = {fleshy=9}, damage_groups = {fleshy=9},
punch_attack_uses = 126, punch_attack_uses = 126,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:iron_ingot", _repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -423,6 +476,7 @@ minetest.register_tool("mcl_tools:axe_gold", {
damage_groups = {fleshy=7}, damage_groups = {fleshy=7},
punch_attack_uses = 17, punch_attack_uses = 17,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:gold_ingot", _repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -442,6 +496,7 @@ minetest.register_tool("mcl_tools:axe_diamond", {
damage_groups = {fleshy=9}, damage_groups = {fleshy=9},
punch_attack_uses = 781, punch_attack_uses = 781,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:diamond", _repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,

View file

@ -22,11 +22,48 @@ local mcl_playerplus_internal = {}
local def = {} local def = {}
local time = 0 local time = 0
local player_collision = function(player)
local pos = player:get_pos()
local vel = player:get_velocity()
local x = 0
local z = 0
local width = .75
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
if object and (object:is_player()
or (object:get_luaentity()._cmi_is_mob == true and object ~= player)) then
local pos2 = object:get_pos()
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z}
local force = (width + 0.5) - vector.distance(
{x = pos.x, y = 0, z = pos.z},
{x = pos2.x, y = 0, z = pos2.z})
x = x + (vec.x * force)
z = z + (vec.z * force)
end
end
return({x * 5,z * 5})
end
-- converts yaw to degrees -- converts yaw to degrees
local function degrees(rad) local function degrees(rad)
return rad * 180.0 / math.pi return rad * 180.0 / math.pi
end end
local pi = math.pi
local atann = math.atan
local atan = function(x)
if not x or x ~= x then
return 0
else
return atann(x)
end
end
local dir_to_pitch = function(dir) local dir_to_pitch = function(dir)
local dir2 = vector.normalize(dir) local dir2 = vector.normalize(dir)
local xz = math.abs(dir.x) + math.abs(dir.z) local xz = math.abs(dir.x) + math.abs(dir.z)
@ -88,6 +125,13 @@ minetest.register_globalstep(function(dtime)
for _,player in pairs(get_connected_players()) do for _,player in pairs(get_connected_players()) do
c_x, c_y = unpack(player_collision(player))
if player:get_velocity().x + player:get_velocity().y < .5 and c_x + c_y > 0 then
--minetest.chat_send_player(player:get_player_name(), "pushed at " .. c_x + c_y .. " parsecs.")
player:add_velocity({x=c_x, y=0, z=c_y})
end
--[[ --[[
_ _ _ _ _ _
__ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___