forked from VoxeLibre/VoxeLibre
master #5
|
@ -0,0 +1,2 @@
|
|||
# textdomain:mcl_explosions
|
||||
@1 was caught in an explosion.=@1 a été pris dans une explosion.
|
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
@ -0,0 +1,2 @@
|
|||
# textdomain:mcl_paintings
|
||||
Painting=Peinture
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
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.
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
Loading…
Reference in New Issue