master #5

Merged
epCode merged 255 commits from VoxeLibre/VoxeLibre:master into master 2021-02-02 23:20:01 +01:00
271 changed files with 1998 additions and 790 deletions
Showing only changes of commit f1a4c493c8 - Show all commits

View File

@ -0,0 +1,2 @@
# textdomain:mcl_explosions
@1 was caught in an explosion.=@1 a été pris dans une explosion.

View File

@ -1,6 +1,8 @@
-- Some global variables (don't overwrite them!)
mcl_vars = {}
mcl_vars.redstone_tick = 0.1
--- GUI / inventory menu settings
mcl_vars.gui_slots = "listcolors[#9990;#FFF7;#FFF0;#000;#FFF]"
-- nonbg is added as formspec prepend in mcl_formspec_prepend
@ -126,5 +128,3 @@ minetest.craftitemdef_default.stack_max = 64
-- Set random seed for all other mods (Remember to make sure no other mod calls this function)
math.randomseed(os.time())

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

View File

@ -114,9 +114,9 @@ end
function mcl_sounds.node_sound_leaves_defaults(table)
table = table or {}
table.footstep = table.footstep or
{name="default_grass_footstep", gain=0.35}
{name="default_grass_footstep", gain=0.1325}
table.dug = table.dug or
{name="default_grass_footstep", gain=0.85}
{name="default_grass_footstep", gain=0.425}
table.dig = table.dig or
{name="default_dig_snappy", gain=0.4}
table.place = table.place or

View File

@ -6,6 +6,13 @@ mobs.mod = "mrm"
mobs.version = "20180531" -- don't rely too much on this, rarely updated, if ever
local MAX_MOB_NAME_LENGTH = 30
local HORNY_TIME = 30
local HORNY_AGAIN_TIME = 300
local CHILD_GROW_TIME = 60*20
local DEATH_DELAY = 0.5
local DEFAULT_FALL_SPEED = -10
local FLOP_HEIGHT = 5.0
local FLOP_HOR_SPEED = 1.5
local MOB_CAP = {}
MOB_CAP.hostile = 70
@ -66,6 +73,9 @@ local show_health = false
local max_per_block = tonumber(minetest.settings:get("max_objects_per_block") or 64)
local mobs_spawn_chance = tonumber(minetest.settings:get("mobs_spawn_chance") or 2.5)
-- Shows helpful debug info above each mob
local mobs_debug = minetest.settings:get_bool("mobs_debug", false)
-- Peaceful mode message so players will know there are no monsters
if minetest.settings:get_bool("only_peaceful_mobs", false) then
minetest.register_on_joinplayer(function(player)
@ -96,6 +106,33 @@ local mod_mobspawners = minetest.get_modpath("mcl_mobspawners") ~= nil
local mod_hunger = minetest.get_modpath("mcl_hunger") ~= nil
local mod_worlds = minetest.get_modpath("mcl_worlds") ~= nil
local mod_armor = minetest.get_modpath("mcl_armor") ~= nil
local mod_experience = minetest.get_modpath("mcl_experience") ~= nil
----For Water Flowing:
local enable_physics = function(object, luaentity, ignore_check)
if luaentity.physical_state == false or ignore_check == true then
luaentity.physical_state = true
object:set_properties({
physical = true
})
object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=-9.81,z=0})
end
end
local disable_physics = function(object, luaentity, ignore_check, reset_movement)
if luaentity.physical_state == true or ignore_check == true then
luaentity.physical_state = false
object:set_properties({
physical = false
})
if reset_movement ~= false then
object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=0,z=0})
end
end
end
-- play sound
local mob_sound = function(self, soundname, is_opinion, fixed_pitch)
@ -139,7 +176,7 @@ local mob_sound = function(self, soundname, is_opinion, fixed_pitch)
end
end
-- Reeturn true if object is in view_range
-- Return true if object is in view_range
local function object_in_range(self, object)
if not object then
return false
@ -158,17 +195,15 @@ local function object_in_range(self, object)
else
dist = self.view_range
end
if vector.distance(self.object:get_pos(), object:get_pos()) > dist then
return false
else
return true
end
local p1, p2 = self.object:get_pos(), object:get_pos()
return p1 and p2 and (vector.distance(p1, p2) <= dist)
end
-- attack player/mob
local do_attack = function(self, player)
if self.state == "attack" then
if self.state == "attack" or self.state == "die" then
return
end
@ -182,25 +217,61 @@ local do_attack = function(self, player)
end
-- collision function borrowed amended from jordan4ibanez open_ai mod
local collision = function(self)
local pos = self.object:get_pos()
local vel = self.object:get_velocity()
local x = 0
local z = 0
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, width)) do
if object:is_player()
or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) 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,z})
end
-- move mob in facing direction
local set_velocity = function(self, v)
-- do not move if mob has been ordered to stay
local c_x, c_y = 0, 0
-- can mob be pushed, if so calculate direction
if self.pushable then
c_x, c_y = unpack(collision(self))
end
-- halt mob if it has been ordered to stay
if self.order == "stand" then
self.object:set_velocity({x = 0, y = 0, z = 0})
return
end
local yaw = (self.object:get_yaw() or 0) + self.rotate
local vel = self.object:get_velocity()
self.object:set_velocity({
x = sin(yaw) * -v,
y = (vel and vel.y) or 0,
z = cos(yaw) * v
x = (sin(yaw) * -v) + c_x,
y = self.object:get_velocity().y,
z = (cos(yaw) * v) + c_y,
})
end
-- calculate mob velocity
local get_velocity = function(self)
@ -267,24 +338,35 @@ local remove_texture_mod = function(self, mod)
end
-- set defined animation
local set_animation = function(self, anim)
if not self.animation
or not anim then return end
local set_animation = function(self, anim, fixed_frame)
if not self.animation or not anim then
return
end
if self.state == "die" and anim ~= "die" and anim ~= "stand" then
return
end
self.animation.current = self.animation.current or ""
if anim == self.animation.current
if (anim == self.animation.current
or not self.animation[anim .. "_start"]
or not self.animation[anim .. "_end"] then
or not self.animation[anim .. "_end"]) and self.state ~= "die" then
return
end
self.animation.current = anim
local a_start = self.animation[anim .. "_start"]
local a_end
if fixed_frame then
a_end = a_start
else
a_end = self.animation[anim .. "_end"]
end
self.object:set_animation({
x = self.animation[anim .. "_start"],
y = self.animation[anim .. "_end"]},
x = a_start,
y = a_end},
self.animation[anim .. "_speed"] or self.animation.speed_normal or 15,
0, self.animation[anim .. "_loop"] ~= false)
end
@ -323,7 +405,7 @@ local is_node_waterhazard = function(self, nodename)
return true
end
end
if minetest.registered_nodes[nn].drowning > 0 then
if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].drowning and minetest.registered_nodes[nn].drowning > 0 then
if self.breath_max ~= -1 then
-- check if the mob is water-breathing _and_ the block is water; only return true if neither is the case
-- this will prevent water-breathing mobs to classify water or e.g. sand below them as dangerous
@ -495,7 +577,7 @@ local damage_effect = function(self, damage)
end
end
mobs.death_effect = function(pos, collisionbox)
mobs.death_effect = function(pos, yaw, collisionbox, rotate)
local min, max
if collisionbox then
min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]}
@ -504,25 +586,57 @@ mobs.death_effect = function(pos, collisionbox)
min = { x = -0.5, y = 0, z = -0.5 }
max = { x = 0.5, y = 0.5, z = 0.5 }
end
if rotate then
min = vector.rotate(min, {x=0, y=yaw, z=pi/2})
max = vector.rotate(max, {x=0, y=yaw, z=pi/2})
min, max = vector.sort(min, max)
min = vector.multiply(min, 0.5)
max = vector.multiply(max, 0.5)
end
minetest.add_particlespawner({
amount = 40,
time = 0.1,
amount = 50,
time = 0.001,
minpos = vector.add(pos, min),
maxpos = vector.add(pos, max),
minvel = {x = -0.2, y = -0.1, z = -0.2},
maxvel = {x = 0.2, y = 0.1, z = 0.2},
minexptime = 0.5,
minvel = vector.new(-5,-5,-5),
maxvel = vector.new(5,5,5),
minexptime = 1.1,
maxexptime = 1.5,
minsize = 0.5,
maxsize = 1.5,
texture = "mcl_particles_smoke.png",
minsize = 1,
maxsize = 2,
collisiondetection = false,
vertical = false,
texture = "mcl_particles_mob_death.png^[colorize:#000000:255",
})
minetest.sound_play("mcl_mobs_mob_poof", {
pos = pos,
gain = 1.0,
max_hear_distance = 8,
}, true)
end
local update_tag = function(self)
local tag
if mobs_debug then
tag = "nametag = '"..tostring(self.nametag).."'\n"..
"state = '"..tostring(self.state).."'\n"..
"order = '"..tostring(self.order).."'\n"..
"attack = "..tostring(self.attack).."\n"..
"health = "..tostring(self.health).."\n"..
"breath = "..tostring(self.breath).."\n"..
"gotten = "..tostring(self.gotten).."\n"..
"tamed = "..tostring(self.tamed).."\n"..
"horny = "..tostring(self.horny).."\n"..
"hornytimer = "..tostring(self.hornytimer).."\n"..
"runaway_timer = "..tostring(self.runaway_timer).."\n"..
"following = "..tostring(self.following)
else
tag = self.nametag
end
self.object:set_properties({
nametag = self.nametag,
nametag = tag,
})
end
@ -585,6 +699,10 @@ end
-- check if mob is dead or only hurt
local check_for_death = function(self, cause, cmi_cause)
if self.state == "die" then
return true
end
-- has health actually changed?
if self.health == self.old_health and self.health > 0 then
return false
@ -629,6 +747,9 @@ local check_for_death = function(self, cause, cmi_cause)
return false
end
mob_sound(self, "death")
local function death_handle(self)
-- dropped cooked item if mob died in fire or lava
if cause == "lava" or cause == "fire" then
item_drop(self, true)
@ -636,55 +757,79 @@ local check_for_death = function(self, cause, cmi_cause)
item_drop(self, nil)
end
mob_sound(self, "death")
local pos = self.object:get_pos()
if mcl_experience.throw_experience and self.hp_min and self.hp_max then
mcl_experience.throw_experience(pos, math.ceil( math.random(self.hp_min,self.hp_max+5) / 5) )
if mod_experience and ((not self.child) or self.type ~= "animal") then
mcl_experience.throw_experience(pos, math.random(self.xp_min, self.xp_max))
end
end
-- execute custom death function
if self.on_die then
self.on_die(self, pos)
local pos = self.object:get_pos()
local on_die_exit = self.on_die(self, pos)
if on_die_exit ~= true then
death_handle(self)
end
if use_cmi then
cmi.notify_die(self.object, cmi_cause)
end
if on_die_exit == true then
self.state = "die"
self.object:remove()
return true
end
end
local collisionbox
if self.collisionbox then
collisionbox = table.copy(self.collisionbox)
end
self.state = "die"
self.attack = nil
self.v_start = false
self.fall_speed = DEFAULT_FALL_SPEED
self.timer = 0
self.blinktimer = 0
remove_texture_mod(self, "^[colorize:#FF000040")
remove_texture_mod(self, "^[brighten")
self.passive = true
self.object:set_properties({
pointable = false,
collide_with_objects = false,
})
set_velocity(self, 0)
local acc = self.object:get_acceleration()
acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0
self.object:set_acceleration(acc)
local length
-- default death function and die animation (if defined)
if self.animation
if self.instant_death then
length = 0
elseif self.animation
and self.animation.die_start
and self.animation.die_end then
local frames = self.animation.die_end - self.animation.die_start
local speed = self.animation.die_speed or 15
local length = max(frames / speed, 0)
self.attack = nil
self.v_start = false
self.timer = 0
self.blinktimer = 0
self.passive = true
self.state = "die"
self.object:set_properties({
pointable = false,
})
set_velocity(self, 0)
length = max(frames / speed, 0) + DEATH_DELAY
set_animation(self, "die")
else
local rot = self.object:get_rotation()
rot.z = pi/2
self.object:set_rotation(rot)
length = 1 + DEATH_DELAY
set_animation(self, "stand", true)
end
minetest.after(length, function(self)
-- Remove body after a few seconds and drop stuff
local kill = function(self)
if not self.object:get_luaentity() then
return
end
@ -692,17 +837,17 @@ local check_for_death = function(self, cause, cmi_cause)
cmi.notify_die(self.object, cmi_cause)
end
death_handle(self)
local dpos = self.object:get_pos()
local cbox = self.collisionbox
local yaw = self.object:get_rotation().y
self.object:remove()
mobs.death_effect(pos)
end, self)
else
if use_cmi then
cmi.notify_die(self.object, cmi_cause)
mobs.death_effect(dpos, yaw, cbox, not self.instant_death)
end
self.object:remove()
mobs.death_effect(pos, collisionbox)
if length <= 0 then
kill(self)
else
minetest.after(length, kill, self)
end
return true
@ -710,18 +855,23 @@ end
-- check if within physical map limits (-30911 to 30927)
local within_limits = function(pos, radius)
if (pos.x - radius) > -30913
and (pos.x + radius) < 30928
and (pos.y - radius) > -30913
and (pos.y + radius) < 30928
and (pos.z - radius) > -30913
and (pos.z + radius) < 30928 then
return true -- within limits
local within_limits, wmin, wmax = nil, -30913, 30928
within_limits = function(pos, radius)
if mcl_vars then
if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then
wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max
within_limits = function(pos, radius)
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
return false -- beyond limits
end
end
return pos
and (pos.x - radius) > wmin and (pos.x + radius) < wmax
and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
@ -753,7 +903,9 @@ local is_at_cliff_or_danger = function(self)
return true
else
local def = minetest.registered_nodes[bnode.name]
return (not def and def.walkable)
if def and def.walkable then
return false
end
end
end
@ -789,7 +941,9 @@ local is_at_water_danger = function(self)
return true
else
local def = minetest.registered_nodes[bnode.name]
return (not def and def.walkable)
if def and def.walkable then
return false
end
end
end
@ -1110,7 +1264,7 @@ local do_jump = function(self)
-- when in air move forward
minetest.after(0.3, function(self, v)
if not self.object or not self.object:get_luaentity() then
if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then
return
end
self.object:set_acceleration({
@ -1211,12 +1365,13 @@ end
-- find two animals of same type and breed if nearby and horny
local breed = function(self)
-- child takes 240 seconds before growing into adult
-- child takes a long time before growing into adult
if self.child == true then
-- When a child, hornytimer is used to count age until adulthood
self.hornytimer = self.hornytimer + 1
if self.hornytimer > 240 then
if self.hornytimer >= CHILD_GROW_TIME then
self.child = false
self.hornytimer = 0
@ -1245,14 +1400,14 @@ local breed = function(self)
return
end
-- horny animal can mate for 40 seconds,
-- afterwards horny animal cannot mate again for 200 seconds
-- horny animal can mate for HORNY_TIME seconds,
-- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds
if self.horny == true
and self.hornytimer < 240 then
and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then
self.hornytimer = self.hornytimer + 1
if self.hornytimer >= 240 then
if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then
self.hornytimer = 0
self.horny = false
end
@ -1260,7 +1415,7 @@ local breed = function(self)
-- find another same animal who is also horny and mate if nearby
if self.horny == true
and self.hornytimer <= 40 then
and self.hornytimer <= HORNY_TIME then
local pos = self.object:get_pos()
@ -1299,15 +1454,15 @@ local breed = function(self)
if ent
and canmate == true
and ent.horny == true
and ent.hornytimer <= 40 then
and ent.hornytimer <= HORNY_TIME then
num = num + 1
end
-- found your mate? then have a baby
if num > 1 then
self.hornytimer = 41
ent.hornytimer = 41
self.hornytimer = HORNY_TIME + 1
ent.hornytimer = HORNY_TIME + 1
-- spawn baby
minetest.after(5, function(parent1, parent2, pos)
@ -1318,6 +1473,11 @@ local breed = function(self)
return
end
-- Give XP
if mod_experience then
mcl_experience.throw_experience(pos, math.random(1, 7))
end
-- custom breed function
if parent1.on_breed then
-- when false, skip going any further
@ -1384,10 +1544,11 @@ local replace = function(self, pos)
pos.y = pos.y + y_offset
if #minetest.find_nodes_in_area(pos, pos, what) > 0 then
local node = minetest.get_node(pos)
if node.name == what then
local oldnode = {name = what}
local newnode = {name = with}
local oldnode = {name = what, param2 = node.param2}
local newnode = {name = with, param2 = node.param2}
local on_replace_return
if self.on_replace then
@ -1397,7 +1558,7 @@ local replace = function(self, pos)
if on_replace_return ~= false then
if mobs_griefing then
minetest.set_node(pos, {name = with})
minetest.set_node(pos, newnode)
end
end
@ -1810,7 +1971,7 @@ end
-- find someone to runaway from
local runaway_from = function(self)
if not self.runaway_from then
if not self.runaway_from and self.state ~= "flop" then
return
end
@ -1927,10 +2088,12 @@ local follow_flop = function(self)
self.following = nil
end
else
-- stop following player if not holding specific item
-- stop following player if not holding specific item,
-- mob is horny, fleeing or attacking
if self.following
and self.following:is_player()
and follow_holding(self, self.following) == false then
and (follow_holding(self, self.following) == false or
self.horny or self.state == "runaway") then
self.following = nil
end
@ -1995,13 +2158,26 @@ local follow_flop = function(self)
if not flight_check(self, s) then
self.state = "flop"
self.object:set_velocity({x = 0, y = -5, z = 0})
self.object:set_acceleration({x = 0, y = DEFAULT_FALL_SPEED, z = 0})
set_animation(self, "stand")
local sdef = minetest.registered_nodes[self.standing_on]
-- Flop on ground
if sdef and sdef.walkable then
mob_sound(self, "flop")
self.object:set_velocity({
x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
y = FLOP_HEIGHT,
z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
})
end
set_animation(self, "stand", true)
return
elseif self.state == "flop" then
self.state = "stand"
self.object:set_acceleration({x = 0, y = 0, z = 0})
set_velocity(self, 0)
end
end
end
@ -2222,10 +2398,8 @@ local do_states = function(self, dtime)
-- attack routines (explode, dogfight, shoot, dogshoot)
elseif self.state == "attack" then
-- calculate distance from mob and enemy
local s = self.object:get_pos()
local p = self.attack:get_pos() or s
local dist = vector.distance(p, s)
-- stop attacking if player invisible or out of range
if not self.attack
@ -2246,6 +2420,9 @@ local do_states = function(self, dtime)
return
end
-- calculate distance from mob and enemy
local dist = vector.distance(p, s)
if self.attack_type == "explode" then
local vec = {
@ -2588,7 +2765,7 @@ end
-- returns true if mob died
local falling = function(self, pos)
if self.fly then
if self.fly and self.state ~= "die" then
return
end
@ -2801,7 +2978,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
}, true)
else
minetest.sound_play("default_punch", {
object = self.object, --hitter,
object = self.object,
max_hear_distance = 5
}, true)
end
@ -2853,7 +3030,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
end -- END if damage
-- if skittish then run away
if not die and self.runaway == true then
if not die and self.runaway == true and self.state ~= "flop" then
local lp = hitter:get_pos()
local s = self.object:get_pos()
@ -3153,6 +3330,10 @@ local mob_step = function(self, dtime)
local pos = self.object:get_pos()
local yaw = 0
if mobs_debug then
update_tag(self)
end
-- Despawning: when lifetimer expires, remove mob
if remove_far
and self.can_despawn == true
@ -3184,6 +3365,10 @@ local mob_step = function(self, dtime)
end
end
if self.state == "die" then
return
end
if self.jump_sound_cooloff > 0 then
self.jump_sound_cooloff = self.jump_sound_cooloff - dtime
end
@ -3315,6 +3500,46 @@ local mob_step = function(self, dtime)
end
end
-- Add water flowing for mobs from mcl_item_entity
local p, node, nn, def
p = self.object:get_pos()
node = minetest.get_node_or_nil(p)
if node then
nn = node.name
def = minetest.registered_nodes[nn]
end
-- Move item around on flowing liquids
if def and def.liquidtype == "flowing" then
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]]
local vec = flowlib.quick_flow(p, node)
-- Just to make sure we don't manipulate the speed for no reason
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
local f = 1.39
-- Set new item moving speed into the direciton of the liquid
local newv = vector.multiply(vec, f)
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
self.physical_state = true
self._flowing = true
self.object:set_properties({
physical = true
})
return
end
elseif self._flowing == true then
-- Disable flowing physics if not on/in flowing liquid
self._flowing = false
enable_physics(self.object, self, true)
return
end
--Mob following code.
follow_flop(self)
if is_at_cliff_or_danger(self) then
@ -3422,6 +3647,8 @@ minetest.register_entity(name, {
lifetimer = def.lifetimer or 57.73,
hp_min = scale_difficulty(def.hp_min, 5, 1),
hp_max = scale_difficulty(def.hp_max, 10, 1),
xp_min = def.xp_min or 0,
xp_max = def.xp_max or 0,
breath_max = def.breath_max or 15,
breathes_in_water = def.breathes_in_water or false,
physical = true,
@ -3442,7 +3669,7 @@ minetest.register_entity(name, {
fire_damage = def.fire_damage or 1,
suffocation = def.suffocation or true,
fall_damage = def.fall_damage or 1,
fall_speed = def.fall_speed or -10, -- must be lower than -2 (default: -10)
fall_speed = def.fall_speed or DEFAULT_FALL_SPEED, -- must be lower than -2
drops = def.drops or {},
armor = def.armor or 100,
on_rightclick = create_mob_on_rightclick(def.on_rightclick),
@ -3500,6 +3727,8 @@ minetest.register_entity(name, {
owner_loyal = def.owner_loyal,
facing_fence = false,
_cmi_is_mob = true,
pushable = def.pushable or true,
-- MCL2 extensions
teleport = teleport,
@ -3516,6 +3745,7 @@ minetest.register_entity(name, {
explosion_strength = def.explosion_strength,
suffocation_timer = 0,
follow_velocity = def.follow_velocity or 2.4,
instant_death = def.instant_death or false,
-- End of MCL2 extensions
on_spawn = def.on_spawn,
@ -3771,15 +4001,14 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
end
end
-- spawn mob 1/2 node above ground
pos.y = pos.y + 0.5
-- tweak X/Z spawn pos
-- 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))
@ -4063,9 +4292,10 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
return itemstack
end
pos.y = pos.y + 1
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, mob)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
local ent = mob:get_luaentity()
-- don't set owner if monster or sneak pressed
@ -4130,6 +4360,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
clicker:set_wielded_item(item)
end
mob_sound(self, "eat", nil, true)
-- increase health
self.health = self.health + 4
@ -4149,7 +4381,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
-- make children grow quicker
if self.child == true then
self.hornytimer = self.hornytimer + 20
-- deduct 10% of the time to adulthood
self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1)
return true
end

View File

@ -145,12 +145,14 @@ functions needed for the mob to work properly which contains the following:
'base_pitch' base pitch to use adult mobs, default is 1.0 (MCL2 extension)
'random' played randomly from time to time.
also played for overfeeding animal.
'eat' played when mob eats something
'war_cry' what you hear when mob starts to attack player. (currently disabled)
'attack' what you hear when being attacked.
'shoot_attack' sound played when mob shoots.
'damage' sound heard when mob is hurt.
'death' played when mob is killed.
'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam
'flop' played when mob flops (like a stranded fish)
'fuse' sound played when mob explode timer starts.
'explode' sound played when mob explodes.
@ -222,6 +224,8 @@ functions needed for the mob to work properly which contains the following:
'speed_normal' is used for animation speed for compatibility with some
older mobs.
'pushable' Allows players, & other mobs to push the mob.
MineClone 2 extensions:
@ -242,6 +246,10 @@ functions needed for the mob to work properly which contains the following:
'sounds_child' same as sounds, but for childs. If not defined, childs will use same
sound as adults but with higher pitch
'follow_velocity' The speed at which a mob moves toward the player when they're holding the appropriate follow item.
'instant_death' If true, mob dies instantly (no death animation or delay) (default: false)
'xp_min' the minimum XP it drops on death (default: 0)
'xp_max' the maximum XP it drops on death (default: 0)
Node Replacement
@ -282,10 +290,9 @@ Custom Definition Functions
Along with the above mob registry settings we can also use custom functions to
enhance mob functionality and have them do many interesting things:
'on_die' a function that is called when the mob is killed the
parameters are (self, pos). When this function is used,
the death particles will be skipped on death. You can get
them back by calling mobs:death_effect manually
'on_die' a function that is called when the mob is killed; the
parameters are (self, pos). Return true to skip the builtin
death animation and death effects
'on_rightclick' its same as in minetest.register_entity()
'on_blast' is called when an explosion happens near mob when using TNT
functions, parameters are (object, damage) and returns
@ -342,6 +349,14 @@ for each mob.
dogs
'self.order' set to "follow" or "stand" so that npc will follow owner
or stand it's ground
'self.state' Current mob state.
"stand": no movement (except turning around)
"walk": walk or move around aimlessly
"attack": chase and attack enemy
"runaway": flee from target
"flop": bounce around aimlessly
(for swimming mobs that have stranded)
"die": during death
'self.nametag' contains the name of the mob which it can show above

View File

@ -1,3 +1,3 @@
name = mcl_mobs
depends = mcl_particles
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience

View File

@ -10,13 +10,14 @@ This mod contains the API only for adding your own mobs into the world, so pleas
https://forum.minetest.net/viewtopic.php?f=11&t=9917
------------
Credits:
Items:
- Nametag (paper, black dye, string) can be used right-click on a tamed mob to give them a name.
Lucky Block items: 1
mcl_mobs_mob_poof.ogg:
- by Planman (license: Creative Commons Zero)
- Source: <https://freesound.org/people/Planman/sounds/208111/>
------------
Changelog from original Mobs Redo mod:
- 1.41- Mob pathfinding has been updated thanks to Elkien3

Binary file not shown.

View File

@ -0,0 +1,2 @@
# textdomain:mcl_paintings
Painting=Peinture

View File

@ -84,6 +84,12 @@ Origin of those models:
* [AGFX](http://www.freesound.org/people/DrMinky/sounds/) (CC0)
* `mobs_mc_chicken_child.ogg`
* Source: <https://freesound.org/people/AGFX/sounds/43380/>
* [evsecrets](https://freesound.org/people/evsecrets/sounds/) (CC0)
* `mobs_mc_chicken_*.ogg`
* Source: <https://freesound.org/people/evsecrets/sounds/346961/>
* [contramundum](https://freesound.org/people/contramundum/sounds/)
* `mobs_mc_parrot_*.ogg`
* Source: <https://freesound.org/people/contramundum/sounds/388417/>
* Randomation (CC0)
* `green_slime_damage.ogg`
* `green_slime_attack.ogg`
@ -99,27 +105,78 @@ Origin of those models:
* `mobs_mc_cow_hurt.ogg` (CC0)
* Heavily modified
* Source: <https://freesound.org/people/Bird_man/packs/16972/>
* [Klaraschick](https://freesound.org/people/Klaraschick/)
* `mobs_mc_cow_milk.ogg` (CC0)
* shortened
* Source: <https://freesound.org/people/Klaraschick/sounds/415312/>
* [Hitrison](https://freesound.org/people/Hitrison/)
* `mobs_mc_cow_mushroom_stew.ogg` (CC BY 3.0)
* sound was modified
* Source: <https://freesound.org/people/Hitrison/sounds/251411/>
* [NPXcoot](https://github.com/NPXcoot1) (CC BY-SA 4.0)
* `mobs_mc_ender_dragon_*`
* [bevibeldesign](https://freesound.org/people/bevibeldesign/)
* `mobs_mc_wither_spawn.ogg` (CC0)
* Source: <https://freesound.org/people/bevibeldesign/sounds/366095/>
* [rubberduck](https://opengameart.org/users/rubberduck)
* `mobs_mc_endermite_*.ogg` (CC0)
* `mobs_mc_zombiepig_*.ogg` (CC0)
* `mobs_mc_enderman_teleport_*.ogg` (CC0)
* Source 1: <https://opengameart.org/content/80-cc0-creature-sfx>
* Source 2: <https://opengameart.org/content/80-cc0-creture-sfx-2>
* [Soundscapes55](https://freesound.org/people/Soundscapes55/)
* `mobs_mc_enderman_random.1.ogg` (CC0)
* Source: <https://freesound.org/people/Soundscapes55/sounds/434973/>
* [griffinjennings](https://freesound.org/people/griffinjennings/)
* `mobs_mc_enderman_death.*.ogg` (CC BY 3.0)
* `mobs_mc_enderman_hurt.*.ogg` (CC BY 3.0)
* Sounds were heavily modified
* Source: <https://freesound.org/people/griffinjennings/sounds/463972/>
* [pointparkcinema](https://freesound.org/people/pointparkcinema/)
* `mobs_mc_guardian_random.1.ogg` (CC0)
* Source: <https://freesound.org/people/pointparkcinema/sounds/407252/>
* [nornalbion](https://freesound.org/people/nornalbion/)
* `mobs_mc_guardian_random.2.ogg` (CC BY 3.0)
* `mobs_mc_guardian_random.3.ogg` (CC BY 3.0)
* `mobs_mc_guardian_hurt.*.ogg` (CC BY 3.0)
* Sounds were modified
* Source: <https://freesound.org/people/nornalbion/sounds/195733/>
* [TheBuilder15](https://freesound.org/people/TheBuilder15/)
* `mobs_mc_guardian_death.ogg` (CC0)
* Source: <https://freesound.org/people/pointparkcinema/sounds/407252/>
* Blender Foundation (CC BY 3.0)
* `mobs_sheep.ogg`,
* daufinsyd (MIT License)
* `mobs_mc_blaze_breath.ogg`
* `mobs_mc_blaze_died.ogg`
* `mobs_mc_squid_hurt.ogg`
* [qubodup](https://opengameart.org/content/slime-monster)
* `mobs_mc_squid_hurt.*.ogg` (CC BY 3.0)
* `mobs_mc_squid_death.*.ogg` (CC BY 3.0)
* Changes were made
* Source: <https://opengameart.org/content/slime-monster>
* [kyles](https://freesound.org/people/kyles/)
* `mobs_mc_squid_flop.*.ogg` (CC0)
* Source: <https://freesound.org/people/kyles/sounds/450830/>
* `mobs_mc_snowman_hurt.1.ogg` (CC0)
* Source: <https://freesound.org/people/kyles/sounds/450848/>
* [thefilmbakery](https://freesound.org/people/thefilmbakery/) (CC0)
* `mobs_mc_blaze_hurt.ogg`
* Source: <https://freesound.org/people/thefilmbakery/sounds/137836/>
* TenPlus1, from `mobs_monster` or `mobs_animal` mod (MIT License)
* `mobs_chicken.ogg`
* `mobs_fireball.ogg`
* `mobs_mc_cat_idle.1.ogg`
* `mobs_mc_llama.ogg`
* `mobs_pig.ogg`
* `mobs_pig_angry.ogg`
* `mobs_rat.ogg`
* `mobs_sandmonster.ogg`
* `mobs_spider.ogg`
* [Daysycho](https://freesound.org/people/Darsycho/)
* `mobs_mc_spider_hurt.*.ogg` (CC0)
* Source: <https://freesound.org/people/Darsycho/sounds/505185/>
* [columbia23](https://freesound.org/people/columbia23/)
* `mobs_mc_spider_death.ogg` (CC BY 3.0)
* `mobs_mc_spider_random.*.ogg` (CC BY 3.0)
* `mobs_mc_spider_attack.*.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/columbia23/sounds/395395/>
* BrandonReese (LGPL v2.1)
* `mobs_eerie.ogg`
* [Under7dude](https://freesound.org/people/Under7dude/) (CC0)
@ -147,6 +204,13 @@ Origin of those models:
* Source: <https://freesound.org/people/GoodListener/sounds/322454/>
* `mobs_mc_horse_death.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/GoodListener/sounds/322445/>
* [Garuda1982](https://freesound.org/people/Garuda1982/)
* `mobs_mc_donkey_random.1.ogg` (CC BY 3.0)
* `mobs_mc_donkey_hurt.ogg` (CC BY 3.0)
* `mobs_mc_donkey_death.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/Garuda1982/sounds/539505/>
* [JarredGibb](https://freesound.org/people/JarredGibb/sounds/233131/)
* `mobs_mc_donkey_random.2.ogg` (CC0)
* [ERH](https://freesound.org/people/ERH/)
* `mobs_mc_horse_random.2.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/ERH/sounds/32043/>
@ -164,6 +228,10 @@ Origin of those models:
* [suonho](https://freesound.org/people/suonho/)
* `mobs_mc_bat_idle.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/suonho/sounds/59344/>
* [toefur](https://freesound.org/people/toefur/)
* `mobs_mc_bat_hurt.*.ogg` (CC0)
* `mobs_mc_bat_death.ogg` (CC0)
* Source: <https://freesound.org/people/toefur/sounds/288941/>
* [cmusounddesign](https://freesound.org/people/cmusounddesign/)
* `mobs_mc_cat_hiss.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/cmusounddesign/sounds/71899/>
@ -173,6 +241,16 @@ Origin of those models:
* [ebcrosby](https://freesound.org/people/ebcrosby/)
* `mobs_mc_ocelot_hurt.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/ebcrosby/sounds/332979/>
* Hybrid Dog (forum.minetest.net)
* `mobs_mc_wolf_hurt.*.ogg` (CC0)
* `mobs_mc_wolf_bark.*.ogg` (CC0)
* `mobs_mc_wolf_death.*.ogg` (CC0)
* `mobs_mc_wolf_growl.*.ogg` (CC0)
* Sounds modified and simplified
* Source: "dogblocks" mod by Hybrid Dog <https://github.com/HybridDog/dogblocks/>
* [cliftoncarlson](https://freesound.org/people/cliftonmcarlson/)
* `mobs_mc_wolf_take_bone.ogg` (CC0)
* Source: <https://freesound.org/people/cliftonmcarlson/sounds/392883/>
* [Inocodum](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3115)
* `mobs_mc_silverfish_hurt.ogg` (CC BY-SA 4.0)
* `mobs_mc_silverfish_death.ogg` (CC BY-SA 4.0)
@ -186,6 +264,45 @@ Origin of those models:
* [kbnevel](https://freesound.org/people/kbnevel/)
* `mobs_mc_magma_cube_attack.ogg` (CC0)
* Derived from: <https://freesound.org/people/kbnevel/sounds/119863/>
* [InspectorJ](https://freesound.org/people/InspectorJ/sounds/429591/)
* `mobs_mc_animal_eat_generic.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/InspectorJ/>
* [tbsounddesigns](https://freesound.org/people/tbsounddesigns/)
* `mobs_mc_bear_random.*.ogg` (CC BY 3.0)
* Source 1: <https://freesound.org/people/tbsounddesigns/sounds/416853/>
* Source 2: <https://freesound.org/people/tbsounddesigns/sounds/416857/>
* Source 3: <https://freesound.org/people/tbsounddesigns/sounds/416855/>
* `mobs_mc_bear_growl.*.ogg` (CC BY 3.0)
* Source 1: <https://freesound.org/people/tbsounddesigns/sounds/416861/>
* Source 2: <https://freesound.org/people/tbsounddesigns/sounds/416859/>
* Source 3: <https://freesound.org/people/tbsounddesigns/sounds/416862/>
* [YleArkisto](https://freesound.org/people/YleArkisto/)
* `mobs_mc_bear_attack.*.ogg` (CC BY 3.0)
* `mobs_mc_bear_death.*.ogg` (CC BY 3.0)
* `mobs_mc_bear_hurt.1.ogg` (CC BY 3.0)
* Changes were made
* Source: <https://freesound.org/people/YleArkisto/sounds/249441/>
* [alexo400](https://freesound.org/people/alexo400/)
* `mobs_mc_snowman_death.*.ogg` (CC0)
* Source: <https://freesound.org/people/alexo400/sounds/543385/>
* [cabled\_mess](https://freesound.org/people/cabled_mess/)
* `mobs_mc_snowman_hurt.2.ogg` (CC0)
* Source: <https://freesound.org/people/cabled_mess/sounds/384424/>
* `mobs_mc_snowman_hurt.3.ogg` (CC0)
* Source: <https://freesound.org/people/cabled_mess/sounds/384421/>
* [kessir](https://freesound.org/people/kessir/sounds/)
* `mobs_mc_rabbit_hurt.*.ogg` (CC0)
* `mobs_mc_rabbit_death.2.ogg` (CC0)
* `mobs_mc_rabbit_death.3.ogg` (CC0)
* Source: <https://freesound.org/people/kessir/sounds/372075/>
* `mobs_mc_rabbit_attack.*.ogg` (CC0)
* Source: <https://freesound.org/people/kessir/sounds/372076/>
* `mobs_mc_rabbit_death.1.ogg` (CC0)
* Source: <https://freesound.org/people/kessir/sounds/385850/>
* [Alshred](https://freesound.org/people/Alshred/sounds/403773/)
* `mobs_mc_rabbit_random.*.ogg` (CC0)
* Changes were made.
* Source: <https://freesound.org/people/Alshred/>
Note: Many of these sounds have been more or less modified to fit the game.

View File

@ -18,6 +18,8 @@ mobs:register_mob("mobs_mc:bat", {
visual_size = {x=1, y=1},
sounds = {
random = "mobs_mc_bat_idle",
damage = "mobs_mc_bat_hurt",
death = "mobs_mc_bat_death",
distance = 16,
},
walk_velocity = 4.5,
@ -33,18 +35,19 @@ mobs:register_mob("mobs_mc:bat", {
run_speed = 80,
run_start = 0,
run_end = 40,
-- TODO: Less ugly death animation
--[[ die_speed = 60,
die_speed = 60,
die_start = 40,
die_end = 80,
die_loop = false,
]]
},
walk_chance = 100,
fall_damage = 0,
view_range = 16,
fear_height = 0,
jump = false,
fly = true,
makes_footstep_sound = false,
})

View File

@ -15,6 +15,8 @@ mobs:register_mob("mobs_mc:blaze", {
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
xp_min = 10,
xp_max = 10,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3},
rotate = -180,
visual = "mesh",
@ -68,6 +70,7 @@ mobs:register_mob("mobs_mc:blaze", {
jump = true,
jump_height = 4,
fly = true,
makes_footstep_sound = false,
fear_height = 0,
glow = 14,
})

View File

@ -14,6 +14,8 @@ mobs:register_mob("mobs_mc:chicken", {
hp_min = 4,
hp_max = 4,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2},
runaway = true,
floats = 1,
@ -39,14 +41,17 @@ mobs:register_mob("mobs_mc:chicken", {
fall_damage = 0,
fall_speed = -2.25,
sounds = {
random = "mobs_chicken",
-- TODO: death, damage
random = "mobs_mc_chicken_buck",
damage = "mobs_mc_chicken_hurt",
death = "mobs_mc_chicken_hurt",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
sounds_child = {
random = "mobs_mc_chicken_child",
damage = "mobs_mc_chicken_child",
death = "mobs_mc_chicken_child",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
animation = {

View File

@ -7,6 +7,8 @@ local cow_def = {
spawn_class = "passive",
hp_min = 10,
hp_max = 10,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45},
visual = "mesh",
mesh = "mobs_mc_cow.b3d",
@ -32,6 +34,7 @@ local cow_def = {
random = "mobs_mc_cow",
damage = "mobs_mc_cow_hurt",
death = "mobs_mc_cow_hurt",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
animation = {
@ -54,6 +57,7 @@ local cow_def = {
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
local inv = clicker:get_inventory()
inv:remove_item("main", mobs_mc.items.bucket)
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
-- if room add bucket of milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", mobs_mc.items.milk)
@ -89,7 +93,7 @@ mooshroom_def.on_rightclick = function(self, clicker)
-- Use shears to get mushrooms and turn mooshroom into cow
if item:get_name() == mobs_mc.items.shears then
local pos = self.object:get_pos()
minetest.sound_play("shears", {pos = pos}, true)
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_brown .. " 5")
@ -110,6 +114,7 @@ mooshroom_def.on_rightclick = function(self, clicker)
elseif item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
local inv = clicker:get_inventory()
inv:remove_item("main", mobs_mc.items.bucket)
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
-- If room, add milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", mobs_mc.items.milk)
@ -122,6 +127,7 @@ mooshroom_def.on_rightclick = function(self, clicker)
elseif item:get_name() == mobs_mc.items.bowl and clicker:get_inventory() then
local inv = clicker:get_inventory()
inv:remove_item("main", mobs_mc.items.bowl)
minetest.sound_play("mobs_mc_cow_mushroom_stew", {pos=self.object:get_pos(), gain=0.6})
-- If room, add mushroom stew to inventory, otherwise drop as item
if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then
clicker:get_inventory():add_item("main", mobs_mc.items.mushroom_stew)

View File

@ -14,6 +14,8 @@ mobs:register_mob("mobs_mc:creeper", {
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
xp_min = 5,
xp_max = 5,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3},
pathfinding = 1,
visual = "mesh",
@ -81,7 +83,6 @@ mobs:register_mob("mobs_mc:creeper", {
local r = math.random(1, #mobs_mc.items.music_discs)
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[r])
end
mobs.death_effect(pos, self.collisionbox)
end,
maxdrops = 2,
drops = {

View File

@ -12,6 +12,8 @@ mobs:register_mob("mobs_mc:enderdragon", {
walk_chance = 100,
hp_max = 200,
hp_min = 200,
xp_min = 500,
xp_max = 500,
collisionbox = {-2, 3, -2, 2, 5, 2},
physical = false,
visual = "mesh",
@ -34,6 +36,7 @@ mobs:register_mob("mobs_mc:enderdragon", {
jump = true,
jump_height = 14,
fly = true,
makes_footstep_sound = false,
dogshoot_switch = 1,
dogshoot_count_max =5,
dogshoot_count2_max = 5,

View File

@ -8,7 +8,6 @@
-- However, they have a reduced viewing range to make them less dangerous.
-- This differs from MC, in which endermen only become hostile when provoked,
-- and they are provoked by looking directly at them.
-- TODO: Implement MC behaviour.
-- Rootyjr
-----------------------------
@ -27,6 +26,16 @@
local S = minetest.get_translator("mobs_mc")
local telesound = function(pos, is_source)
local snd
if is_source then
snd = "mobs_mc_enderman_teleport_src"
else
snd = "mobs_mc_enderman_teleport_dst"
end
minetest.sound_play(snd, {pos=pos, max_hear_distance=16}, true)
end
--###################
--################### ENDERMAN
--###################
@ -181,13 +190,14 @@ end
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
mobs:register_mob("mobs_mc:enderman", {
-- TODO: Endermen should be classified as passive
type = "monster",
spawn_class = "passive",
passive = true,
pathfinding = 1,
hp_min = 40,
hp_max = 40,
xp_min = 5,
xp_max = 5,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3},
visual = "mesh",
mesh = "mobs_mc_enderman.b3d",
@ -195,9 +205,11 @@ mobs:register_mob("mobs_mc:enderman", {
visual_size = {x=3, y=3},
makes_footstep_sound = true,
sounds = {
-- TODO: Custom war cry sound
war_cry = "mobs_sandmonster",
death = "green_slime_death",
-- TODO: damage, random
death = {name="mobs_mc_enderman_death", gain=0.7},
damage = {name="mobs_mc_enderman_hurt", gain=0.5},
random = {name="mobs_mc_enderman_random", gain=0.5},
distance = 16,
},
walk_velocity = 0.2,
@ -212,7 +224,6 @@ mobs:register_mob("mobs_mc:enderman", {
},
animation = select_enderman_animation("normal"),
_taken_node = "",
-- TODO: Teleport enderman on damage, etc.
do_custom = function(self, dtime)
-- PARTICLE BEHAVIOUR HERE.
local enderpos = self.object:get_pos()
@ -362,7 +373,7 @@ mobs:register_mob("mobs_mc:enderman", {
self._take_place_timer = 0
self._next_take_place_time = math.random(place_frequency_min, place_frequency_max)
local pos = self.object:get_pos()
local takable_nodes = minetest.find_nodes_in_area({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, mobs_mc.enderman_takable)
local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, mobs_mc.enderman_takable)
if #takable_nodes >= 1 then
local r = pr:next(1, #takable_nodes)
local take_pos = takable_nodes[r]
@ -462,7 +473,9 @@ mobs:register_mob("mobs_mc:enderman", {
end
end
if telepos then
telesound(self.object:get_pos(), false)
self.object:set_pos(telepos)
telesound(telepos, true)
end
end
end
@ -490,7 +503,10 @@ mobs:register_mob("mobs_mc:enderman", {
end
end
if node_ok then
self.object:set_pos({x=nodepos.x, y=nodepos.y+1, z=nodepos.z})
telesound(self.object:get_pos(), false)
local telepos = {x=nodepos.x, y=nodepos.y+1, z=nodepos.z}
self.object:set_pos(telepos)
telesound(telepos, true)
break
end
end
@ -507,7 +523,6 @@ mobs:register_mob("mobs_mc:enderman", {
if self._taken_node ~= nil and self._taken_node ~= "" then
minetest.add_item(pos, self._taken_node)
end
mobs.death_effect(pos, self.collisionbox)
end,
do_punch = function(self, hitter, tflp, tool_caps, dir)
-- damage from rain caused by itself so we don't want it to attack itself.

View File

@ -10,6 +10,8 @@ mobs:register_mob("mobs_mc:endermite", {
passive = false,
hp_min = 8,
hp_max = 8,
xp_min = 3,
xp_max = 3,
armor = {fleshy = 100, arthropod = 100},
group_attack = true,
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.29, 0.2},
@ -21,9 +23,10 @@ mobs:register_mob("mobs_mc:endermite", {
visual_size = {x=3, y=3},
makes_footstep_sound = false,
sounds = {
random = "mobs_rat",
random = "mobs_mc_endermite_random",
damage = "mobs_mc_endermite_hurt",
death = "mobs_mc_endermite_death",
distance = 16,
-- TODO: more sounds
},
walk_velocity = 1,
run_velocity = 2,

View File

@ -17,6 +17,8 @@ mobs:register_mob("mobs_mc:ghast", {
group_attack = true,
hp_min = 10,
hp_max = 10,
xp_min = 5,
xp_max = 5,
collisionbox = {-2, 5, -2, 2, 9, 2},
visual = "mesh",
mesh = "mobs_mc_ghast.b3d",
@ -58,6 +60,8 @@ mobs:register_mob("mobs_mc:ghast", {
jump_height = 4,
floats=1,
fly = true,
makes_footstep_sound = false,
instant_death = true,
})

View File

@ -1,5 +1,3 @@
-- v1.4
--###################
--################### GUARDIAN
--###################
@ -11,6 +9,8 @@ mobs:register_mob("mobs_mc:guardian", {
spawn_class = "hostile",
hp_min = 30,
hp_max = 30,
xp_min = 10,
xp_max = 10,
breath_max = -1,
passive = false,
attack_type = "dogfight",
@ -28,8 +28,11 @@ mobs:register_mob("mobs_mc:guardian", {
},
visual_size = {x=3, y=3},
sounds = {
damage = "mobs_mc_squid_hurt",
-- TODO: more and better sounds
random = "mobs_mc_guardian_random",
war_cry = "mobs_mc_guardian_random",
damage = {name="mobs_mc_guardian_hurt", gain=0.3},
death = "mobs_mc_guardian_death",
flop = "mobs_mc_squid_flop",
distance = 16,
},
animation = {
@ -76,6 +79,7 @@ mobs:register_mob("mobs_mc:guardian", {
max = 1,},
},
fly = true,
makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false,
view_range = 16,

View File

@ -11,6 +11,8 @@ mobs:register_mob("mobs_mc:guardian_elder", {
spawn_class = "hostile",
hp_min = 80,
hp_max = 80,
xp_min = 10,
xp_max = 10,
breath_max = -1,
passive = false,
attack_type = "dogfight",
@ -28,8 +30,12 @@ mobs:register_mob("mobs_mc:guardian_elder", {
},
visual_size = {x=7, y=7},
sounds = {
damage = "mobs_mc_squid_hurt",
-- TODO: more and better sounds
random = "mobs_mc_guardian_random",
war_cry = "mobs_mc_guardian_random",
damage = {name="mobs_mc_guardian_hurt", gain=0.3},
death = "mobs_mc_guardian_death",
flop = "mobs_mc_squid_flop",
base_pitch = 0.6,
distance = 16,
},
animation = {
@ -83,6 +89,7 @@ mobs:register_mob("mobs_mc:guardian_elder", {
max = 1,},
},
fly = true,
makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false,
view_range = 16,

View File

@ -106,6 +106,7 @@ local horse = {
-- TODO: Separate damage sound
damage = "mobs_mc_horse_death",
death = "mobs_mc_horse_death",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
fear_height = 4,
@ -116,6 +117,8 @@ local horse = {
passive = true,
hp_min = 15,
hp_max = 30,
xp_min = 1,
xp_max = 3,
floats = 1,
makes_footstep_sound = true,
jump = true,
@ -175,8 +178,6 @@ local horse = {
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
mobs.death_effect(pos, self.collisionbox)
end,
on_rightclick = function(self, clicker)
@ -364,6 +365,8 @@ skeleton_horse.sounds = {
random = "mobs_mc_skeleton_random",
death = "mobs_mc_skeleton_death",
damage = "mobs_mc_skeleton_hurt",
eat = "mobs_mc_animal_eat_generic",
base_pitch = 0.95,
distance = 16,
}
skeleton_horse.harmed_by_heal = true
@ -381,9 +384,12 @@ zombie_horse.drops = {
max = 2,},
}
zombie_horse.sounds = {
random = "mobs_mc_zombie_growl",
death = "mobs_mc_zombie_death",
damage = "mobs_mc_zombie_hurt",
random = "mobs_mc_horse_random",
-- TODO: Separate damage sound
damage = "mobs_mc_horse_death",
death = "mobs_mc_horse_death",
eat = "mobs_mc_animal_eat_generic",
base_pitch = 0.5,
distance = 16,
}
zombie_horse.harmed_by_heal = true
@ -398,8 +404,13 @@ donkey.animation = {
stand_start = 0, stand_end = 0,
walk_start = 0, walk_end = 40,
}
-- TODO: donkey sounds
donkey.sounds = nil
donkey.sounds = {
random = "mobs_mc_donkey_random",
damage = "mobs_mc_donkey_hurt",
death = "mobs_mc_donkey_death",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
}
donkey.visual_size = { x=horse.visual_size.x*d, y=horse.visual_size.y*d }
donkey.collisionbox = {
horse.collisionbox[1] * d,
@ -419,7 +430,8 @@ local m = 0.94
local mule = table.copy(donkey)
mule.textures = {{"blank.png", "mobs_mc_mule.png", "blank.png"}}
mule.visual_size = { x=horse.visual_size.x*m, y=horse.visual_size.y*m }
mule.sounds = horse.sounds
mule.sounds = table.copy(donkey.sounds)
mule.sounds.base_pitch = 1.15
mule.collisionbox = {
horse.collisionbox[1] * m,
horse.collisionbox[2] * m,

View File

@ -29,6 +29,8 @@ mobs:register_mob("mobs_mc:llama", {
spawn_class = "passive",
hp_min = 15,
hp_max = 30,
xp_min = 1,
xp_max = 3,
passive = false,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45},
visual = "mesh",
@ -57,6 +59,7 @@ mobs:register_mob("mobs_mc:llama", {
fear_height = 4,
sounds = {
random = "mobs_mc_llama",
eat = "mobs_mc_animal_eat_generic",
-- TODO: Death and damage sounds
distance = 16,
},
@ -111,7 +114,6 @@ mobs:register_mob("mobs_mc:llama", {
if self.driver then
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
mobs.death_effect(pos, self.collisionbox)
end,

View File

@ -32,6 +32,8 @@ local ocelot = {
can_despawn = true,
hp_min = 10,
hp_max = 10,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.69, 0.3},
visual = "mesh",
mesh = "mobs_mc_cat.b3d",
@ -49,6 +51,7 @@ local ocelot = {
sounds = {
damage = "mobs_mc_ocelot_hurt",
death = "mobs_mc_ocelot_hurt",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
animation = {
@ -113,6 +116,7 @@ cat.sounds = {
random = "mobs_mc_cat_idle",
damage = "mobs_mc_cat_hiss",
death = "mobs_mc_ocelot_hurt",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
}
cat.on_rightclick = function(self, clicker)

View File

@ -17,15 +17,22 @@ mobs:register_mob("mobs_mc:parrot", {
pathfinding = 1,
hp_min = 6,
hp_max = 6,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
visual = "mesh",
mesh = "mobs_mc_parrot.b3d",
textures = {{"mobs_mc_parrot_blue.png"},{"mobs_mc_parrot_green.png"},{"mobs_mc_parrot_grey.png"},{"mobs_mc_parrot_red_blue.png"},{"mobs_mc_parrot_yellow_blue.png"}},
visual_size = {x=3, y=3},
makes_footstep_sound = true,
walk_velocity = 3,
run_velocity = 5,
-- TODO: sounds
sounds = {
random = "mobs_mc_parrot_random",
damage = {name="mobs_mc_parrot_hurt", gain=0.3},
death = {name="mobs_mc_parrot_death", gain=0.6},
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
drops = {
{name = mobs_mc.items.feather,
chance = 1,
@ -35,25 +42,27 @@ mobs:register_mob("mobs_mc:parrot", {
animation = {
stand_speed = 50,
walk_speed = 50,
stand_start = 0,
stand_end = 0,
walk_start = 0,
walk_end = 130,
--run_start = 0,
--run_end = 20,
--fly_start = 30,
--fly_end = 45,
fly_speed = 50,
stand_start = 30,
stand_end = 45,
fly_start = 30,
fly_end = 45,
walk_start = 30,
walk_end = 45,
-- TODO: actual walk animation
--walk_start = 0,
--walk_end = 20,
-- TODO: more unused animations between 45 and 130
},
walk_chance = 100,
fall_damage = 0,
fall_speed = -2.25,
attack_type = "dogfight",
jump = true,
jump_height = 4,
floats = 1,
physical = true,
fly = true,
fear_height = 4,
makes_footstep_sound = false,
fear_height = 0,
view_range = 16,
follow = mobs_mc.follow.parrot,
on_rightclick = function(self, clicker)
@ -61,6 +70,7 @@ mobs:register_mob("mobs_mc:parrot", {
local item = clicker:get_wielded_item()
-- Kill parrot if fed with cookie
if item:get_name() == mobs_mc.items.cookie then
minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true)
self.health = 0
-- Doomed to die
self._doomed = true
@ -79,10 +89,8 @@ mobs:register_mob("mobs_mc:parrot", {
})
-- Spawn disabled because parrots are not very smart.
-- TODO: Re-enable when parrots are finished
--mobs:spawn_specific("mobs_mc:parrot", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 30000, 1, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max)
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome*
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)
-- spawn eggs
mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0, true)
mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)

View File

@ -8,6 +8,8 @@ mobs:register_mob("mobs_mc:pig", {
runaway = true,
hp_min = 10,
hp_max = 10,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 0.865, 0.45},
visual = "mesh",
mesh = "mobs_mc_pig.b3d",
@ -32,6 +34,7 @@ mobs:register_mob("mobs_mc:pig", {
random = "mobs_pig",
death = "mobs_pig_angry",
damage = "mobs_pig",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
animation = {
@ -79,7 +82,6 @@ mobs:register_mob("mobs_mc:pig", {
if self.driver then
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
mobs.death_effect(pos, self.collisionbox)
end,
on_rightclick = function(self, clicker)

View File

@ -14,6 +14,8 @@ mobs:register_mob("mobs_mc:polar_bear", {
passive = false,
hp_min = 30,
hp_max = 30,
xp_min = 1,
xp_max = 3,
breath_max = -1,
collisionbox = {-0.7, -0.01, -0.7, 0.7, 1.39, 0.7},
visual = "mesh",
@ -44,7 +46,14 @@ mobs:register_mob("mobs_mc:polar_bear", {
},
floats = 1,
fear_height = 4,
-- TODO: sounds
sounds = {
random = "mobs_mc_bear_random",
attack = "mobs_mc_bear_attack",
damage = "mobs_mc_bear_hurt",
death = "mobs_mc_bear_death",
war_cry = "mobs_mc_bear_growl",
distance = 16,
},
animation = {
speed_normal = 25, speed_run = 50,
stand_start = 0, stand_end = 0,

View File

@ -10,6 +10,8 @@ local rabbit = {
hp_min = 3,
hp_max = 3,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2},
visual = "mesh",
@ -23,7 +25,14 @@ local rabbit = {
{"mobs_mc_rabbit_black.png"},
},
visual_size = {x=1.5, y=1.5},
-- TODO: sounds: random, damage, death
sounds = {
random = "mobs_mc_rabbit_random",
damage = "mobs_mc_rabbit_hurt",
death = "mobs_mc_rabbit_death",
attack = "mobs_mc_rabbit_attack",
eat = "mobs_mc_animal_eat_generic",
distance = 16,
},
makes_footstep_sound = false,
walk_velocity = 1,
run_velocity = 3.7,

View File

@ -47,7 +47,8 @@ mobs:register_mob("mobs_mc:sheep", {
spawn_class = "passive",
hp_min = 8,
hp_max = 8,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45},
visual = "mesh",
@ -73,6 +74,7 @@ mobs:register_mob("mobs_mc:sheep", {
random = "mobs_sheep",
death = "mobs_sheep",
damage = "mobs_sheep",
sounds = "mobs_mc_animal_eat_generic",
distance = 16,
},
animation = {
@ -156,7 +158,7 @@ mobs:register_mob("mobs_mc:sheep", {
if item:get_name() == mobs_mc.items.shears and not self.gotten and not self.child then
self.gotten = true
local pos = self.object:get_pos()
minetest.sound_play("shears", {pos = pos}, true)
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
pos.y = pos.y + 0.5
if not self.color then
self.color = "unicolor_white"

View File

@ -21,6 +21,8 @@ mobs:register_mob("mobs_mc:shulker", {
passive = false,
hp_min = 30,
hp_max = 30,
xp_min = 5,
xp_max = 5,
armor = 150,
collisionbox = {-0.5, -0.01, -0.5, 0.5, 0.99, 0.5},
visual = "mesh",

View File

@ -12,6 +12,8 @@ mobs:register_mob("mobs_mc:silverfish", {
reach = 1,
hp_min = 8,
hp_max = 8,
xp_min = 5,
xp_max = 5,
armor = {fleshy = 100, arthropod = 100},
collisionbox = {-0.4, -0.01, -0.4, 0.4, 0.44, 0.4},
visual = "mesh",

View File

@ -17,6 +17,8 @@ local skeleton = {
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
xp_min = 6,
xp_max = 6,
breath_max = -1,
armor = {undead = 100, fleshy = 100},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3},

View File

@ -14,6 +14,8 @@ mobs:register_mob("mobs_mc:witherskeleton", {
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
xp_min = 6,
xp_max = 6,
breath_max = -1,
armor = {undead = 100, fleshy = 100},
pathfinding = 1,

View File

@ -51,6 +51,7 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
end
end, children, self.attack)
end
return true
end
end
@ -62,6 +63,8 @@ local slime_big = {
group_attack = { "mobs_mc:slime_big", "mobs_mc:slime_small", "mobs_mc:slime_tiny" },
hp_min = 16,
hp_max = 16,
xp_min = 4,
xp_max = 4,
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
visual_size = {x=12.5, y=12.5},
textures = {{"mobs_mc_slime.png"}},
@ -113,6 +116,8 @@ local slime_small = table.copy(slime_big)
slime_small.sounds.base_pitch = 1.15
slime_small.hp_min = 4
slime_small.hp_max = 4
slime_small.xp_min = 2
slime_small.xp_max = 2
slime_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51}
slime_small.visual_size = {x=6.25, y=6.25}
slime_small.damage = 3
@ -128,6 +133,8 @@ local slime_tiny = table.copy(slime_big)
slime_tiny.sounds.base_pitch = 1.3
slime_tiny.hp_min = 1
slime_tiny.hp_max = 1
slime_tiny.xp_min = 1
slime_tiny.xp_max = 1
slime_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505}
slime_tiny.visual_size = {x=3.125, y=3.125}
slime_tiny.damage = 0
@ -160,6 +167,8 @@ local magma_cube_big = {
spawn_class = "hostile",
hp_min = 16,
hp_max = 16,
xp_min = 4,
xp_max = 4,
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
visual_size = {x=12.5, y=12.5},
textures = {{ "mobs_mc_magmacube.png" }},
@ -220,6 +229,8 @@ magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small"
magma_cube_small.sounds.death = "mobs_mc_magma_cube_small"
magma_cube_small.hp_min = 4
magma_cube_small.hp_max = 4
magma_cube_small.xp_min = 2
magma_cube_small.xp_max = 2
magma_cube_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51}
magma_cube_small.visual_size = {x=6.25, y=6.25}
magma_cube_small.damage = 3
@ -240,6 +251,8 @@ magma_cube_tiny.sounds.death = "mobs_mc_magma_cube_small"
magma_cube_tiny.sounds.base_pitch = 1.25
magma_cube_tiny.hp_min = 1
magma_cube_tiny.hp_max = 1
magma_cube_tiny.xp_min = 1
magma_cube_tiny.xp_max = 1
magma_cube_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505}
magma_cube_tiny.visual_size = {x=3.125, y=3.125}
magma_cube_tiny.walk_velocity = 1.02

View File

@ -36,7 +36,11 @@ mobs:register_mob("mobs_mc:snowman", {
collisionbox = {-0.35, -0.01, -0.35, 0.35, 1.89, 0.35},
visual = "mesh",
mesh = "mobs_mc_snowman.b3d",
-- TODO: sounds: damage, death
sounds = {
damage = { name = "mobs_mc_snowman_hurt", gain = 0.2 },
death = { name = "mobs_mc_snowman_death", gain = 0.25 },
distance = 16,
},
textures = {
"mobs_mc_snowman.png", --snowman texture
"farming_pumpkin_side.png", --top
@ -74,7 +78,7 @@ mobs:register_mob("mobs_mc:snowman", {
run_end = 20,
die_start = 40,
die_end = 50,
die_speed = 25,
die_speed = 15,
die_loop = false,
},
do_custom = function(self, dtime)
@ -117,7 +121,7 @@ mobs:register_mob("mobs_mc:snowman", {
})
local pos = self.object:get_pos()
minetest.sound_play("shears", {pos = pos}, true)
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
-- Wear out
if not minetest.is_creative_enabled(clicker:get_player_name()) then

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More