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 00000000..cb9a0f38 --- /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 61322614..a1346f50 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 00000000..6dc9cdc6 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 b4d43f0c..13ca7bf7 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 a4e87341..a6f0fd09 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 e585c995..d1c478a9 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 986fef08..c3d97137 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 0d332f85..aa79d909 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 00000000..9f683c0c 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 00000000..56fa1493 --- /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 69615048..dad31abb 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 be0d72e8..103579b6 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 d281a59e..aae82a39 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 d0c9c7c7..618d1e0f 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 dc231627..e8482d82 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 ddba6523..a52e6e1e 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 71627aad..dd68cbcc 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 3f62bdb2..934497a1 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 256ad496..da3922a1 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 2b39b593..71333308 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 b5c736c2..dd273c1e 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 84f9ddb8..7094dee2 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 95cba7ac..95a02bfc 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 8cb32a16..58a70de2 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 89a41fe4..eca74d3b 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 a6a2a276..90bf215e 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 3ed821b3..09bda319 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 fd1eaa1c..d974c7a6 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 783a24ff..e2f9d213 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 374ea4b5..ecf3ad5c 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 0f38f68a..97de5aba 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 d4ae7ca3..43321150 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 104ee4f5..45cc6b97 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 c9e087db..6dd2fcdb 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 d361b89b..ddf925bb 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 5069240b..1ee88b36 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 be64c94c..00000000 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 00000000..cdf6969b 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 00000000..f9e7798b 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 00000000..0aa1723b 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 00000000..2e09e3e9 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 00000000..156e6ba1 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 00000000..35901a46 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 00000000..bd6c14b4 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 00000000..fcfcffa8 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 00000000..863e15ba 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 00000000..72ff5790 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 00000000..710d3f63 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 00000000..630f0998 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 00000000..8b3498ba 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 00000000..b8d1a67d 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 00000000..3d83696f 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 00000000..506d040a 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 00000000..858362b9 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 00000000..ca090123 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 00000000..32c4337b 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 00000000..a9163e1b 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 00000000..d120e860 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 00000000..908a82b9 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 00000000..9d1001fd 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 00000000..26e1e9a5 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 00000000..293a2b99 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 00000000..6f92ffdc 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 00000000..6b125fa4 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 00000000..427069c8 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 00000000..104bdd7e 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 00000000..1dc588d4 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 00000000..1896d7d4 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 00000000..7b08a488 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 00000000..74b3336b 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 00000000..02aec38c 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 00000000..68a7fee5 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 00000000..578732d9 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 00000000..5d8cda08 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 00000000..07650e3b 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 00000000..93c093d0 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 00000000..7d7cad3f 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 00000000..9d870486 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 00000000..d33157c1 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 00000000..5853e16c 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 00000000..9fc4df09 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 00000000..b4d181e0 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 00000000..96315f21 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 00000000..ecfc30ef 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 00000000..e9ad247e 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 00000000..70b40465 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 00000000..b1f6ef77 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 00000000..afd18ff2 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 00000000..c628437f 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 00000000..c7133e08 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 00000000..10bdea14 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 00000000..7578bea2 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 00000000..f000ff1a 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 00000000..7ccf4509 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 00000000..3e37b8c2 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 00000000..21bcb427 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 00000000..d446f400 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 00000000..4794d7e0 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 00000000..aa1fb3f9 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 00000000..5de0b0dd 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 00000000..b7ac7d7a 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 00000000..e2765e62 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 00000000..5abb1b19 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 00000000..9dac01d1 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 00000000..76a66c48 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 00000000..cf2c7dc2 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 00000000..bb750f43 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 00000000..de76a688 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 00000000..47961768 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 00000000..32b77461 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 00000000..869c3ae1 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 00000000..0fde5dc8 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 00000000..0a2efd46 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 00000000..d371fc7a 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 00000000..956db6ac 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 00000000..2b68ba9f 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 00000000..fc47997e 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 58c02297..00000000 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 00000000..8f006114 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 00000000..4434015f 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 00000000..f721eb22 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 00000000..4352e36d 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 00000000..c5b39bcb 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 00000000..aa3286e4 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 00000000..203dd9b5 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 00000000..cf57285a 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 00000000..c603e07a 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 00000000..3c1b6913 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 00000000..1c05e706 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 00000000..6c0bc489 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 00000000..b20b636f 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 00000000..8a654371 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 00000000..79776601 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 00000000..f266a5c3 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 00000000..efa398c3 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 0e992671..00000000 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 f4206d2a..72a99603 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 a43bade3..39214332 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 00000000..fc09566a 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 00000000..7dde7e5a 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 4c648577..cccdebe7 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 babb1d57..9788d58c 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 3b9b1578..b865a2bd 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 0e41f4e9..30e9f6f3 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 d7d6f273..825ffd88 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 6f7e3e5a..524a918d 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 fcc05627..5cddd5b4 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 e3604f94..28c1a213 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 058c5715..fe303189 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 94b441bf..beb51d89 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 3a336456..a552f6d2 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 ae7c7700..3d6a85e5 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 56d150d9..cf35d788 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 9622fd82..ae2f28a9 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 f59e97af..66c5adca 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 00000000..e5a400e9 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 7ffa20bd..048bd43c 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 00000000..a186b549 --- /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 19eb6cc6..8494504e 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 46a7e0c0..bc06bee4 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 bdb3d5bd..841ab98b 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 00000000..31a1fa9d --- /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 5ff15ecc..377a24c0 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 9d56bb8c..00000000 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 53d45c18..5ddc1932 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 00000000..23f53c40 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 8319ce21..a9a11bce 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 d0daa96a..2bc0e2b4 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 eb69d338..fba702ed 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 053990ed..f73ee038 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 53d45c18..00000000 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 20ac848d..df1a2317 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 d18fbe5d..8301dfa3 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 5660f922..fe879c95 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 1bc17354..bc95fdb4 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 6e41007c..d4c5fb08 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 c8911e5f..ca8b0f71 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 00000000..6956e4d8 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 b27c9cf3..7725acdf 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 00000000..232026fb --- /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 847b9700..0d9a1f60 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 f9ac0e01..82ce39e1 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 277cc565..9c0077ea 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 f9ede771..bbfe7566 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 4ed94a0b..c3bfa05d 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 1202ec70..ac12857b 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 79dd2aee..78c5b7f9 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 39140587..dc091a0f 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 b46a6628..6ab7a3c6 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 e6fcd4f2..2daaf1e5 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 27a4513a..59321099 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 fb17734d..40321efe 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 36fbac01..1bc75626 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 71221cc5..026428db 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 ba76b749..da85b8e3 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 f81f381e..bfa62488 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 048072be..78b8a453 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 f546d16c..2cfdd370 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 0d578faf..7b505216 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 2eff8c60..2e0dfe1a 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 9fb4f8e1..975976db 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 560030e8..d3faaa8e 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 5a5e74b3..9dadc3a0 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 e7f69644..d3552001 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 00000000..82311b3d 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 dab96351..f1384ab3 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 f04b655f..cea04523 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 ca685c20..2bc4380e 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 14c7f455..d5cf3078 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 00000000..f5df4dab 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 00000000..2490b0cf 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 00000000..ffefb89b 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 00000000..5614729b 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 00000000..579defa7 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 00000000..1b96ef2d 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 00000000..634b74fa 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 00000000..1869a58f 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 00000000..2a69bd4a 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 00000000..8ae960cc 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 00000000..d68983b5 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 00000000..9ac3985e 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 c91a537e..a1ad06a8 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 e46055e8..5fe34b45 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 00000000..acd9c045 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 00000000..8089da92 --- /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 00000000..8c32a649 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 74f5282e..56b3c3ae 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 35171447..211536bb 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 42fa219f..5a1e34ee 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 00000000..445dc915 --- /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)