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 000000000..cb9a0f38e --- /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 613226144..a1346f50b 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 000000000..6dc9cdc69 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 b4d43f0c8..13ca7bf72 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 a4e87341f..a6f0fd095 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 e585c9950..d1c478a99 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 986fef084..c3d971374 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 0d332f85c..aa79d909c 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 000000000..9f683c0cf 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 000000000..56fa14937 --- /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 696150480..dad31abb8 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 be0d72e82..103579b67 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 d281a59ed..aae82a39b 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 d0c9c7c71..618d1e0f0 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 dc231627c..e8482d820 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 ddba6523e..a52e6e1e1 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 71627aada..dd68cbcce 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 3f62bdb2a..934497a10 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 256ad4963..da3922a10 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 2b39b5937..713333085 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 b5c736c27..dd273c1eb 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 84f9ddb83..7094dee24 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 95cba7aca..95a02bfca 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 8cb32a165..58a70de2f 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 89a41fe44..eca74d3ba 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 a6a2a276d..90bf215ed 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 3ed821b34..09bda3199 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 fd1eaa1ce..d974c7a60 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 783a24ff4..e2f9d213f 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 374ea4b59..ecf3ad5c0 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 0f38f68a3..97de5aba6 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 d4ae7ca33..433211503 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 104ee4f57..45cc6b979 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 c9e087db3..6dd2fcdbe 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 d361b89b6..ddf925bbb 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 5069240bd..1ee88b362 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 be64c94c0..000000000 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 000000000..cdf6969bb 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 000000000..f9e7798b8 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 000000000..0aa1723b1 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 000000000..2e09e3e93 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 000000000..156e6ba18 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 000000000..35901a46e 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 000000000..bd6c14b47 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 000000000..fcfcffa88 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 000000000..863e15baa 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 000000000..72ff57902 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 000000000..710d3f632 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 000000000..630f09987 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 000000000..8b3498baf 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 000000000..b8d1a67d0 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 000000000..3d83696f9 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 000000000..506d040a4 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 000000000..858362b92 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 000000000..ca090123f 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 000000000..32c4337ba 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 000000000..a9163e1b3 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 000000000..d120e860f 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 000000000..908a82b9e 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 000000000..9d1001fd3 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 000000000..26e1e9a56 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 000000000..293a2b998 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 000000000..6f92ffdc3 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 000000000..6b125fa4f 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 000000000..427069c85 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 000000000..104bdd7ec 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 000000000..1dc588d4d 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 000000000..1896d7d4d 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 000000000..7b08a4884 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 000000000..74b3336be 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 000000000..02aec38c6 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 000000000..68a7fee53 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 000000000..578732d91 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 000000000..5d8cda08d 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 000000000..07650e3bb 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 000000000..93c093d05 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 000000000..7d7cad3f8 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 000000000..9d870486b 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 000000000..d33157c14 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 000000000..5853e16c5 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 000000000..9fc4df09d 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 000000000..b4d181e0e 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 000000000..96315f210 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 000000000..ecfc30ef6 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 000000000..e9ad247eb 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 000000000..70b404651 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 000000000..b1f6ef770 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 000000000..afd18ff23 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 000000000..c628437f2 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 000000000..c7133e084 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 000000000..10bdea141 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 000000000..7578bea25 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 000000000..f000ff1a4 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 000000000..7ccf45091 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 000000000..3e37b8c28 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 000000000..21bcb4270 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 000000000..d446f400a 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 000000000..4794d7e0b 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 000000000..aa1fb3f96 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 000000000..5de0b0dd2 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 000000000..b7ac7d7a6 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 000000000..e2765e620 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 000000000..5abb1b190 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 000000000..9dac01d1a 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 000000000..76a66c483 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 000000000..cf2c7dc26 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 000000000..bb750f430 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 000000000..de76a688a 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 000000000..479617681 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 000000000..32b774615 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 000000000..869c3ae10 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 000000000..0fde5dc80 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 000000000..0a2efd469 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 000000000..d371fc7ae 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 000000000..956db6ac4 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 000000000..2b68ba9f3 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 000000000..fc47997e8 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 58c02297c..000000000 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 000000000..8f0061144 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 000000000..4434015f8 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 000000000..f721eb221 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 000000000..4352e36dd 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 000000000..c5b39bcbc 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 000000000..aa3286e47 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 000000000..203dd9b57 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 000000000..cf57285a1 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 000000000..c603e07ac 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 000000000..3c1b6913e 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 000000000..1c05e7068 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 000000000..6c0bc4899 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 000000000..b20b636fc 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 000000000..8a6543716 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 000000000..79776601e 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 000000000..f266a5c36 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 000000000..efa398c32 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 0e992671e..000000000 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 f4206d2ac..72a996038 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 a43bade39..392143321 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 000000000..fc09566a5 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 000000000..7dde7e5a8 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 4c648577d..cccdebe7a 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 babb1d573..9788d58c6 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 3b9b15787..b865a2bd5 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 0e41f4e99..30e9f6f36 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 d7d6f273a..825ffd88f 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 6f7e3e5aa..524a918de 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 fcc056271..5cddd5b42 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 e3604f947..28c1a2138 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 058c57153..fe3031895 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 94b441bfe..beb51d89f 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 3a3364560..a552f6d23 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 ae7c77004..3d6a85e51 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 56d150d95..cf35d788b 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 9622fd829..ae2f28a9c 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 f59e97af6..66c5adcac 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 000000000..e5a400e95 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 7ffa20bdf..048bd43c6 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 000000000..a186b549b --- /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 19eb6cc60..8494504e9 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 46a7e0c00..bc06bee43 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 bdb3d5bdc..841ab98b4 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 000000000..31a1fa9de --- /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 5ff15eccb..377a24c00 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 9d56bb8c2..000000000 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 53d45c18a..5ddc1932d 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 000000000..23f53c404 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 8319ce210..a9a11bce5 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 d0daa96a6..2bc0e2b46 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 eb69d3380..fba702ede 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 053990ed4..f73ee0387 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 53d45c18a..000000000 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 20ac848dc..df1a2317b 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 d18fbe5de..8301dfa33 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 5660f922b..fe879c95c 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 1bc17354c..bc95fdb4f 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 6e41007cd..d4c5fb081 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 c8911e5fe..ca8b0f718 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 000000000..6956e4d8d 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 b27c9cf37..7725acdfd 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 000000000..232026fba --- /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 847b97001..0d9a1f601 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 f9ac0e01e..82ce39e1a 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 277cc565f..9c0077ea2 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 f9ede7718..bbfe75668 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 4ed94a0b3..c3bfa05df 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 1202ec70d..ac12857b9 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 79dd2aee0..78c5b7f93 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 391405879..dc091a0f4 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 b46a66288..6ab7a3c67 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 e6fcd4f21..2daaf1e5d 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 27a4513aa..59321099a 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 fb17734d7..40321efe9 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 36fbac012..1bc756260 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 71221cc5c..026428db2 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 ba76b749e..da85b8e3c 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 f81f381e2..bfa62488c 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 048072be5..78b8a453e 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 f546d16ca..2cfdd370b 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 0d578faf1..7b5052166 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 2eff8c602..2e0dfe1a5 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 9fb4f8e13..975976db2 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 560030e8d..d3faaa8e2 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 5a5e74b33..9dadc3a0d 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 e7f696440..d35520015 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 000000000..82311b3dc 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 dab96351e..f1384ab30 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 f04b655f4..cea045233 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 ca685c202..2bc4380ec 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 14c7f455e..d5cf30782 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 000000000..f5df4dab6 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 000000000..2490b0cfb 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 000000000..ffefb89bf 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 000000000..5614729ba 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 000000000..579defa71 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 000000000..1b96ef2d9 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 000000000..634b74fad 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 000000000..1869a58ff 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 000000000..2a69bd4a8 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 000000000..8ae960cc9 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 000000000..d68983b5a 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 000000000..9ac3985e2 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 c91a537e8..a1ad06a8e 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 e46055e8a..5fe34b45e 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 000000000..acd9c0450 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 000000000..8089da923 --- /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 000000000..8c32a649a 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 74f5282ef..56b3c3ae0 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 351714474..211536bbf 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 42fa219f8..5a1e34ee3 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 000000000..445dc9151 --- /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)