diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr
new file mode 100644
index 0000000000..cb9a0f38e8
--- /dev/null
+++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr
@@ -0,0 +1,2 @@
+# textdomain:mcl_explosions
+@1 was caught in an explosion.=@1 a été pris dans une explosion.
\ No newline at end of file
diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua
index 613226144e..a1346f50b8 100644
--- a/mods/CORE/mcl_init/init.lua
+++ b/mods/CORE/mcl_init/init.lua
@@ -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())
-
-
diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_mob_death.png b/mods/CORE/mcl_particles/textures/mcl_particles_mob_death.png
new file mode 100644
index 0000000000..6dc9cdc694
Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_mob_death.png differ
diff --git a/mods/CORE/mcl_sounds/init.lua b/mods/CORE/mcl_sounds/init.lua
index b4d43f0c8d..13ca7bf720 100644
--- a/mods/CORE/mcl_sounds/init.lua
+++ b/mods/CORE/mcl_sounds/init.lua
@@ -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
diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua
index a4e87341f5..a6f0fd0957 100644
--- a/mods/ENTITIES/mcl_mobs/api.lua
+++ b/mods/ENTITIES/mcl_mobs/api.lua
@@ -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,33 +747,41 @@ local check_for_death = function(self, cause, cmi_cause)
return false
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")
- 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
- mcl_experience.throw_experience(pos, math.ceil( math.random(self.hp_min,self.hp_max+5) / 5) )
+ local pos = self.object:get_pos()
+
+ 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
- self.object:remove()
-
- return true
+ if on_die_exit == true then
+ self.state = "die"
+ self.object:remove()
+ return true
+ end
end
local collisionbox
@@ -663,46 +789,65 @@ local check_for_death = function(self, cause, cmi_cause)
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")
-
- 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
+ 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)
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, 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
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
+ end
end
-
- return false -- beyond limits
+ 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
diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt
index e585c99503..d1c478a990 100644
--- a/mods/ENTITIES/mcl_mobs/api.txt
+++ b/mods/ENTITIES/mcl_mobs/api.txt
@@ -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
diff --git a/mods/ENTITIES/mcl_mobs/mod.conf b/mods/ENTITIES/mcl_mobs/mod.conf
index 986fef084b..c3d9713744 100644
--- a/mods/ENTITIES/mcl_mobs/mod.conf
+++ b/mods/ENTITIES/mcl_mobs/mod.conf
@@ -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
diff --git a/mods/ENTITIES/mcl_mobs/readme.MD b/mods/ENTITIES/mcl_mobs/readme.MD
index 0d332f85c8..aa79d909cb 100644
--- a/mods/ENTITIES/mcl_mobs/readme.MD
+++ b/mods/ENTITIES/mcl_mobs/readme.MD
@@ -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:
+------------
Changelog from original Mobs Redo mod:
- 1.41- Mob pathfinding has been updated thanks to Elkien3
diff --git a/mods/ENTITIES/mcl_mobs/sounds/mcl_mobs_mob_poof.ogg b/mods/ENTITIES/mcl_mobs/sounds/mcl_mobs_mob_poof.ogg
new file mode 100644
index 0000000000..9f683c0cfa
Binary files /dev/null and b/mods/ENTITIES/mcl_mobs/sounds/mcl_mobs_mob_poof.ogg differ
diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.fr.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.fr.tr
new file mode 100644
index 0000000000..56fa14937f
--- /dev/null
+++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.fr.tr
@@ -0,0 +1,2 @@
+# textdomain:mcl_paintings
+Painting=Peinture
\ No newline at end of file
diff --git a/mods/ENTITIES/mobs_mc/LICENSE-media.md b/mods/ENTITIES/mobs_mc/LICENSE-media.md
index 696150480b..dad31abb85 100644
--- a/mods/ENTITIES/mobs_mc/LICENSE-media.md
+++ b/mods/ENTITIES/mobs_mc/LICENSE-media.md
@@ -84,6 +84,12 @@ Origin of those models:
* [AGFX](http://www.freesound.org/people/DrMinky/sounds/) (CC0)
* `mobs_mc_chicken_child.ogg`
* Source:
+* [evsecrets](https://freesound.org/people/evsecrets/sounds/) (CC0)
+ * `mobs_mc_chicken_*.ogg`
+ * Source:
+* [contramundum](https://freesound.org/people/contramundum/sounds/)
+ * `mobs_mc_parrot_*.ogg`
+ * Source:
* 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:
+* [Klaraschick](https://freesound.org/people/Klaraschick/)
+ * `mobs_mc_cow_milk.ogg` (CC0)
+ * shortened
+ * Source:
+* [Hitrison](https://freesound.org/people/Hitrison/)
+ * `mobs_mc_cow_mushroom_stew.ogg` (CC BY 3.0)
+ * sound was modified
+ * Source:
* [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:
+* [rubberduck](https://opengameart.org/users/rubberduck)
+ * `mobs_mc_endermite_*.ogg` (CC0)
+ * `mobs_mc_zombiepig_*.ogg` (CC0)
+ * `mobs_mc_enderman_teleport_*.ogg` (CC0)
+ * Source 1:
+ * Source 2:
+* [Soundscapes55](https://freesound.org/people/Soundscapes55/)
+ * `mobs_mc_enderman_random.1.ogg` (CC0)
+ * Source:
+* [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:
+* [pointparkcinema](https://freesound.org/people/pointparkcinema/)
+ * `mobs_mc_guardian_random.1.ogg` (CC0)
+ * Source:
+* [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:
+* [TheBuilder15](https://freesound.org/people/TheBuilder15/)
+ * `mobs_mc_guardian_death.ogg` (CC0)
+ * Source:
* 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:
+* [kyles](https://freesound.org/people/kyles/)
+ * `mobs_mc_squid_flop.*.ogg` (CC0)
+ * Source:
+ * `mobs_mc_snowman_hurt.1.ogg` (CC0)
+ * Source:
* [thefilmbakery](https://freesound.org/people/thefilmbakery/) (CC0)
* `mobs_mc_blaze_hurt.ogg`
* Source:
* 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:
+* [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:
* BrandonReese (LGPL v2.1)
* `mobs_eerie.ogg`
* [Under7dude](https://freesound.org/people/Under7dude/) (CC0)
@@ -147,6 +204,13 @@ Origin of those models:
* Source:
* `mobs_mc_horse_death.ogg` (CC BY 3.0)
* Source:
+* [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:
+* [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:
@@ -164,6 +228,10 @@ Origin of those models:
* [suonho](https://freesound.org/people/suonho/)
* `mobs_mc_bat_idle.ogg` (CC BY 3.0)
* Source:
+* [toefur](https://freesound.org/people/toefur/)
+ * `mobs_mc_bat_hurt.*.ogg` (CC0)
+ * `mobs_mc_bat_death.ogg` (CC0)
+ * Source:
* [cmusounddesign](https://freesound.org/people/cmusounddesign/)
* `mobs_mc_cat_hiss.ogg` (CC BY 3.0)
* Source:
@@ -173,6 +241,16 @@ Origin of those models:
* [ebcrosby](https://freesound.org/people/ebcrosby/)
* `mobs_mc_ocelot_hurt.ogg` (CC BY 3.0)
* Source:
+* 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
+* [cliftoncarlson](https://freesound.org/people/cliftonmcarlson/)
+ * `mobs_mc_wolf_take_bone.ogg` (CC0)
+ * Source:
* [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:
+* [InspectorJ](https://freesound.org/people/InspectorJ/sounds/429591/)
+ * `mobs_mc_animal_eat_generic.ogg` (CC BY 3.0)
+ * Source:
+* [tbsounddesigns](https://freesound.org/people/tbsounddesigns/)
+ * `mobs_mc_bear_random.*.ogg` (CC BY 3.0)
+ * Source 1:
+ * Source 2:
+ * Source 3:
+ * `mobs_mc_bear_growl.*.ogg` (CC BY 3.0)
+ * Source 1:
+ * Source 2:
+ * Source 3:
+* [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:
+* [alexo400](https://freesound.org/people/alexo400/)
+ * `mobs_mc_snowman_death.*.ogg` (CC0)
+ * Source:
+* [cabled\_mess](https://freesound.org/people/cabled_mess/)
+ * `mobs_mc_snowman_hurt.2.ogg` (CC0)
+ * Source:
+ * `mobs_mc_snowman_hurt.3.ogg` (CC0)
+ * Source:
+* [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:
+ * `mobs_mc_rabbit_attack.*.ogg` (CC0)
+ * Source:
+ * `mobs_mc_rabbit_death.1.ogg` (CC0)
+ * Source:
+* [Alshred](https://freesound.org/people/Alshred/sounds/403773/)
+ * `mobs_mc_rabbit_random.*.ogg` (CC0)
+ * Changes were made.
+ * Source:
Note: Many of these sounds have been more or less modified to fit the game.
diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua
index be0d72e820..103579b67f 100644
--- a/mods/ENTITIES/mobs_mc/bat.lua
+++ b/mods/ENTITIES/mobs_mc/bat.lua
@@ -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,
})
diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua
index d281a59ed5..aae82a39b3 100644
--- a/mods/ENTITIES/mobs_mc/blaze.lua
+++ b/mods/ENTITIES/mobs_mc/blaze.lua
@@ -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,
})
diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua
index d0c9c7c714..618d1e0f09 100644
--- a/mods/ENTITIES/mobs_mc/chicken.lua
+++ b/mods/ENTITIES/mobs_mc/chicken.lua
@@ -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 = {
diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua
index dc231627c3..e8482d8204 100644
--- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua
+++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua
@@ -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)
diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua
index ddba6523e8..a52e6e1e19 100644
--- a/mods/ENTITIES/mobs_mc/creeper.lua
+++ b/mods/ENTITIES/mobs_mc/creeper.lua
@@ -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 = {
diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua
index 71627aadad..dd68cbcced 100644
--- a/mods/ENTITIES/mobs_mc/ender_dragon.lua
+++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua
index 3f62bdb2a7..934497a104 100644
--- a/mods/ENTITIES/mobs_mc/enderman.lua
+++ b/mods/ENTITIES/mobs_mc/enderman.lua
@@ -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.
diff --git a/mods/ENTITIES/mobs_mc/endermite.lua b/mods/ENTITIES/mobs_mc/endermite.lua
index 256ad4963d..da3922a106 100644
--- a/mods/ENTITIES/mobs_mc/endermite.lua
+++ b/mods/ENTITIES/mobs_mc/endermite.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua
index 2b39b59376..7133330854 100644
--- a/mods/ENTITIES/mobs_mc/ghast.lua
+++ b/mods/ENTITIES/mobs_mc/ghast.lua
@@ -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,
})
diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua
index b5c736c277..dd273c1ebd 100644
--- a/mods/ENTITIES/mobs_mc/guardian.lua
+++ b/mods/ENTITIES/mobs_mc/guardian.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua
index 84f9ddb834..7094dee247 100644
--- a/mods/ENTITIES/mobs_mc/guardian_elder.lua
+++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua
index 95cba7aca9..95a02bfca5 100644
--- a/mods/ENTITIES/mobs_mc/horse.lua
+++ b/mods/ENTITIES/mobs_mc/horse.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua
index 8cb32a165b..58a70de2fc 100644
--- a/mods/ENTITIES/mobs_mc/llama.lua
+++ b/mods/ENTITIES/mobs_mc/llama.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua
index 89a41fe440..eca74d3ba5 100644
--- a/mods/ENTITIES/mobs_mc/ocelot.lua
+++ b/mods/ENTITIES/mobs_mc/ocelot.lua
@@ -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)
diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua
index a6a2a276d5..90bf215edf 100644
--- a/mods/ENTITIES/mobs_mc/parrot.lua
+++ b/mods/ENTITIES/mobs_mc/parrot.lua
@@ -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)
diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua
index 3ed821b343..09bda3199f 100644
--- a/mods/ENTITIES/mobs_mc/pig.lua
+++ b/mods/ENTITIES/mobs_mc/pig.lua
@@ -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)
diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua
index fd1eaa1ced..d974c7a603 100644
--- a/mods/ENTITIES/mobs_mc/polar_bear.lua
+++ b/mods/ENTITIES/mobs_mc/polar_bear.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua
index 783a24ff40..e2f9d213f2 100644
--- a/mods/ENTITIES/mobs_mc/rabbit.lua
+++ b/mods/ENTITIES/mobs_mc/rabbit.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua
index 374ea4b590..ecf3ad5c01 100644
--- a/mods/ENTITIES/mobs_mc/sheep.lua
+++ b/mods/ENTITIES/mobs_mc/sheep.lua
@@ -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"
diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua
index 0f38f68a3a..97de5aba68 100644
--- a/mods/ENTITIES/mobs_mc/shulker.lua
+++ b/mods/ENTITIES/mobs_mc/shulker.lua
@@ -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",
diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua
index d4ae7ca332..433211503b 100644
--- a/mods/ENTITIES/mobs_mc/silverfish.lua
+++ b/mods/ENTITIES/mobs_mc/silverfish.lua
@@ -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",
diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua
index 104ee4f579..45cc6b9798 100644
--- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua
+++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua
@@ -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},
diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua
index c9e087db3c..6dd2fcdbe6 100644
--- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua
+++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua
@@ -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,
diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua
index d361b89b68..ddf925bbb3 100644
--- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua
+++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua
@@ -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
diff --git a/mods/ENTITIES/mobs_mc/snowman.lua b/mods/ENTITIES/mobs_mc/snowman.lua
index 5069240bdb..1ee88b3623 100644
--- a/mods/ENTITIES/mobs_mc/snowman.lua
+++ b/mods/ENTITIES/mobs_mc/snowman.lua
@@ -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
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_chicken.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_chicken.ogg
deleted file mode 100644
index be64c94c07..0000000000
Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_chicken.ogg and /dev/null differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_animal_eat_generic.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_animal_eat_generic.ogg
new file mode 100644
index 0000000000..cdf6969bb0
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_animal_eat_generic.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_death.ogg
new file mode 100644
index 0000000000..f9e7798b86
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.1.ogg
new file mode 100644
index 0000000000..0aa1723b1b
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.2.ogg
new file mode 100644
index 0000000000..2e09e3e93d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.3.ogg
new file mode 100644
index 0000000000..156e6ba184
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bat_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_attack.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_attack.1.ogg
new file mode 100644
index 0000000000..35901a46e3
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_attack.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_attack.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_attack.2.ogg
new file mode 100644
index 0000000000..bd6c14b470
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_attack.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_death.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_death.1.ogg
new file mode 100644
index 0000000000..fcfcffa881
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_death.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.1.ogg
new file mode 100644
index 0000000000..863e15baa2
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.2.ogg
new file mode 100644
index 0000000000..72ff579029
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.3.ogg
new file mode 100644
index 0000000000..710d3f6320
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_growl.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_hurt.1.ogg
new file mode 100644
index 0000000000..630f099877
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.1.ogg
new file mode 100644
index 0000000000..8b3498baf4
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.2.ogg
new file mode 100644
index 0000000000..b8d1a67d01
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.3.ogg
new file mode 100644
index 0000000000..3d83696f91
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_bear_random.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.1.ogg
new file mode 100644
index 0000000000..506d040a4d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.2.ogg
new file mode 100644
index 0000000000..858362b929
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.3.ogg
new file mode 100644
index 0000000000..ca090123fb
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_buck.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_hurt.ogg
new file mode 100644
index 0000000000..32c4337ba8
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_chicken_hurt.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_cow_milk.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_cow_milk.ogg
new file mode 100644
index 0000000000..a9163e1b3c
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_cow_milk.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_cow_mushroom_stew.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_cow_mushroom_stew.ogg
new file mode 100644
index 0000000000..d120e860f0
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_cow_mushroom_stew.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_death.ogg
new file mode 100644
index 0000000000..908a82b9e7
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_hurt.ogg
new file mode 100644
index 0000000000..9d1001fd3b
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_hurt.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_random.1.ogg
new file mode 100644
index 0000000000..26e1e9a56c
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_random.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_random.2.ogg
new file mode 100644
index 0000000000..293a2b9983
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_donkey_random.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_death.ogg
new file mode 100644
index 0000000000..6f92ffdc39
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.1.ogg
new file mode 100644
index 0000000000..6b125fa4fc
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.2.ogg
new file mode 100644
index 0000000000..427069c855
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.3.ogg
new file mode 100644
index 0000000000..104bdd7ecb
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_random.1.ogg
new file mode 100644
index 0000000000..1dc588d4d9
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_teleport_dst.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_teleport_dst.ogg
new file mode 100644
index 0000000000..1896d7d4df
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_teleport_dst.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_teleport_src.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_teleport_src.ogg
new file mode 100644
index 0000000000..7b08a4884c
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_enderman_teleport_src.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_death.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_death.1.ogg
new file mode 100644
index 0000000000..74b3336bed
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_death.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_death.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_death.2.ogg
new file mode 100644
index 0000000000..02aec38c65
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_death.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.1.ogg
new file mode 100644
index 0000000000..68a7fee533
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.2.ogg
new file mode 100644
index 0000000000..578732d919
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.3.ogg
new file mode 100644
index 0000000000..5d8cda08d5
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_random.1.ogg
new file mode 100644
index 0000000000..07650e3bb6
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_endermite_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_death.ogg
new file mode 100644
index 0000000000..93c093d058
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_hurt.1.ogg
new file mode 100644
index 0000000000..7d7cad3f82
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_hurt.2.ogg
new file mode 100644
index 0000000000..9d870486b9
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.1.ogg
new file mode 100644
index 0000000000..d33157c14a
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.2.ogg
new file mode 100644
index 0000000000..5853e16c52
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.3.ogg
new file mode 100644
index 0000000000..9fc4df09df
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_guardian_random.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_death.ogg
new file mode 100644
index 0000000000..b4d181e0ef
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_hurt.ogg
new file mode 100644
index 0000000000..96315f2101
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_hurt.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_random.1.ogg
new file mode 100644
index 0000000000..ecfc30ef60
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_random.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_random.2.ogg
new file mode 100644
index 0000000000..e9ad247eb5
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_parrot_random.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_attack.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_attack.1.ogg
new file mode 100644
index 0000000000..70b404651a
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_attack.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_attack.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_attack.2.ogg
new file mode 100644
index 0000000000..b1f6ef7705
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_attack.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.1.ogg
new file mode 100644
index 0000000000..afd18ff23e
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.2.ogg
new file mode 100644
index 0000000000..c628437f25
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.3.ogg
new file mode 100644
index 0000000000..c7133e0848
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_death.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.1.ogg
new file mode 100644
index 0000000000..10bdea141d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.2.ogg
new file mode 100644
index 0000000000..7578bea254
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.3.ogg
new file mode 100644
index 0000000000..f000ff1a47
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.1.ogg
new file mode 100644
index 0000000000..7ccf450911
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.2.ogg
new file mode 100644
index 0000000000..3e37b8c286
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.3.ogg
new file mode 100644
index 0000000000..21bcb42707
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.4.ogg
new file mode 100644
index 0000000000..d446f400ac
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_rabbit_random.4.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.1.ogg
new file mode 100644
index 0000000000..4794d7e0b6
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.2.ogg
new file mode 100644
index 0000000000..aa1fb3f961
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.3.ogg
new file mode 100644
index 0000000000..5de0b0dd24
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_death.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.1.ogg
new file mode 100644
index 0000000000..b7ac7d7a65
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.2.ogg
new file mode 100644
index 0000000000..e2765e6201
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.3.ogg
new file mode 100644
index 0000000000..5abb1b190d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_snowman_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_attack.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_attack.1.ogg
new file mode 100644
index 0000000000..9dac01d1a5
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_attack.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_attack.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_attack.2.ogg
new file mode 100644
index 0000000000..76a66c4837
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_attack.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_death.ogg
new file mode 100644
index 0000000000..cf2c7dc264
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.1.ogg
new file mode 100644
index 0000000000..bb750f4300
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.2.ogg
new file mode 100644
index 0000000000..de76a688a6
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.3.ogg
new file mode 100644
index 0000000000..4796176819
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_random.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_random.ogg
new file mode 100644
index 0000000000..32b7746155
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_spider_random.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_death.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_death.1.ogg
new file mode 100644
index 0000000000..869c3ae103
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_death.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.1.ogg
new file mode 100644
index 0000000000..0fde5dc809
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.2.ogg
new file mode 100644
index 0000000000..0a2efd469f
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.3.ogg
new file mode 100644
index 0000000000..d371fc7aed
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.4.ogg
new file mode 100644
index 0000000000..956db6ac4d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_flop.4.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.1.ogg
new file mode 100644
index 0000000000..2b68ba9f38
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.2.ogg
new file mode 100644
index 0000000000..fc47997e82
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.ogg
deleted file mode 100644
index 58c02297c2..0000000000
Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_squid_hurt.ogg and /dev/null differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wither_spawn.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wither_spawn.ogg
new file mode 100644
index 0000000000..8f00611448
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wither_spawn.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.1.ogg
new file mode 100644
index 0000000000..4434015f8a
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.2.ogg
new file mode 100644
index 0000000000..f721eb2212
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.3.ogg
new file mode 100644
index 0000000000..4352e36dd9
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_bark.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_death.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_death.ogg
new file mode 100644
index 0000000000..c5b39bcbc0
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_death.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_growl.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_growl.ogg
new file mode 100644
index 0000000000..aa3286e47f
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_growl.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.1.ogg
new file mode 100644
index 0000000000..203dd9b577
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.2.ogg
new file mode 100644
index 0000000000..cf57285a11
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.3.ogg
new file mode 100644
index 0000000000..c603e07ac7
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_take_bone.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_take_bone.ogg
new file mode 100644
index 0000000000..3c1b6913ee
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_wolf_take_bone.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_death.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_death.1.ogg
new file mode 100644
index 0000000000..1c05e70686
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_death.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_death.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_death.2.ogg
new file mode 100644
index 0000000000..6c0bc48994
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_death.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.1.ogg
new file mode 100644
index 0000000000..b20b636fcd
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.2.ogg
new file mode 100644
index 0000000000..8a65437161
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.2.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.3.ogg
new file mode 100644
index 0000000000..79776601e5
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_hurt.3.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_random.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_random.1.ogg
new file mode 100644
index 0000000000..f266a5c36d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_random.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_war_cry.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_war_cry.1.ogg
new file mode 100644
index 0000000000..efa398c32d
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_zombiepig_war_cry.1.ogg differ
diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_rat.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_rat.ogg
deleted file mode 100644
index 0e992671ef..0000000000
Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_rat.ogg and /dev/null differ
diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua
index f4206d2ac3..72a9960380 100644
--- a/mods/ENTITIES/mobs_mc/spider.lua
+++ b/mods/ENTITIES/mobs_mc/spider.lua
@@ -23,6 +23,8 @@ local spider = {
reach = 2,
hp_min = 16,
hp_max = 16,
+ xp_min = 5,
+ xp_max = 5,
armor = {fleshy = 100, arthropod = 100},
collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7},
visual = "mesh",
@@ -33,9 +35,11 @@ local spider = {
visual_size = {x=3, y=3},
makes_footstep_sound = false,
sounds = {
- random = "mobs_spider",
- attack = "mobs_spider",
- -- TODO: sounds: walk, death
+ random = "mobs_mc_spider_random",
+ attack = "mobs_mc_spider_attack",
+ damage = "mobs_mc_spider_hurt",
+ death = "mobs_mc_spider_death",
+ -- TODO: sounds: walk
distance = 16,
},
walk_velocity = 1.3,
@@ -76,6 +80,8 @@ cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.49, 0.35}
cave_spider.visual_size = {x=1.66666, y=1.5}
cave_spider.walk_velocity = 1.3
cave_spider.run_velocity = 3.2
+cave_spider.sounds = table.copy(spider.sounds)
+cave_spider.sounds.base_pitch = 1.25
mobs:register_mob("mobs_mc:cave_spider", cave_spider)
diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua
index a43bade397..392143321c 100644
--- a/mods/ENTITIES/mobs_mc/squid.lua
+++ b/mods/ENTITIES/mobs_mc/squid.lua
@@ -13,6 +13,8 @@ mobs:register_mob("mobs_mc:squid", {
passive = true,
hp_min = 10,
hp_max = 10,
+ xp_min = 1,
+ xp_max = 3,
armor = 100,
-- FIXME: If the squid is near the floor, it turns black
collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.9, 0.4},
@@ -22,9 +24,10 @@ mobs:register_mob("mobs_mc:squid", {
{"mobs_mc_squid.png"}
},
sounds = {
- damage = "mobs_mc_squid_hurt",
- death = "mobs_mc_squid_hurt",
- -- TODO: sounds: random, damage, death
+ damage = {name="mobs_mc_squid_hurt", gain=0.3},
+ death = {name="mobs_mc_squid_death", gain=0.4},
+ flop = "mobs_mc_squid_flop",
+ -- TODO: sounds: random
distance = 16,
},
animation = {
@@ -47,7 +50,6 @@ mobs:register_mob("mobs_mc:squid", {
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
breathes_in_water = true,
jump = false,
- fall_speed = 0.5,
view_range = 16,
runaway = true,
fear_height = 4,
diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png
new file mode 100644
index 0000000000..fc09566a53
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png differ
diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png
new file mode 100644
index 0000000000..7dde7e5a86
Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png differ
diff --git a/mods/ENTITIES/mobs_mc/vex.lua b/mods/ENTITIES/mobs_mc/vex.lua
index 4c648577d4..cccdebe7a5 100644
--- a/mods/ENTITIES/mobs_mc/vex.lua
+++ b/mods/ENTITIES/mobs_mc/vex.lua
@@ -18,6 +18,8 @@ mobs:register_mob("mobs_mc:vex", {
physical = false,
hp_min = 14,
hp_max = 14,
+ xp_min = 6,
+ xp_max = 6,
collisionbox = {-0.2, 0.2, -0.2, 0.2, 1.0, 0.2}, --bat
visual = "mesh",
mesh = "mobs_mc_vex.b3d",
@@ -86,6 +88,7 @@ mobs:register_mob("mobs_mc:vex", {
end
end,
fly = true,
+ makes_footstep_sound = false,
})
diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua
index babb1d5736..9788d58c65 100644
--- a/mods/ENTITIES/mobs_mc/villager.lua
+++ b/mods/ENTITIES/mobs_mc/villager.lua
@@ -1053,7 +1053,6 @@ mobs:register_mob("mobs_mc:villager", {
return_fields(player)
end
end
- mobs.death_effect(pos, self.collisionbox)
end,
})
diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua
index 3b9b157871..b865a2bd56 100644
--- a/mods/ENTITIES/mobs_mc/villager_evoker.lua
+++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua
@@ -18,6 +18,8 @@ mobs:register_mob("mobs_mc:evoker", {
pathfinding = 1,
hp_min = 24,
hp_max = 24,
+ xp_min = 10,
+ xp_max = 10,
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.95, 0.4},
visual = "mesh",
mesh = "mobs_mc_villager.b3d",
diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua
index 0e41f4e998..30e9f6f364 100644
--- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua
+++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua
@@ -22,6 +22,8 @@ mobs:register_mob("mobs_mc:illusioner", {
end,
hp_min = 32,
hp_max = 32,
+ xp_min = 6,
+ xp_max = 6,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
visual = "mesh",
mesh = "mobs_mc_illusioner.b3d",
diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua
index d7d6f273ad..825ffd88f1 100644
--- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua
+++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua
@@ -17,6 +17,8 @@ mobs:register_mob("mobs_mc:vindicator", {
pathfinding = 1,
hp_min = 24,
hp_max = 24,
+ xp_min = 6,
+ xp_max = 6,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
visual = "mesh",
mesh = "mobs_mc_vindicator.b3d",
@@ -57,7 +59,7 @@ mobs:register_mob("mobs_mc:vindicator", {
punch_speed = 25,
punch_start = 90,
punch_end = 110,
- die_speed = 25,
+ die_speed = 15,
die_start = 170,
die_end = 180,
die_loop = false,
diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua
index 6f7e3e5aaf..524a918dee 100644
--- a/mods/ENTITIES/mobs_mc/villager_zombie.lua
+++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua
@@ -17,6 +17,8 @@ mobs:register_mob("mobs_mc:villager_zombie", {
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
+ xp_min = 5,
+ xp_max = 5,
breath_max = -1,
armor = {undead = 90, fleshy = 90},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua
index fcc056271d..5cddd5b422 100644
--- a/mods/ENTITIES/mobs_mc/witch.lua
+++ b/mods/ENTITIES/mobs_mc/witch.lua
@@ -17,6 +17,8 @@ mobs:register_mob("mobs_mc:witch", {
spawn_class = "hostile",
hp_min = 26,
hp_max = 26,
+ xp_min = 5,
+ xp_max = 5,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
visual = "mesh",
mesh = "mobs_mc_witch.b3d",
diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua
index e3604f947f..28c1a2138c 100644
--- a/mods/ENTITIES/mobs_mc/wither.lua
+++ b/mods/ENTITIES/mobs_mc/wither.lua
@@ -14,6 +14,8 @@ mobs:register_mob("mobs_mc:wither", {
spawn_class = "hostile",
hp_max = 300,
hp_min = 300,
+ xp_min = 50,
+ xp_max = 50,
armor = {undead = 80, fleshy = 80},
-- This deviates from MC Wiki's size, which makes no sense
collisionbox = {-0.9, 0.4, -0.9, 0.9, 2.45, 0.9},
@@ -37,6 +39,7 @@ mobs:register_mob("mobs_mc:wither", {
jump = true,
jump_height = 10,
fly = true,
+ makes_footstep_sound = false,
dogshoot_switch = 1,
dogshoot_count_max =1,
attack_animals = true,
@@ -62,6 +65,9 @@ mobs:register_mob("mobs_mc:wither", {
run_start = 0, run_end = 20,
},
harmed_by_heal = true,
+ on_spawn = function(self)
+ minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64})
+ end,
})
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua
index 058c571535..fe30318954 100644
--- a/mods/ENTITIES/mobs_mc/wolf.lua
+++ b/mods/ENTITIES/mobs_mc/wolf.lua
@@ -24,6 +24,8 @@ local wolf = {
can_despawn = true,
hp_min = 8,
hp_max = 8,
+ xp_min = 1,
+ xp_max = 3,
passive = false,
group_attack = true,
collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3},
@@ -34,7 +36,14 @@ local wolf = {
},
visual_size = {x=3, y=3},
makes_footstep_sound = true,
- -- TODO: sounds
+ sounds = {
+ attack = "mobs_mc_wolf_bark",
+ war_cry = "mobs_mc_wolf_growl",
+ damage = {name = "mobs_mc_wolf_hurt", gain=0.6},
+ death = {name = "mobs_mc_wolf_death", gain=0.6},
+ eat = "mobs_mc_animal_eat_generic",
+ distance = 16,
+ },
pathfinding = 1,
floats = 1,
view_range = 16,
@@ -53,6 +62,7 @@ local wolf = {
local dog, ent
if tool:get_name() == mobs_mc.items.bone then
+ minetest.sound_play("mobs_mc_wolf_take_bone", {object=self.object, max_hear_distance=16}, true)
if not minetest.is_creative_enabled(clicker:get_player_name()) then
tool:take_item()
clicker:set_wielded_item(tool)
@@ -64,6 +74,9 @@ local wolf = {
dog:set_yaw(yaw)
ent = dog:get_luaentity()
ent.owner = clicker:get_player_name()
+ -- cornfirm taming
+ minetest.sound_play("mobs_mc_wolf_bark", {object=dog, max_hear_distance=16}, true)
+ -- Replace wolf
self.object:remove()
end
end
@@ -189,16 +202,30 @@ dog.on_rightclick = function(self, clicker)
self.owner = clicker:get_player_name()
end
+ local pos = self.object:get_pos()
+ local particle
if not self.order or self.order == "" or self.order == "sit" then
+ particle = "mobs_mc_wolf_icon_roam.png"
self.order = "roam"
self.walk_chance = default_walk_chance
self.jump = true
- else
-- TODO: Add sitting model
+ else
+ particle = "mobs_mc_wolf_icon_sit.png"
self.order = "sit"
self.walk_chance = 0
self.jump = false
end
+ -- Display icon to show current order (sit or roam)
+ minetest.add_particle({
+ pos = vector.add(pos, {x=0,y=1,z=0}),
+ velocity = {x=0,y=0.2,z=0},
+ expirationtime = 1,
+ size = 4,
+ texture = particle,
+ playername = self.owner,
+ glow = minetest.LIGHT_MAX,
+ })
end
end
diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua
index 94b441bfe2..beb51d89fa 100644
--- a/mods/ENTITIES/mobs_mc/zombie.lua
+++ b/mods/ENTITIES/mobs_mc/zombie.lua
@@ -43,6 +43,8 @@ local zombie = {
spawn_class = "hostile",
hp_min = 20,
hp_max = 20,
+ xp_min = 5,
+ xp_max = 5,
breath_max = -1,
armor = {undead = 90, fleshy = 90},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3},
@@ -89,6 +91,8 @@ mobs:register_mob("mobs_mc:zombie", zombie)
local baby_zombie = table.copy(zombie)
baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25}
+baby_zombie.xp_min = 12
+baby_zombie.xp_max = 12
baby_zombie.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2}
baby_zombie.walk_velocity = 1.2
baby_zombie.run_velocity = 2.4
@@ -110,6 +114,8 @@ mobs:register_mob("mobs_mc:husk", husk)
-- A smaller and more dangerous variant of the husk
local baby_husk = table.copy(husk)
baby_husk.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25}
+baby_husk.xp_min = 12
+baby_husk.xp_max = 12
baby_husk.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2}
baby_husk.walk_velocity = 1.2
baby_husk.run_velocity = 2.4
diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua
index 3a3364560e..a552f6d234 100644
--- a/mods/ENTITIES/mobs_mc/zombiepig.lua
+++ b/mods/ENTITIES/mobs_mc/zombiepig.lua
@@ -17,6 +17,8 @@ local pigman = {
spawn_class = "passive",
hp_min = 20,
hp_max = 20,
+ xp_min = 6,
+ xp_max = 6,
breath_max = -1,
armor = {undead = 90, fleshy = 90},
attack_type = "dogfight",
@@ -33,10 +35,10 @@ local pigman = {
} },
visual_size = {x=3, y=3},
sounds = {
- random = "mobs_mc_zombie_growl",
- war_cry = "mobs_mc_zombie_growl",
- death = "mobs_mc_zombie_death",
- damage = "mobs_mc_zombie_hurt",
+ random = "mobs_mc_zombiepig_random",
+ war_cry = "mobs_mc_zombiepig_war_cry",
+ death = "mobs_mc_zombiepig_death",
+ damage = "mobs_mc_zombiepig_hurt",
distance = 16,
},
jump = true,
@@ -89,6 +91,8 @@ mobs:register_mob("mobs_mc:pigman", pigman)
local baby_pigman = table.copy(pigman)
baby_pigman.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25}
+baby_pigman.xp_min = 13
+baby_pigman.xp_max = 13
baby_pigman.visual_size = {x=pigman.visual_size.x/2, y=pigman.visual_size.y/2}
baby_pigman.textures = { {
"mobs_mc_zombie_pigman.png", --baby
diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua
index ae7c770047..3d6a85e516 100644
--- a/mods/ENVIRONMENT/lightning/init.lua
+++ b/mods/ENVIRONMENT/lightning/init.lua
@@ -120,7 +120,7 @@ lightning.strike = function(pos)
glow = minetest.LIGHT_MAX,
})
- minetest.sound_play({ pos = pos, name = "lightning_thunder", gain = 10, max_hear_distance = 500 }, true)
+ minetest.sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
-- damage nearby objects, transform mobs
local objs = minetest.get_objects_inside_radius(pos2, 3.5)
diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.fr.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.fr.tr
index 56d150d952..cf35d788b5 100644
--- a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.fr.tr
+++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.fr.tr
@@ -28,7 +28,7 @@ Usage @1 of @2=Usage @1 de @2
Recipe @1 of @2=Recette @1 de @2
Burning time: @1=Temps de combustion : @1
Cooking time: @1=Temps de cuisson : @1
-Recipe is too big to be displayed (@1×@2)=La recette est trop grande pour être affichée (@1×@2)
+Recipe is too big to be displayed (@1×@2)=La recette est trop grande pour être affichée (@1x@2)
Shapeless=Sans forme
Cooking=Cuisson
Increase window size=Agrandir la fenêtre
diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr
index 9622fd8290..ae2f28a9c9 100644
--- a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr
+++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr
@@ -28,7 +28,6 @@ Usage @1 of @2=Использование @1 из @2
Recipe @1 of @2=Рецепт @1 из @2
Burning time: @1=Время горения: @1
Cooking time: @1=Время приготовления: @1
-Any item belonging to the group(s): @1=Любой элемент из групп(ы): @1
Recipe is too big to be displayed (@1×@2)=Рецепт слишком большой для отображения (@1×@2)
Shapeless=Бесформенный
Cooking=Приготовление
diff --git a/mods/HELP/mcl_craftguide/locale/template.txt b/mods/HELP/mcl_craftguide/locale/template.txt
index f59e97af62..66c5adcac3 100644
--- a/mods/HELP/mcl_craftguide/locale/template.txt
+++ b/mods/HELP/mcl_craftguide/locale/template.txt
@@ -28,7 +28,7 @@ Usage @1 of @2=
Recipe @1 of @2=
Burning time: @1=
Cooking time: @1=
-Recipe is too big to be displayed (@1x@2)=
+Recipe is too big to be displayed (@1×@2)=
Shapeless=
Cooking=
Increase window size=
diff --git a/mods/HUD/mcl_base_textures/textures/object_crosshair.png b/mods/HUD/mcl_base_textures/textures/object_crosshair.png
new file mode 100644
index 0000000000..e5a400e951
Binary files /dev/null and b/mods/HUD/mcl_base_textures/textures/object_crosshair.png differ
diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua
index 7ffa20bdf5..048bd43c61 100644
--- a/mods/HUD/mcl_experience/init.lua
+++ b/mods/HUD/mcl_experience/init.lua
@@ -240,7 +240,7 @@ function mcl_experience.add_experience(player, experience)
temp_pool.xp = math.min(math.max(temp_pool.xp + experience, 0), max_xp)
if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then
- temp_pool.bar = temp_pool.bar + temp_pool.bar_step * experience
+ temp_pool.bar = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level)
else
temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp)
temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level)
@@ -278,9 +278,9 @@ minetest.register_on_dieplayer(function(player)
temp_pool = pool[name]
xp_amount = temp_pool.xp
- temp_pool.bar = 0
- temp_pool.level = 0
temp_pool.xp = 0
+ temp_pool.level = 0
+ temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level)
hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(temp_pool.level)})
hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "number", data = math.floor(temp_pool.bar)})
diff --git a/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr b/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr
new file mode 100644
index 0000000000..a186b549bd
--- /dev/null
+++ b/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr
@@ -0,0 +1,6 @@
+[[] ]=[[] ]
+Gives a player some XP=Donne de l'XP à un joueur
+Error: Too many parameters!=Erreur: Trop de paramètres!
+Error: Incorrect value of XP=Erreur: Valeur incorrecte de XP
+Error: Player not found=Erreur: Joueur introuvable
+Added @1 XP to @2, total: @3, experience level: @4=Ajout de @1 XP à @2, total: @3, niveau d'expérience: @4
diff --git a/mods/HUD/mcl_experience/locale/template.txt b/mods/HUD/mcl_experience/locale/template.txt
index 19eb6cc608..8494504e9b 100644
--- a/mods/HUD/mcl_experience/locale/template.txt
+++ b/mods/HUD/mcl_experience/locale/template.txt
@@ -4,3 +4,4 @@ Error: Too many parameters!=
Error: Incorrect value of XP=
Error: Player not found=
Added @1 XP to @2, total: @3, experience level: @4=
+XP are disabled!=
diff --git a/mods/HUD/show_wielded_item/init.lua b/mods/HUD/show_wielded_item/init.lua
index 46a7e0c00f..bc06bee436 100644
--- a/mods/HUD/show_wielded_item/init.lua
+++ b/mods/HUD/show_wielded_item/init.lua
@@ -7,6 +7,7 @@ local dtimes = {}
local dlimit = 3 -- HUD element will be hidden after this many seconds
local hudbars_mod = minetest.get_modpath("hudbars")
+local xp_mod = minetest.get_modpath("mcl_experience")
local function set_hud(player)
if not player:is_player() then return end
@@ -28,6 +29,9 @@ local function set_hud(player)
local vmargin = tonumber(minetest.settings:get("hudbars_vmargin")) or 28
off.y = -76 - vmargin*rows
end
+ if xp_mod then
+ off.y = off.y - 25
+ end
-- Dirty trick to avoid collision with Minetest's status text (e.g. “Volume changed to 0%”)
if off.y >= -167 and off.y <= -156 then
diff --git a/mods/ITEMS/REDSTONE/mcl_observers/init.lua b/mods/ITEMS/REDSTONE/mcl_observers/init.lua
index bdb3d5bdc6..841ab98b4a 100644
--- a/mods/ITEMS/REDSTONE/mcl_observers/init.lua
+++ b/mods/ITEMS/REDSTONE/mcl_observers/init.lua
@@ -1,5 +1,13 @@
local S = minetest.get_translator("mcl_observers")
+mcl_observers = {}
+
+-- Warning! TODO: Remove this message.
+-- 'realtime' is experimental feature! It can slow down the everything!
+-- Please set it to false and restart the game if something's wrong:
+local realtime = true
+--local realtime = false
+
local rules_flat = {
{ x = 0, y = 0, z = -1, spread = true },
}
@@ -14,6 +22,26 @@ end
local rules_down = {{ x = 0, y = 1, z = 0, spread = true }}
local rules_up = {{ x = 0, y = -1, z = 0, spread = true }}
+function mcl_observers.observer_activate(pos)
+ minetest.after(mcl_vars.redstone_tick, function(pos)
+ node = minetest.get_node(pos)
+ if not node then
+ return
+ end
+ local nn = node.name
+ if nn == "mcl_observers:observer_off" then
+ minetest.set_node(pos, {name = "mcl_observers:observer_on", param2 = node.param2})
+ mesecon.receptor_on(pos, get_rules_flat(node))
+ elseif nn == "mcl_observers:observer_down_off" then
+ minetest.set_node(pos, {name = "mcl_observers:observer_down_on"})
+ mesecon.receptor_on(pos, rules_down)
+ elseif nn == "mcl_observers:observer_up_off" then
+ minetest.set_node(pos, {name = "mcl_observers:observer_up_on"})
+ mesecon.receptor_on(pos, rules_up)
+ end
+ end, {x=pos.x, y=pos.y, z=pos.z})
+end
+
-- Scan the node in front of the observer
-- and update the observer state if needed.
-- TODO: Also scan metadata changes.
@@ -34,7 +62,7 @@ local observer_scan = function(pos, initialize)
local oldparam2 = meta:get_string("node_param2")
local meta_needs_updating = false
if oldnode ~= "" and not initialize then
- if not (frontnode.name == oldnode and frontnode.param2) then
+ if not (frontnode.name == oldnode and tostring(frontnode.param2) == oldparam2) then
-- Node state changed! Activate observer
if node.name == "mcl_observers:observer_off" then
minetest.set_node(pos, {name = "mcl_observers:observer_on", param2 = node.param2})
@@ -53,7 +81,7 @@ local observer_scan = function(pos, initialize)
end
if meta_needs_updating then
meta:set_string("node_name", frontnode.name)
- meta:set_string("node_param2", frontnode.param2)
+ meta:set_string("node_param2", tostring(frontnode.param2))
end
return frontnode
end
@@ -102,7 +130,9 @@ mesecon.register_node("mcl_observers:observer",
rules = get_rules_flat,
}},
on_construct = function(pos)
- observer_scan(pos, true)
+ if not realtime then
+ observer_scan(pos, true)
+ end
end,
after_place_node = observer_orientate,
},
@@ -122,8 +152,7 @@ mesecon.register_node("mcl_observers:observer",
-- VERY quickly disable observer after construction
on_construct = function(pos)
local timer = minetest.get_node_timer(pos)
- -- 1 redstone tick = 0.1 seconds
- timer:start(0.1)
+ timer:start(mcl_vars.redstone_tick)
end,
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
@@ -154,7 +183,9 @@ mesecon.register_node("mcl_observers:observer_down",
rules = rules_down,
}},
on_construct = function(pos)
- observer_scan(pos, true)
+ if not realtime then
+ observer_scan(pos, true)
+ end
end,
},
{
@@ -172,8 +203,7 @@ mesecon.register_node("mcl_observers:observer_down",
-- VERY quickly disable observer after construction
on_construct = function(pos)
local timer = minetest.get_node_timer(pos)
- -- 1 redstone tick = 0.1 seconds
- timer:start(0.1)
+ timer:start(mcl_vars.redstone_tick)
end,
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
@@ -203,7 +233,9 @@ mesecon.register_node("mcl_observers:observer_up",
rules = rules_up,
}},
on_construct = function(pos)
- observer_scan(pos, true)
+ if not realtime then
+ observer_scan(pos, true)
+ end
end,
},
{
@@ -221,8 +253,7 @@ mesecon.register_node("mcl_observers:observer_up",
-- VERY quickly disable observer after construction
on_construct = function(pos)
local timer = minetest.get_node_timer(pos)
- -- 1 redstone tick = 0.1 seconds
- timer:start(0.1)
+ timer:start(mcl_vars.redstone_tick)
end,
on_timer = function(pos, elapsed)
minetest.set_node(pos, {name = "mcl_observers:observer_up_off"})
@@ -230,22 +261,6 @@ mesecon.register_node("mcl_observers:observer_up",
end,
})
-
-
-
--- Regularily check the observer nodes.
--- TODO: This is rather slow and clunky. Find a more efficient way to do this.
-minetest.register_abm({
- label = "Observer node check",
- nodenames = {"mcl_observers:observer_off", "mcl_observers:observer_down_off", "mcl_observers:observer_up_off"},
- interval = 1,
- chance = 1,
- action = function(pos, node)
- observer_scan(pos)
- end,
-})
-
-
minetest.register_craft({
output = "mcl_observers:observer_off",
recipe = {
@@ -263,3 +278,154 @@ minetest.register_craft({
}
})
+if realtime then
+ -- Override basic functions for observing:
+ mcl_observers.add_node = minetest.add_node
+ mcl_observers.set_node = minetest.set_node
+ mcl_observers.swap_node = minetest.swap_node
+ mcl_observers.remove_node = minetest.remove_node
+
+ minetest.add_node=function(pos,node)
+ mcl_observers.add_node(pos,node)
+ local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then
+ mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then
+ mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z})
+ end
+ end
+ minetest.set_node=function(pos,node)
+ mcl_observers.set_node(pos,node)
+ local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then
+ mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then
+ mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z})
+ end
+ end
+ minetest.swap_node=function(pos,node)
+ mcl_observers.swap_node(pos,node)
+ local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then
+ mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then
+ mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z})
+ end
+ end
+ minetest.remove_node=function(pos)
+ mcl_observers.remove_node(pos)
+ local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then
+ mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then
+ mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z})
+ end
+ n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
+ if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then
+ mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z})
+ end
+ end
+
+else -- if realtime then ^^^ else:
+ minetest.register_abm({
+ label = "Observer node check",
+ nodenames = {"mcl_observers:observer_off", "mcl_observers:observer_down_off", "mcl_observers:observer_up_off"},
+ interval = 1,
+ chance = 1,
+ action = function(pos, node)
+ observer_scan(pos)
+ end,
+ })
+end
+--[[
+ With the following code the observer will detect loading of areas where it is placed.
+ We need to restore signal generated by it before the area was unloaded.
+
+ Observer movement and atomic clock (one observer watches another) fails without this often.
+
+ But it WILL cause wrong single signal for all other cases, and I hope it's nothing.
+ After all, why it can't detect the loading of areas, if we haven't a better solution...
+]]
+minetest.register_lbm({
+ name = "mcl_observers:activate_lbm",
+ nodenames = {
+ "mcl_observers:observer_off",
+ "mcl_observers:observer_down_off",
+ "mcl_observers:observer_up_off",
+ "mcl_observers:observer_on",
+ "mcl_observers:observer_down_on",
+ "mcl_observers:observer_up_on",
+ },
+ run_at_every_load = true,
+ action = function(pos)
+ minetest.after(1, mcl_observers.observer_activate, {x=pos.x, y=pos.y, z=pos.z})
+ end,
+})
diff --git a/mods/ITEMS/REDSTONE/mesecons_button/README.md b/mods/ITEMS/REDSTONE/mesecons_button/README.md
new file mode 100644
index 0000000000..31a1fa9de8
--- /dev/null
+++ b/mods/ITEMS/REDSTONE/mesecons_button/README.md
@@ -0,0 +1,16 @@
+Mesecons button mod.
+This mod adds the buttons for MineClone 2.
+
+MEDIA FILE CREDITS:
+
+`mesecons_button_push.ogg`
+ * Author: junggle
+ * License: CC BY 3.0
+ * Original name: `btn121.ogg`, created on January 16th, 2007
+ * Source:
+`mesecons_button_push_wood.ogg`
+ * Author: junggle
+ * License: (CC BY 3.0
+ * Original name: `btn314.ogg`, created on January 16th, 2007
+ * Sound file was modified
+ * Source:
diff --git a/mods/ITEMS/REDSTONE/mesecons_button/init.lua b/mods/ITEMS/REDSTONE/mesecons_button/init.lua
index 5ff15eccb4..377a24c00a 100644
--- a/mods/ITEMS/REDSTONE/mesecons_button/init.lua
+++ b/mods/ITEMS/REDSTONE/mesecons_button/init.lua
@@ -3,6 +3,8 @@
local S = minetest.get_translator("mesecons_button")
+local button_sounds = {} -- remember button push sounds
+
local button_get_output_rules = mesecon.rules.wallmounted_get
local boxes_off = {
@@ -27,7 +29,10 @@ mesecon.push_button = function(pos, node)
local def = minetest.registered_nodes[node.name]
minetest.set_node(pos, {name="mesecons_button:button_"..def._mcl_button_basename.."_on", param2=node.param2})
mesecon.receptor_on(pos, button_get_output_rules(node))
- minetest.sound_play("mesecons_button_push", {pos=pos}, true)
+ local sfx = button_sounds[node.name]
+ if sfx then
+ minetest.sound_play(sfx, {pos=pos}, true)
+ end
local timer = minetest.get_node_timer(pos)
timer:start(def._mcl_button_timer)
end
@@ -81,7 +86,7 @@ end
local buttonuse = S("Use the button to push it.")
-mesecon.register_button = function(basename, description, texture, recipeitem, sounds, plusgroups, button_timer, push_by_arrow, longdesc)
+mesecon.register_button = function(basename, description, texture, recipeitem, sounds, plusgroups, button_timer, push_by_arrow, longdesc, button_sound)
local groups_off = table.copy(plusgroups)
groups_off.attached_node=1
groups_off.dig_by_water=1
@@ -93,6 +98,11 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s
groups_on.not_in_creative_inventory=1
groups_on.button=2 -- button (on)
+ if not button_sound then
+ button_sound = "mesecons_button_push"
+ end
+ button_sounds["mesecons_button:button_"..basename.."_off"] = button_sound
+
if push_by_arrow then
groups_off.button_push_by_arrow = 1
groups_on.button_push_by_arrow = 1
@@ -179,7 +189,7 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s
-- Normal operation: Un-press the button
minetest.set_node(pos, {name="mesecons_button:button_"..basename.."_off",param2=node.param2})
- minetest.sound_play("mesecons_button_pop", {pos=pos}, true)
+ minetest.sound_play(button_sound, {pos=pos, pitch=0.9}, true)
mesecon.receptor_off(pos, button_get_output_rules(node))
end
end,
@@ -203,7 +213,8 @@ mesecon.register_button(
{material_stone=1,handy=1,pickaxey=1},
1,
false,
- S("A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second."))
+ S("A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second."),
+ "mesecons_button_push")
local woods = {
{ "wood", "mcl_core:wood", "default_wood.png", S("Oak Button") },
@@ -224,7 +235,8 @@ for w=1, #woods do
{material_wood=1,handy=1,axey=1},
1.5,
true,
- S("A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows."))
+ S("A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows."),
+ "mesecons_button_push_wood")
minetest.register_craft({
type = "fuel",
diff --git a/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_pop.ogg b/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_pop.ogg
deleted file mode 100644
index 9d56bb8c27..0000000000
Binary files a/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_pop.ogg and /dev/null differ
diff --git a/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push.ogg b/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push.ogg
index 53d45c18af..5ddc1932d4 100644
Binary files a/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push.ogg and b/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push.ogg differ
diff --git a/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push_wood.ogg b/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push_wood.ogg
new file mode 100644
index 0000000000..23f53c4042
Binary files /dev/null and b/mods/ITEMS/REDSTONE/mesecons_button/sounds/mesecons_button_push_wood.ogg differ
diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua
index 8319ce2101..a9a11bce53 100644
--- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua
+++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua
@@ -6,6 +6,8 @@ mesecon.mvps_droppers = {}
mesecon.on_mvps_move = {}
mesecon.mvps_unmov = {}
+local is_protected = minetest.is_protected
+
--- Objects (entities) that cannot be moved
function mesecon.register_mvps_unmov(objectname)
mesecon.mvps_unmov[objectname] = true;
@@ -34,25 +36,13 @@ function mesecon.register_mvps_dropper(nodename, get_dropper)
end
-- Nodes that cannot be pushed / pulled by movestones, pistons
-function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
+function mesecon.is_mvps_stopper(node)
-- unknown nodes are always stoppers
- if not minetest.registered_nodes[node.name] then
- return true
- end
-
- local get_stopper = mesecon.mvps_stoppers[node.name]
- if type (get_stopper) == "function" then
- get_stopper = get_stopper(node, pushdir, stack, stackid)
- end
-
- return get_stopper
+ return mesecon.mvps_stoppers[node.name] or not minetest.registered_nodes[node.name]
end
-function mesecon.register_mvps_stopper(nodename, get_stopper)
- if get_stopper == nil then
- get_stopper = true
- end
- mesecon.mvps_stoppers[nodename] = get_stopper
+function mesecon.register_mvps_stopper(nodename)
+ mesecon.mvps_stoppers[nodename] = true
end
-- For nodes which ignore sticky sides.
@@ -112,7 +102,31 @@ local function node_replaceable(name)
return false
end
-function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
+local function is_available(pos)
+ local n = minetest.get_node(pos)
+ if not n then
+ return false, n
+ end
+ local name = n.name
+ if name == "ignore" then
+ minetest.get_voxel_manip():read_from_map(pos, pos)
+ n = minetest.get_node(pos)
+ if not n then
+ return false, n
+ end
+ name = n.name
+ end
+ if name == "ignore" then
+ return false, n
+ end
+ if minetest.registered_nodes[name] then
+ return minetest.registered_nodes[name].buildable_to, n or false, n
+ end
+ return false, n
+end
+
+
+function mesecon.mvps_get_stack(pos, dir, maximum, piston_pos)
-- determine the number of nodes to be pushed
local nodes = {}
local frontiers = {pos}
@@ -124,8 +138,13 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
minetest.get_voxel_manip():read_from_map(np, np)
nn = minetest.get_node(np)
end
+
+ if mesecon.is_mvps_stopper(nn) then
+ return
+ end
+
if not node_replaceable(nn.name) then
- if #nodes >= maximum then return nil end
+ if #nodes >= maximum then return nil, false end
table.insert(nodes, {node = nn, pos = np})
-- add connected nodes to frontiers, connected is a vector list
@@ -133,33 +152,13 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
local connected = {}
if minetest.registered_nodes[nn.name]
and minetest.registered_nodes[nn.name].mvps_sticky then
- connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
- end
-
- table.insert(connected, vector.add(np, dir))
-
- -- If adjacent node is sticky block and connects add that
- -- position to the connected table
- for _, r in ipairs(mesecon.rules.alldirs) do
- local adjpos = vector.add(np, r)
- local adjnode = minetest.get_node(adjpos)
- if minetest.registered_nodes[adjnode.name]
- and minetest.registered_nodes[adjnode.name].mvps_sticky then
- local sticksto = minetest.registered_nodes[adjnode.name]
- .mvps_sticky(adjpos, adjnode)
-
- -- connects to this position?
- for _, link in ipairs(sticksto) do
- if vector.equals(link, np) then
- table.insert(connected, adjpos)
- end
- end
+ connected, has_loop = minetest.registered_nodes[nn.name].mvps_sticky(np, nn, piston_pos)
+ if has_loop then
+ return {}, true
end
end
- if all_pull_sticky then
- table.insert(connected, vector.subtract(np, dir))
- end
+ table.insert(connected, vector.add(np, dir))
-- Make sure there are no duplicates in frontiers / nodes before
-- adding nodes in "connected" to frontiers
@@ -175,7 +174,7 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
duplicate = true
end
end
- if not duplicate then
+ if not duplicate and not mesecon.is_mvps_stopper(minetest.get_node(cp)) then
table.insert(frontiers, cp)
end
end
@@ -183,34 +182,74 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
table.remove(frontiers, 1)
end
- return nodes
+ return nodes, false
end
-function mesecon.mvps_push(pos, dir, maximum)
- return mesecon.mvps_push_or_pull(pos, dir, dir, maximum, nil, false)
+function mesecon.mvps_set_owner(pos, placer)
+ local meta = minetest.get_meta(pos)
+ local owner = placer and placer.get_player_name and placer:get_player_name()
+ if owner and owner ~= "" then
+ meta:set_string("owner", owner)
+ else
+ meta:set_string("owner", "$unknown") -- to distinguish from older pistons
+ end
end
-function mesecon.mvps_pull_all(pos, dir, maximum)
- return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true, true)
+local function are_protected(positions, player_name)
+ local name = player_name
+ for _, pos in pairs(positions) do
+ if is_protected(pos, name) then
+ return true
+ end
+ end
+ return false
end
-function mesecon.mvps_pull_single(pos, dir, maximum)
- return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, nil, true)
+function mesecon.mvps_push(pos, dir, maximum, player_name, piston_pos)
+ return mesecon.mvps_push_or_pull(pos, dir, dir, maximum, player_name, piston_pos)
+end
+
+function mesecon.mvps_pull_single(pos, dir, maximum, player_name, piston_pos)
+ return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, player_name, piston_pos)
end
-- pos: pos of mvps; stackdir: direction of building the stack
-- movedir: direction of actual movement
-- maximum: maximum nodes to be pushed
--- all_pull_sticky: All nodes are sticky in the direction that they are pulled from
-function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky)
- local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
+function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, piston_pos)
+ local nodes, has_loop = mesecon.mvps_get_stack(pos, movedir, maximum, piston_pos)
+
+ if has_loop then
+ return false
+ end
if not nodes then return end
- -- determine if one of the nodes blocks the push / pull
- for id, n in ipairs(nodes) do
- if mesecon.is_mvps_stopper(n.node, movedir, nodes, id) then
+
+ local newpos={}
+ -- check node availability to push/pull into, and fill newpos[i]
+ for i in ipairs(nodes) do
+ newpos[i] = vector.add(nodes[i].pos, movedir)
+ if (newpos[i].x == piston_pos.x) and (newpos[i].y == piston_pos.y) and (newpos[i].z == piston_pos.z) then
return
end
+ if not is_available(newpos[i]) then
+ local available = false
+ for j in ipairs(nodes) do
+ if i ~= j then
+ if (newpos[i].x == nodes[j].pos.x) and (newpos[i].y == nodes[j].pos.y) and (newpos[i].z == nodes[j].pos.z) then
+ available = true
+ break
+ end
+ end
+ end
+ if not available then
+ return
+ end
+ end
+ end
+
+ if are_protected(nodes, player_name) then
+ return
end
local first_dropper = nil
@@ -223,6 +262,10 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
minetest.dig_node(n.pos)
else
minetest.remove_node(n.pos)
+ local node_timer = minetest.get_node_timer(n.pos)
+ if node_timer:is_started() then
+ n.node_timer = {node_timer:get_timeout(), node_timer:get_elapsed()}
+ end
end
if is_dropper then
first_dropper = id
@@ -243,9 +286,16 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
if first_dropper and id >= first_dropper then
break
end
- local np = vector.add(n.pos, movedir)
+ local np = newpos[id]
minetest.add_node(np, n.node)
minetest.get_meta(np):from_table(n.meta)
+ if n.node_timer then
+ minetest.get_node_timer(np):set(unpack(n.node_timer))
+ end
+ if string.find(n.node.name, "mcl_observers:observer") then
+ -- It also counts as a block update when the observer itself is moved by a piston (Wiki):
+ mcl_observers.observer_activate(np)
+ end
end
local moved_nodes = {}
@@ -256,10 +306,11 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
end
moved_nodes[i] = {}
moved_nodes[i].oldpos = nodes[i].pos
- nodes[i].pos = vector.add(nodes[i].pos, movedir)
+ nodes[i].pos = newpos[i]
moved_nodes[i].pos = nodes[i].pos
moved_nodes[i].node = nodes[i].node
moved_nodes[i].meta = nodes[i].meta
+ moved_nodes[i].node_timer = nodes[i].node_timer
end
on_mvps_move(moved_nodes)
diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/template.txt
index d0daa96a68..2bc0e2b462 100644
--- a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/template.txt
+++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/template.txt
@@ -7,16 +7,16 @@ Use the note block to choose the next musical note (there are 25 semitones, or 2
• Stone: Bass drum=
• Sand or gravel: Snare drum=
• Anything else: Piano=
-• Block of Gold: Bell
-• Clay: Flute
-• Packed Ice: Chime
-• Wool: Guitar
-• Bone Block: Xylophne
-• Block of Iron: Iron xylophne
-• Soul Sand: Cow bell
-• Pumpkin: Didgeridoo
-• Block of Emerald: Square wave
-• Hay Bale: Banjo
-• Glowstone: Electric piano
+• Block of Gold: Bell=
+• Clay: Flute=
+• Packed Ice: Chime=
+• Wool: Guitar=
+• Bone Block: Xylophne=
+• Block of Iron: Iron xylophne=
+• Soul Sand: Cow bell=
+• Pumpkin: Didgeridoo=
+• Block of Emerald: Square wave=
+• Hay Bale: Banjo=
+• Glowstone: Electric piano=
The note block will only play a note when it is below air, otherwise, it stays silent.=
Plays a musical note when powered by redstone power=
diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua
index eb69d33800..fba702ede4 100644
--- a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua
+++ b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua
@@ -94,10 +94,11 @@ local piston_on = function (pos, node)
local dir = piston_get_direction(pistonspec.dir, node)
local np = vector.add(pos, dir)
- local success, stack, oldstack = mesecon.mvps_push(np, dir, PISTON_MAXIMUM_PUSH)
+ local meta = minetest.get_meta(pos)
+ local success, stack, oldstack = mesecon.mvps_push(np, dir, PISTON_MAXIMUM_PUSH, meta:get_string("owner"), pos)
if success then
- minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname})
- minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher})
+ minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
+ minetest.set_node(np, {param2 = node.param2, name = pistonspec.pusher})
local below = minetest.get_node({x=np.x,y=np.y-1,z=np.z})
if below.name == "mcl_farming:soil" or below.name == "mcl_farming:soil_wet" then
minetest.set_node({x=np.x,y=np.y-1,z=np.z}, {name = "mcl_core:dirt"})
@@ -116,16 +117,22 @@ local piston_off = function (pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.offname})
piston_remove_pusher (pos, node)
+ if not pistonspec.sticky then
+ return
+ end
- if pistonspec.sticky then
- local dir = piston_get_direction(pistonspec.dir, node)
- local pullpos = vector.add(pos, vector.multiply(dir, 2))
- local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), PISTON_MAXIMUM_PUSH)
+ local dir = piston_get_direction(pistonspec.dir, node)
+ local pullpos = vector.add(pos, vector.multiply(dir, 2))
+ local meta = minetest.get_meta(pos)
+ local success, stack, oldstack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), PISTON_MAXIMUM_PUSH, meta:get_string("owner"), pos)
+ if success then
mesecon.mvps_process_stack(pos, dir, stack)
end
end
local piston_orientate = function (pos, placer)
+ mesecon.mvps_set_owner(pos, placer)
+
-- not placed by player
if not placer then return end
@@ -812,75 +819,18 @@ minetest.register_node("mesecons_pistons:piston_down_pusher_sticky", {
})
--- Register pushers as stoppers if they would be seperated from the piston
-local piston_pusher_get_stopper = function (node, dir, stack, stackid)
- if (stack[stackid + 1]
- and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].corresponding_piston
- and stack[stackid + 1].node.param2 == node.param2)
- or (stack[stackid - 1]
- and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].corresponding_piston
- and stack[stackid - 1].node.param2 == node.param2) then
- return false
- end
- return true
-end
-
-local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
- if (stack[stackid + 1]
- and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].corresponding_piston)
- or (stack[stackid - 1]
- and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].corresponding_piston) then
- return false
- end
- return true
-end
-
-mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
-mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
-
-mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper)
-mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper)
-
-mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper)
-mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper)
-
-
--- Register pistons as stoppers if they would be seperated from the stopper
-local piston_up_down_get_stopper = function (node, dir, stack, stackid)
- if (stack[stackid + 1]
- and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].mesecons_piston.pusher)
- or (stack[stackid - 1]
- and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].mesecons_piston.pusher) then
- return false
- end
- return true
-end
-
-local piston_get_stopper = function (node, dir, stack, stackid)
- local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
- dir = piston_get_direction(pistonspec.dir, node)
- local pusherpos = vector.add(stack[stackid].pos, dir)
- local pushernode = minetest.get_node(pusherpos)
-
- if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
- for _, s in ipairs(stack) do
- if vector.equals(s.pos, pusherpos) -- pusher is also to be pushed
- and s.node.param2 == node.param2 then
- return false
- end
- end
- end
- return true
-end
-
-mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
-mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
-
-mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper)
-mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper)
-
-mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper)
-mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper)
+mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on")
+mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on")
--craft recipes
minetest.register_craft({
diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua b/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua
index 053990ed41..f73ee0387e 100644
--- a/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua
+++ b/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua
@@ -53,7 +53,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
on_rightclick = function (pos, node)
minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_on", param2=node.param2})
mesecon.receptor_on(pos, lever_get_output_rules(node))
- minetest.sound_play("mesecons_lever", {pos=pos}, true)
+ minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16}, true)
end,
node_placement_prediction = "",
on_place = function(itemstack, placer, pointed_thing)
@@ -152,7 +152,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
on_rightclick = function (pos, node)
minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_off", param2=node.param2})
mesecon.receptor_off(pos, lever_get_output_rules(node))
- minetest.sound_play("mesecons_lever", {pos=pos}, true)
+ minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16, pitch=0.9}, true)
end,
sounds = mcl_sounds.node_sound_stone_defaults(),
mesecons = {receptor = {
diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/sounds/mesecons_lever.ogg b/mods/ITEMS/REDSTONE/mesecons_walllever/sounds/mesecons_lever.ogg
deleted file mode 100644
index 53d45c18af..0000000000
Binary files a/mods/ITEMS/REDSTONE/mesecons_walllever/sounds/mesecons_lever.ogg and /dev/null differ
diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua
index 20ac848dc3..df1a2317b0 100644
--- a/mods/ITEMS/mcl_beds/functions.lua
+++ b/mods/ITEMS/mcl_beds/functions.lua
@@ -210,11 +210,11 @@ end
local function update_formspecs(finished, ges)
local ges = ges or #minetest.get_connected_players()
- local form_n = "size[6,5;true]"
+ local form_n = "size[12,5;true]"
local all_in_bed = ges == player_in_bed
local night_skip = is_night_skip_enabled()
- local button_leave = "button_exit[1,3;4,0.75;leave;"..F(S("Leave bed")).."]"
- local button_abort = "button_exit[1,3;4,0.75;leave;"..F(S("Abort sleep")).."]"
+ local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]"
+ local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]"
local bg_presleep = "bgcolor[#00000080;true]"
local bg_sleep = "bgcolor[#000000FF;true]"
@@ -238,7 +238,7 @@ local function update_formspecs(finished, ges)
form_n = form_n .. bg_presleep
form_n = form_n .. button_leave
end
- form_n = form_n .. "label[1,1;"..F(text).."]"
+ form_n = form_n .. "label[0.5,1;"..F(text).."]"
else
local text
if night_skip then
@@ -250,7 +250,7 @@ local function update_formspecs(finished, ges)
form_n = form_n .. bg_presleep
form_n = form_n .. button_leave
end
- form_n = form_n .. "label[1,1;"..F(text).."]"
+ form_n = form_n .. "label[0.5,1;"..F(text).."]"
end
for name,_ in pairs(mcl_beds.player) do
diff --git a/mods/ITEMS/mcl_beds/locale/template.txt b/mods/ITEMS/mcl_beds/locale/template.txt
index d18fbe5deb..8301dfa335 100644
--- a/mods/ITEMS/mcl_beds/locale/template.txt
+++ b/mods/ITEMS/mcl_beds/locale/template.txt
@@ -1,7 +1,7 @@
# textdomain: mcl_beds
Beds allow you to sleep at night and make the time pass faster.=
To use a bed, stand close to it and right-click the bed to sleep in it. Sleeping only works when the sun sets, at night or during a thunderstorm. The bed must also be clear of any danger.=
-You have heard of other worlds in which a bed would set the start point for your next life. But this world is not one of them.
+You have heard of other worlds in which a bed would set the start point for your next life. But this world is not one of them.=
By using a bed, you set the starting point for your next life. If you die, you will start your next life at this bed, unless it is obstructed or destroyed.=
In this world, going to bed won't skip the night, but it will skip thunderstorms.=
Sleeping allows you to skip the night. The night is skipped when all players in this world went to sleep. The night is skipped after sleeping for a few seconds. Thunderstorms can be skipped in the same manner.=
diff --git a/mods/ITEMS/mcl_bows/README.txt b/mods/ITEMS/mcl_bows/README.txt
index 5660f922bc..fe879c95cf 100644
--- a/mods/ITEMS/mcl_bows/README.txt
+++ b/mods/ITEMS/mcl_bows/README.txt
@@ -7,7 +7,10 @@ License:
* Textures: See MineClone 2 license notes.
* Sounds:
- * mcl_bows_bow_shoot.ogg: MIT License
+ * mcl_bows_bow_shoot.ogg: CC0 by Freesound.org user JoeDinesSound
+ https://freesound.org/people/JoeDinesSound/sounds/534942/
+ * mcl_bows_hit_other.ogg: CC0 by Freesound.org user JoeDinesSound
+ https://freesound.org/people/JoeDinesSound/sounds/534952/
* mcl_bows_hit_player.ogg: CC BY 3.0 by Freesound.org user tim.kahn.
https://freesound.org/people/tim.kahn/sounds/38495/
http://creativecommons.org/licenses/by/3.0/
diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua
index 1bc17354cd..bc95fdb4fe 100644
--- a/mods/ITEMS/mcl_bows/arrow.lua
+++ b/mods/ITEMS/mcl_bows/arrow.lua
@@ -254,7 +254,7 @@ ARROW_ENTITY.on_step = function(self, dtime)
if is_player then
if self._shooter and self._shooter:is_player() then
-- “Ding” sound for hitting another player
- minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter}, true)
+ minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true)
end
end
@@ -269,6 +269,7 @@ ARROW_ENTITY.on_step = function(self, dtime)
end
end
end
+ minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true)
end
self.object:remove()
return
@@ -320,6 +321,8 @@ ARROW_ENTITY.on_step = function(self, dtime)
self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration({x=0, y=0, z=0})
+ minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true)
+
-- Push the button! Push, push, push the button!
if mod_button and minetest.get_item_group(node.name, "button") > 0 and minetest.get_item_group(node.name, "button_push_by_arrow") == 1 then
local bdir = minetest.wallmounted_to_dir(node.param2)
diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua
index 6e41007cdb..d4c5fb081d 100644
--- a/mods/ITEMS/mcl_bows/bow.lua
+++ b/mods/ITEMS/mcl_bows/bow.lua
@@ -60,7 +60,7 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag
le._is_critical = is_critical
le._startpos = pos
le._knockback = knockback
- minetest.sound_play("mcl_bows_bow_shoot", {pos=pos}, true)
+ minetest.sound_play("mcl_bows_bow_shoot", {pos=pos, max_hear_distance=16}, true)
if shooter ~= nil and shooter:is_player() then
if obj:get_luaentity().player == "" then
obj:get_luaentity().player = shooter
@@ -128,11 +128,9 @@ S("The speed and damage of the arrow increases the longer you charge. The regula
inventory_image = "mcl_bows_bow.png",
wield_scale = { x = 1.8, y = 1.8, z = 1 },
stack_max = 1,
- -- Trick to disable melee damage to entities.
- -- Range not set to 0 (unlike the others) so it can be placed into item frames
- range = 1,
+ range = 4,
-- Trick to disable digging as well
- on_use = function() end,
+ on_use = function() return end,
groups = {weapon=1,weapon_ranged=1,bow=1,enchantability=1},
})
@@ -174,6 +172,8 @@ for level=0, 2 do
stack_max = 1,
range = 0, -- Pointing range to 0 to prevent punching with bow :D
groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1},
+ -- Trick to disable digging as well
+ on_use = function() return end,
on_drop = function(itemstack, dropper, pos)
reset_bow_state(dropper)
if mcl_enchanting.is_enchanted(itemstack:get_name()) then
diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_bow_shoot.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_bow_shoot.ogg
index c8911e5fed..ca8b0f7186 100644
Binary files a/mods/ITEMS/mcl_bows/sounds/mcl_bows_bow_shoot.ogg and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_bow_shoot.ogg differ
diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_hit_other.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_hit_other.ogg
new file mode 100644
index 0000000000..6956e4d8dd
Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_hit_other.ogg differ
diff --git a/mods/ITEMS/mcl_brewing/init.lua b/mods/ITEMS/mcl_brewing/init.lua
index b27c9cf37e..7725acdfdb 100644
--- a/mods/ITEMS/mcl_brewing/init.lua
+++ b/mods/ITEMS/mcl_brewing/init.lua
@@ -965,7 +965,7 @@ minetest.register_node("mcl_brewing:stand_111", {
})
minetest.register_craft({
- output = "mcl_brewing:stand",
+ output = "mcl_brewing:stand_000",
recipe = {
{ "", "mcl_mobitems:blaze_rod", "" },
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr
new file mode 100644
index 0000000000..232026fbaa
--- /dev/null
+++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr
@@ -0,0 +1,10 @@
+# textdomain: mcl_brewing
+Brewing Stand=Alambic
+Inventory=Inventaire
+To use a brewing stand, rightclick it.=Pour utiliser un alambic, faites un clic droit dessus.
+To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Pour distiller, vous avez besoin de poudre de blaze comme carburant, d'un ingrédient à distiller et d'au moins 1 bouteille en verre remplie d'un liquide.
+Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Placez la poudre de blaze dans l'emplacement de gauche, l'ingrédient à distiller dans l'emplacement du milieu et 1 à 3 bouteilles dans les emplacements restantes.
+When you have found a good combination, the brewing will commence automatically and steam starts to appear, using up the fuel and brewing material. The potions will soon be ready.=Lorsque vous avez trouvé une bonne combinaison, la distillation commencera automatiquement et de la vapeur commencera à apparaître, consommant le carburant et l'ingrédient à distiller. Les potions seront bientôt prêtes.
+Different combinations of brewing materials and liquids will give different results. Try to experiment!=Différentes combinaisons d'ingrédients et de liquides donneront des résultats différents. Essayez d'expérimenter!
+The stand allows you to brew potions!=L'alambic permet de produire des potions!
+Brew Potions=Potions
diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua
index 847b970010..0d9a1f6011 100644
--- a/mods/ITEMS/mcl_core/functions.lua
+++ b/mods/ITEMS/mcl_core/functions.lua
@@ -1416,7 +1416,7 @@ function mcl_core.check_vines_supported(pos, node)
return supported
end
--- Melt ice at pos. mcl_core:ice MUST be a post if you call this!
+-- Melt ice at pos. mcl_core:ice MUST be at pos if you call this!
function mcl_core.melt_ice(pos)
-- Create a water source if ice is destroyed and there was something below it
local below = {x=pos.x, y=pos.y-1, z=pos.z}
@@ -1427,6 +1427,17 @@ function mcl_core.melt_ice(pos)
else
minetest.remove_node(pos)
end
+ local neighbors = {
+ {x=-1, y=0, z=0},
+ {x=1, y=0, z=0},
+ {x=0, y=-1, z=0},
+ {x=0, y=1, z=0},
+ {x=0, y=0, z=-1},
+ {x=0, y=0, z=1},
+ }
+ for n=1, #neighbors do
+ minetest.check_single_for_falling(vector.add(pos, neighbors[n]))
+ end
end
---- FUNCTIONS FOR SNOWED NODES ----
diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua
index f9ac0e01e1..82ce39e1ab 100644
--- a/mods/ITEMS/mcl_core/nodes_base.lua
+++ b/mods/ITEMS/mcl_core/nodes_base.lua
@@ -363,7 +363,7 @@ minetest.register_node("mcl_core:dirt_with_grass", {
groups = {handy=1,shovely=1,dirt=2,grass_block=1, grass_block_no_snow=1, soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, spreading_dirt_type=1, enderman_takable=1, building_block=1},
drop = 'mcl_core:dirt',
sounds = mcl_sounds.node_sound_dirt_defaults({
- footstep = {name="default_grass_footstep", gain=0.4},
+ footstep = {name="default_grass_footstep", gain=0.1},
}),
on_construct = function(pos)
local node = minetest.get_node(pos)
@@ -399,7 +399,7 @@ minetest.register_node("mcl_core:grass_path", {
},
groups = {handy=1,shovely=1, cultivatable=2, dirtifies_below_solid=1, dirtifier=1, deco_block=1 },
sounds = mcl_sounds.node_sound_dirt_defaults({
- footstep = {name="default_grass_footstep", gain=0.4},
+ footstep = {name="default_grass_footstep", gain=0.1},
}),
_mcl_blast_resistance = 0.65,
_mcl_hardness = 0.6,
@@ -415,7 +415,7 @@ minetest.register_node("mcl_core:mycelium", {
groups = {handy=1,shovely=1, dirt=2,spreading_dirt_type=1, enderman_takable=1, building_block=1},
drop = 'mcl_core:dirt',
sounds = mcl_sounds.node_sound_dirt_defaults({
- footstep = {name="default_grass_footstep", gain=0.4},
+ footstep = {name="default_grass_footstep", gain=0.1},
}),
on_construct = mcl_core.on_snowable_construct,
diff --git a/mods/ITEMS/mcl_core/nodes_cactuscane.lua b/mods/ITEMS/mcl_core/nodes_cactuscane.lua
index 277cc565f3..9c0077ea2f 100644
--- a/mods/ITEMS/mcl_core/nodes_cactuscane.lua
+++ b/mods/ITEMS/mcl_core/nodes_cactuscane.lua
@@ -87,24 +87,26 @@ minetest.register_node("mcl_core:reeds", {
-- Placement rules:
-- * On top of group:soil_sugarcane AND next to water or frosted ice. OR
-- * On top of sugar canes
+ -- * Not inside liquid
if snn == "mcl_core:reeds" then
return true
elseif minetest.get_item_group(snn, "soil_sugarcane") == 0 then
return false
end
+ local place_node = minetest.get_node(place_pos)
+ local pdef = minetest.registered_nodes[place_node.name]
+ if pdef and pdef.liquidtype ~= "none" then
+ return false
+ end
- local posses = {
- { x=0, y=0, z=1},
- { x=0, y=0, z=-1},
- { x=1, y=0, z=0},
- { x=-1, y=0, z=0},
- }
- for p=1, #posses do
- local checknode = minetest.get_node(vector.add(soil_pos, posses[p]))
- if minetest.get_item_group(checknode.name, "water") ~= 0 or minetest.get_item_group(checknode.name, "frosted_ice") ~= 0 then
- -- Water found! Sugar canes are happy! :-)
- return true
- end
+ -- Legal water position rules are the same as for decoration spawn_by rules.
+ -- This differs from MC, which does not allow diagonal neighbors
+ -- and neighbors 1 layer above.
+ local np1 = {x=soil_pos.x-1, y=soil_pos.y, z=soil_pos.z-1}
+ local np2 = {x=soil_pos.x+1, y=soil_pos.y+1, z=soil_pos.z+1}
+ if #minetest.find_nodes_in_area(np1, np2, {"group:water", "group:frosted_ice"}) > 0 then
+ -- Water found! Sugar canes are happy! :-)
+ return true
end
-- No water found! Sugar canes are not amuzed and refuses to be placed. :-(
diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua
index f9ede7718c..bbfe75668e 100644
--- a/mods/ITEMS/mcl_core/nodes_misc.lua
+++ b/mods/ITEMS/mcl_core/nodes_misc.lua
@@ -6,6 +6,7 @@ local on_rotate
if mod_screwdriver then
on_rotate = screwdriver.rotate_3way
end
+local alldirs = {{x=0,y=0,z=1}, {x=1,y=0,z=0}, {x=0,y=0,z=-1}, {x=-1,y=0,z=0}, {x=0,y=-1,z=0}, {x=0,y=1,z=0}}
minetest.register_node("mcl_core:bone_block", {
description = S("Bone Block"),
@@ -52,14 +53,39 @@ minetest.register_node("mcl_core:slimeblock", {
},
_mcl_blast_resistance = 0,
_mcl_hardness = 0,
- mvps_sticky = function (pos, node)
+ mvps_sticky = function (pos, node, piston_pos)
local connected = {}
- if mesecon.rules.alldirs then
- for _, r in ipairs(mesecon.rules.alldirs) do
- table.insert(connected, vector.add(pos, r))
+ for n, v in ipairs(alldirs) do
+ local neighbor_pos = vector.add(pos, v)
+ local neighbor_node = minetest.get_node(neighbor_pos)
+ if neighbor_node then
+ if neighbor_node.name == "ignore" then
+ minetest.get_voxel_manip():read_from_map(neighbor_pos, neighbor_pos)
+ neighbor_node = minetest.get_node(neighbor_pos)
+ end
+ local name = neighbor_node.name
+ if name ~= "air" and name ~= "ignore" then
+ local piston, piston_side, piston_up, piston_down = false, false, false, false
+ if name == "mesecons_pistons:piston_sticky_off" or name == "mesecons_pistons:piston_normal_off" then
+ piston, piston_side = true, true
+ elseif name == "mesecons_pistons:piston_up_sticky_off" or name == "mesecons_pistons:piston_up_normal_off" then
+ piston, piston_up = true, true
+ elseif name == "mesecons_pistons:piston_down_sticky_off" or name == "mesecons_pistons:piston_down_normal_off" then
+ piston, piston_down = true, true
+ end
+ if not( (piston_side and (n-1==neighbor_node.param2)) or (piston_up and (n==5)) or (piston_down and (n==6)) ) then
+ if piston and piston_pos then
+ if piston_pos.x == neighbor_pos.x and piston_pos.y == neighbor_pos.y and piston_pos.z == neighbor_pos.z then
+ -- Loopback to the same piston! Preventing unwanted behavior:
+ return {}, true
+ end
+ end
+ table.insert(connected, neighbor_pos)
+ end
+ end
end
end
- return connected
+ return connected, false
end,
})
diff --git a/mods/CORE/mcl_enchanting/LICENSE b/mods/ITEMS/mcl_enchanting/LICENSE
similarity index 100%
rename from mods/CORE/mcl_enchanting/LICENSE
rename to mods/ITEMS/mcl_enchanting/LICENSE
diff --git a/mods/CORE/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua
similarity index 83%
rename from mods/CORE/mcl_enchanting/enchantments.lua
rename to mods/ITEMS/mcl_enchanting/enchantments.lua
index 4ed94a0b37..c3bfa05df1 100644
--- a/mods/CORE/mcl_enchanting/enchantments.lua
+++ b/mods/ITEMS/mcl_enchanting/enchantments.lua
@@ -1,3 +1,5 @@
+local S = minetest.get_translator("mcl_enchanting")
+
-- Taken from https://minecraft.gamepedia.com/Enchanting
local function increase_damage(damage_group, factor)
@@ -10,14 +12,14 @@ end
-- requires engine change
--[[mcl_enchanting.enchantments.aqua_affinity = {
- name = "Aqua Affinity",
+ name = S("Aqua Affinity"),
max_level = 1,
primary = {armor_head = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {},
weight = 2,
- description = "Increases underwater mining speed.",
+ description = S("Increases underwater mining speed."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -27,14 +29,14 @@ end
-- implemented via on_enchant and additions in mobs_mc; Slowness IV part unimplemented
mcl_enchanting.enchantments.bane_of_arthropods = {
- name = "Bane of Arthropods",
+ name = S("Bane of Arthropods"),
max_level = 5,
primary = {sword = true},
secondary = {axe = true},
disallow = {},
incompatible = {smite = true, shaprness = true},
weight = 5,
- description = "Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).",
+ description = S("Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites)."),
curse = false,
on_enchant = increase_damage("anthropod", 2.5),
requires_tool = false,
@@ -44,14 +46,14 @@ mcl_enchanting.enchantments.bane_of_arthropods = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.blast_protection = {
- name = "Blast Protection",
+ name = S("Blast Protection"),
max_level = 4,
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {fire_protection = true, protection = true, projectile_protection = true},
weight = 2,
- description = "Reduces explosion damage and knockback.",
+ description = S("Reduces explosion damage and knockback."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -61,14 +63,14 @@ mcl_enchanting.enchantments.blast_protection = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.channeling = {
- name = "Channeling",
+ name = S("Channeling"),
max_level = 1,
primary = {trident = true},
secondary = {},
disallow = {},
incompatible = {riptide = true},
weight = 1,
- description = "Trident \"channels\" a bolt of lightning toward a hit entity. Functions only during thunderstorms and if target is unobstructed with opaque blocks.",
+ description = S("Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -78,14 +80,14 @@ mcl_enchanting.enchantments.blast_protection = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.curse_of_binding = {
- name = "Curse of Binding",
+ name = S("Curse of Binding"),
max_level = 1,
primary = {},
secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
disallow = {},
incompatible = {},
weight = 1,
- description = "Except when in creative mode, items cannot be removed from armor slots except due to death or breaking.",
+ description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."),
curse = true,
on_enchant = function() end,
requires_tool = false,
@@ -95,14 +97,14 @@ mcl_enchanting.enchantments.curse_of_binding = {
-- implemented in mcl_death_drop
mcl_enchanting.enchantments.curse_of_vanishing = {
- name = "Curse of Vanishing",
+ name = S("Curse of Vanishing"),
max_level = 1,
primary = {},
secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true, tool = true, weapon = true},
disallow = {},
incompatible = {},
weight = 1,
- description = "Item destroyed on death.",
+ description = S("Item destroyed on death."),
curse = true,
on_enchant = function() end,
requires_tool = false,
@@ -112,14 +114,14 @@ mcl_enchanting.enchantments.curse_of_vanishing = {
-- unimplemented
--[[mcl_enchanting.enchantments.depth_strider = {
- name = "Depth Strider",
+ name = S("Depth Strider"),
max_level = 3,
primary = {},
secondary = {armor_feet = true},
disallow = {non_combat_armor = true},
incompatible = {frost_walker = true},
weight = 2,
- description = "Increases underwater movement speed.",
+ description = S("Increases underwater movement speed."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -129,14 +131,14 @@ mcl_enchanting.enchantments.curse_of_vanishing = {
-- implemented via on_enchant
mcl_enchanting.enchantments.efficiency = {
- name = "Efficiency",
+ name = S("Efficiency"),
max_level = 5,
primary = {pickaxe = true, shovel = true, axe = true, hoe = true},
secondary = {shears = true},
disallow = {},
incompatible = {},
weight = 10,
- description = "Increases mining speed.",
+ description = S("Increases mining speed."),
curse = false,
on_enchant = function(itemstack, level)
local tool_capabilities = itemstack:get_tool_capabilities()
@@ -156,14 +158,14 @@ mcl_enchanting.enchantments.efficiency = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.feather_falling = {
- name = "Feather Falling",
+ name = S("Feather Falling"),
max_level = 4,
primary = {armor_feet = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {},
weight = 5,
- description = "Reduces fall damage.",curse = false,
+ description = S("Reduces fall damage."),curse = false,
on_enchant = function() end,
requires_tool = false,
treasure = false,
@@ -172,14 +174,14 @@ mcl_enchanting.enchantments.feather_falling = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.fire_aspect = {
- name = "Fire Aspect",
+ name = S("Fire Aspect"),
max_level = 2,
primary = {sword = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Sets target on fire.",
+ description = S("Sets target on fire."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -189,14 +191,14 @@ mcl_enchanting.enchantments.feather_falling = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.fire_protection = {
- name = "Fire Protection",
+ name = S("Fire Protection"),
max_level = 4,
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {blast_protection = true, protection = true, projectile_protection = true},
weight = 5,
- description = "Reduces fire damage.",
+ description = S("Reduces fire damage."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -206,14 +208,14 @@ mcl_enchanting.enchantments.fire_protection = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.flame = {
- name = "Flame",
+ name = S("Flame"),
max_level = 1,
primary = {bow = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Arrows set target on fire.",
+ description = S("Arrows set target on fire."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -223,14 +225,14 @@ mcl_enchanting.enchantments.fire_protection = {
-- implemented in mcl_item_entity
mcl_enchanting.enchantments.fortune = {
- name = "Fortune",
+ name = S("Fortune"),
max_level = 3,
primary = {pickaxe = true, shovel = true, axe = true, hoe = true},
secondary = {},
disallow = {},
incompatible = {silk_touch = true},
weight = 2,
- description = "Increases certain block drops.",
+ description = S("Increases certain block drops."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -240,14 +242,14 @@ mcl_enchanting.enchantments.fortune = {
-- implemented via walkover.register_global
mcl_enchanting.enchantments.frost_walker = {
- name = "Frost Walker",
+ name = S("Frost Walker"),
max_level = 2,
primary = {},
secondary = {armor_feet = true},
disallow = {non_combat_armor = true},
incompatible = {depth_strider = true},
weight = 2,
- description = "Turns water beneath the player into frosted ice and prevents the damage the player would take from standing on magma blocks.",
+ description = S("Turns water beneath the player into frosted ice and prevents the damage from magma blocks."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -274,14 +276,14 @@ end)
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.impaling = {
- name = "Impaling",
+ name = S("Impaling"),
max_level = 5,
primary = {trident = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Trident deals additional damage to mobs that spawn naturally in the ocean.",
+ description = S("Trident deals additional damage to ocean mobs."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -291,14 +293,14 @@ end)
-- implemented in mcl_bows
mcl_enchanting.enchantments.infinity = {
- name = "Infinity",
+ name = S("Infinity"),
max_level = 1,
primary = {bow = true},
secondary = {},
disallow = {},
incompatible = {mending = true},
weight = 1,
- description = "Shooting consumes no regular arrows.",
+ description = S("Shooting consumes no regular arrows."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -308,14 +310,14 @@ mcl_enchanting.enchantments.infinity = {
-- implemented via minetest.calculate_knockback
mcl_enchanting.enchantments.knockback = {
- name = "Knockback",
+ name = S("Knockback"),
max_level = 2,
primary = {sword = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 5,
- description = "Increases knockback.",
+ description = S("Increases knockback."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -341,14 +343,14 @@ end
-- unimplemented
--[[mcl_enchanting.enchantments.looting = {
- name = "Looting",
+ name = S("Looting"),
max_level = 3,
primary = {sword = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Increases mob loot.",
+ description = S("Increases mob loot."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -358,14 +360,14 @@ end
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.loyalty = {
- name = "Loyalty",
+ name = S("Loyalty"),
max_level = 3,
primary = {trident = true},
secondary = {},
disallow = {},
incompatible = {riptide = true},
weight = 5,
- description = "Trident returns after being thrown. Higher levels reduce return time.",
+ description = S("Trident returns after being thrown. Higher levels reduce return time."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -375,14 +377,14 @@ end
-- unimplemented
--[[mcl_enchanting.enchantments.luck_of_the_sea = {
- name = "Luck of the Sea",
+ name = S("Luck of the Sea"),
max_level = 3,
primary = {fishing_rod = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Increases rate of good loot (enchanting books, etc.)",
+ description = S("Increases rate of good loot (enchanting books, etc.)"),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -392,14 +394,14 @@ end
-- implemented in mcl_fishing
mcl_enchanting.enchantments.lure = {
- name = "Lure",
+ name = S("Lure"),
max_level = 3,
primary = {fishing_rod = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Decreases wait time until fish/junk/loot \"bites\".",
+ description = S("Decreases time until rod catches something."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -409,14 +411,14 @@ mcl_enchanting.enchantments.lure = {
-- unimplemented
--[[mcl_enchanting.enchantments.mending = {
- name = "Mending",
+ name = S("Mending"),
max_level = 1,
primary = {},
secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true, tool = true, weapon = true},
disallow = {},
incompatible = {infinity = true},
weight = 2,
- description = "Repair the item while gaining XP orbs.",
+ description = S("Repair the item while gaining XP orbs."),
curse = false,
on_enchant = function() end,
requires_tool = true,
@@ -426,14 +428,14 @@ mcl_enchanting.enchantments.lure = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.multishot = {
- name = "Multishot",
+ name = S("Multishot"),
max_level = 1,
primary = {crossbow = true},
secondary = {},
disallow = {},
incompatible = {piercing = true},
weight = 2,
- description = "Shoot 3 arrows at the cost of one.",
+ description = S("Shoot 3 arrows at the cost of one."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -443,14 +445,14 @@ mcl_enchanting.enchantments.lure = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.piercing = {
- name = "Piercing",
+ name = S("Piercing"),
max_level = 4,
primary = {crossbow = true},
secondary = {},
disallow = {},
incompatible = {multishot = true},
weight = 10,
- description = "Arrows pass through multiple entities.",
+ description = S("Arrows passes through multiple objects."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -460,14 +462,14 @@ mcl_enchanting.enchantments.lure = {
-- implemented in mcl_bows
mcl_enchanting.enchantments.power = {
- name = "Power",
+ name = S("Power"),
max_level = 5,
primary = {bow = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 10,
- description = "Increases arrow damage.",
+ description = S("Increases arrow damage."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -477,14 +479,14 @@ mcl_enchanting.enchantments.power = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.projectile_protection = {
- name = "Projectile Protection",
+ name = S("Projectile Protection"),
max_level = 4,
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {blast_protection = true, fire_protection = true, protection = true},
weight = 5,
- description = "Reduces projectile damage.",
+ description = S("Reduces projectile damage."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -494,14 +496,14 @@ mcl_enchanting.enchantments.projectile_protection = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.protection = {
- name = "Protection",
+ name = S("Protection"),
max_level = 4,
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
weight = 10,
- description = "Reduces most types of damage by 4% for each level.",
+ description = S("Reduces most types of damage by 4% for each level."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -511,14 +513,14 @@ mcl_enchanting.enchantments.protection = {
-- implemented via minetest.calculate_knockback (together with the Knockback enchantment) and mcl_bows
mcl_enchanting.enchantments.punch = {
- name = "Punch",
+ name = S("Punch"),
max_level = 2,
primary = {},
secondary = {bow = true},
disallow = {},
incompatible = {},
weight = 2,
- description = "Increases arrow knockback.",
+ description = S("Increases arrow knockback."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -528,14 +530,14 @@ mcl_enchanting.enchantments.punch = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.quick_charge = {
- name = "Quick Charge",
+ name = S("Quick Charge"),
max_level = 3,
primary = {crossbow = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 5,
- description = "Decreases crossbow charging time.",
+ description = S("Decreases crossbow charging time."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -545,14 +547,14 @@ mcl_enchanting.enchantments.punch = {
-- unimplemented
--[[mcl_enchanting.enchantments.respiration = {
- name = "Respiration",
+ name = S("Respiration"),
max_level = 3,
primary = {armor_head = true},
secondary = {},
disallow = {non_combat_armor = true},
incompatible = {},
weight = 2,
- description = "Extends underwater breathing time.",
+ description = S("Extends underwater breathing time."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -562,14 +564,14 @@ mcl_enchanting.enchantments.punch = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.riptide = {
- name = "Riptide",
+ name = S("Riptide"),
max_level = 3,
primary = {trident = true},
secondary = {},
disallow = {},
incompatible = {channeling = true, loyalty = true},
weight = 2,
- description = "Trident launches player with itself when thrown. Functions only in water or rain.",
+ description = S("Trident launches player with itself when thrown. Works only in water or rain."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -579,14 +581,14 @@ mcl_enchanting.enchantments.punch = {
-- implemented via on_enchant
mcl_enchanting.enchantments.sharpness = {
- name = "Sharpness",
+ name = S("Sharpness"),
max_level = 5,
primary = {sword = true},
secondary = {axe = true},
disallow = {},
incompatible = {bane_of_arthropods = true, smite = true},
weight = 5,
- description = "Increases damage.",
+ description = S("Increases damage."),
curse = false,
on_enchant = increase_damage("fleshy", 0.5),
requires_tool = false,
@@ -596,14 +598,14 @@ mcl_enchanting.enchantments.sharpness = {
-- implemented in mcl_item_entity
mcl_enchanting.enchantments.silk_touch = {
- name = "Silk Touch",
+ name = S("Silk Touch"),
max_level = 1,
primary = {pickaxe = true, shovel = true, axe = true, hoe = true},
secondary = {shears = true},
disallow = {},
incompatible = {fortune = true},
weight = 1,
- description = "Mined blocks drop themselves.",
+ description = S("Mined blocks drop themselves."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -613,14 +615,14 @@ mcl_enchanting.enchantments.silk_touch = {
-- implemented via on_enchant and additions in mobs_mc
mcl_enchanting.enchantments.smite = {
- name = "Smite",
+ name = S("Smite"),
max_level = 5,
primary = {sword = true},
secondary = {axe = true},
disallow = {},
incompatible = {bane_of_arthropods = true, sharpness = true},
weight = 5,
- description = "Increases damage to undead mobs.",
+ description = S("Increases damage to undead mobs."),
curse = false,
on_enchant = increase_damage("undead", 2.5),
requires_tool = false,
@@ -630,14 +632,14 @@ mcl_enchanting.enchantments.smite = {
-- implemented in mcl_playerplus
mcl_enchanting.enchantments.soul_speed = {
- name = "Soul Speed",
+ name = S("Soul Speed"),
max_level = 3,
primary = {},
secondary = {armor_feet = true},
disallow = {non_combat_armor = true},
incompatible = {frost_walker = true},
weight = 2,
- description = "Increases walking speed on soul sand.",
+ description = S("Increases walking speed on soul sand."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -647,14 +649,14 @@ mcl_enchanting.enchantments.soul_speed = {
-- requires missing MineClone2 feature
--[[mcl_enchanting.enchantments.sweeping_edge = {
- name = "Sweeping Edge",
+ name = S("Sweeping Edge"),
max_level = 3,
primary = {sword = true},
secondary = {},
disallow = {},
incompatible = {},
weight = 2,
- description = "Increases sweeping attack damage.",
+ description = S("Increases sweeping attack damage."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -664,14 +666,14 @@ mcl_enchanting.enchantments.soul_speed = {
-- implemented in mcl_armor
mcl_enchanting.enchantments.thorns = {
- name = "Thorns",
+ name = S("Thorns"),
max_level = 3,
primary = {armor_head = true},
secondary = {armor_torso = true, armor_legs = true, armor_feet = true},
disallow = {non_combat_armor = true},
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
weight = 1,
- description = "Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.",
+ description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."),
curse = false,
on_enchant = function() end,
requires_tool = false,
@@ -681,14 +683,14 @@ mcl_enchanting.enchantments.thorns = {
-- for tools & weapons implemented via on_enchant; for bows implemented in mcl_bows; for armor implemented in mcl_armor and mcl_tt; for fishing rods implemented in mcl_fishing
mcl_enchanting.enchantments.unbreaking = {
- name = "Unbreaking",
+ name = S("Unbreaking"),
max_level = 3,
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true, pickaxe = true, shovel = true, axe = true, hoe = true, sword = true, fishing_rod = true, bow = true},
secondary = {tool = true},
disallow = {non_combat_armor = true},
incompatible = {},
weight = 5,
- description = "Increases item durability.",
+ description = S("Increases item durability."),
curse = false,
on_enchant = function(itemstack, level)
local tool_capabilities = itemstack:get_tool_capabilities()
diff --git a/mods/CORE/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua
similarity index 96%
rename from mods/CORE/mcl_enchanting/engine.lua
rename to mods/ITEMS/mcl_enchanting/engine.lua
index 1202ec70df..ac12857b97 100644
--- a/mods/CORE/mcl_enchanting/engine.lua
+++ b/mods/ITEMS/mcl_enchanting/engine.lua
@@ -1,3 +1,6 @@
+local S = minetest.get_translator("mcl_enchanting")
+local F = minetest.formspec_escape
+
function mcl_enchanting.is_book(itemname)
return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted"
end
@@ -388,13 +391,13 @@ function mcl_enchanting.show_enchanting_formspec(player)
local formspec = ""
.. "size[9.07,8.6;]"
.. "formspec_version[3]"
- .. "label[0,0;" .. C("#313131") .. table_name .. "]"
+ .. "label[0,0;" .. C("#313131") .. F(table_name) .. "]"
.. mcl_formspec.get_itemslot_bg(0.2, 2.4, 1, 1)
.. "list[detached:" .. name .. "_enchanting;enchanting;0.2,2.4;1,1;1]"
.. mcl_formspec.get_itemslot_bg(1.1, 2.4, 1, 1)
.. "image[1.1,2.4;1,1;mcl_enchanting_lapis_background.png]"
.. "list[detached:" .. name .. "_enchanting;enchanting;1.1,2.4;1,1;2]"
- .. "label[0,4;" .. C("#313131") .. "Inventory]"
+ .. "label[0,4;" .. C("#313131") .. F(S("Inventory")).."]"
.. mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3)
.. mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1)
.. "list[current_player;main;0,4.5;9,3;9]"
@@ -417,7 +420,7 @@ function mcl_enchanting.show_enchanting_formspec(player)
local hover_ending = (can_enchant and "_hovered" or "_off")
formspec = formspec
.. "container[3.2," .. y .. "]"
- .. (slot and "tooltip[button_" .. i .. ";" .. C("#818181") .. slot.description .. " " .. C("#FFFFFF") .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and "#818181" or "#FC5454") .. i .. " Lapis Lazuli\n" .. C("#818181") .. i .. " Enchantment Levels" or C("#FC5454") .. "Level Requirement: " .. slot.level_requirement) .. "]" or "")
+ .. (slot and "tooltip[button_" .. i .. ";" .. C("#818181") .. F(slot.description) .. " " .. C("#FFFFFF") .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and "#818181" or "#FC5454") .. F(S("@1 × Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("Enchantment levels: @1", i)) or C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "")
.. "style[button_" .. i .. ";bgimg=mcl_enchanting_button" .. ending .. ".png;bgimg_hovered=mcl_enchanting_button" .. hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]"
.. "button[0,0;7.5,1.3;button_" .. i .. ";]"
.. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "")
@@ -571,20 +574,6 @@ function mcl_enchanting.look_at(self, pos2)
self.object:set_yaw(yaw + math.pi)
end
-function mcl_enchanting.check_book(pos)
- local obj_pos = vector.add(pos, mcl_enchanting.book_offset)
- for _, obj in pairs(minetest.get_objects_inside_radius(obj_pos, 0.1)) do
- local luaentity = obj:get_luaentity()
- if luaentity and luaentity.name == "mcl_enchanting:book" then
- if minetest.get_node(pos).name ~= "mcl_enchanting:table" then
- obj:remove()
- end
- return
- end
- end
- minetest.add_entity(obj_pos, "mcl_enchanting:book")
-end
-
function mcl_enchanting.get_bookshelves(pos)
local absolute, relative = {}, {}
for i, rp in ipairs(mcl_enchanting.bookshelf_positions) do
diff --git a/mods/CORE/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua
similarity index 71%
rename from mods/CORE/mcl_enchanting/init.lua
rename to mods/ITEMS/mcl_enchanting/init.lua
index 79dd2aee0e..78c5b7f930 100644
--- a/mods/CORE/mcl_enchanting/init.lua
+++ b/mods/ITEMS/mcl_enchanting/init.lua
@@ -1,4 +1,5 @@
local modpath = minetest.get_modpath("mcl_enchanting")
+local S = minetest.get_translator("mcl_enchanting")
mcl_enchanting = {
book_offset = vector.new(0, 0.75, 0),
@@ -58,8 +59,8 @@ dofile(modpath .. "/engine.lua")
dofile(modpath .. "/enchantments.lua")
minetest.register_chatcommand("enchant", {
- description = "Enchant an item.",
- params = " []",
+ description = S("Enchant an item"),
+ params = S(" []"),
privs = {give = true},
func = function(_, param)
local sparam = param:split(" ")
@@ -68,40 +69,41 @@ minetest.register_chatcommand("enchant", {
local level_str = sparam[3]
local level = tonumber(level_str or "1")
if not target_name or not enchantment then
- return false, "Usage: /enchant []"
+ return false, S("Usage: /enchant []")
end
local target = minetest.get_player_by_name(target_name)
if not target then
- return false, "Player '" .. target_name .. "' cannot be found"
+ return false, S("Player '@1' cannot be found.", target_name)
end
local itemstack = target:get_wielded_item()
local can_enchant, errorstring, extra_info = mcl_enchanting.can_enchant(itemstack, enchantment, level)
if not can_enchant then
if errorstring == "enchantment invalid" then
- return false, "There is no such enchantment '" .. enchantment .. "'"
+ return false, S("There is no such enchantment '@1'.", enchantment)
elseif errorstring == "item missing" then
- return false, "The target doesn't hold an item"
+ return false, S("The target doesn't hold an item.")
elseif errorstring == "item not supported" then
- return false, "The selected enchantment can't be added to the target item"
+ return false, S("The selected enchantment can't be added to the target item.")
elseif errorstring == "level invalid" then
- return false, "'" .. level_str .. "' is not a valid number"
+ return false, S("'@1' is not a valid number", level_str)
elseif errorstring == "level too high" then
- return false, "The number you have entered (" .. level_str .. ") is too big, it must be at most " .. extra_info
+ return false, S("The number you have entered (@1) is too big, it must be at most @2.", level_str, extra_info)
elseif errorstring == "level too small" then
- return false, "The number you have entered (" .. level_str .. ") is too small, it must be at least " .. extra_info
+ return false, S("The number you have entered (@1) is too small, it must be at least @2.", level_str, extra_info)
elseif errorstring == "incompatible" then
- return false, mcl_enchanting.get_enchantment_description(enchantment, level) .. " can't be combined with " .. extra_info
+ return false, S("@1 can't be combined with @2.", mcl_enchanting.get_enchantment_description(enchantment, level), extra_info)
end
else
target:set_wielded_item(mcl_enchanting.enchant(itemstack, enchantment, level))
- return true, "Enchanting succeded"
+ return true, S("Enchanting succeded.")
end
end
})
minetest.register_chatcommand("forceenchant", {
- description = "Forcefully enchant an item.",
- params = " []",
+ description = S("Forcefully enchant an item"),
+ params = S(" []"),
+ privs = {give = true},
func = function(_, param)
local sparam = param:split(" ")
local target_name = sparam[1]
@@ -109,54 +111,79 @@ minetest.register_chatcommand("forceenchant", {
local level_str = sparam[3]
local level = tonumber(level_str or "1")
if not target_name or not enchantment then
- return false, "Usage: /forceenchant []"
+ return false, S("Usage: /forceenchant []")
end
local target = minetest.get_player_by_name(target_name)
if not target then
- return false, "Player '" .. target_name .. "' cannot be found"
+ return false, S("Player '@1' cannot be found.", target_name)
end
local itemstack = target:get_wielded_item()
local can_enchant, errorstring, extra_info = mcl_enchanting.can_enchant(itemstack, enchantment, level)
if errorstring == "enchantment invalid" then
- return false, "There is no such enchantment '" .. enchantment .. "'"
+ return false, S("There is no such enchantment '@1'.", enchantment)
elseif errorstring == "item missing" then
- return false, "The target doesn't hold an item"
+ return false, S("The target doesn't hold an item.")
elseif errorstring == "item not supported" and not mcl_enchanting.is_enchantable(itemstack:get_name()) then
- return false, "The target item is not enchantable"
+ return false, S("The target item is not enchantable.")
elseif errorstring == "level invalid" then
- return false, "'" .. level_str .. "' is not a valid number"
+ return false, S("'@1' is not a valid number.", level_str)
else
target:set_wielded_item(mcl_enchanting.enchant(itemstack, enchantment, level))
- return true, "Enchanting succeded"
+ return true, S("Enchanting succeded.")
end
end
})
minetest.register_craftitem("mcl_enchanting:book_enchanted", {
- description = "Enchanted Book",
+ description = S("Enchanted Book"),
inventory_image = "mcl_enchanting_book_enchanted.png" .. mcl_enchanting.overlay,
groups = {enchanted = 1, not_in_creative_inventory = 1, enchantability = 1},
_mcl_enchanting_enchanted_tool = "mcl_enchanting:book_enchanted",
stack_max = 1,
})
+local spawn_book_entity = function(pos, respawn)
+ if respawn then
+ -- Check if we already have a book
+ local objs = minetest.get_objects_inside_radius(pos, 1)
+ for o=1, #objs do
+ local obj = objs[o]
+ local lua = obj:get_luaentity()
+ if lua and lua.name == "mcl_enchanting:book" then
+ if lua._table_pos and vector.equals(pos, lua._table_pos) then
+ return
+ end
+ end
+ end
+ end
+ local obj = minetest.add_entity(vector.add(pos, mcl_enchanting.book_offset), "mcl_enchanting:book")
+ if obj then
+ local lua = obj:get_luaentity()
+ if lua then
+ lua._table_pos = table.copy(pos)
+ end
+ end
+end
+
minetest.register_entity("mcl_enchanting:book", {
initial_properties = {
visual = "mesh",
mesh = "mcl_enchanting_book.b3d",
visual_size = {x = 12.5, y = 12.5},
collisionbox = {0, 0, 0},
+ pointable = false,
physical = false,
textures = {"mcl_enchanting_book_entity.png"},
+ static_save = false,
},
- player_near = false,
- on_activate = function(self)
+ _player_near = false,
+ _table_pos = nil,
+ on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
mcl_enchanting.set_book_animation(self, "close")
- mcl_enchanting.check_book(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset))
end,
on_step = function(self, dtime)
- local old_player_near = self.player_near
+ local old_player_near = self._player_near
local player_near = false
local player
for _, obj in ipairs(minetest.get_objects_inside_radius(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset), 2.5)) do
@@ -175,13 +202,18 @@ minetest.register_entity("mcl_enchanting:book", {
if player then
mcl_enchanting.look_at(self, player:get_pos())
end
- self.player_near = player_near
+ self._player_near = player_near
mcl_enchanting.check_animation_schedule(self, dtime)
end,
})
+local rotate
+if minetest.get_modpath("screwdriver") then
+ rotate = screwdriver.rotate_simple
+end
+
minetest.register_node("mcl_enchanting:table", {
- description = "Enchanting Table",
+ description = S("Enchanting Table"),
drawtype = "nodebox",
tiles = {"mcl_enchanting_table_top.png", "mcl_enchanting_table_bottom.png", "mcl_enchanting_table_side.png", "mcl_enchanting_table_side.png", "mcl_enchanting_table_side.png", "mcl_enchanting_table_side.png"},
node_box = {
@@ -189,24 +221,30 @@ minetest.register_node("mcl_enchanting:table", {
fixed = {-0.5, -0.5, -0.5, 0.5, 0.25, 0.5},
},
sounds = mcl_sounds.node_sound_stone_defaults(),
- groups = {pickaxey = 2},
- on_rotate = (rawget(_G, "screwdriver") or {}).rotate_simple,
+ groups = {pickaxey = 2, deco_block = 1},
+ on_rotate = rotate,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local player_meta = clicker:get_meta()
local table_meta = minetest.get_meta(pos)
local num_bookshelves = table_meta:get_int("mcl_enchanting:num_bookshelves")
local table_name = table_meta:get_string("name")
if table_name == "" then
- table_name = "Enchant"
+ table_name = S("Enchant")
end
player_meta:set_int("mcl_enchanting:num_bookshelves", num_bookshelves)
player_meta:set_string("mcl_enchanting:table_name", table_name)
mcl_enchanting.show_enchanting_formspec(clicker)
+ -- Respawn book entity just in case it got lost
+ spawn_book_entity(pos, true)
end,
on_construct = function(pos)
- minetest.add_entity(vector.add(pos, mcl_enchanting.book_offset), "mcl_enchanting:book")
+ spawn_book_entity(pos)
end,
- on_destruct = function(pos)
+ after_dig_node = function(pos, oldnode, oldmetadata, digger)
+ local dname = (digger and digger:get_player_name()) or ""
+ if minetest.is_creative_enabled(dname) then
+ return
+ end
local itemstack = ItemStack("mcl_enchanting:table")
local meta = minetest.get_meta(pos)
local itemmeta = itemstack:get_meta()
@@ -220,7 +258,18 @@ minetest.register_node("mcl_enchanting:table", {
meta:set_string("name", itemmeta:get_string("name"))
meta:set_string("description", itemmeta:get_string("description"))
end,
- after_destruct = mcl_enchanting.check_table,
+ after_destruct = function(pos)
+ local objs = minetest.get_objects_inside_radius(pos, 1)
+ for o=1, #objs do
+ local obj = objs[o]
+ local lua = obj:get_luaentity()
+ if lua and lua.name == "mcl_enchanting:book" then
+ if lua._table_pos and vector.equals(pos, lua._table_pos) then
+ obj:remove()
+ end
+ end
+ end
+ end,
drop = "",
_mcl_blast_resistance = 1200,
_mcl_hardness = 5,
@@ -236,12 +285,11 @@ minetest.register_craft({
})
minetest.register_abm({
- name = "Enchanting table bookshelf particles",
+ label = "Enchanting table bookshelf particles",
interval = 1,
chance = 1,
nodenames = "mcl_enchanting:table",
action = function(pos)
- mcl_enchanting.check_book(pos)
local absolute, relative = mcl_enchanting.get_bookshelves(pos)
for i, ap in ipairs(absolute) do
if math.random(10) == 1 then
@@ -262,6 +310,17 @@ minetest.register_abm({
end
})
+minetest.register_lbm({
+ label = "(Re-)spawn book entity above enchanting table",
+ name = "mcl_enchanting:spawn_book_entity",
+ nodenames = {"mcl_enchanting:table"},
+ run_at_every_load = true,
+ action = function(pos)
+ spawn_book_entity(pos)
+ end,
+})
+
+
minetest.register_on_mods_loaded(mcl_enchanting.initialize)
minetest.register_on_joinplayer(mcl_enchanting.initialize_player)
minetest.register_on_player_receive_fields(mcl_enchanting.handle_formspec_fields)
diff --git a/mods/CORE/mcl_enchanting/mod.conf b/mods/ITEMS/mcl_enchanting/mod.conf
similarity index 100%
rename from mods/CORE/mcl_enchanting/mod.conf
rename to mods/ITEMS/mcl_enchanting/mod.conf
diff --git a/mods/CORE/mcl_enchanting/models/mcl_enchanting_book.b3d b/mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book.b3d
similarity index 100%
rename from mods/CORE/mcl_enchanting/models/mcl_enchanting_book.b3d
rename to mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book.b3d
diff --git a/mods/CORE/mcl_enchanting/models/mcl_enchanting_book_entity.png b/mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book_entity.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/models/mcl_enchanting_book_entity.png
rename to mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book_entity.png
diff --git a/mods/CORE/mcl_enchanting/roman_numerals.lua b/mods/ITEMS/mcl_enchanting/roman_numerals.lua
similarity index 100%
rename from mods/CORE/mcl_enchanting/roman_numerals.lua
rename to mods/ITEMS/mcl_enchanting/roman_numerals.lua
diff --git a/mods/CORE/mcl_enchanting/sounds/mcl_enchanting_enchant.ogg b/mods/ITEMS/mcl_enchanting/sounds/mcl_enchanting_enchant.ogg
similarity index 100%
rename from mods/CORE/mcl_enchanting/sounds/mcl_enchanting_enchant.ogg
rename to mods/ITEMS/mcl_enchanting/sounds/mcl_enchanting_enchant.ogg
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_closed.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_closed.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_closed.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_closed.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_open.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_open.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_open.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_open.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_button.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_button.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_button_background.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_background.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_button_background.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_background.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_button_hovered.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_hovered.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_button_hovered.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_hovered.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_button_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_off.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_button_off.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_off.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_1.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_1.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_1.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_1.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_10.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_10.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_10.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_10.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_11.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_11.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_11.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_11.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_12.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_12.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_12.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_12.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_13.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_13.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_13.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_13.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_14.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_14.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_14.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_14.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_15.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_15.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_15.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_15.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_16.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_16.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_16.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_16.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_17.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_17.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_17.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_17.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_18.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_18.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_18.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_18.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_2.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_2.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_2.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_2.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_3.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_3.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_3.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_3.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_4.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_4.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_4.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_4.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_5.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_5.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_5.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_5.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_6.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_6.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_6.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_6.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_7.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_7.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_7.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_7.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_8.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_8.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_8.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_8.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_9.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_9.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_glyph_9.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_9.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_lapis_background.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_lapis_background.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_lapis_background.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_lapis_background.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_1.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_1.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_1_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1_off.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_1_off.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1_off.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_2.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_2.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_2_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2_off.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_2_off.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2_off.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_3.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_3.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_3_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3_off.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_number_3_off.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3_off.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_table_bottom.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_bottom.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_table_bottom.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_bottom.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_table_side.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_side.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_table_side.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_side.png
diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_table_top.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_top.png
similarity index 100%
rename from mods/CORE/mcl_enchanting/textures/mcl_enchanting_table_top.png
rename to mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_top.png
diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr b/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr
index 3914058794..dc091a0f40 100644
--- a/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr
+++ b/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr
@@ -26,3 +26,9 @@ The stem attaches itself to end stone and other chorus blocks.=La tige s'attache
Grows on end stone=Pousse sur la pierre d'End
Randomly teleports you when eaten=Vous téléporte au hasard quand il est mangé
Guides the way to the mysterious End dimension=Guide le chemin vers la dimension mystérieuse de l'End
+End Crystal=Cristal de l'End
+End Crystals are explosive devices. They can be placed on Obsidian or Bedrock. Ignite them by a punch or a hit with an arrow. End Crystals can also be used the spawn the Ender Dragon by placing one at each side of the End Exit Portal.=Les cristaux de l'End sont des dispositifs explosifs. Ils peuvent être placés sur de l'Obsidienne ou de la Bedrock. Allumez-les par un coup de poing ou avec une flèche. Les cristaux de l'End peuvent également être utilisés pour engendrer l'Ender dragon en en plaçant un de chaque côté du portail de sortie de l'End.
+Explosion radius: @1=Rayon d'explosion: @1
+Ignited by a punch or a hit with an arrow=Enflammé par un coup de poing ou un coup avec une flèche
+Place the End Crystal on Obsidian or Bedrock, then punch it or hit it with an arrow to cause an huge and probably deadly explosion. To Spawn the Ender Dragon, place one at each side of the End Exit Portal.=Placez le cristal de l'End sur l'obsidienne ou le substrat rocheux, puis frappez-le à coup de poing ou avec une flèche pour provoquer une énorme explosion probablement mortelle. Pour engendrer l'Ender dragon, placez-en un de chaque côté du portail de sortie de l'End.
+
diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr b/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr
index b46a66288d..6ab7a3c670 100644
--- a/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr
+++ b/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr
@@ -26,3 +26,8 @@ The stem attaches itself to end stone and other chorus blocks.=Стебель п
Grows on end stone=Растёт на камнях Предела
Randomly teleports you when eaten=Телепортирует случайным образом при употреблении в пищу
Guides the way to the mysterious End dimension=Показывает путь к загадочному измерению Предела
+End Crystal=Кристалл Предела
+End Crystals are explosive devices. They can be placed on Obsidian or Bedrock. Ignite them by a punch or a hit with an arrow. End Crystals can also be used the spawn the Ender Dragon by placing one at each side of the End Exit Portal.=Кристаллы Предела - это взрывные устройства. Их можно размещать на обсидиане или бедроке. Подрывайте их ударом или попаданием стрелы. Кристаллы Предела также можно использовать для порождения Дракона Предела, для этого их нужно поместить по одной штуке с каждой стороны выходного портала Предела.
+Explosion radius: @1=Радиус взрыва: @1
+Ignited by a punch or a hit with an arrow=Поджигается ударом или при попадании стрелы
+Place the End Crystal on Obsidian or Bedrock, then punch it or hit it with an arrow to cause an huge and probably deadly explosion. To Spawn the Ender Dragon, place one at each side of the End Exit Portal.=Разместите кристалл Предела на обсидиане или бедроке и ударьте по нему или попадите в него стрелой, чтобы вызвать огромный и, вероятно, смертельный взрыв. Чтобы вызвать Дракона Предела, поместите по одной штуке с каждой стороны портала выходного портала Предела.
diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua
index e6fcd4f218..2daaf1e5d7 100644
--- a/mods/ITEMS/mcl_fire/init.lua
+++ b/mods/ITEMS/mcl_fire/init.lua
@@ -5,6 +5,29 @@ mcl_fire = {}
local S = minetest.get_translator("mcl_fire")
local N = function(s) return s end
+-- inverse pyramid pattern above lava source, floor 1 of 2:
+local lava_fire=
+{
+ { x =-1, y = 1, z =-1},
+ { x =-1, y = 1, z = 0},
+ { x =-1, y = 1, z = 1},
+ { x = 0, y = 1, z =-1},
+ { x = 0, y = 1, z = 0},
+ { x = 0, y = 1, z = 1},
+ { x = 1, y = 1, z =-1},
+ { x = 1, y = 1, z = 0},
+ { x = 1, y = 1, z = 1}
+}
+local alldirs=
+{
+ { x =-1, y = 0, z = 0},
+ { x = 1, y = 0, z = 0},
+ { x = 0, y =-1, z = 0},
+ { x = 0, y = 1, z = 0},
+ { x = 0, y = 0, z =-1},
+ { x = 0, y = 0, z = 1}
+}
+
local spawn_smoke = function(pos)
mcl_particles.add_node_particlespawner(pos, {
amount = 0.1,
@@ -402,6 +425,18 @@ minetest.register_abm({
-- Enable the following ABMs according to 'enable fire' setting
+local function has_flammable(pos)
+ local npos, node
+ for n, v in ipairs(alldirs) do
+ npos = vector.add(pos, v)
+ node = minetest.get_node_or_nil(npos)
+ if node and node.name and minetest.get_item_group(node.name, "flammable") ~= 0 then
+ return npos
+ end
+ end
+ return false
+end
+
if not fire_enabled then
-- Occasionally remove fire if fire disabled
@@ -417,39 +452,58 @@ if not fire_enabled then
else -- Fire enabled
- -- Set fire to air nodes (inverse pyramid pattern) above lava source
+ -- Set fire to air nodes
minetest.register_abm({
label = "Ignite fire by lava",
nodenames = {"group:lava"},
+ neighbors = {"air"},
interval = 7,
- chance = 2,
+ chance = 3,
catch_up = false,
action = function(pos)
- local node = minetest.get_node(pos)
- local def = minetest.registered_nodes[node.name]
- -- Check if liquid source node
- if def and def.liquidtype ~= "source" then
- return
+ local i, dir, target, node, i2, f
+ i = math.random(1,9)
+ dir = lava_fire[i]
+ target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}
+ node = minetest.get_node(target)
+ if not node or node.name ~= "air" then
+ i = ((i + math.random(0,7)) % 9) + 1
+ dir = lava_fire[i]
+ target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}
+ node = minetest.get_node(target)
+ if not node or node.name ~= "air" then
+ return
+ end
end
- local function try_ignite(airs)
- while #airs > 0 do
- local r = math.random(1, #airs)
- if minetest.find_node_near(airs[r], 1, {"group:flammable"}) then
- spawn_fire(airs[r])
- return true
- else
- table.remove(airs, r)
+ i2 = math.random(1,15)
+ if i2 < 10 then
+ local dir2, target2, node2
+ dir2 = lava_fire[i2]
+ target2 = {x=target.x+dir2.x, y=target.y+dir2.y, z=target.z+dir2.z}
+ node2 = minetest.get_node(target2)
+ if node2 and node2.name == "air" then
+ f = has_flammable(target2)
+ if f then
+ minetest.after(1, spawn_fire, {x=target2.x, y=target2.y, z=target2.z})
+ minetest.add_particle({
+ pos = vector.new({x=pos.x, y=pos.y+0.5, z=pos.z}),
+ velocity={x=f.x-pos.x, y=math.max(f.y-pos.y,0.7), z=f.z-pos.z},
+ expirationtime=1, size=1.5, collisiondetection=false,
+ glow=minetest.LIGHT_MAX, texture="mcl_particles_flame.png"
+ })
+ return
end
end
- return false
end
- local airs1 = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y+1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, {"air"})
- local h = math.random(1, 2)
- if h == 2 and #airs1 > 0 then
- local airs2 = minetest.find_nodes_in_area({x=pos.x-2, y=pos.y+2, z=pos.z-2}, {x=pos.x+2, y=pos.y+2, z=pos.z+2}, {"air"})
- try_ignite(airs2)
- else
- try_ignite(airs1)
+ f = has_flammable(target)
+ if f then
+ minetest.after(1, spawn_fire, {x=target.x, y=target.y, z=target.z})
+ minetest.add_particle({
+ pos = vector.new({x=pos.x, y=pos.y+0.5, z=pos.z}),
+ velocity={x=f.x-pos.x, y=math.max(f.y-pos.y,0.25), z=f.z-pos.z},
+ expirationtime=1, size=1, collisiondetection=false,
+ glow=minetest.LIGHT_MAX, texture="mcl_particles_flame.png"
+ })
end
end,
})
diff --git a/mods/ITEMS/mcl_heads/locale/template.txt b/mods/ITEMS/mcl_heads/locale/template.txt
index 27a4513aa0..59321099aa 100644
--- a/mods/ITEMS/mcl_heads/locale/template.txt
+++ b/mods/ITEMS/mcl_heads/locale/template.txt
@@ -1,11 +1,11 @@
# textdomain: mcl_heads
Zombie Head=
-A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.
+A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=
Creeper Head=
-A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.
+A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.=
Human Head=
A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=
Skeleton Skull=
-A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%.
+A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%.=
Wither Skeleton Skull=
A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.=
diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua
index fb17734d7c..40321efe9c 100644
--- a/mods/ITEMS/mcl_itemframes/init.lua
+++ b/mods/ITEMS/mcl_itemframes/init.lua
@@ -1,13 +1,16 @@
local S = minetest.get_translator("mcl_itemframes")
+local VISUAL_SIZE = 0.3
+
minetest.register_entity("mcl_itemframes:item",{
hp_max = 1,
visual = "wielditem",
- visual_size = {x=0.3,y=0.3},
+ visual_size = {x=VISUAL_SIZE, y=VISUAL_SIZE},
physical = false,
pointable = false,
- textures = { "empty.png" },
- _texture = "empty.png",
+ textures = { "blank.png" },
+ _texture = "blank.png",
+ _scale = 1,
on_activate = function(self, staticdata)
if staticdata ~= nil and staticdata ~= "" then
@@ -15,22 +18,37 @@ minetest.register_entity("mcl_itemframes:item",{
if data and data[1] and data[2] then
self._nodename = data[1]
self._texture = data[2]
+ if data[3] then
+ self._scale = data[3]
+ else
+ self._scale = 1
+ end
end
end
if self._texture ~= nil then
- self.object:set_properties({textures={self._texture}})
+ self.object:set_properties({
+ textures={self._texture},
+ visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale},
+ })
end
end,
get_staticdata = function(self)
if self._nodename ~= nil and self._texture ~= nil then
- return self._nodename .. ';' .. self._texture
+ local ret = self._nodename .. ';' .. self._texture
+ if self._scale ~= nil then
+ ret = ret .. ';' .. self._scale
+ end
+ return ret
end
return ""
end,
_update_texture = function(self)
if self._texture ~= nil then
- self.object:set_properties({textures={self._texture}})
+ self.object:set_properties({
+ textures={self._texture},
+ visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale},
+ })
end
end,
})
@@ -74,10 +92,18 @@ local update_item_entity = function(pos, node, param2)
local e = minetest.add_entity(pos, "mcl_itemframes:item")
local lua = e:get_luaentity()
lua._nodename = node.name
- if item:get_name() == "" then
+ local itemname = item:get_name()
+ if itemname == "" or itemname == nil then
lua._texture = "blank.png"
+ lua._scale = 1
else
- lua._texture = item:get_name()
+ lua._texture = itemname
+ local def = minetest.registered_items[itemname]
+ if def and def.wield_scale then
+ lua._scale = def.wield_scale.x
+ else
+ lua._scale = 1
+ end
end
lua:_update_texture()
if node.name == "mcl_itemframes:item_frame" then
diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr
index 36fbac0122..1bc7562608 100644
--- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr
+++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr
@@ -36,9 +36,9 @@ Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it
Cooked Rabbit=Lapin Cuit
This is a food item which can be eaten.=Il s'agit d'un aliment qui peut être mangé.
Milk=Lait
-Removes all status effects=
+Removes all status effects=Supprime tous les effets de statut!
-Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points.=
+Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points.=Le lait est très rafraîchissant et peut être obtenu en utilisant un seau sur une vache. Le boire supprimera tous les effets de statut, mais ne restaure aucun point de faim.
Use the placement key to drink the milk.=
Spider Eye=Oeil d'Araignée
@@ -91,12 +91,4 @@ Carrot on a Stick=Carotte sur un Batôn
Lets you ride a saddled pig=Vous permet de monter un cochon sellé
A carrot on a stick can be used on saddled pigs to ride them.=Une carotte sur un bâton peut être utilisée sur les porcs sellés pour les monter.
-Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.=Placez-le sur un cochon sellé pour le monter. Vous pouvez maintenant monter le cochon comme un cheval. Les porcs marcheront également vers vous lorsque vous brandirez la carotte sur un bâton.
-
-
-
-##### not used anymore #####
-
-
-Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will cure all forms of poisoning, but restores no hunger points.=Le lait est très rafraîchissant et peut être obtenu en utilisant un seau sur une vache. Le boire guérira toutes les formes d'empoisonnement, mais ne restaure pas de points de faim.
-
+Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.=Placez-le sur un cochon sellé pour le monter. Vous pouvez maintenant monter le cochon comme un cheval. Les porcs marcheront également vers vous lorsque vous brandirez la carotte sur un bâton.
\ No newline at end of file
diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua
index 71221cc5c3..026428db23 100644
--- a/mods/ITEMS/mcl_nether/init.lua
+++ b/mods/ITEMS/mcl_nether/init.lua
@@ -106,6 +106,9 @@ minetest.register_node("mcl_nether:magma", {
sounds = mcl_sounds.node_sound_stone_defaults(),
-- From walkover mod
on_walk_over = function(loc, nodeiamon, player)
+ if minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(player, "fire_proof") then
+ return
+ end
-- Hurt players standing on top of this block
if player:get_hp() > 0 then
if mod_death_messages then
diff --git a/mods/ITEMS/mcl_nether/lava.lua b/mods/ITEMS/mcl_nether/lava.lua
index ba76b749e9..da85b8e3c8 100644
--- a/mods/ITEMS/mcl_nether/lava.lua
+++ b/mods/ITEMS/mcl_nether/lava.lua
@@ -1,6 +1,12 @@
-- Lava in the Nether
local S = minetest.get_translator("mcl_nether")
+local N = function(s) return s end
+
+local msg = {
+ N("@1 has become one with the lava."),
+ N("@1 has been consumed by the lava."),
+}
-- TODO: Increase flow speed. This could be done by reducing viscosity,
-- but this would also allow players to swim faster in lava.
@@ -14,6 +20,7 @@ lava_src_def._doc_items_usagehelp = nil
lava_src_def.liquid_range = 7
lava_src_def.liquid_alternative_source = "mcl_nether:nether_lava_source"
lava_src_def.liquid_alternative_flowing = "mcl_nether:nether_lava_flowing"
+lava_src_def._mcl_node_death_message = msg,
minetest.register_node("mcl_nether:nether_lava_source", lava_src_def)
local lava_flow_def = table.copy(minetest.registered_nodes["mcl_core:lava_flowing"])
@@ -22,6 +29,7 @@ lava_flow_def._doc_items_create_entry = false
lava_flow_def.liquid_range = 7
lava_flow_def.liquid_alternative_flowing = "mcl_nether:nether_lava_flowing"
lava_flow_def.liquid_alternative_source = "mcl_nether:nether_lava_source"
+lava_flow_def._mcl_node_death_message = msg,
minetest.register_node("mcl_nether:nether_lava_flowing", lava_flow_def)
-- Add entry aliases for the Help
diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr
index f81f381e25..bfa62488c1 100644
--- a/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr
+++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr
@@ -38,3 +38,5 @@ Place this item on soul sand to plant it and watch it grow.=Platzieren Sie den G
Burns your feet=Verbrennt Ihre Füße
Grows on soul sand=Wächst auf Seelensand
Reduces walking speed=Reduziert das Schritttempo
+@1 has become one with the lava.=@1 wurde eins mit der Lava.
+@1 has been consumed by the lava.=@1 wurde von der Lava verzehrt.
diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr
index 048072be56..78b8a453e7 100644
--- a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr
+++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr
@@ -38,3 +38,5 @@ Place this item on soul sand to plant it and watch it grow.=Placez cet article s
Burns your feet=Vous brûle les pieds
Grows on soul sand=Pousse sur le sable de l'âme
Reduces walking speed=Réduit la vitesse de marche
+@1 has become one with the lava.=@1 est devenu un avec la lave.
+@1 has been consumed by the lava.=@1 a été consumé par la lave.
\ No newline at end of file
diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr
index f546d16ca7..2cfdd370b0 100644
--- a/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr
+++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr
@@ -38,3 +38,5 @@ Place this item on soul sand to plant it and watch it grow.=Поместите
Burns your feet=Обжигает ваши ноги
Grows on soul sand=Растёт на песке душ
Reduces walking speed=Уменьшает скорость ходьбы
+@1 has become one with the lava.=@1 породнился(лась) с лавой.
+@1 has been consumed by the lava.=@1 был(а) поглощен(а) лавой.
diff --git a/mods/ITEMS/mcl_nether/locale/template.txt b/mods/ITEMS/mcl_nether/locale/template.txt
index 0d578faf1b..7b50521661 100644
--- a/mods/ITEMS/mcl_nether/locale/template.txt
+++ b/mods/ITEMS/mcl_nether/locale/template.txt
@@ -38,3 +38,5 @@ Place this item on soul sand to plant it and watch it grow.=
Burns your feet=
Grows on soul sand=
Reduces walking speed=
+@1 has become one with the lava.=
+@1 has been consumed by the lava.=
diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua
index 2eff8c602e..2e0dfe1a51 100644
--- a/mods/ITEMS/mcl_ocean/kelp.lua
+++ b/mods/ITEMS/mcl_ocean/kelp.lua
@@ -41,6 +41,30 @@ local function grow_param2_step(param2, snap_into_grid)
return param2, param2 ~= old_param2
end
+local function kelp_check_place(pos_above, node_above, def_above)
+ if minetest.get_item_group(node_above.name, "water") == 0 then
+ return false
+ end
+ local can_place = false
+ if (def_above.liquidtype == "source") then
+ can_place = true
+ elseif (def_above.liquidtype == "flowing") then
+ -- Check if bit 3 (downwards flowing) is set
+ can_place = (math.floor(node_above.param2 / 8) % 2) == 1
+ if not can_place then
+ -- If not, also check node above (this is needed due a weird quirk in the definition of
+ -- "downwards flowing" liquids in Minetest)
+ local node_above_above = minetest.get_node({x=pos_above.x,y=pos_above.y+1,z=pos_above.z})
+ local naa_def = minetest.registered_nodes[node_above_above.name]
+ can_place = naa_def.liquidtype == "source"
+ if not can_place then
+ can_place = (naa_def.liquidtype == "flowing") and ((math.floor(node_above_above.param2 / 8) % 2) == 1)
+ end
+ end
+ end
+ return can_place
+end
+
local function kelp_on_place(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" or not placer then
return itemstack
@@ -96,11 +120,12 @@ local function kelp_on_place(itemstack, placer, pointed_thing)
-- Placed on side or below node, abort
return itemstack
end
- -- New kelp top must also be submerged in water source
- local _, top_node = get_kelp_top(pos_under, node_under)
- submerged = get_submerged(top_node)
- if submerged ~= "source" then
- -- Not submerged in water source, abort
+ -- New kelp top must also be submerged in water
+ local top_pos, top_node = get_kelp_top(pos_under, node_under)
+ local top_def = minetest.registered_nodes[top_node.name]
+ submerged = kelp_check_place(top_pos, top_node, top_def)
+ if not submerged then
+ -- Not submerged in water, abort
return itemstack
end
else
@@ -109,11 +134,10 @@ local function kelp_on_place(itemstack, placer, pointed_thing)
-- Placed on side or below node, abort
return itemstack
end
- -- Kelp can be placed inside a water source on top of a surface node
- local g_above_water = minetest.get_item_group(node_above.name, "water")
- if not (g_above_water ~= 0 and def_above.liquidtype == "source") then
+ -- Kelp can be placed inside a water source or water flowing downwards on top of a surface node
+ local can_place = kelp_check_place(pos_above, node_above, def_above)
+ if not can_place then
return itemstack
- -- TODO: Also allow placement into downwards flowing liquid
end
node_under.param2 = minetest.registered_items[node_under.name].place_param2 or 16
end
@@ -130,6 +154,10 @@ local function kelp_on_place(itemstack, placer, pointed_thing)
return itemstack
end
+local get_kelp_height = function(param2)
+ return math.floor(param2 / 16)
+end
+
minetest.register_craftitem("mcl_ocean:kelp", {
description = S("Kelp"),
_tt_help = S("Grows in water on dirt, sand, gravel"),
@@ -194,7 +222,19 @@ for s=1, #surfaces do
after_dig_node = function(pos)
minetest.set_node(pos, {name=surfaces[s][2]})
end,
- drop = "mcl_ocean:kelp",
+ on_dig = function(pos, node, digger)
+ -- Drop kelp as item; item count depends on height
+ local dname = ""
+ if digger then
+ dname = digger:get_player_name()
+ end
+ local creative = minetest.is_creative_enabled(dname)
+ if not creative then
+ minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_ocean:kelp "..get_kelp_height(node.param2))
+ end
+ minetest.node_dig(pos, node, digger)
+ end,
+ drop = "", -- drops are handled in on_dig
_mcl_falling_node_alternative = alt,
_mcl_hardness = 0,
_mcl_blast_resistance = 0,
diff --git a/mods/ITEMS/mcl_ocean/locale/template.txt b/mods/ITEMS/mcl_ocean/locale/template.txt
index 9fb4f8e13a..975976db29 100644
--- a/mods/ITEMS/mcl_ocean/locale/template.txt
+++ b/mods/ITEMS/mcl_ocean/locale/template.txt
@@ -50,7 +50,7 @@ A decorative block that serves as a great furnace fuel.=
Dried kelp is a food item.=
Grows on coral block of same species=
Needs water to live=
-Grows in water on dirt, sand, gravel
+Grows in water on dirt, sand, gravel=
Glows in the water=
4 possible sizes=
Grows on dead brain coral block=
diff --git a/mods/ITEMS/mcl_portals/README.md b/mods/ITEMS/mcl_portals/README.md
index 560030e8d0..d3faaa8e2d 100644
--- a/mods/ITEMS/mcl_portals/README.md
+++ b/mods/ITEMS/mcl_portals/README.md
@@ -10,6 +10,12 @@ Code license: MIT License (see `LICENSE`).
Texture license: See README.md in main MineClone 2 directory.
-License of sound: [CC BY 3.0](http://creativecommons.org/licenses/by/3.0/)
-Authors: [FreqMan](https://freesound.org/people/FreqMan/) and Wuzzy
-Source:
+`mcl_portals_teleport.ogg`
+ * License: [CC BY 3.0](http://creativecommons.org/licenses/by/3.0/)
+ * Authors: [FreqMan](https://freesound.org/people/FreqMan/) and Wuzzy
+ * Source:
+
+`mcl_portals_open_end_portal.ogg`
+ * License: CC0
+ * Author: Johnnie\_Holiday
+ * Source:
diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua
index 5a5e74b33f..9dadc3a0d4 100644
--- a/mods/ITEMS/mcl_portals/portal_end.lua
+++ b/mods/ITEMS/mcl_portals/portal_end.lua
@@ -362,6 +362,8 @@ minetest.register_node("mcl_portals:end_portal_frame_eye", {
on_construct = function(pos)
local ok, ppos = check_end_portal_frame(pos)
if ok then
+ -- Epic 'portal open' sound effect that can be heard everywhere
+ minetest.sound_play("mcl_portals_open_end_portal", {gain=0.8}, true)
end_portal_area(ppos)
end
end,
diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua
index e7f6964403..d35520015c 100644
--- a/mods/ITEMS/mcl_portals/portal_nether.lua
+++ b/mods/ITEMS/mcl_portals/portal_nether.lua
@@ -114,7 +114,7 @@ minetest.register_node("mcl_portals:portal", {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
- length = 0.5,
+ length = 1.25,
},
},
{
@@ -123,7 +123,7 @@ minetest.register_node("mcl_portals:portal", {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
- length = 0.5,
+ length = 1.25,
},
},
},
@@ -723,6 +723,9 @@ local function animation(player, playername)
local chatter = touch_chatter_prevention[player] or 0
if mcl_portals.nether_portal_cooloff[player] or minetest.get_us_time() - chatter < TOUCH_CHATTER_TIME_US then
local pos = player:get_pos()
+ if not pos then
+ return
+ end
minetest.add_particlespawner({
amount = 1,
minpos = {x = pos.x - 0.1, y = pos.y + 1.4, z = pos.z - 0.1},
diff --git a/mods/ITEMS/mcl_portals/sounds/mcl_portals_open_end_portal.ogg b/mods/ITEMS/mcl_portals/sounds/mcl_portals_open_end_portal.ogg
new file mode 100644
index 0000000000..82311b3dc4
Binary files /dev/null and b/mods/ITEMS/mcl_portals/sounds/mcl_portals_open_end_portal.ogg differ
diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua
index dab96351e1..f1384ab309 100644
--- a/mods/ITEMS/mcl_potions/functions.lua
+++ b/mods/ITEMS/mcl_potions/functions.lua
@@ -1,22 +1,29 @@
-local is_invisible = {}
-local is_poisoned = {}
-local is_regenerating = {}
-local is_strong = {}
-local is_weak = {}
-local is_water_breathing = {}
-local is_leaping = {}
-local is_swift = {}
-local is_cat = {}
-local is_fire_proof = {}
+local EF = {}
+EF.invisible = {}
+EF.poisoned = {}
+EF.regenerating = {}
+EF.strong = {}
+EF.weak = {}
+EF.water_breathing = {}
+EF.leaping = {}
+EF.swift = {} -- for swiftness AND slowness
+EF.night_vision = {}
+EF.fire_proof = {}
+local EFFECT_TYPES = 0
+for _,_ in pairs(EF) do
+ EFFECT_TYPES = EFFECT_TYPES + 1
+end
+
+local icon_ids = {}
local function potions_set_hudbar(player)
- if is_poisoned[player] and is_regenerating[player] then
+ if EF.poisoned[player] and EF.regenerating[player] then
hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_regen_poison.png", nil, "hudbars_bar_health.png")
- elseif is_poisoned[player] then
+ elseif EF.poisoned[player] then
hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_health_poison.png", nil, "hudbars_bar_health.png")
- elseif is_regenerating[player] then
+ elseif EF.regenerating[player] then
hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_regenerate.png", nil, "hudbars_bar_health.png")
else
hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_health.png", nil, "hudbars_bar_health.png")
@@ -24,6 +31,57 @@ local function potions_set_hudbar(player)
end
+local function potions_init_icons(player)
+ local name = player:get_player_name()
+ icon_ids[name] = {}
+ for e=1, EFFECT_TYPES do
+ local x = -7 + -38 * e
+ local id = player:hud_add({
+ hud_elem_type = "image",
+ text = "blank.png",
+ position = { x = 1, y = 0 },
+ offset = { x = x, y = 272 },
+ scale = { x = 2, y = 2 },
+ alignment = { x = 1, y = 1 },
+ z_index = 100,
+ })
+ table.insert(icon_ids[name], id)
+ end
+end
+
+local function potions_set_icons(player)
+ local name = player:get_player_name()
+ if not icon_ids[name] then
+ return
+ end
+ local active_effects = {}
+ for effect_name, effect in pairs(EF) do
+ if effect[player] then
+ table.insert(active_effects, effect_name)
+ end
+ end
+
+ for i=1, EFFECT_TYPES do
+ local icon = icon_ids[name][i]
+ local effect_name = active_effects[i]
+ if effect_name == "swift" and EF.swift[player].is_slow then
+ effect_name = "slow"
+ end
+ if effect_name == nil then
+ player:hud_change(icon, "text", "blank.png")
+ else
+ player:hud_change(icon, "text", "mcl_potions_effect_"..effect_name..".png")
+ end
+ end
+
+end
+
+local function potions_set_hud(player)
+
+ potions_set_hudbar(player)
+ potions_set_icons(player)
+
+end
-- ███╗░░░███╗░█████╗░██╗███╗░░██╗ ███████╗███████╗███████╗███████╗░█████╗░████████╗
@@ -45,101 +103,101 @@ local is_player, entity, meta
minetest.register_globalstep(function(dtime)
-- Check for invisible players
- for player, vals in pairs(is_invisible) do
+ for player, vals in pairs(EF.invisible) do
- is_invisible[player].timer = is_invisible[player].timer + dtime
+ EF.invisible[player].timer = EF.invisible[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#B0B0B0") end
- if is_invisible[player].timer >= is_invisible[player].dur then
+ if EF.invisible[player].timer >= EF.invisible[player].dur then
mcl_potions.make_invisible(player, false)
- is_invisible[player] = nil
+ EF.invisible[player] = nil
if player:is_player() then
meta = player:get_meta()
- meta:set_string("_is_invisible", minetest.serialize(is_invisible[player]))
+ meta:set_string("_is_invisible", minetest.serialize(EF.invisible[player]))
end
end
end
-- Check for poisoned players
- for player, vals in pairs(is_poisoned) do
+ for player, vals in pairs(EF.poisoned) do
is_player = player:is_player()
entity = player:get_luaentity()
- is_poisoned[player].timer = is_poisoned[player].timer + dtime
- is_poisoned[player].hit_timer = (is_poisoned[player].hit_timer or 0) + dtime
+ EF.poisoned[player].timer = EF.poisoned[player].timer + dtime
+ EF.poisoned[player].hit_timer = (EF.poisoned[player].hit_timer or 0) + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#225533") end
- if is_poisoned[player].hit_timer >= is_poisoned[player].step then
+ if EF.poisoned[player].hit_timer >= EF.poisoned[player].step then
if entity and entity._cmi_is_mob then
entity.health = math.max(entity.health - 1, 1)
- is_poisoned[player].hit_timer = 0
+ EF.poisoned[player].hit_timer = 0
elseif is_player then
player:set_hp( math.max(player:get_hp() - 1, 1), { type = "punch", other = "poison"})
- is_poisoned[player].hit_timer = 0
+ EF.poisoned[player].hit_timer = 0
else -- if not player or mob then remove
- is_poisoned[player] = nil
+ EF.poisoned[player] = nil
end
end
- if is_poisoned[player] and is_poisoned[player].timer >= is_poisoned[player].dur then
- is_poisoned[player] = nil
+ if EF.poisoned[player] and EF.poisoned[player].timer >= EF.poisoned[player].dur then
+ EF.poisoned[player] = nil
if is_player then
meta = player:get_meta()
- meta:set_string("_is_poisoned", minetest.serialize(is_poisoned[player]))
- potions_set_hudbar(player)
+ meta:set_string("_is_poisoned", minetest.serialize(EF.poisoned[player]))
+ potions_set_hud(player)
end
end
end
-- Check for regnerating players
- for player, vals in pairs(is_regenerating) do
+ for player, vals in pairs(EF.regenerating) do
is_player = player:is_player()
entity = player:get_luaentity()
- is_regenerating[player].timer = is_regenerating[player].timer + dtime
- is_regenerating[player].heal_timer = (is_regenerating[player].heal_timer or 0) + dtime
+ EF.regenerating[player].timer = EF.regenerating[player].timer + dtime
+ EF.regenerating[player].heal_timer = (EF.regenerating[player].heal_timer or 0) + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#A52BB2") end
- if is_regenerating[player].heal_timer >= is_regenerating[player].step then
+ if EF.regenerating[player].heal_timer >= EF.regenerating[player].step then
if is_player then
player:set_hp(math.min(player:get_properties().hp_max or 20, player:get_hp() + 1), { type = "set_hp", other = "regeneration" })
- is_regenerating[player].heal_timer = 0
+ EF.regenerating[player].heal_timer = 0
elseif entity and entity._cmi_is_mob then
entity.health = math.min(entity.hp_max, entity.health + 1)
- is_regenerating[player].heal_timer = 0
+ EF.regenerating[player].heal_timer = 0
else -- stop regenerating if not a player or mob
- is_regenerating[player] = nil
+ EF.regenerating[player] = nil
end
end
- if is_regenerating[player] and is_regenerating[player].timer >= is_regenerating[player].dur then
- is_regenerating[player] = nil
+ if EF.regenerating[player] and EF.regenerating[player].timer >= EF.regenerating[player].dur then
+ EF.regenerating[player] = nil
if is_player then
meta = player:get_meta()
- meta:set_string("_is_regenerating", minetest.serialize(is_regenerating[player]))
- potions_set_hudbar(player)
+ meta:set_string("_is_regenerating", minetest.serialize(EF.regenerating[player]))
+ potions_set_hud(player)
end
end
end
-- Check for water breathing players
- for player, vals in pairs(is_water_breathing) do
+ for player, vals in pairs(EF.water_breathing) do
if player:is_player() then
- is_water_breathing[player].timer = is_water_breathing[player].timer + dtime
+ EF.water_breathing[player].timer = EF.water_breathing[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#0000AA") end
@@ -147,146 +205,146 @@ minetest.register_globalstep(function(dtime)
if player:get_breath() < 10 then player:set_breath(10) end
end
- if is_water_breathing[player].timer >= is_water_breathing[player].dur then
+ if EF.water_breathing[player].timer >= EF.water_breathing[player].dur then
meta = player:get_meta()
- meta:set_string("_is_water_breathing", minetest.serialize(is_water_breathing[player]))
- is_water_breathing[player] = nil
+ meta:set_string("_is_water_breathing", minetest.serialize(EF.water_breathing[player]))
+ EF.water_breathing[player] = nil
end
else
- is_water_breathing[player] = nil
+ EF.water_breathing[player] = nil
end
end
-- Check for leaping players
- for player, vals in pairs(is_leaping) do
+ for player, vals in pairs(EF.leaping) do
if player:is_player() then
- is_leaping[player].timer = is_leaping[player].timer + dtime
+ EF.leaping[player].timer = EF.leaping[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#00CC33") end
- if is_leaping[player].timer >= is_leaping[player].dur then
+ if EF.leaping[player].timer >= EF.leaping[player].dur then
playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping")
- is_leaping[player] = nil
+ EF.leaping[player] = nil
meta = player:get_meta()
- meta:set_string("_is_leaping", minetest.serialize(is_leaping[player]))
+ meta:set_string("_is_leaping", minetest.serialize(EF.leaping[player]))
end
else
- is_leaping[player] = nil
+ EF.leaping[player] = nil
end
end
-- Check for swift players
- for player, vals in pairs(is_swift) do
+ for player, vals in pairs(EF.swift) do
if player:is_player() then
- is_swift[player].timer = is_swift[player].timer + dtime
+ EF.swift[player].timer = EF.swift[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#009999") end
- if is_swift[player].timer >= is_swift[player].dur then
+ if EF.swift[player].timer >= EF.swift[player].dur then
playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness")
- is_swift[player] = nil
+ EF.swift[player] = nil
meta = player:get_meta()
- meta:set_string("_is_swift", minetest.serialize(is_swift[player]))
+ meta:set_string("_is_swift", minetest.serialize(EF.swift[player]))
end
else
- is_swift[player] = nil
+ EF.swift[player] = nil
end
end
-- Check for Night Vision equipped players
- for player, vals in pairs(is_cat) do
+ for player, vals in pairs(EF.night_vision) do
if player:is_player() then
- is_cat[player].timer = is_cat[player].timer + dtime
+ EF.night_vision[player].timer = EF.night_vision[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#1010AA") end
- if is_cat[player].timer >= is_cat[player].dur then
- is_cat[player] = nil
+ if EF.night_vision[player].timer >= EF.night_vision[player].dur then
+ EF.night_vision[player] = nil
meta = player:get_meta()
- meta:set_string("_is_cat", minetest.serialize(is_cat[player]))
+ meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player]))
meta:set_int("night_vision", 0)
end
mcl_weather.skycolor.update_sky_color({player})
else
- is_cat[player] = nil
+ EF.night_vision[player] = nil
end
end
-- Check for Fire Proof players
- for player, vals in pairs(is_fire_proof) do
+ for player, vals in pairs(EF.fire_proof) do
if player:is_player() then
player = player or player:get_luaentity()
- is_fire_proof[player].timer = is_fire_proof[player].timer + dtime
+ EF.fire_proof[player].timer = EF.fire_proof[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#E0B050") end
- if is_fire_proof[player].timer >= is_fire_proof[player].dur then
- is_fire_proof[player] = nil
+ if EF.fire_proof[player].timer >= EF.fire_proof[player].dur then
+ EF.fire_proof[player] = nil
meta = player:get_meta()
- meta:set_string("_is_fire_proof", minetest.serialize(is_fire_proof[player]))
+ meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player]))
end
else
- is_fire_proof[player] = nil
+ EF.fire_proof[player] = nil
end
end
-- Check for Weak players
- for player, vals in pairs(is_weak) do
+ for player, vals in pairs(EF.weak) do
if player:is_player() then
- is_weak[player].timer = is_weak[player].timer + dtime
+ EF.weak[player].timer = EF.weak[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#7700BB") end
- if is_weak[player].timer >= is_weak[player].dur then
- is_weak[player] = nil
+ if EF.weak[player].timer >= EF.weak[player].dur then
+ EF.weak[player] = nil
meta = player:get_meta()
- meta:set_string("_is_weak", minetest.serialize(is_weak[player]))
+ meta:set_string("_is_weak", minetest.serialize(EF.weak[player]))
end
else
- is_weak[player] = nil
+ EF.weak[player] = nil
end
end
-- Check for Strong players
- for player, vals in pairs(is_strong) do
+ for player, vals in pairs(EF.strong) do
if player:is_player() then
- is_strong[player].timer = is_strong[player].timer + dtime
+ EF.strong[player].timer = EF.strong[player].timer + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#7700BB") end
- if is_strong[player].timer >= is_strong[player].dur then
- is_strong[player] = nil
+ if EF.strong[player].timer >= EF.strong[player].dur then
+ EF.strong[player] = nil
meta = player:get_meta()
- meta:set_string("_is_strong", minetest.serialize(is_strong[player]))
+ meta:set_string("_is_strong", minetest.serialize(EF.strong[player]))
end
else
- is_strong[player] = nil
+ EF.strong[player] = nil
end
end
@@ -307,7 +365,7 @@ local is_fire_node = { ["mcl_core:lava_flowing"]=true,
-- Prevent damage to player with Fire Resistance enabled
minetest.register_on_player_hpchange(function(player, hp_change, reason)
- if is_fire_proof[player] and hp_change < 0 then
+ if EF.fire_proof[player] and hp_change < 0 then
-- This is a bit forced, but it assumes damage is taken by fire and avoids it
-- also assumes any change in hp happens between calls to this function
-- it's worth noting that you don't take damage from players in this case...
@@ -342,7 +400,7 @@ end, true)
-- ╚══════╝░╚════╝░╚═╝░░╚═╝╚═════╝░╚═╝░░░░╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝
-function mcl_potions._reset_player_effects(player)
+function mcl_potions._reset_player_effects(player, set_hud)
if not player:is_player() then
return
@@ -350,26 +408,28 @@ function mcl_potions._reset_player_effects(player)
meta = player:get_meta()
mcl_potions.make_invisible(player, false)
- is_invisible[player] = nil
- is_poisoned[player] = nil
- is_regenerating[player] = nil
- is_strong[player] = nil
- is_weak[player] = nil
- is_water_breathing[player] = nil
+ EF.invisible[player] = nil
+ EF.poisoned[player] = nil
+ EF.regenerating[player] = nil
+ EF.strong[player] = nil
+ EF.weak[player] = nil
+ EF.water_breathing[player] = nil
- is_leaping[player] = nil
+ EF.leaping[player] = nil
playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping")
- is_swift[player] = nil
+ EF.swift[player] = nil
playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness")
- is_cat[player] = nil
+ EF.night_vision[player] = nil
meta:set_int("night_vision", 0)
mcl_weather.skycolor.update_sky_color({player})
- is_fire_proof[player] = nil
+ EF.fire_proof[player] = nil
- potions_set_hudbar(player)
+ if set_hud ~= false then
+ potions_set_hud(player)
+ end
end
@@ -380,16 +440,16 @@ function mcl_potions._save_player_effects(player)
end
meta = player:get_meta()
- meta:set_string("_is_invisible", minetest.serialize(is_invisible[player]))
- meta:set_string("_is_poisoned", minetest.serialize(is_poisoned[player]))
- meta:set_string("_is_regenerating", minetest.serialize(is_regenerating[player]))
- meta:set_string("_is_strong", minetest.serialize(is_strong[player]))
- meta:set_string("_is_weak", minetest.serialize(is_weak[player]))
- meta:set_string("_is_water_breathing", minetest.serialize(is_water_breathing[player]))
- meta:set_string("_is_leaping", minetest.serialize(is_leaping[player]))
- meta:set_string("_is_swift", minetest.serialize(is_swift[player]))
- meta:set_string("_is_cat", minetest.serialize(is_cat[player]))
- meta:set_string("_is_fire_proof", minetest.serialize(is_fire_proof[player]))
+ meta:set_string("_is_invisible", minetest.serialize(EF.invisible[player]))
+ meta:set_string("_is_poisoned", minetest.serialize(EF.poisoned[player]))
+ meta:set_string("_is_regenerating", minetest.serialize(EF.regenerating[player]))
+ meta:set_string("_is_strong", minetest.serialize(EF.strong[player]))
+ meta:set_string("_is_weak", minetest.serialize(EF.weak[player]))
+ meta:set_string("_is_water_breathing", minetest.serialize(EF.water_breathing[player]))
+ meta:set_string("_is_leaping", minetest.serialize(EF.leaping[player]))
+ meta:set_string("_is_swift", minetest.serialize(EF.swift[player]))
+ meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player]))
+ meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player]))
end
@@ -401,62 +461,80 @@ function mcl_potions._load_player_effects(player)
meta = player:get_meta()
if minetest.deserialize(meta:get_string("_is_invisible")) then
- is_invisible[player] = minetest.deserialize(meta:get_string("_is_invisible"))
+ EF.invisible[player] = minetest.deserialize(meta:get_string("_is_invisible"))
mcl_potions.make_invisible(player, true)
end
if minetest.deserialize(meta:get_string("_is_poisoned")) then
- is_poisoned[player] = minetest.deserialize(meta:get_string("_is_poisoned"))
+ EF.poisoned[player] = minetest.deserialize(meta:get_string("_is_poisoned"))
end
if minetest.deserialize(meta:get_string("_is_regenerating")) then
- is_regenerating[player] = minetest.deserialize(meta:get_string("_is_regenerating"))
+ EF.regenerating[player] = minetest.deserialize(meta:get_string("_is_regenerating"))
end
if minetest.deserialize(meta:get_string("_is_strong")) then
- is_strong[player] = minetest.deserialize(meta:get_string("_is_strong"))
+ EF.strong[player] = minetest.deserialize(meta:get_string("_is_strong"))
end
if minetest.deserialize(meta:get_string("_is_weak")) then
- is_weak[player] = minetest.deserialize(meta:get_string("_is_weak"))
+ EF.weak[player] = minetest.deserialize(meta:get_string("_is_weak"))
end
if minetest.deserialize(meta:get_string("_is_water_breathing")) then
- is_water_breathing[player] = minetest.deserialize(meta:get_string("_is_water_breathing"))
+ EF.water_breathing[player] = minetest.deserialize(meta:get_string("_is_water_breathing"))
end
if minetest.deserialize(meta:get_string("_is_leaping")) then
- is_leaping[player] = minetest.deserialize(meta:get_string("_is_leaping"))
+ EF.leaping[player] = minetest.deserialize(meta:get_string("_is_leaping"))
end
if minetest.deserialize(meta:get_string("_is_swift")) then
- is_swift[player] = minetest.deserialize(meta:get_string("_is_swift"))
+ EF.swift[player] = minetest.deserialize(meta:get_string("_is_swift"))
end
if minetest.deserialize(meta:get_string("_is_cat")) then
- is_cat[player] = minetest.deserialize(meta:get_string("_is_cat"))
+ EF.night_vision[player] = minetest.deserialize(meta:get_string("_is_cat"))
end
if minetest.deserialize(meta:get_string("_is_fire_proof")) then
- is_fire_proof[player] = minetest.deserialize(meta:get_string("_is_fire_proof"))
+ EF.fire_proof[player] = minetest.deserialize(meta:get_string("_is_fire_proof"))
end
- potions_set_hudbar(player)
+end
+-- Returns true if player has given effect
+function mcl_potions.player_has_effect(player, effect_name)
+ if not EF[effect_name] then
+ return false
+ end
+ return EF[effect_name][player] ~= nil
end
minetest.register_on_leaveplayer( function(player)
mcl_potions._save_player_effects(player)
mcl_potions._reset_player_effects(player) -- clearout the buffer to prevent looking for a player not there
+ icon_ids[player:get_player_name()] = nil
end)
minetest.register_on_dieplayer( function(player)
mcl_potions._reset_player_effects(player)
+ potions_set_hud(player)
end)
minetest.register_on_joinplayer( function(player)
- mcl_potions._reset_player_effects(player) -- make sure there are no wierd holdover effects
+ mcl_potions._reset_player_effects(player, false) -- make sure there are no wierd holdover effects
mcl_potions._load_player_effects(player)
+ potions_init_icons(player)
+ -- .after required because player:hud_change doesn't work when called
+ -- in same tick as player:hud_add
+ -- (see )
+ -- FIXME: Remove minetest.after
+ minetest.after(3, function(player)
+ if player and player:is_player() then
+ potions_set_hud(player)
+ end
+ end, player)
end)
minetest.register_on_shutdown(function()
@@ -516,9 +594,9 @@ function mcl_potions.make_invisible(player, toggle)
if toggle then -- hide player
if player:is_player() then
- is_invisible[player].old_size = player:get_properties().visual_size
+ EF.invisible[player].old_size = player:get_properties().visual_size
elseif entity then
- is_invisible[player].old_size = entity.visual_size
+ EF.invisible[player].old_size = entity.visual_size
else -- if not a player or entity, do nothing
return
end
@@ -526,9 +604,9 @@ function mcl_potions.make_invisible(player, toggle)
player:set_properties({visual_size = {x = 0, y = 0}})
player:set_nametag_attributes({color = {a = 0}})
- elseif is_invisible[player] then -- show player
+ elseif EF.invisible[player] then -- show player
- player:set_properties({visual_size = is_invisible[player].old_size})
+ player:set_properties({visual_size = EF.invisible[player].old_size})
player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}})
end
@@ -645,21 +723,26 @@ function mcl_potions.swiftness_func(player, factor, duration)
return false
end
- if not is_swift[player] then
+ if not EF.swift[player] then
- is_swift[player] = {dur = duration, timer = 0}
+ EF.swift[player] = {dur = duration, timer = 0, is_slow = factor < 1}
playerphysics.add_physics_factor(player, "speed", "mcl_potions:swiftness", factor)
else
- local victim = is_swift[player]
+ local victim = EF.swift[player]
playerphysics.add_physics_factor(player, "speed", "mcl_potions:swiftness", factor)
victim.dur = math.max(duration, victim.dur - victim.timer)
victim.timer = 0
+ victim.is_slow = factor < 1
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.leaping_func(player, factor, duration)
@@ -668,14 +751,14 @@ function mcl_potions.leaping_func(player, factor, duration)
return false
end
- if not is_leaping[player] then
+ if not EF.leaping[player] then
- is_leaping[player] = {dur = duration, timer = 0}
+ EF.leaping[player] = {dur = duration, timer = 0}
playerphysics.add_physics_factor(player, "jump", "mcl_potions:leaping", factor)
else
- local victim = is_leaping[player]
+ local victim = EF.leaping[player]
playerphysics.add_physics_factor(player, "jump", "mcl_potions:leaping", factor)
victim.dur = math.max(duration, victim.dur - victim.timer)
@@ -683,18 +766,22 @@ function mcl_potions.leaping_func(player, factor, duration)
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.weakness_func(player, factor, duration)
- if not is_weak[player] then
+ if not EF.weak[player] then
- is_weak[player] = {dur = duration, timer = 0, factor = factor}
+ EF.weak[player] = {dur = duration, timer = 0, factor = factor}
else
- local victim = is_weak[player]
+ local victim = EF.weak[player]
victim.factor = factor
victim.dur = math.max(duration, victim.dur - victim.timer)
@@ -702,18 +789,22 @@ function mcl_potions.weakness_func(player, factor, duration)
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.strength_func(player, factor, duration)
- if not is_strong[player] then
+ if not EF.strong[player] then
- is_strong[player] = {dur = duration, timer = 0, factor = factor}
+ EF.strong[player] = {dur = duration, timer = 0, factor = factor}
else
- local victim = is_strong[player]
+ local victim = EF.strong[player]
victim.factor = factor
victim.dur = math.max(duration, victim.dur - victim.timer)
@@ -721,18 +812,22 @@ function mcl_potions.strength_func(player, factor, duration)
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.poison_func(player, factor, duration)
- if not is_poisoned[player] then
+ if not EF.poisoned[player] then
- is_poisoned[player] = {step = factor, dur = duration, timer = 0}
+ EF.poisoned[player] = {step = factor, dur = duration, timer = 0}
else
- local victim = is_poisoned[player]
+ local victim = EF.poisoned[player]
victim.step = math.min(victim.step, factor)
victim.dur = math.max(duration, victim.dur - victim.timer)
@@ -741,7 +836,7 @@ function mcl_potions.poison_func(player, factor, duration)
end
if player:is_player() then
- potions_set_hudbar(player)
+ potions_set_hud(player)
end
end
@@ -749,13 +844,13 @@ end
function mcl_potions.regeneration_func(player, factor, duration)
- if not is_regenerating[player] then
+ if not EF.regenerating[player] then
- is_regenerating[player] = {step = factor, dur = duration, timer = 0}
+ EF.regenerating[player] = {step = factor, dur = duration, timer = 0}
else
- local victim = is_regenerating[player]
+ local victim = EF.regenerating[player]
victim.step = math.min(victim.step, factor)
victim.dur = math.max(duration, victim.dur - victim.timer)
@@ -764,7 +859,7 @@ function mcl_potions.regeneration_func(player, factor, duration)
end
if player:is_player() then
- potions_set_hudbar(player)
+ potions_set_hud(player)
end
end
@@ -772,67 +867,79 @@ end
function mcl_potions.invisiblility_func(player, null, duration)
- if not is_invisible[player] then
+ if not EF.invisible[player] then
- is_invisible[player] = {dur = duration, timer = 0}
+ EF.invisible[player] = {dur = duration, timer = 0}
mcl_potions.make_invisible(player, true)
else
- local victim = is_invisible[player]
+ local victim = EF.invisible[player]
victim.dur = math.max(duration, victim.dur - victim.timer)
victim.timer = 0
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.water_breathing_func(player, null, duration)
- if not is_water_breathing[player] then
+ if not EF.water_breathing[player] then
- is_water_breathing[player] = {dur = duration, timer = 0}
+ EF.water_breathing[player] = {dur = duration, timer = 0}
else
- local victim = is_water_breathing[player]
+ local victim = EF.water_breathing[player]
victim.dur = math.max(duration, victim.dur - victim.timer)
victim.timer = 0
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.fire_resistance_func(player, null, duration)
- if not is_fire_proof[player] then
+ if not EF.fire_proof[player] then
- is_fire_proof[player] = {dur = duration, timer = 0}
+ EF.fire_proof[player] = {dur = duration, timer = 0}
else
- local victim = is_fire_proof[player]
+ local victim = EF.fire_proof[player]
victim.dur = math.max(duration, victim.dur - victim.timer)
victim.timer = 0
end
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions.night_vision_func(player, null, duration)
meta = player:get_meta()
- if not is_cat[player] then
+ if not EF.night_vision[player] then
- is_cat[player] = {dur = duration, timer = 0}
+ EF.night_vision[player] = {dur = duration, timer = 0}
else
- local victim = is_cat[player]
+ local victim = EF.night_vision[player]
victim.dur = math.max(duration, victim.dur - victim.timer)
victim.timer = 0
@@ -847,6 +954,10 @@ function mcl_potions.night_vision_func(player, null, duration)
end
mcl_weather.skycolor.update_sky_color({player})
+ if player:is_player() then
+ potions_set_icons(player)
+ end
+
end
function mcl_potions._extinguish_nearby_fire(pos, radius)
diff --git a/mods/ITEMS/mcl_potions/lingering.lua b/mods/ITEMS/mcl_potions/lingering.lua
index f04b655f44..cea045233c 100644
--- a/mods/ITEMS/mcl_potions/lingering.lua
+++ b/mods/ITEMS/mcl_potions/lingering.lua
@@ -108,6 +108,7 @@ function mcl_potions.register_lingering(name, descr, color, def)
local velocity = 10
local dir = placer:get_look_dir();
local pos = placer:getpos();
+ minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
obj:setvelocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:setacceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
@@ -120,7 +121,9 @@ function mcl_potions.register_lingering(name, descr, color, def)
stack_max = 1,
_on_dispense = function(stack, dispenserpos, droppos, dropnode, dropdir)
local s_pos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51))
- local obj = minetest.add_entity({x=s_pos.x+dropdir.x,y=s_pos.y+dropdir.y,z=s_pos.z+dropdir.z}, id.."_flying")
+ local pos = {x=s_pos.x+dropdir.x,y=s_pos.y+dropdir.y,z=s_pos.z+dropdir.z}
+ minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
+ local obj = minetest.add_entity(pos, id.."_flying")
local velocity = 22
obj:set_velocity({x=dropdir.x*velocity,y=dropdir.y*velocity,z=dropdir.z*velocity})
obj:set_acceleration({x=dropdir.x*-3, y=-9.8, z=dropdir.z*-3})
diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr
index ca685c202c..2bc4380ecf 100644
--- a/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr
+++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr
@@ -114,17 +114,3 @@ A throwable potion that will shatter on impact, where it gives all nearby player
This particular arrow is tipped and will give an effect when it hits a player or mob.=Эта необычная стрела с обработанным наконечником даёт эффект при попадании в игрока или моба.
-
-##### not used anymore #####
-
-Lingering Weakness Potion=Оседающее зелье слабости
-Lingering Weakness Potion +=Оседающее зелье слабости +
-Lingering Strength Potion=Оседающее зелье силы
-Lingering Strength Potion II=Оседающее зелье силы II
-Lingering Strength Potion +=Оседающее зелье силы +
-Weakness Splash Potion=Взрывающееся зелье слабости
-Weakness Splash Potion +=Взрывающееся зелье слабости +
-Strength Splash Potion=Взрывающееся зелье силы
-Strength Splash Potion II=Взрывающееся зелье силы II
-Strength Splash Potion +=Взрывающееся зелье силы +
-Grants the ability to see in darkness.=Даёт возможность видеть в темноте
diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua
index 14c7f455e4..d5cf307821 100644
--- a/mods/ITEMS/mcl_potions/splash.lua
+++ b/mods/ITEMS/mcl_potions/splash.lua
@@ -30,6 +30,7 @@ function mcl_potions.register_splash(name, descr, color, def)
local velocity = 10
local dir = placer:get_look_dir();
local pos = placer:get_pos();
+ minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
@@ -42,7 +43,9 @@ function mcl_potions.register_splash(name, descr, color, def)
stack_max = 1,
_on_dispense = function(stack, dispenserpos, droppos, dropnode, dropdir)
local s_pos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51))
- local obj = minetest.add_entity({x=s_pos.x+dropdir.x,y=s_pos.y+dropdir.y,z=s_pos.z+dropdir.z}, id.."_flying")
+ local pos = {x=s_pos.x+dropdir.x,y=s_pos.y+dropdir.y,z=s_pos.z+dropdir.z}
+ minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
+ local obj = minetest.add_entity(pos, id.."_flying")
local velocity = 22
obj:set_velocity({x=dropdir.x*velocity,y=dropdir.y*velocity,z=dropdir.z*velocity})
obj:set_acceleration({x=dropdir.x*-3, y=-9.8, z=dropdir.z*-3})
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_fire_proof.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_fire_proof.png
new file mode 100644
index 0000000000..f5df4dab63
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_fire_proof.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_food_poisoning.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_food_poisoning.png
new file mode 100644
index 0000000000..2490b0cfbf
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_food_poisoning.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_invisible.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_invisible.png
new file mode 100644
index 0000000000..ffefb89bfb
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_invisible.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_leaping.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_leaping.png
new file mode 100644
index 0000000000..5614729bad
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_leaping.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_night_vision.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_night_vision.png
new file mode 100644
index 0000000000..579defa710
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_night_vision.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_poisoned.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_poisoned.png
new file mode 100644
index 0000000000..1b96ef2d9f
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_poisoned.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_regenerating.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_regenerating.png
new file mode 100644
index 0000000000..634b74fada
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_regenerating.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_slow.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_slow.png
new file mode 100644
index 0000000000..1869a58ffb
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_slow.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_strong.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_strong.png
new file mode 100644
index 0000000000..2a69bd4a80
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_strong.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_swift.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_swift.png
new file mode 100644
index 0000000000..8ae960cc91
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_swift.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_water_breathing.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_water_breathing.png
new file mode 100644
index 0000000000..d68983b5af
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_water_breathing.png differ
diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_weak.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_weak.png
new file mode 100644
index 0000000000..9ac3985e23
Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_weak.png differ
diff --git a/mods/ITEMS/mcl_throwing/README.md b/mods/ITEMS/mcl_throwing/README.md
index c91a537e88..a1ad06a8e8 100644
--- a/mods/ITEMS/mcl_throwing/README.md
+++ b/mods/ITEMS/mcl_throwing/README.md
@@ -23,4 +23,10 @@ It's a MineClone 2 mod containing throwable items like snowballs.
- Author: dav0r (freesound.org)
- Source:
- Original title: `d0_step_on_egg_04` (file was edited)
+- `mcl_throwing_throw.ogg`:
+ - License: CC0
+ - Author: kretopi (freesound.org)
+ - Source:
+ - Original title: `Arrow002.wav` (file was edited)
+
- Everything else: See MineClone 2 license infos
diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua
index e46055e8a0..5fe34b45e3 100644
--- a/mods/ITEMS/mcl_throwing/init.lua
+++ b/mods/ITEMS/mcl_throwing/init.lua
@@ -31,6 +31,7 @@ mcl_throwing.throw = function(throw_item, pos, dir, velocity, thrower)
if velocity == nil then
velocity = 22
end
+ minetest.sound_play("mcl_throwing_throw", {pos=pos, gain=0.4, max_hear_distance=16}, true)
local itemstring = ItemStack(throw_item):get_name()
local obj = minetest.add_entity(pos, entity_mapping[itemstring])
diff --git a/mods/ITEMS/mcl_throwing/sounds/mcl_throwing_throw.ogg b/mods/ITEMS/mcl_throwing/sounds/mcl_throwing_throw.ogg
new file mode 100644
index 0000000000..acd9c04506
Binary files /dev/null and b/mods/ITEMS/mcl_throwing/sounds/mcl_throwing_throw.ogg differ
diff --git a/mods/ITEMS/mcl_tools/README.md b/mods/ITEMS/mcl_tools/README.md
new file mode 100644
index 0000000000..8089da9231
--- /dev/null
+++ b/mods/ITEMS/mcl_tools/README.md
@@ -0,0 +1,10 @@
+This mod adds tools for MineClone 2.
+
+## Credits
+
+* `default_shears_cut.ogg:`
+ * Author: SmartWentCody (CC BY 3.0)
+ * Source:
+
+Other files:
+See main MineClone 2 README.
diff --git a/mods/ITEMS/mcl_tools/sounds/mcl_tools_shears_cut.ogg b/mods/ITEMS/mcl_tools/sounds/mcl_tools_shears_cut.ogg
new file mode 100644
index 0000000000..8c32a649ab
Binary files /dev/null and b/mods/ITEMS/mcl_tools/sounds/mcl_tools_shears_cut.ogg differ
diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.fr.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.fr.tr
index 74f5282efe..56b3c3ae0d 100644
--- a/mods/MAPGEN/mcl_structures/locale/mcl_structures.fr.tr
+++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.fr.tr
@@ -1,6 +1,7 @@
# textdomain: mcl_structures
Generate a pre-defined structure near your position.=Générez une structure prédéfinie près de votre position.
Structure placed.=Structure placée.
+Village built. WARNING: Villages are experimental and might have bugs.=Village construit. AVERTISSEMENT: les villages sont expérimentaux et peuvent avoir des bogues.
Error: No structure type given. Please use “/spawnstruct ”.=Erreur: Aucun type de structure indiqué. Veuillez utiliser "/spawnstruct ".
Error: Unknown structure type. Please use “/spawnstruct ”.=Erreur: Type de structure inconnu. Veuillez utiliser "/spawnstruct ".
Use /help spawnstruct to see a list of avaiable types.=Utilisez /help spawnstruct pour voir une liste des types disponibles.
diff --git a/mods/MISC/mcl_wip/init.lua b/mods/MISC/mcl_wip/init.lua
index 351714474c..211536bbfe 100644
--- a/mods/MISC/mcl_wip/init.lua
+++ b/mods/MISC/mcl_wip/init.lua
@@ -11,7 +11,6 @@ local wip_items = {
"mcl_minecarts:furnace_minecart",
"mobs_mc:enderdragon",
"mobs_mc:wither",
- "mobs_mc:parrot",
"mobs_mc:witch",
"screwdriver:screwdriver",
"mcl_paintings:painting",
diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua
index 42fa219f8d..5a1e34ee39 100644
--- a/mods/PLAYER/mcl_hunger/hunger.lua
+++ b/mods/PLAYER/mcl_hunger/hunger.lua
@@ -18,6 +18,10 @@ minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, p
end
end
end
+ -- Also don't eat when pointing object (it could be an animal)
+ if pointed_thing.type == "object" then
+ return itemstack
+ end
local old_itemstack = itemstack
diff --git a/tools/check_translate_files.py b/tools/check_translate_files.py
new file mode 100644
index 0000000000..445dc91516
--- /dev/null
+++ b/tools/check_translate_files.py
@@ -0,0 +1,61 @@
+# Output indicator
+# !< Indicates a text line without '=' in template.txt
+# << Indicates an untranslated line in template.txt
+# !> Indicates a text line without '=' in translate file (.tr)
+# >> Indicates an unknown translated line in translate file (.tr)
+# >> Missing file: Indicates a missing translate file (.tr)
+
+import os
+import argparse
+
+parser = argparse.ArgumentParser(description='Check translation file with template.txt for a given language.')
+parser.add_argument("language", help='language code')
+args = parser.parse_args()
+
+path = "../mods/"
+code_lang = args.language
+
+def LoadTranslateFile(filename, direction):
+ result = set()
+ file = open(filename, 'r', encoding="utf-8")
+ for line in file:
+ line = line.strip()
+ if line.startswith('#') or line == '':
+ continue
+ if '=' in line:
+ result.add(line.split('=')[0])
+ else:
+ print (direction + line)
+
+ return result
+
+def CompareFiles(f1, f2):
+ r1 = LoadTranslateFile(f1, "!> ")
+ r2 = LoadTranslateFile(f2, "!< ")
+
+ for key in r1.difference(r2):
+ print (">> " + key )
+ for key in r2.difference(r1):
+ print ("<< " + key )
+
+for root, directories, files in os.walk(path):
+ if root.endswith('locale'):
+ template = None
+ language = None
+
+ for name in files:
+ if name == 'template.txt':
+ template = os.path.join(root, name)
+ if name.endswith("." + code_lang + ".tr"):
+ language = os.path.join(root, name)
+
+ if template is not None:
+ if language is None:
+ language = os.path.join(root, os.path.basename(os.path.dirname(root))) + "." + code_lang + ".tr"
+
+ if os.path.exists(language) and os.path.isfile(language):
+ print("Compare files %s with %s" % (template, language))
+ CompareFiles(template, language)
+ else:
+ LoadTranslateFile(filename, "!> ")
+ print(">> Missing file = " + language)