mirror of
https://codeberg.org/tenplus1/mobs_redo.git
synced 2025-07-17 15:50:28 +02:00
Version MFF.
This commit is contained in:
389
api.lua
Normal file → Executable file
389
api.lua
Normal file → Executable file
@ -1,6 +1,4 @@
|
||||
|
||||
-- Mobs Api (15th April 2016)
|
||||
|
||||
-- Mobs Api (4th March 2016)
|
||||
mobs = {}
|
||||
mobs.mod = "redo"
|
||||
|
||||
@ -79,8 +77,6 @@ set_animation = function(self, type)
|
||||
|
||||
self.animation.current = self.animation.current or ""
|
||||
|
||||
self.animation.speed_normal = self.animation.speed_normal or 15
|
||||
|
||||
if type == "stand"
|
||||
and self.animation.current ~= "stand" then
|
||||
|
||||
@ -121,7 +117,7 @@ set_animation = function(self, type)
|
||||
self.object:set_animation({
|
||||
x = self.animation.run_start,
|
||||
y = self.animation.run_end},
|
||||
(self.animation.speed_run or self.animation.speed_normal), 0)
|
||||
self.animation.speed_run, 0)
|
||||
|
||||
self.animation.current = "run"
|
||||
end
|
||||
@ -136,7 +132,7 @@ set_animation = function(self, type)
|
||||
self.object:set_animation({
|
||||
x = self.animation.punch_start,
|
||||
y = self.animation.punch_end},
|
||||
(self.animation.speed_punch or self.animation.speed_normal), 0)
|
||||
self.animation.speed_normal, 0)
|
||||
|
||||
self.animation.current = "punch"
|
||||
end
|
||||
@ -172,19 +168,17 @@ function line_of_sight_water(self, pos1, pos2, stepsize)
|
||||
end
|
||||
|
||||
-- particle effects
|
||||
function effect(pos, amount, texture, max_size, radius)
|
||||
|
||||
radius = radius or 2
|
||||
function effect(pos, amount, texture, max_size)
|
||||
|
||||
minetest.add_particlespawner({
|
||||
amount = amount,
|
||||
time = 0.25,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x = -radius, y = -radius, z = -radius},
|
||||
maxvel = {x = radius, y = radius, z = radius},
|
||||
minacc = {x = -radius, y = -radius, z = -radius},
|
||||
maxacc = {x = radius, y = radius, z = radius},
|
||||
minvel = {x = -0, y = -2, z = -0},
|
||||
maxvel = {x = 2, y = 2, z = 2},
|
||||
minacc = {x = -4, y = -4, z = -4},
|
||||
maxacc = {x = 4, y = 4, z = 4},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 1,
|
||||
minsize = 0.5,
|
||||
@ -221,15 +215,17 @@ end
|
||||
-- check if mob is dead or only hurt
|
||||
function check_for_death(self)
|
||||
|
||||
-- has health actually changed?
|
||||
if self.health == self.old_health then
|
||||
return
|
||||
-- return if no change
|
||||
local hp = self.object:get_hp()
|
||||
|
||||
if hp == self.health then
|
||||
return false
|
||||
end
|
||||
|
||||
self.old_health = self.health
|
||||
|
||||
-- still got some health? play hurt sound
|
||||
if self.health > 0 then
|
||||
if hp > 0 then
|
||||
|
||||
self.health = hp
|
||||
|
||||
if self.sounds.damage then
|
||||
|
||||
@ -240,11 +236,6 @@ function check_for_death(self)
|
||||
})
|
||||
end
|
||||
|
||||
-- make sure health isn't higher than max
|
||||
if self.health > self.hp_max then
|
||||
self.health = self.hp_max
|
||||
end
|
||||
|
||||
update_tag(self)
|
||||
|
||||
return false
|
||||
@ -375,7 +366,7 @@ do_env_damage = function(self)
|
||||
and self.time_of_day < 0.8
|
||||
and (minetest.get_node_light(pos) or 0) > 12 then
|
||||
|
||||
self.health = self.health - self.light_damage
|
||||
self.object:set_hp(self.object:get_hp() - self.light_damage)
|
||||
|
||||
effect(pos, 5, "tnt_smoke.png")
|
||||
end
|
||||
@ -396,7 +387,7 @@ do_env_damage = function(self)
|
||||
if self.water_damage ~= 0
|
||||
and nodef.groups.water then
|
||||
|
||||
self.health = self.health - self.water_damage
|
||||
self.object:set_hp(self.object:get_hp() - self.water_damage)
|
||||
|
||||
effect(pos, 5, "bubble.png")
|
||||
end
|
||||
@ -407,7 +398,7 @@ do_env_damage = function(self)
|
||||
or self.standing_in == "fire:basic_flame"
|
||||
or self.standing_in == "fire:permanent_flame") then
|
||||
|
||||
self.health = self.health - self.lava_damage
|
||||
self.object:set_hp(self.object:get_hp() - self.lava_damage)
|
||||
|
||||
effect(pos, 5, "fire_basic_flame.png")
|
||||
end
|
||||
@ -456,9 +447,8 @@ do_jump = function(self)
|
||||
|
||||
--print ("in front:", nod.name, pos.y + 0.5)
|
||||
|
||||
if (minetest.registered_items[nod.name].walkable
|
||||
if minetest.registered_items[nod.name].walkable
|
||||
and not nod.name:find("fence")
|
||||
and not nod.name:find("gate"))
|
||||
or self.walk_chance == 0 then
|
||||
|
||||
local v = self.object:getvelocity()
|
||||
@ -485,6 +475,26 @@ do_jump = function(self)
|
||||
end
|
||||
end
|
||||
|
||||
function calc_velocity(pos1, pos2, old_vel, power) --MFF we use this function
|
||||
-- If the two positions are equal the vector will contain nan and crash the game
|
||||
if (pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z) then
|
||||
return {
|
||||
x = 0,
|
||||
y = 0,
|
||||
z = 0
|
||||
}
|
||||
end
|
||||
|
||||
local vel = vector.direction(pos1, pos2)
|
||||
vel = vector.normalize(vel)
|
||||
vel = vector.multiply(vel, power)
|
||||
local dist = vector.distance(pos1, pos2)
|
||||
dist = math.max(dist, 1)
|
||||
vel = vector.divide(vel, dist)
|
||||
vel = vector.add(vel, old_vel)
|
||||
return vel
|
||||
end
|
||||
|
||||
-- this is a faster way to calculate distance
|
||||
local get_distance = function(a, b)
|
||||
|
||||
@ -494,33 +504,27 @@ local get_distance = function(a, b)
|
||||
end
|
||||
|
||||
-- blast damage to entities nearby (modified from TNT mod)
|
||||
function entity_physics(pos, radius)
|
||||
function entity_physics(pos, radius, self) --/MFF (Crabman|06/23/2015)add self to use punch function
|
||||
|
||||
radius = radius * 2
|
||||
|
||||
local objs = minetest.get_objects_inside_radius(pos, radius)
|
||||
local obj_pos, dist
|
||||
local obj_pos, obj_vel, dist
|
||||
|
||||
for _, obj in pairs(objs) do
|
||||
|
||||
obj_pos = obj:getpos()
|
||||
|
||||
dist = math.max(1, get_distance(pos, obj_pos))
|
||||
|
||||
local damage = math.floor((4 / dist) * radius)
|
||||
local ent = obj:get_luaentity()
|
||||
|
||||
if obj:is_player() then
|
||||
obj:set_hp(obj:get_hp() - damage)
|
||||
|
||||
else --if ent.health then
|
||||
|
||||
obj:punch(obj, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = damage},
|
||||
}, nil)
|
||||
|
||||
end
|
||||
--MFF DEBUT pumpkins
|
||||
obj_vel = obj:getvelocity()
|
||||
if obj_vel ~= nil then
|
||||
if not (obj:get_entity_name() == "__builtin:item" and self.do_not_project_items) then
|
||||
obj:setvelocity(calc_velocity(pos, obj_pos, obj_vel, radius * 10))
|
||||
end
|
||||
end --MFF FIN pumpkins
|
||||
--dist = math.max(1, get_distance(pos, obj_pos))
|
||||
--local damage = math.floor((4 / dist) * radius)
|
||||
--obj:set_hp(obj:get_hp() - damage)
|
||||
obj:punch(self.object, 1.0,{full_punch_interval=1.0, damage_groups = {fleshy=self.damage} })--/MFF (Crabman|06/23/2015) use punch
|
||||
end
|
||||
end
|
||||
|
||||
@ -882,13 +886,9 @@ function smart_mobs(self, s, p, dist, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
mobs.spawning_mobs = {}
|
||||
|
||||
-- register mob function
|
||||
function mobs:register_mob(name, def)
|
||||
|
||||
mobs.spawning_mobs[name] = true
|
||||
|
||||
minetest.register_entity(name, {
|
||||
|
||||
stepheight = def.stepheight or 0.6,
|
||||
@ -938,7 +938,7 @@ minetest.register_entity(name, {
|
||||
--fov = def.fov or 120,
|
||||
passive = def.passive or false,
|
||||
recovery_time = def.recovery_time or 0.5,
|
||||
knock_back = def.knock_back or 3,
|
||||
knock_back = def.knock_back or 1, --Modif MFF, default value is "or 3",
|
||||
blood_amount = def.blood_amount or 5,
|
||||
blood_texture = def.blood_texture or "mobs_blood.png",
|
||||
shoot_offset = def.shoot_offset or 0,
|
||||
@ -958,6 +958,7 @@ minetest.register_entity(name, {
|
||||
health = 0,
|
||||
reach = def.reach or 3,
|
||||
htimer = 0,
|
||||
do_not_project_items = def.do_not_project_items or false, --MFF pumpkins
|
||||
child_texture = def.child_texture,
|
||||
docile_by_day = def.docile_by_day or false,
|
||||
time_of_day = 0.5,
|
||||
@ -965,8 +966,6 @@ minetest.register_entity(name, {
|
||||
runaway = def.runaway,
|
||||
runaway_timer = 0,
|
||||
pathfinding = def.pathfinding,
|
||||
immune_to = def.immune_to or {},
|
||||
explosion_radius = def.explosion_radius,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
|
||||
@ -1048,8 +1047,7 @@ minetest.register_entity(name, {
|
||||
|
||||
if d > 5 then
|
||||
|
||||
--self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
|
||||
self.health = self.health - math.floor(d - 5)
|
||||
self.object:set_hp(self.object:get_hp() - math.floor(d - 5))
|
||||
|
||||
effect(pos, 5, "tnt_smoke.png")
|
||||
|
||||
@ -1192,6 +1190,7 @@ minetest.register_entity(name, {
|
||||
and self.state ~= "attack" then
|
||||
|
||||
local s = self.object:getpos()
|
||||
local p, dist --MFF
|
||||
local obj = nil
|
||||
|
||||
for _, oir in pairs(minetest.get_objects_inside_radius(s, self.view_range)) do
|
||||
@ -1499,10 +1498,10 @@ minetest.register_entity(name, {
|
||||
local dist = get_distance(p, s)
|
||||
|
||||
-- stop attacking if player or out of range
|
||||
if dist > self.view_range
|
||||
if (dist > self.view_range
|
||||
or not self.attack
|
||||
or not self.attack:getpos()
|
||||
or self.attack:get_hp() <= 0 then
|
||||
or self.attack:get_hp() <= 0) and not self.exploding then -- MFF
|
||||
|
||||
--print(" ** stop attacking **", dist, self.view_range)
|
||||
self.state = "stand"
|
||||
@ -1536,7 +1535,7 @@ minetest.register_entity(name, {
|
||||
self.object:setyaw(yaw)
|
||||
end
|
||||
|
||||
if dist > self.reach then
|
||||
if dist > self.reach and not self.exploding then
|
||||
|
||||
if not self.v_start then
|
||||
|
||||
@ -1560,7 +1559,8 @@ minetest.register_entity(name, {
|
||||
end
|
||||
|
||||
set_animation(self, "run")
|
||||
else
|
||||
else -- MFF(Mg|06/10/2016) #509
|
||||
self.exploding = true --MFF
|
||||
set_velocity(self, 0)
|
||||
self.timer = self.timer + dtime
|
||||
self.blinktimer = (self.blinktimer or 0) + dtime
|
||||
@ -1581,10 +1581,9 @@ minetest.register_entity(name, {
|
||||
if self.timer > 3 then
|
||||
|
||||
local pos = self.object:getpos()
|
||||
local radius = self.explosion_radius or 1
|
||||
|
||||
-- hurt player/mobs caught in blast area
|
||||
entity_physics(pos, radius)
|
||||
entity_physics(pos, 3, self) --/MFF (Crabman|06/23/2015)add self to use punch function
|
||||
|
||||
-- dont damage anything if area protected or next to water
|
||||
if minetest.find_node_near(pos, 1, {"group:water"})
|
||||
@ -1608,7 +1607,7 @@ minetest.register_entity(name, {
|
||||
|
||||
pos.y = pos.y - 1
|
||||
|
||||
mobs:explosion(pos, radius, 0, 1, self.sounds.explode)
|
||||
mobs:explosion(pos, 2, 0, 1, self.sounds.explode)
|
||||
|
||||
self.object:remove()
|
||||
|
||||
@ -1839,14 +1838,14 @@ minetest.register_entity(name, {
|
||||
local obj = minetest.add_entity(p, self.arrow)
|
||||
local ent = obj:get_luaentity()
|
||||
local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5
|
||||
local v = ent.velocity or 1 -- or set to default
|
||||
local v = ent.velocity
|
||||
ent.switch = 1
|
||||
|
||||
-- offset makes shoot aim accurate
|
||||
vec.y = vec.y + self.shoot_offset
|
||||
vec.x = vec.x * (v / amount)
|
||||
vec.y = vec.y * (v / amount)
|
||||
vec.z = vec.z * (v / amount)
|
||||
vec.x = vec.x * v / amount
|
||||
vec.y = vec.y * v / amount
|
||||
vec.z = vec.z * v / amount
|
||||
|
||||
obj:setvelocity(vec)
|
||||
end
|
||||
@ -1861,45 +1860,17 @@ minetest.register_entity(name, {
|
||||
dir = dir or {x = 0, y = 0, z = 0}
|
||||
|
||||
-- weapon wear
|
||||
local attach = hitter:get_attach()
|
||||
if attach and attach:get_luaentity() then
|
||||
local luaentity = attach:get_luaentity()
|
||||
if luaentity.driver then
|
||||
luaentity.driver = nil
|
||||
end
|
||||
hitter:set_detach() --MFF (crabman|27/7/2015) anti usebug, immortal if attached
|
||||
end
|
||||
local weapon = hitter:get_wielded_item()
|
||||
local punch_interval = 1.4
|
||||
|
||||
-- calculate mob damage
|
||||
local damage = 0
|
||||
local armor = self.object:get_armor_groups() or {}
|
||||
local tmp
|
||||
|
||||
-- quick error check incase it ends up 0 (serialize.h check test)
|
||||
if tflp == 0 then
|
||||
tflp = 0.2
|
||||
end
|
||||
|
||||
for group,_ in pairs(tool_capabilities.damage_groups) do
|
||||
|
||||
tmp = tflp / (tool_capabilities.full_punch_interval or 1.4)
|
||||
|
||||
if tmp < 0 then
|
||||
tmp = 0.0
|
||||
elseif tmp > 1 then
|
||||
tmp = 1.0
|
||||
end
|
||||
|
||||
damage = damage + (tool_capabilities.damage_groups[group] or 0)
|
||||
* tmp * ((armor[group] or 0) / 100.0)
|
||||
end
|
||||
|
||||
-- check for tool immunity or special damage
|
||||
for _, no in pairs(self.immune_to) do
|
||||
|
||||
if no[1] == weapon:get_name() then
|
||||
damage = no[2] or 0
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- print ("Mob Damage is", damage)
|
||||
|
||||
-- add weapon wear
|
||||
if tool_capabilities then
|
||||
punch_interval = tool_capabilities.full_punch_interval or 1.4
|
||||
end
|
||||
@ -1927,23 +1898,11 @@ minetest.register_entity(name, {
|
||||
})
|
||||
end
|
||||
|
||||
-- do damage
|
||||
self.health = self.health - math.floor(damage)
|
||||
|
||||
-- exit here if dead
|
||||
if check_for_death(self) then
|
||||
return
|
||||
end
|
||||
|
||||
-- add healthy afterglow when hit
|
||||
core.after(0.1, function()
|
||||
self.object:settexturemod("^[colorize:#c9900070")
|
||||
|
||||
core.after(0.3, function()
|
||||
self.object:settexturemod("")
|
||||
end)
|
||||
end)
|
||||
|
||||
-- blood_particles
|
||||
if self.blood_amount > 0
|
||||
and not disable_blood then
|
||||
@ -1955,9 +1914,8 @@ minetest.register_entity(name, {
|
||||
effect(pos, self.blood_amount, self.blood_texture)
|
||||
end
|
||||
|
||||
-- knock back effect (only on full punch)
|
||||
if self.knock_back > 0
|
||||
and tflp > punch_interval then
|
||||
-- knock back effect
|
||||
if self.knock_back > 0 then
|
||||
|
||||
local v = self.object:getvelocity()
|
||||
local r = 1.4 - math.min(punch_interval, 1.4)
|
||||
@ -2119,9 +2077,9 @@ minetest.register_entity(name, {
|
||||
self.path.stuck_timer = 0 -- if stuck for too long search for path
|
||||
-- end init
|
||||
|
||||
self.object:set_armor_groups({immortal = 1, fleshy = self.armor})
|
||||
self.object:set_hp(self.health)
|
||||
self.object:set_armor_groups({fleshy = self.armor})
|
||||
self.old_y = self.object:getpos().y
|
||||
self.old_health = self.health
|
||||
self.object:setyaw((math.random(0, 360) - 180) / 180 * pi)
|
||||
self.sounds.distance = self.sounds.distance or 10
|
||||
self.textures = textures
|
||||
@ -2183,8 +2141,68 @@ end -- END mobs:register_mob function
|
||||
|
||||
-- global functions
|
||||
|
||||
mobs.spawning_mobs = {}
|
||||
|
||||
function mobs:spawn_special(name, nodes, neighbors, interval, chance, active_object_count) -- MFF to special mobs
|
||||
mobs.spawning_mobs[name] = true
|
||||
-- chance override in minetest.conf for registered mob
|
||||
local new_chance = tonumber(minetest.setting_get(name .. "_chance"))
|
||||
if new_chance ~= nil then
|
||||
if new_chance == 0 then
|
||||
return
|
||||
end
|
||||
chance = new_chance
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = nodes,
|
||||
neighbors = neighbors,
|
||||
interval = interval,
|
||||
chance = chance,
|
||||
action = function(pos, node, _, active_object_count_wider)
|
||||
-- do not spawn if too many active entities in area
|
||||
local count = 0
|
||||
local objs = minetest.get_objects_inside_radius(pos, 60)
|
||||
for k, obj in pairs(objs) do
|
||||
if obj:get_luaentity() ~= nil and obj:get_luaentity().name == name then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > active_object_count then
|
||||
return
|
||||
end
|
||||
-- spawn above node
|
||||
pos.y = pos.y + 1
|
||||
-- only spawn away from player
|
||||
local objs = minetest.get_objects_inside_radius(pos, 10)
|
||||
for _,oir in pairs(objs) do
|
||||
if oir:is_player() then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- are we spawning inside solid nodes?
|
||||
if minetest.registered_nodes[node_ok(pos).name].walkable == true then
|
||||
return
|
||||
end
|
||||
|
||||
pos.y = pos.y + 1
|
||||
if minetest.registered_nodes[node_ok(pos).name].walkable == true then
|
||||
return
|
||||
end
|
||||
|
||||
-- spawn mob half block higher than ground
|
||||
pos.y = pos.y - 0.5
|
||||
minetest.add_entity(pos, name)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
interval, chance, active_object_count, min_height, max_height, day_toggle)
|
||||
interval, chance, active_object_count, min_height, max_height, spawn_in_area, day_toggle) --MFF crabman "spawn_in_area"
|
||||
|
||||
mobs.spawning_mobs[name] = true
|
||||
|
||||
-- chance override in minetest.conf for registered mob
|
||||
local new_chance = tonumber(minetest.setting_get(name .. "_chance"))
|
||||
@ -2192,7 +2210,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
if new_chance ~= nil then
|
||||
|
||||
if new_chance == 0 then
|
||||
print("[Mobs Redo] " .. name .. " has spawning disabled")
|
||||
--print("[Mobs Redo] " .. name .. " has spawning disabled")
|
||||
return
|
||||
end
|
||||
|
||||
@ -2209,11 +2227,12 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
interval = interval,
|
||||
chance = chance,
|
||||
|
||||
action = function(pos, node, aoc, active_object_count_wider)
|
||||
action = function(pos, node, _, active_object_count_wider)
|
||||
|
||||
-- do not spawn if too many active entities in area
|
||||
if active_object_count_wider > active_object_count
|
||||
or not mobs.spawning_mobs[name] then
|
||||
or not mobs.spawning_mobs[name]
|
||||
or not pos then --MFF fix crash
|
||||
return
|
||||
end
|
||||
|
||||
@ -2250,7 +2269,8 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
|
||||
-- mobs cannot spawn in protected areas when enabled
|
||||
if spawn_protected == 1
|
||||
and minetest.is_protected(pos, "") then
|
||||
and minetest.is_protected(pos, "")
|
||||
and not spawn_in_area then --MFF crabman
|
||||
return
|
||||
end
|
||||
|
||||
@ -2294,10 +2314,10 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
end
|
||||
|
||||
-- compatibility with older mob registration
|
||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
|
||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, spawn_in_area, day_toggle)
|
||||
|
||||
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
|
||||
chance, active_object_count, -31000, max_height, day_toggle)
|
||||
chance, active_object_count, -31000, max_height, spawn_in_area, day_toggle)
|
||||
end
|
||||
|
||||
-- set content id's
|
||||
@ -2349,7 +2369,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
||||
p.y = pos.y + y
|
||||
p.z = pos.z + z
|
||||
|
||||
if (x * x) + (y * y) + (z * z) <= (radius * radius) + pr:next(-radius, radius)
|
||||
if p.y >= -19600 --MFF
|
||||
and(x * x) + (y * y) + (z * z) <= (radius * radius) + pr:next(-radius, radius)
|
||||
and data[vi] ~= c_air
|
||||
and data[vi] ~= c_ignore
|
||||
and data[vi] ~= c_obsidian
|
||||
@ -2360,8 +2381,48 @@ function mobs:explosion(pos, radius, fire, smoke, sound)
|
||||
local on_blast = minetest.registered_nodes[n].on_blast
|
||||
|
||||
if on_blast then
|
||||
return on_blast(p)
|
||||
else
|
||||
local drops = on_blast(p) or {} -- MFF(Lymkwi) : Chests and bones return their drops now
|
||||
for _, name in ipairs(drops) do
|
||||
local obj = minetest.add_item(p, ItemStack(name))
|
||||
if obj then
|
||||
obj:setvelocity({
|
||||
x = math.random(-2, 2),
|
||||
y = 7,
|
||||
z = math.random(-2, 2)
|
||||
})
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not minetest.is_protected(p, "") --/MFF (Crabman|06/23/2015) re-added node protected in areas
|
||||
and minetest.get_item_group(n, "unbreakable") ~= 1
|
||||
and minetest.get_item_group(n, "nether") == 0 then
|
||||
|
||||
-- if chest then drop items inside
|
||||
if n == "default:chest"
|
||||
or n == "3dchest:chest"
|
||||
or n == "bones:bones" then
|
||||
|
||||
local meta = minetest.get_meta(p)
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
for i = 1, inv:get_size("main") do
|
||||
|
||||
local m_stack = inv:get_stack("main", i)
|
||||
local obj = minetest.add_item(p, m_stack)
|
||||
|
||||
if obj then
|
||||
|
||||
obj:setvelocity({
|
||||
x = math.random(-2, 2),
|
||||
y = 7,
|
||||
z = math.random(-2, 2)
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- after effects
|
||||
if fire > 0
|
||||
and (minetest.registered_nodes[n].groups.flammable
|
||||
@ -2420,13 +2481,6 @@ function mobs:register_arrow(name, def)
|
||||
return
|
||||
end
|
||||
|
||||
-- does arrow have a tail (fireball)
|
||||
if def.tail
|
||||
and def.tail == 1
|
||||
and def.tail_texture then
|
||||
effect(pos, 1, def.tail_texture, 10, 0)
|
||||
end
|
||||
|
||||
if self.hit_node then
|
||||
|
||||
local node = node_ok(pos).name
|
||||
@ -2488,30 +2542,20 @@ function mobs:register_arrow(name, def)
|
||||
end
|
||||
|
||||
-- Spawn Egg
|
||||
function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||
|
||||
local grp = {}
|
||||
|
||||
-- do NOT add this egg to creative inventory (e.g. dungeon master)
|
||||
if creative and no_creative == true then
|
||||
grp = {not_in_creative_inventory = 1}
|
||||
end
|
||||
function mobs:register_egg(mob, desc, background, addegg)
|
||||
|
||||
local invimg = background
|
||||
|
||||
if addegg == 1 then
|
||||
invimg = "mobs_chicken_egg.png^(" .. invimg ..
|
||||
"^[mask:mobs_chicken_egg_overlay.png)"
|
||||
invimg = invimg .. "^mobs_egg_inv.png" -- MFF
|
||||
end
|
||||
|
||||
minetest.register_craftitem(mob, {
|
||||
|
||||
description = desc,
|
||||
inventory_image = invimg,
|
||||
groups = grp,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
|
||||
local pos = pointed_thing.above
|
||||
|
||||
if pos
|
||||
@ -2523,11 +2567,6 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||
local mob = minetest.add_entity(pos, mob)
|
||||
local ent = mob:get_luaentity()
|
||||
|
||||
if not ent then
|
||||
mob:remove()
|
||||
return
|
||||
end
|
||||
|
||||
if ent.type ~= "monster" then
|
||||
-- set owner and tame if not monster
|
||||
ent.owner = placer:get_player_name()
|
||||
@ -2774,41 +2813,3 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
-- used to drop items inside a chest or container
|
||||
local drop_items = function(pos, invstring)
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
for i = 1, inv:get_size(invstring) do
|
||||
|
||||
local m_stack = inv:get_stack(invstring, i)
|
||||
local obj = minetest.add_item(pos, m_stack)
|
||||
|
||||
if obj then
|
||||
|
||||
obj:setvelocity({
|
||||
x = math.random(-10, 10) / 9,
|
||||
y = 3,
|
||||
z = math.random(-10, 10) / 9
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- override chest node so it drops items on explode
|
||||
minetest.override_item("default:chest", {
|
||||
|
||||
on_blast = function(p)
|
||||
|
||||
minetest.after(0, function()
|
||||
|
||||
drop_items(p, "main")
|
||||
|
||||
minetest.remove_node(p)
|
||||
end)
|
||||
end,
|
||||
|
||||
})
|
||||
|
Reference in New Issue
Block a user