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!) -- Some global variables (don't overwrite them!)
mcl_vars = {} mcl_vars = {}
mcl_vars.redstone_tick = 0.1
--- GUI / inventory menu settings --- GUI / inventory menu settings
mcl_vars.gui_slots = "listcolors[#9990;#FFF7;#FFF0;#000;#FFF]" mcl_vars.gui_slots = "listcolors[#9990;#FFF7;#FFF0;#000;#FFF]"
-- nonbg is added as formspec prepend in mcl_formspec_prepend -- 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) -- Set random seed for all other mods (Remember to make sure no other mod calls this function)
math.randomseed(os.time()) 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) function mcl_sounds.node_sound_leaves_defaults(table)
table = table or {} table = table or {}
table.footstep = table.footstep 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 table.dug = table.dug or
{name="default_grass_footstep", gain=0.85} {name="default_grass_footstep", gain=0.425}
table.dig = table.dig or table.dig = table.dig or
{name="default_dig_snappy", gain=0.4} {name="default_dig_snappy", gain=0.4}
table.place = table.place or 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 mobs.version = "20180531" -- don't rely too much on this, rarely updated, if ever
local MAX_MOB_NAME_LENGTH = 30 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 = {} local MOB_CAP = {}
MOB_CAP.hostile = 70 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 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) 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 -- Peaceful mode message so players will know there are no monsters
if minetest.settings:get_bool("only_peaceful_mobs", false) then if minetest.settings:get_bool("only_peaceful_mobs", false) then
minetest.register_on_joinplayer(function(player) 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_hunger = minetest.get_modpath("mcl_hunger") ~= nil
local mod_worlds = minetest.get_modpath("mcl_worlds") ~= nil local mod_worlds = minetest.get_modpath("mcl_worlds") ~= nil
local mod_armor = minetest.get_modpath("mcl_armor") ~= 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 -- play sound
local mob_sound = function(self, soundname, is_opinion, fixed_pitch) 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
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) local function object_in_range(self, object)
if not object then if not object then
return false return false
@ -158,17 +195,15 @@ local function object_in_range(self, object)
else else
dist = self.view_range dist = self.view_range
end end
if vector.distance(self.object:get_pos(), object:get_pos()) > dist then
return false local p1, p2 = self.object:get_pos(), object:get_pos()
else return p1 and p2 and (vector.distance(p1, p2) <= dist)
return true
end
end end
-- attack player/mob -- attack player/mob
local do_attack = function(self, player) local do_attack = function(self, player)
if self.state == "attack" then if self.state == "attack" or self.state == "die" then
return return
end end
@ -182,25 +217,61 @@ local do_attack = function(self, player)
end 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 -- move mob in facing direction
local set_velocity = function(self, v) 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 if self.order == "stand" then
self.object:set_velocity({x = 0, y = 0, z = 0}) self.object:set_velocity({x = 0, y = 0, z = 0})
return return
end end
local yaw = (self.object:get_yaw() or 0) + self.rotate local yaw = (self.object:get_yaw() or 0) + self.rotate
local vel = self.object:get_velocity()
self.object:set_velocity({ self.object:set_velocity({
x = sin(yaw) * -v, x = (sin(yaw) * -v) + c_x,
y = (vel and vel.y) or 0, y = self.object:get_velocity().y,
z = cos(yaw) * v z = (cos(yaw) * v) + c_y,
}) })
end end
-- calculate mob velocity -- calculate mob velocity
local get_velocity = function(self) local get_velocity = function(self)
@ -267,24 +338,35 @@ local remove_texture_mod = function(self, mod)
end end
-- set defined animation -- set defined animation
local set_animation = function(self, anim) local set_animation = function(self, anim, fixed_frame)
if not self.animation or not anim then
if not self.animation return
or not anim then return end end
if self.state == "die" and anim ~= "die" and anim ~= "stand" then
return
end
self.animation.current = self.animation.current or "" 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 .. "_start"]
or not self.animation[anim .. "_end"] then or not self.animation[anim .. "_end"]) and self.state ~= "die" then
return return
end end
self.animation.current = anim 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({ self.object:set_animation({
x = self.animation[anim .. "_start"], x = a_start,
y = self.animation[anim .. "_end"]}, y = a_end},
self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, self.animation[anim .. "_speed"] or self.animation.speed_normal or 15,
0, self.animation[anim .. "_loop"] ~= false) 0, self.animation[anim .. "_loop"] ~= false)
end end
@ -323,7 +405,7 @@ local is_node_waterhazard = function(self, nodename)
return true return true
end end
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 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 -- 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 -- 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
end end
mobs.death_effect = function(pos, collisionbox) mobs.death_effect = function(pos, yaw, collisionbox, rotate)
local min, max local min, max
if collisionbox then if collisionbox then
min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]} 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 } min = { x = -0.5, y = 0, z = -0.5 }
max = { x = 0.5, y = 0.5, z = 0.5 } max = { x = 0.5, y = 0.5, z = 0.5 }
end 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({ minetest.add_particlespawner({
amount = 40, amount = 50,
time = 0.1, time = 0.001,
minpos = vector.add(pos, min), minpos = vector.add(pos, min),
maxpos = vector.add(pos, max), maxpos = vector.add(pos, max),
minvel = {x = -0.2, y = -0.1, z = -0.2}, minvel = vector.new(-5,-5,-5),
maxvel = {x = 0.2, y = 0.1, z = 0.2}, maxvel = vector.new(5,5,5),
minexptime = 0.5, minexptime = 1.1,
maxexptime = 1.5, maxexptime = 1.5,
minsize = 0.5, minsize = 1,
maxsize = 1.5, maxsize = 2,
texture = "mcl_particles_smoke.png", 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 end
local update_tag = function(self) 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({ self.object:set_properties({
nametag = self.nametag, nametag = tag,
}) })
end end
@ -585,6 +699,10 @@ end
-- check if mob is dead or only hurt -- check if mob is dead or only hurt
local check_for_death = function(self, cause, cmi_cause) local check_for_death = function(self, cause, cmi_cause)
if self.state == "die" then
return true
end
-- has health actually changed? -- has health actually changed?
if self.health == self.old_health and self.health > 0 then if self.health == self.old_health and self.health > 0 then
return false return false
@ -629,33 +747,41 @@ local check_for_death = function(self, cause, cmi_cause)
return false return false
end end
-- dropped cooked item if mob died in fire or lava
if cause == "lava" or cause == "fire" then
item_drop(self, true)
else
item_drop(self, nil)
end
mob_sound(self, "death") mob_sound(self, "death")
local pos = self.object:get_pos() 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)
else
item_drop(self, nil)
end
if mcl_experience.throw_experience and self.hp_min and self.hp_max then local pos = self.object:get_pos()
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 end
-- execute custom death function -- execute custom death function
if self.on_die then 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 if use_cmi then
cmi.notify_die(self.object, cmi_cause) cmi.notify_die(self.object, cmi_cause)
end end
self.object:remove() if on_die_exit == true then
self.state = "die"
return true self.object:remove()
return true
end
end end
local collisionbox local collisionbox
@ -663,46 +789,65 @@ local check_for_death = function(self, cause, cmi_cause)
collisionbox = table.copy(self.collisionbox) collisionbox = table.copy(self.collisionbox)
end 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) -- 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_start
and self.animation.die_end then and self.animation.die_end then
local frames = self.animation.die_end - self.animation.die_start local frames = self.animation.die_end - self.animation.die_start
local speed = self.animation.die_speed or 15 local speed = self.animation.die_speed or 15
local length = max(frames / speed, 0) length = max(frames / speed, 0) + DEATH_DELAY
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)
set_animation(self, "die") set_animation(self, "die")
minetest.after(length, function(self)
if not self.object:get_luaentity() then
return
end
if use_cmi then
cmi.notify_die(self.object, cmi_cause)
end
self.object:remove()
mobs.death_effect(pos)
end, self)
else 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
if use_cmi then
-- Remove body after a few seconds and drop stuff
local kill = function(self)
if not self.object:get_luaentity() then
return
end
if use_cmi then
cmi.notify_die(self.object, cmi_cause) cmi.notify_die(self.object, cmi_cause)
end end
death_handle(self)
local dpos = self.object:get_pos()
local cbox = self.collisionbox
local yaw = self.object:get_rotation().y
self.object:remove() self.object:remove()
mobs.death_effect(pos, collisionbox) mobs.death_effect(dpos, yaw, cbox, not self.instant_death)
end
if length <= 0 then
kill(self)
else
minetest.after(length, kill, self)
end end
return true return true
@ -710,18 +855,23 @@ end
-- check if within physical map limits (-30911 to 30927) -- check if within physical map limits (-30911 to 30927)
local within_limits = function(pos, radius) local within_limits, wmin, wmax = nil, -30913, 30928
within_limits = function(pos, radius)
if (pos.x - radius) > -30913 if mcl_vars then
and (pos.x + radius) < 30928 if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then
and (pos.y - radius) > -30913 wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max
and (pos.y + radius) < 30928 within_limits = function(pos, radius)
and (pos.z - radius) > -30913 return pos
and (pos.z + radius) < 30928 then and (pos.x - radius) > wmin and (pos.x + radius) < wmax
return true -- within limits and (pos.y - radius) > wmin and (pos.y + radius) < wmax
and (pos.z - radius) > wmin and (pos.z + radius) < wmax
end
end
end end
return pos
return false -- beyond limits 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 end
@ -753,7 +903,9 @@ local is_at_cliff_or_danger = function(self)
return true return true
else else
local def = minetest.registered_nodes[bnode.name] local def = minetest.registered_nodes[bnode.name]
return (not def and def.walkable) if def and def.walkable then
return false
end
end end
end end
@ -789,7 +941,9 @@ local is_at_water_danger = function(self)
return true return true
else else
local def = minetest.registered_nodes[bnode.name] local def = minetest.registered_nodes[bnode.name]
return (not def and def.walkable) if def and def.walkable then
return false
end
end end
end end
@ -1110,7 +1264,7 @@ local do_jump = function(self)
-- when in air move forward -- when in air move forward
minetest.after(0.3, function(self, v) 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 return
end end
self.object:set_acceleration({ self.object:set_acceleration({
@ -1211,12 +1365,13 @@ end
-- find two animals of same type and breed if nearby and horny -- find two animals of same type and breed if nearby and horny
local breed = function(self) 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 if self.child == true then
-- When a child, hornytimer is used to count age until adulthood
self.hornytimer = self.hornytimer + 1 self.hornytimer = self.hornytimer + 1
if self.hornytimer > 240 then if self.hornytimer >= CHILD_GROW_TIME then
self.child = false self.child = false
self.hornytimer = 0 self.hornytimer = 0
@ -1245,14 +1400,14 @@ local breed = function(self)
return return
end end
-- horny animal can mate for 40 seconds, -- horny animal can mate for HORNY_TIME seconds,
-- afterwards horny animal cannot mate again for 200 seconds -- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds
if self.horny == true if self.horny == true
and self.hornytimer < 240 then and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then
self.hornytimer = self.hornytimer + 1 self.hornytimer = self.hornytimer + 1
if self.hornytimer >= 240 then if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then
self.hornytimer = 0 self.hornytimer = 0
self.horny = false self.horny = false
end end
@ -1260,7 +1415,7 @@ local breed = function(self)
-- find another same animal who is also horny and mate if nearby -- find another same animal who is also horny and mate if nearby
if self.horny == true if self.horny == true
and self.hornytimer <= 40 then and self.hornytimer <= HORNY_TIME then
local pos = self.object:get_pos() local pos = self.object:get_pos()
@ -1299,15 +1454,15 @@ local breed = function(self)
if ent if ent
and canmate == true and canmate == true
and ent.horny == true and ent.horny == true
and ent.hornytimer <= 40 then and ent.hornytimer <= HORNY_TIME then
num = num + 1 num = num + 1
end end
-- found your mate? then have a baby -- found your mate? then have a baby
if num > 1 then if num > 1 then
self.hornytimer = 41 self.hornytimer = HORNY_TIME + 1
ent.hornytimer = 41 ent.hornytimer = HORNY_TIME + 1
-- spawn baby -- spawn baby
minetest.after(5, function(parent1, parent2, pos) minetest.after(5, function(parent1, parent2, pos)
@ -1318,6 +1473,11 @@ local breed = function(self)
return return
end end
-- Give XP
if mod_experience then
mcl_experience.throw_experience(pos, math.random(1, 7))
end
-- custom breed function -- custom breed function
if parent1.on_breed then if parent1.on_breed then
-- when false, skip going any further -- when false, skip going any further
@ -1384,10 +1544,11 @@ local replace = function(self, pos)
pos.y = pos.y + y_offset 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 oldnode = {name = what, param2 = node.param2}
local newnode = {name = with} local newnode = {name = with, param2 = node.param2}
local on_replace_return local on_replace_return
if self.on_replace then if self.on_replace then
@ -1397,7 +1558,7 @@ local replace = function(self, pos)
if on_replace_return ~= false then if on_replace_return ~= false then
if mobs_griefing then if mobs_griefing then
minetest.set_node(pos, {name = with}) minetest.set_node(pos, newnode)
end end
end end
@ -1810,7 +1971,7 @@ end
-- find someone to runaway from -- find someone to runaway from
local runaway_from = function(self) local runaway_from = function(self)
if not self.runaway_from then if not self.runaway_from and self.state ~= "flop" then
return return
end end
@ -1927,10 +2088,12 @@ local follow_flop = function(self)
self.following = nil self.following = nil
end end
else 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 if self.following
and self.following:is_player() 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 self.following = nil
end end
@ -1995,13 +2158,26 @@ local follow_flop = function(self)
if not flight_check(self, s) then if not flight_check(self, s) then
self.state = "flop" 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 return
elseif self.state == "flop" then elseif self.state == "flop" then
self.state = "stand" self.state = "stand"
self.object:set_acceleration({x = 0, y = 0, z = 0})
set_velocity(self, 0)
end end
end end
end end
@ -2222,10 +2398,8 @@ local do_states = function(self, dtime)
-- attack routines (explode, dogfight, shoot, dogshoot) -- attack routines (explode, dogfight, shoot, dogshoot)
elseif self.state == "attack" then elseif self.state == "attack" then
-- calculate distance from mob and enemy
local s = self.object:get_pos() local s = self.object:get_pos()
local p = self.attack:get_pos() or s local p = self.attack:get_pos() or s
local dist = vector.distance(p, s)
-- stop attacking if player invisible or out of range -- stop attacking if player invisible or out of range
if not self.attack if not self.attack
@ -2246,6 +2420,9 @@ local do_states = function(self, dtime)
return return
end end
-- calculate distance from mob and enemy
local dist = vector.distance(p, s)
if self.attack_type == "explode" then if self.attack_type == "explode" then
local vec = { local vec = {
@ -2588,7 +2765,7 @@ end
-- returns true if mob died -- returns true if mob died
local falling = function(self, pos) local falling = function(self, pos)
if self.fly then if self.fly and self.state ~= "die" then
return return
end end
@ -2801,7 +2978,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
}, true) }, true)
else else
minetest.sound_play("default_punch", { minetest.sound_play("default_punch", {
object = self.object, --hitter, object = self.object,
max_hear_distance = 5 max_hear_distance = 5
}, true) }, true)
end end
@ -2853,7 +3030,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
end -- END if damage end -- END if damage
-- if skittish then run away -- 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 lp = hitter:get_pos()
local s = self.object: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 pos = self.object:get_pos()
local yaw = 0 local yaw = 0
if mobs_debug then
update_tag(self)
end
-- Despawning: when lifetimer expires, remove mob -- Despawning: when lifetimer expires, remove mob
if remove_far if remove_far
and self.can_despawn == true and self.can_despawn == true
@ -3184,6 +3365,10 @@ local mob_step = function(self, dtime)
end end
end end
if self.state == "die" then
return
end
if self.jump_sound_cooloff > 0 then if self.jump_sound_cooloff > 0 then
self.jump_sound_cooloff = self.jump_sound_cooloff - dtime self.jump_sound_cooloff = self.jump_sound_cooloff - dtime
end end
@ -3315,6 +3500,46 @@ local mob_step = function(self, dtime)
end end
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) follow_flop(self)
if is_at_cliff_or_danger(self) then if is_at_cliff_or_danger(self) then
@ -3422,6 +3647,8 @@ minetest.register_entity(name, {
lifetimer = def.lifetimer or 57.73, lifetimer = def.lifetimer or 57.73,
hp_min = scale_difficulty(def.hp_min, 5, 1), hp_min = scale_difficulty(def.hp_min, 5, 1),
hp_max = scale_difficulty(def.hp_max, 10, 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, breath_max = def.breath_max or 15,
breathes_in_water = def.breathes_in_water or false, breathes_in_water = def.breathes_in_water or false,
physical = true, physical = true,
@ -3442,7 +3669,7 @@ minetest.register_entity(name, {
fire_damage = def.fire_damage or 1, fire_damage = def.fire_damage or 1,
suffocation = def.suffocation or true, suffocation = def.suffocation or true,
fall_damage = def.fall_damage or 1, 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 {}, drops = def.drops or {},
armor = def.armor or 100, armor = def.armor or 100,
on_rightclick = create_mob_on_rightclick(def.on_rightclick), on_rightclick = create_mob_on_rightclick(def.on_rightclick),
@ -3500,6 +3727,8 @@ minetest.register_entity(name, {
owner_loyal = def.owner_loyal, owner_loyal = def.owner_loyal,
facing_fence = false, facing_fence = false,
_cmi_is_mob = true, _cmi_is_mob = true,
pushable = def.pushable or true,
-- MCL2 extensions -- MCL2 extensions
teleport = teleport, teleport = teleport,
@ -3516,6 +3745,7 @@ minetest.register_entity(name, {
explosion_strength = def.explosion_strength, explosion_strength = def.explosion_strength,
suffocation_timer = 0, suffocation_timer = 0,
follow_velocity = def.follow_velocity or 2.4, follow_velocity = def.follow_velocity or 2.4,
instant_death = def.instant_death or false,
-- End of MCL2 extensions -- End of MCL2 extensions
on_spawn = def.on_spawn, on_spawn = def.on_spawn,
@ -3771,15 +4001,14 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
end end
end end
-- spawn mob 1/2 node above ground -- tweak X/Y/Z spawn pos
pos.y = pos.y + 0.5
-- tweak X/Z spawn pos
if width_x % 2 == 0 then if width_x % 2 == 0 then
pos.x = pos.x + 0.5 pos.x = pos.x + 0.5
end end
if width_z % 2 == 0 then if width_z % 2 == 0 then
pos.z = pos.z + 0.5 pos.z = pos.z + 0.5
end end
pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, name) local mob = minetest.add_entity(pos, name)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos)) 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 return itemstack
end end
pos.y = pos.y + 1 pos.y = pos.y - 0.5
local mob = minetest.add_entity(pos, mob) local mob = minetest.add_entity(pos, mob)
minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos))
local ent = mob:get_luaentity() local ent = mob:get_luaentity()
-- don't set owner if monster or sneak pressed -- 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) clicker:set_wielded_item(item)
end end
mob_sound(self, "eat", nil, true)
-- increase health -- increase health
self.health = self.health + 4 self.health = self.health + 4
@ -4149,7 +4381,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
-- make children grow quicker -- make children grow quicker
if self.child == true then 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 return true
end 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) 'base_pitch' base pitch to use adult mobs, default is 1.0 (MCL2 extension)
'random' played randomly from time to time. 'random' played randomly from time to time.
also played for overfeeding animal. also played for overfeeding animal.
'eat' played when mob eats something
'war_cry' what you hear when mob starts to attack player. (currently disabled) 'war_cry' what you hear when mob starts to attack player. (currently disabled)
'attack' what you hear when being attacked. 'attack' what you hear when being attacked.
'shoot_attack' sound played when mob shoots. 'shoot_attack' sound played when mob shoots.
'damage' sound heard when mob is hurt. 'damage' sound heard when mob is hurt.
'death' played when mob is killed. 'death' played when mob is killed.
'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam '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. 'fuse' sound played when mob explode timer starts.
'explode' sound played when mob explodes. '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 'speed_normal' is used for animation speed for compatibility with some
older mobs. older mobs.
'pushable' Allows players, & other mobs to push the mob.
MineClone 2 extensions: 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 'sounds_child' same as sounds, but for childs. If not defined, childs will use same
sound as adults but with higher pitch 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. '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 Node Replacement
@ -282,10 +290,9 @@ Custom Definition Functions
Along with the above mob registry settings we can also use custom functions to Along with the above mob registry settings we can also use custom functions to
enhance mob functionality and have them do many interesting things: enhance mob functionality and have them do many interesting things:
'on_die' a function that is called when the mob is killed the 'on_die' a function that is called when the mob is killed; the
parameters are (self, pos). When this function is used, parameters are (self, pos). Return true to skip the builtin
the death particles will be skipped on death. You can get death animation and death effects
them back by calling mobs:death_effect manually
'on_rightclick' its same as in minetest.register_entity() 'on_rightclick' its same as in minetest.register_entity()
'on_blast' is called when an explosion happens near mob when using TNT 'on_blast' is called when an explosion happens near mob when using TNT
functions, parameters are (object, damage) and returns functions, parameters are (object, damage) and returns
@ -342,6 +349,14 @@ for each mob.
dogs dogs
'self.order' set to "follow" or "stand" so that npc will follow owner 'self.order' set to "follow" or "stand" so that npc will follow owner
or stand it's ground 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 'self.nametag' contains the name of the mob which it can show above

View File

@ -1,3 +1,3 @@
name = mcl_mobs name = mcl_mobs
depends = mcl_particles 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 https://forum.minetest.net/viewtopic.php?f=11&t=9917
------------
Credits:
Items: mcl_mobs_mob_poof.ogg:
- by Planman (license: Creative Commons Zero)
- Nametag (paper, black dye, string) can be used right-click on a tamed mob to give them a name. - Source: <https://freesound.org/people/Planman/sounds/208111/>
Lucky Block items: 1
------------
Changelog from original Mobs Redo mod: Changelog from original Mobs Redo mod:
- 1.41- Mob pathfinding has been updated thanks to Elkien3 - 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) * [AGFX](http://www.freesound.org/people/DrMinky/sounds/) (CC0)
* `mobs_mc_chicken_child.ogg` * `mobs_mc_chicken_child.ogg`
* Source: <https://freesound.org/people/AGFX/sounds/43380/> * 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) * Randomation (CC0)
* `green_slime_damage.ogg` * `green_slime_damage.ogg`
* `green_slime_attack.ogg` * `green_slime_attack.ogg`
@ -99,27 +105,78 @@ Origin of those models:
* `mobs_mc_cow_hurt.ogg` (CC0) * `mobs_mc_cow_hurt.ogg` (CC0)
* Heavily modified * Heavily modified
* Source: <https://freesound.org/people/Bird_man/packs/16972/> * 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) * [NPXcoot](https://github.com/NPXcoot1) (CC BY-SA 4.0)
* `mobs_mc_ender_dragon_*` * `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) * Blender Foundation (CC BY 3.0)
* `mobs_sheep.ogg`, * `mobs_sheep.ogg`,
* daufinsyd (MIT License) * daufinsyd (MIT License)
* `mobs_mc_blaze_breath.ogg` * `mobs_mc_blaze_breath.ogg`
* `mobs_mc_blaze_died.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) * [thefilmbakery](https://freesound.org/people/thefilmbakery/) (CC0)
* `mobs_mc_blaze_hurt.ogg` * `mobs_mc_blaze_hurt.ogg`
* Source: <https://freesound.org/people/thefilmbakery/sounds/137836/> * Source: <https://freesound.org/people/thefilmbakery/sounds/137836/>
* TenPlus1, from `mobs_monster` or `mobs_animal` mod (MIT License) * TenPlus1, from `mobs_monster` or `mobs_animal` mod (MIT License)
* `mobs_chicken.ogg`
* `mobs_fireball.ogg` * `mobs_fireball.ogg`
* `mobs_mc_cat_idle.1.ogg` * `mobs_mc_cat_idle.1.ogg`
* `mobs_mc_llama.ogg` * `mobs_mc_llama.ogg`
* `mobs_pig.ogg` * `mobs_pig.ogg`
* `mobs_pig_angry.ogg` * `mobs_pig_angry.ogg`
* `mobs_rat.ogg`
* `mobs_sandmonster.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) * BrandonReese (LGPL v2.1)
* `mobs_eerie.ogg` * `mobs_eerie.ogg`
* [Under7dude](https://freesound.org/people/Under7dude/) (CC0) * [Under7dude](https://freesound.org/people/Under7dude/) (CC0)
@ -147,6 +204,13 @@ Origin of those models:
* Source: <https://freesound.org/people/GoodListener/sounds/322454/> * Source: <https://freesound.org/people/GoodListener/sounds/322454/>
* `mobs_mc_horse_death.ogg` (CC BY 3.0) * `mobs_mc_horse_death.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/GoodListener/sounds/322445/> * 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/) * [ERH](https://freesound.org/people/ERH/)
* `mobs_mc_horse_random.2.ogg` (CC BY 3.0) * `mobs_mc_horse_random.2.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/ERH/sounds/32043/> * Source: <https://freesound.org/people/ERH/sounds/32043/>
@ -164,6 +228,10 @@ Origin of those models:
* [suonho](https://freesound.org/people/suonho/) * [suonho](https://freesound.org/people/suonho/)
* `mobs_mc_bat_idle.ogg` (CC BY 3.0) * `mobs_mc_bat_idle.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/suonho/sounds/59344/> * 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/) * [cmusounddesign](https://freesound.org/people/cmusounddesign/)
* `mobs_mc_cat_hiss.ogg` (CC BY 3.0) * `mobs_mc_cat_hiss.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/cmusounddesign/sounds/71899/> * Source: <https://freesound.org/people/cmusounddesign/sounds/71899/>
@ -173,6 +241,16 @@ Origin of those models:
* [ebcrosby](https://freesound.org/people/ebcrosby/) * [ebcrosby](https://freesound.org/people/ebcrosby/)
* `mobs_mc_ocelot_hurt.ogg` (CC BY 3.0) * `mobs_mc_ocelot_hurt.ogg` (CC BY 3.0)
* Source: <https://freesound.org/people/ebcrosby/sounds/332979/> * 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) * [Inocodum](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3115)
* `mobs_mc_silverfish_hurt.ogg` (CC BY-SA 4.0) * `mobs_mc_silverfish_hurt.ogg` (CC BY-SA 4.0)
* `mobs_mc_silverfish_death.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/) * [kbnevel](https://freesound.org/people/kbnevel/)
* `mobs_mc_magma_cube_attack.ogg` (CC0) * `mobs_mc_magma_cube_attack.ogg` (CC0)
* Derived from: <https://freesound.org/people/kbnevel/sounds/119863/> * 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. 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}, visual_size = {x=1, y=1},
sounds = { sounds = {
random = "mobs_mc_bat_idle", random = "mobs_mc_bat_idle",
damage = "mobs_mc_bat_hurt",
death = "mobs_mc_bat_death",
distance = 16, distance = 16,
}, },
walk_velocity = 4.5, walk_velocity = 4.5,
@ -33,18 +35,19 @@ mobs:register_mob("mobs_mc:bat", {
run_speed = 80, run_speed = 80,
run_start = 0, run_start = 0,
run_end = 40, run_end = 40,
-- TODO: Less ugly death animation die_speed = 60,
--[[ die_speed = 60,
die_start = 40, die_start = 40,
die_end = 80, die_end = 80,
die_loop = false, die_loop = false,
]]
}, },
walk_chance = 100,
fall_damage = 0, fall_damage = 0,
view_range = 16, view_range = 16,
fear_height = 0,
jump = false,
fly = true, fly = true,
makes_footstep_sound = false,
}) })

View File

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

View File

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

View File

@ -7,6 +7,8 @@ local cow_def = {
spawn_class = "passive", spawn_class = "passive",
hp_min = 10, hp_min = 10,
hp_max = 10, hp_max = 10,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45}, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45},
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_cow.b3d", mesh = "mobs_mc_cow.b3d",
@ -32,6 +34,7 @@ local cow_def = {
random = "mobs_mc_cow", random = "mobs_mc_cow",
damage = "mobs_mc_cow_hurt", damage = "mobs_mc_cow_hurt",
death = "mobs_mc_cow_hurt", death = "mobs_mc_cow_hurt",
eat = "mobs_mc_animal_eat_generic",
distance = 16, distance = 16,
}, },
animation = { animation = {
@ -54,6 +57,7 @@ local cow_def = {
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
local inv = clicker:get_inventory() local inv = clicker:get_inventory()
inv:remove_item("main", mobs_mc.items.bucket) 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 room add bucket of milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", mobs_mc.items.milk) 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 -- Use shears to get mushrooms and turn mooshroom into cow
if item:get_name() == mobs_mc.items.shears then if item:get_name() == mobs_mc.items.shears then
local pos = self.object:get_pos() 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 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") 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 elseif item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
local inv = clicker:get_inventory() local inv = clicker:get_inventory()
inv:remove_item("main", mobs_mc.items.bucket) 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 room, add milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", mobs_mc.items.milk) 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 elseif item:get_name() == mobs_mc.items.bowl and clicker:get_inventory() then
local inv = clicker:get_inventory() local inv = clicker:get_inventory()
inv:remove_item("main", mobs_mc.items.bowl) 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 room, add mushroom stew to inventory, otherwise drop as item
if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then
clicker:get_inventory():add_item("main", mobs_mc.items.mushroom_stew) 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", spawn_class = "hostile",
hp_min = 20, hp_min = 20,
hp_max = 20, hp_max = 20,
xp_min = 5,
xp_max = 5,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3}, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3},
pathfinding = 1, pathfinding = 1,
visual = "mesh", visual = "mesh",
@ -81,7 +83,6 @@ mobs:register_mob("mobs_mc:creeper", {
local r = math.random(1, #mobs_mc.items.music_discs) 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]) minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[r])
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
maxdrops = 2, maxdrops = 2,
drops = { drops = {

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,8 @@ mobs:register_mob("mobs_mc:guardian_elder", {
spawn_class = "hostile", spawn_class = "hostile",
hp_min = 80, hp_min = 80,
hp_max = 80, hp_max = 80,
xp_min = 10,
xp_max = 10,
breath_max = -1, breath_max = -1,
passive = false, passive = false,
attack_type = "dogfight", attack_type = "dogfight",
@ -28,8 +30,12 @@ mobs:register_mob("mobs_mc:guardian_elder", {
}, },
visual_size = {x=7, y=7}, visual_size = {x=7, y=7},
sounds = { sounds = {
damage = "mobs_mc_squid_hurt", random = "mobs_mc_guardian_random",
-- TODO: more and better sounds 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, distance = 16,
}, },
animation = { animation = {
@ -83,6 +89,7 @@ mobs:register_mob("mobs_mc:guardian_elder", {
max = 1,}, max = 1,},
}, },
fly = true, fly = true,
makes_footstep_sound = false,
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false, jump = false,
view_range = 16, view_range = 16,

View File

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

View File

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

View File

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

View File

@ -17,15 +17,22 @@ mobs:register_mob("mobs_mc:parrot", {
pathfinding = 1, pathfinding = 1,
hp_min = 6, hp_min = 6,
hp_max = 6, hp_max = 6,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_parrot.b3d", 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"}}, 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}, visual_size = {x=3, y=3},
makes_footstep_sound = true,
walk_velocity = 3, walk_velocity = 3,
run_velocity = 5, 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 = { drops = {
{name = mobs_mc.items.feather, {name = mobs_mc.items.feather,
chance = 1, chance = 1,
@ -35,25 +42,27 @@ mobs:register_mob("mobs_mc:parrot", {
animation = { animation = {
stand_speed = 50, stand_speed = 50,
walk_speed = 50, walk_speed = 50,
stand_start = 0, fly_speed = 50,
stand_end = 0, stand_start = 30,
walk_start = 0, stand_end = 45,
walk_end = 130, fly_start = 30,
--run_start = 0, fly_end = 45,
--run_end = 20, walk_start = 30,
--fly_start = 30, walk_end = 45,
--fly_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_damage = 0,
fall_speed = -2.25, fall_speed = -2.25,
attack_type = "dogfight", attack_type = "dogfight",
jump = true,
jump_height = 4,
floats = 1, floats = 1,
physical = true, physical = true,
fly = true, fly = true,
fear_height = 4, makes_footstep_sound = false,
fear_height = 0,
view_range = 16, view_range = 16,
follow = mobs_mc.follow.parrot, follow = mobs_mc.follow.parrot,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
@ -61,6 +70,7 @@ mobs:register_mob("mobs_mc:parrot", {
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
-- Kill parrot if fed with cookie -- Kill parrot if fed with cookie
if item:get_name() == mobs_mc.items.cookie then 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 self.health = 0
-- Doomed to die -- Doomed to die
self._doomed = true self._doomed = true
@ -79,10 +89,8 @@ mobs:register_mob("mobs_mc:parrot", {
}) })
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome*
-- Spawn disabled because parrots are not very smart. 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)
-- 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)
-- spawn eggs -- 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, runaway = true,
hp_min = 10, hp_min = 10,
hp_max = 10, hp_max = 10,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 0.865, 0.45}, collisionbox = {-0.45, -0.01, -0.45, 0.45, 0.865, 0.45},
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_pig.b3d", mesh = "mobs_mc_pig.b3d",
@ -32,6 +34,7 @@ mobs:register_mob("mobs_mc:pig", {
random = "mobs_pig", random = "mobs_pig",
death = "mobs_pig_angry", death = "mobs_pig_angry",
damage = "mobs_pig", damage = "mobs_pig",
eat = "mobs_mc_animal_eat_generic",
distance = 16, distance = 16,
}, },
animation = { animation = {
@ -79,7 +82,6 @@ mobs:register_mob("mobs_mc:pig", {
if self.driver then if self.driver then
mobs.detach(self.driver, {x = 1, y = 0, z = 1}) mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end end
mobs.death_effect(pos, self.collisionbox)
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)

View File

@ -14,6 +14,8 @@ mobs:register_mob("mobs_mc:polar_bear", {
passive = false, passive = false,
hp_min = 30, hp_min = 30,
hp_max = 30, hp_max = 30,
xp_min = 1,
xp_max = 3,
breath_max = -1, breath_max = -1,
collisionbox = {-0.7, -0.01, -0.7, 0.7, 1.39, 0.7}, collisionbox = {-0.7, -0.01, -0.7, 0.7, 1.39, 0.7},
visual = "mesh", visual = "mesh",
@ -44,7 +46,14 @@ mobs:register_mob("mobs_mc:polar_bear", {
}, },
floats = 1, floats = 1,
fear_height = 4, 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 = { animation = {
speed_normal = 25, speed_run = 50, speed_normal = 25, speed_run = 50,
stand_start = 0, stand_end = 0, stand_start = 0, stand_end = 0,

View File

@ -10,6 +10,8 @@ local rabbit = {
hp_min = 3, hp_min = 3,
hp_max = 3, hp_max = 3,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2}, collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2},
visual = "mesh", visual = "mesh",
@ -23,7 +25,14 @@ local rabbit = {
{"mobs_mc_rabbit_black.png"}, {"mobs_mc_rabbit_black.png"},
}, },
visual_size = {x=1.5, y=1.5}, 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, makes_footstep_sound = false,
walk_velocity = 1, walk_velocity = 1,
run_velocity = 3.7, run_velocity = 3.7,

View File

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

View File

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

View File

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

View File

@ -17,6 +17,8 @@ local skeleton = {
spawn_class = "hostile", spawn_class = "hostile",
hp_min = 20, hp_min = 20,
hp_max = 20, hp_max = 20,
xp_min = 6,
xp_max = 6,
breath_max = -1, breath_max = -1,
armor = {undead = 100, fleshy = 100}, armor = {undead = 100, fleshy = 100},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, 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", spawn_class = "hostile",
hp_min = 20, hp_min = 20,
hp_max = 20, hp_max = 20,
xp_min = 6,
xp_max = 6,
breath_max = -1, breath_max = -1,
armor = {undead = 100, fleshy = 100}, armor = {undead = 100, fleshy = 100},
pathfinding = 1, pathfinding = 1,

View File

@ -51,6 +51,7 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
end end
end, children, self.attack) end, children, self.attack)
end end
return true
end end
end end
@ -62,6 +63,8 @@ local slime_big = {
group_attack = { "mobs_mc:slime_big", "mobs_mc:slime_small", "mobs_mc:slime_tiny" }, group_attack = { "mobs_mc:slime_big", "mobs_mc:slime_small", "mobs_mc:slime_tiny" },
hp_min = 16, hp_min = 16,
hp_max = 16, hp_max = 16,
xp_min = 4,
xp_max = 4,
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02}, collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
visual_size = {x=12.5, y=12.5}, visual_size = {x=12.5, y=12.5},
textures = {{"mobs_mc_slime.png"}}, 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.sounds.base_pitch = 1.15
slime_small.hp_min = 4 slime_small.hp_min = 4
slime_small.hp_max = 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.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.visual_size = {x=6.25, y=6.25}
slime_small.damage = 3 slime_small.damage = 3
@ -128,6 +133,8 @@ local slime_tiny = table.copy(slime_big)
slime_tiny.sounds.base_pitch = 1.3 slime_tiny.sounds.base_pitch = 1.3
slime_tiny.hp_min = 1 slime_tiny.hp_min = 1
slime_tiny.hp_max = 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.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.visual_size = {x=3.125, y=3.125}
slime_tiny.damage = 0 slime_tiny.damage = 0
@ -160,6 +167,8 @@ local magma_cube_big = {
spawn_class = "hostile", spawn_class = "hostile",
hp_min = 16, hp_min = 16,
hp_max = 16, hp_max = 16,
xp_min = 4,
xp_max = 4,
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02}, collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
visual_size = {x=12.5, y=12.5}, visual_size = {x=12.5, y=12.5},
textures = {{ "mobs_mc_magmacube.png" }}, 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.sounds.death = "mobs_mc_magma_cube_small"
magma_cube_small.hp_min = 4 magma_cube_small.hp_min = 4
magma_cube_small.hp_max = 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.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.visual_size = {x=6.25, y=6.25}
magma_cube_small.damage = 3 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.sounds.base_pitch = 1.25
magma_cube_tiny.hp_min = 1 magma_cube_tiny.hp_min = 1
magma_cube_tiny.hp_max = 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.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.visual_size = {x=3.125, y=3.125}
magma_cube_tiny.walk_velocity = 1.02 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}, collisionbox = {-0.35, -0.01, -0.35, 0.35, 1.89, 0.35},
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_snowman.b3d", 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 = { textures = {
"mobs_mc_snowman.png", --snowman texture "mobs_mc_snowman.png", --snowman texture
"farming_pumpkin_side.png", --top "farming_pumpkin_side.png", --top
@ -74,7 +78,7 @@ mobs:register_mob("mobs_mc:snowman", {
run_end = 20, run_end = 20,
die_start = 40, die_start = 40,
die_end = 50, die_end = 50,
die_speed = 25, die_speed = 15,
die_loop = false, die_loop = false,
}, },
do_custom = function(self, dtime) do_custom = function(self, dtime)
@ -117,7 +121,7 @@ mobs:register_mob("mobs_mc:snowman", {
}) })
local pos = self.object:get_pos() 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 -- Wear out
if not minetest.is_creative_enabled(clicker:get_player_name()) then 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