diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 5872ce742..e894eebd7 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -74,6 +74,18 @@ function mcl_util.check_dtime_timer(self, dtime, timer_name, threshold) return false end +-- While we should always favour the new minetest vector functions such as vector.new or vector.offset which validate on +-- creation. There may be cases where state gets corrupted and we may have to check the vector is valid if created the +-- old way. This allows us to do this as a tactical solution until old style vectors are completely removed. +function mcl_util.validate_vector (vect) + if vect then + if tonumber(vect.x) and tonumber(vect.y) and tonumber(vect.z) then + return true + end + end + return false +end + -- Minetest 5.3.0 or less can only measure the light level. This came in at 5.4 -- This function has been known to fail in multiple places so the error handling is added increase safety and improve -- debugging. See: @@ -612,7 +624,7 @@ function mcl_util.deal_damage(target, damage, mcl_reason) end return end - end + elseif not target:is_player() then return end local is_immortal = target:get_armor_groups().immortal or 0 if is_immortal>0 then diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index fabfae91c..3ceef80ea 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -62,8 +62,13 @@ end local function set_double_attach(boat) boat._driver:set_attach(boat.object, "", {x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0}) - boat._passenger:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0}) + if boat._passenger:is_player() then + boat._passenger:set_attach(boat.object, "", + {x = 0, y = 0.42, z = -6.2}, {x = 0, y = 0, z = 0}) + else + boat._passenger:set_attach(boat.object, "", + {x = 0, y = 0.42, z = -4.5}, {x = 0, y = 270, z = 0}) + end end local function set_choat_attach(boat) boat._driver:set_attach(boat.object, "", @@ -155,7 +160,7 @@ local boat = { minetest.register_on_respawnplayer(detach_object) function boat.on_rightclick(self, clicker) - if self._passenger or not clicker or clicker:get_attach() then + if self._passenger or not clicker or clicker:get_attach() or (self.name == "mcl_boats:chest_boat" and self._driver) then return end attach_object(self, clicker) diff --git a/mods/ENTITIES/mcl_dripping/README.md b/mods/ENTITIES/mcl_dripping/README.md index d6ff75ff1..5f4b2854f 100644 --- a/mods/ENTITIES/mcl_dripping/README.md +++ b/mods/ENTITIES/mcl_dripping/README.md @@ -1,36 +1,36 @@ -# mcl_dripping - -Dripping Mod by kddekadenz, modified for MineClone 2 by Wuzzy, NO11 and AFCM - -## Manual - -- drops are generated rarely under solid nodes -- they will stay some time at the generated block and than they fall down -- when they collide with the ground, a sound is played and they are destroyed - -Water and Lava have builtin drops registered. - -## License - -code & sounds: CC0 - -## API - -```lua -mcl_dripping.register_drop({ - -- The group the liquid's nodes belong to - liquid = "water", - -- The texture used (particles will take a random 2x2 area of it) - texture = "default_water_source_animated.png", - -- Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` - light = 1, - -- The nodes (or node group) the particles will spawn under - nodes = { "group:opaque", "group:leaves" }, - -- The sound that will be played then the particle detaches from the roof, see SimpleSoundSpec in lua_api.txt - sound = "drippingwater_drip", - -- The interval for the ABM to run - interval = 60, - -- The chance of the ABM - chance = 10, -}) -``` +# mcl_dripping + +Dripping Mod by kddekadenz, modified for MineClone 2 by Wuzzy, NO11 and AFCM + +## Manual + +- drops are generated rarely under solid nodes +- they will stay some time at the generated block and than they fall down +- when they collide with the ground, a sound is played and they are destroyed + +Water and Lava have builtin drops registered. + +## License + +code & sounds: CC0 + +## API + +```lua +mcl_dripping.register_drop({ + -- The group the liquid's nodes belong to + liquid = "water", + -- The texture used (particles will take a random 2x2 area of it) + texture = "mcl_core_water_source_animation.png", + -- Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` + light = 1, + -- The nodes (or node group) the particles will spawn under + nodes = { "group:opaque", "group:leaves" }, + -- The sound that will be played then the particle detaches from the roof, see SimpleSoundSpec in lua_api.txt + sound = "drippingwater_drip", + -- The interval for the ABM to run + interval = 60, + -- The chance of the ABM + chance = 10, +}) +``` diff --git a/mods/ENTITIES/mcl_dripping/init.lua b/mods/ENTITIES/mcl_dripping/init.lua index b5a5043b7..5a96e65c4 100644 --- a/mods/ENTITIES/mcl_dripping/init.lua +++ b/mods/ENTITIES/mcl_dripping/init.lua @@ -82,7 +82,7 @@ end mcl_dripping.register_drop({ liquid = "water", - texture = "default_water_source_animated.png", + texture = "mcl_core_water_source_animation.png", light = 1, nodes = { "group:opaque", "group:leaves" }, sound = "drippingwater_drip", @@ -92,7 +92,7 @@ mcl_dripping.register_drop({ mcl_dripping.register_drop({ liquid = "lava", - texture = "default_lava_source_animated.png", + texture = "mcl_core_lava_source_animation.png", light = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), nodes = { "group:opaque" }, sound = "drippingwater_lavadrip", diff --git a/mods/ENTITIES/mcl_mobs/combat.lua b/mods/ENTITIES/mcl_mobs/combat.lua index 4b3393e36..7775c1b8e 100644 --- a/mods/ENTITIES/mcl_mobs/combat.lua +++ b/mods/ENTITIES/mcl_mobs/combat.lua @@ -21,6 +21,8 @@ local function atan(x) end end +mcl_mobs.effect_functions = {} + -- check if daytime and also if mob is docile during daylight hours function mob_class:day_docile() @@ -382,7 +384,8 @@ function mob_class:monster_attack() -- find specific mob to attack, failing that attack player/npc/animal if specific_attack(self.specific_attack, name) and (type == "player" or ( type == "npc" and self.attack_npcs ) - or (type == "animal" and self.attack_animals == true)) then + or (type == "animal" and self.attack_animals == true) + or (self.extra_hostile and not self.attack_exception(player))) then p = player:get_pos() sp = s @@ -1103,6 +1106,11 @@ function mob_class:do_states_attack (dtime) full_punch_interval = 1.0, damage_groups = {fleshy = self.damage} }, nil) + if self.dealt_effect then + mcl_mobs.effect_functions[self.dealt_effect.name]( + self.attack, self.dealt_effect.factor, self.dealt_effect.dur + ) + end end else self.custom_attack(self, p) @@ -1209,6 +1217,9 @@ function mob_class:do_states_attack (dtime) end end end + + elseif self.attack_type == "custom" and self.attack_state then + self.attack_state(self, dtime) else end diff --git a/mods/ENTITIES/mcl_mobs/effects.lua b/mods/ENTITIES/mcl_mobs/effects.lua index aa44a67f7..e746fef39 100644 --- a/mods/ENTITIES/mcl_mobs/effects.lua +++ b/mods/ENTITIES/mcl_mobs/effects.lua @@ -1,5 +1,7 @@ local math, tonumber, vector, minetest, mcl_mobs = math, tonumber, vector, minetest, mcl_mobs local mob_class = mcl_mobs.mob_class +local validate_vector = mcl_util.validate_vector + local active_particlespawners = {} local disable_blood = minetest.settings:get_bool("mobs_disable_blood") local DEFAULT_FALL_SPEED = -9.81*1.5 @@ -9,16 +11,6 @@ local PATHFINDING = "gowp" local player_transfer_distance = tonumber(minetest.settings:get("player_transfer_distance")) or 128 if player_transfer_distance == 0 then player_transfer_distance = math.huge end - -local function validate_vector (vect) - if vect then - if tonumber(vect.x) and tonumber(vect.y) and tonumber(vect.z) then - return true - end - end - return false -end - -- custom particle effects function mcl_mobs.effect(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down) @@ -418,7 +410,7 @@ function mob_class:check_head_swivel(dtime) --final_rotation = vector.new(0,0,0) end - mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horrizonatal_head_height), final_rotation) + mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horizontal_head_height), final_rotation) end diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index 62100c627..843315039 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -147,7 +147,7 @@ function mcl_mobs.register_mob(name, def) head_eye_height = def.head_eye_height or def.bone_eye_height or 0, -- how hight aproximatly the mobs head is fromm the ground to tell the mob how high to look up at the player curiosity = def.curiosity or 1, -- how often mob will look at player on idle head_yaw = def.head_yaw or "y", -- axis to rotate head on - horrizonatal_head_height = def.horrizonatal_head_height or 0, + horizontal_head_height = def.horizontal_head_height or 0, wears_armor = def.wears_armor, -- a number value used to index texture slot for armor stepheight = def.stepheight or 0.6, name = name, @@ -287,6 +287,7 @@ function mcl_mobs.register_mob(name, def) spawn_in_group_min = def.spawn_in_group_min, noyaw = def.noyaw or false, particlespawners = def.particlespawners, + spawn_check = def.spawn_check, -- End of MCL2 extensions on_spawn = def.on_spawn, on_blast = def.on_blast or function(self,damage) @@ -297,6 +298,7 @@ function mcl_mobs.register_mob(name, def) return false, true, {} end, do_punch = def.do_punch, + deal_damage = def.deal_damage, on_breed = def.on_breed, on_grown = def.on_grown, on_pick_up = def.on_pick_up, @@ -311,8 +313,15 @@ function mcl_mobs.register_mob(name, def) return self:mob_activate(staticdata, def, dtime) end, + attack_state = def.attack_state, harmed_by_heal = def.harmed_by_heal, - on_lightning_strike = def.on_lightning_strike + is_boss = def.is_boss, + dealt_effect = def.dealt_effect, + on_lightning_strike = def.on_lightning_strike, + extra_hostile = def.extra_hostile, + attack_exception = def.attack_exception or function(p) return false end, + + _spawner = def._spawner, } minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta)) @@ -343,9 +352,10 @@ function mcl_mobs.register_arrow(name, def) collisionbox = {0, 0, 0, 0, 0, 0}, -- remove box around arrows timer = 0, switch = 0, + _lifetime = def._lifetime or 150, owner_id = def.owner_id, rotate = def.rotate, - on_punch = function(self) + on_punch = def.on_punch or function(self) local vel = self.object:get_velocity() self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1}) end, @@ -362,7 +372,7 @@ function mcl_mobs.register_arrow(name, def) local pos = self.object:get_pos() if self.switch == 0 - or self.timer > 150 + or self.timer > self._lifetime or not within_limits(pos, 0) then mcl_burning.extinguish(self.object) self.object:remove(); diff --git a/mods/ENTITIES/mcl_mobs/physics.lua b/mods/ENTITIES/mcl_mobs/physics.lua index 341e28984..64bcfa822 100644 --- a/mods/ENTITIES/mcl_mobs/physics.lua +++ b/mods/ENTITIES/mcl_mobs/physics.lua @@ -1,5 +1,6 @@ local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs local mob_class = mcl_mobs.mob_class +local validate_vector = mcl_util.validate_vector local ENTITY_CRAMMING_MAX = 24 local CRAMMING_DAMAGE = 3 @@ -355,7 +356,7 @@ function mob_class:set_yaw(yaw, delay, dtime) if math.abs(target_shortest_path_nums) > 10 then self.object:set_yaw(self.object:get_yaw()+(target_shortest_path*(3.6*ddtime))) - if self.acc then + if validate_vector(self.acc) then self.acc=vector.rotate_around_axis(self.acc,vector.new(0,1,0), target_shortest_path*(3.6*ddtime)) end end @@ -681,6 +682,9 @@ function mob_class:do_env_damage() -- don't fall when on ignore, just stand still if self.standing_in == "ignore" then self.object:set_velocity({x = 0, y = 0, z = 0}) + -- wither rose effect + elseif self.standing_in == "mcl_flowers:wither_rose" then + mcl_potions.withering_func(self.object, 1, 2) end local nodef = minetest.registered_nodes[self.standing_in] diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index c677aeacf..9c51c0f86 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -2,6 +2,13 @@ local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs local mob_class = mcl_mobs.mob_class +local modern_lighting = minetest.settings:get_bool("mcl_mobs_modern_lighting", true) +local nether_threshold = tonumber(minetest.settings:get("mcl_mobs_nether_threshold")) or 11 +local end_threshold = tonumber(minetest.settings:get("mcl_mobs_end_threshold")) or 0 +local overworld_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_threshold")) or 0 +local overworld_sky_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_sky_threshold")) or 7 +local overworld_passive_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_passive_threshold")) or 7 + local get_node = minetest.get_node local get_item_group = minetest.get_item_group local get_node_light = minetest.get_node_light @@ -709,9 +716,6 @@ local function spawn_check(pos, spawn_def) and spawn_def.dimension == dimension and biome_check(spawn_def.biomes, gotten_biome) then - --mcl_log("Level 1 spawn check passed") - --minetest.log("Mob: " .. mob_def.name) - if (is_ground or spawn_def.type_of_spawning ~= "ground") and (spawn_def.type_of_spawning ~= "ground" or not is_leaf) and (not is_farm_animal(spawn_def.name) or is_grass) @@ -721,20 +725,42 @@ local function spawn_check(pos, spawn_def) and (spawn_def.check_position and spawn_def.check_position(pos) or spawn_def.check_position == nil) and ( not spawn_protected or not minetest.is_protected(pos, "") ) then - --mcl_log("Level 2 spawn check passed") - local gotten_light = get_node_light(pos) - if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then - --mcl_log("Level 3 spawn check passed") - return true + + if modern_lighting then + local my_node = get_node(pos) + local sky_light = minetest.get_natural_light(pos) + local art_light = minetest.get_artificial_light(my_node.param1) + + if dimension == "nether" then + if art_light <= nether_threshold then + return true + end + elseif dimension == "end" then + if art_light <= end_threshold then + return true + end + elseif dimension == "overworld" then + if mob_type == "monster" then + if mob_def.spawn_check then + return mob_def.spawn_check(pos, gotten_light, art_light, sky_light) + elseif art_light <= overworld_threshold and sky_light <= overworld_sky_threshold then + return true + end + else + if mob_def.spawn_check then + return mob_def.spawn_check(pos, gotten_light, art_light, sky_light) + elseif gotten_light > overworld_passive_threshold then + return true + end + end + end else - --mcl_log("Spawn check level 3 failed") + if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then + return true + end end - else - --mcl_log("Spawn check level 2 failed") end - else - --mcl_log("Spawn check level 1 failed") end return false end diff --git a/mods/ENTITIES/mcl_wither_spawning/init.lua b/mods/ENTITIES/mcl_wither_spawning/init.lua index 74cd1e6e2..2a7a9c595 100644 --- a/mods/ENTITIES/mcl_wither_spawning/init.lua +++ b/mods/ENTITIES/mcl_wither_spawning/init.lua @@ -2,6 +2,9 @@ local dim = {"x", "z"} local modpath = minetest.get_modpath(minetest.get_current_modname()) +local anti_troll = minetest.settings:get_bool("wither_anti_troll_measures", false) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + local function load_schem(filename) local file = io.open(modpath .. "/schems/" .. filename, "r") local data = minetest.deserialize(file:read()) @@ -9,6 +12,14 @@ local function load_schem(filename) return data end +local wboss_overworld = 0 +local wboss_nether = 0 +local wboss_end = 0 + +local LIM_OVERWORLD = tonumber(minetest.settings:get("wither_cap_overworld")) or 3 +local LIM_NETHER = tonumber(minetest.settings:get("wither_cap_nether")) or 10 +local LIM_END = tonumber(minetest.settings:get("wither_cap_end")) or 5 + local wither_spawn_schems = {} for _, d in pairs(dim) do @@ -16,8 +27,13 @@ for _, d in pairs(dim) do end local function check_schem(pos, schem) + local cn_name for _, n in pairs(schem) do - if minetest.get_node(vector.add(pos, n)).name ~= n.name then + cn_name = minetest.get_node(vector.add(pos, n)).name + if string.find(cn_name, "mcl_heads:wither_skeleton") then + cn_name = "mcl_heads:wither_skeleton" + end + if cn_name ~= n.name then return false end end @@ -30,14 +46,32 @@ local function remove_schem(pos, schem) end end -local function wither_spawn(pos) +local function check_limit(pos) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "overworld" and wboss_overworld >= LIM_OVERWORLD then return false + elseif dim == "end" and wboss_end >= LIM_END then return false + elseif wboss_nether >= LIM_NETHER then return false + else return true end +end + +local function wither_spawn(pos, player) + if peaceful then return end for _, d in pairs(dim) do for i = 0, 2 do local p = vector.add(pos, {x = 0, y = -2, z = 0, [d] = -i}) local schem = wither_spawn_schems[d] - if check_schem(p, schem) then + if check_schem(p, schem) and (not anti_troll or check_limit(pos)) then remove_schem(p, schem) - minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither") + local wither = minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither") + if not wither then return end + local wither_ent = wither:get_luaentity() + wither_ent._spawner = player:get_player_name() + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "overworld" then + wboss_overworld = wboss_overworld + 1 + elseif dim == "end" then + wboss_end = wboss_end + 1 + else wboss_nether = wboss_nether + 1 end local objects = minetest.get_objects_inside_radius(pos, 20) for _, players in ipairs(objects) do if players:is_player() then @@ -54,7 +88,19 @@ local old_on_place = wither_head.on_place function wither_head.on_place(itemstack, placer, pointed) local n = minetest.get_node(vector.offset(pointed.above,0,-1,0)) if n and n.name == "mcl_nether:soul_sand" then - minetest.after(0, wither_spawn, pointed.above) + minetest.after(0, wither_spawn, pointed.above, placer) end return old_on_place(itemstack, placer, pointed) end + +if anti_troll then + -- pull wither counts per dimension + minetest.register_globalstep(function(dtime) + wboss_overworld = mobs_mc.wither_count_overworld + wboss_nether = mobs_mc.wither_count_nether + wboss_end = mobs_mc.wither_count_end + mobs_mc.wither_count_overworld = 0 + mobs_mc.wither_count_nether = 0 + mobs_mc.wither_count_end = 0 + end) +end diff --git a/mods/ENTITIES/mobs_mc/axolotl.lua b/mods/ENTITIES/mobs_mc/axolotl.lua index 087f201c7..563db8bf7 100644 --- a/mods/ENTITIES/mobs_mc/axolotl.lua +++ b/mods/ENTITIES/mobs_mc/axolotl.lua @@ -13,7 +13,7 @@ local axolotl = { head_swivel = "head.control", bone_eye_height = -1, head_eye_height = -0.5, - horrizonatal_head_height = 0, + horizontal_head_height = 0, curiosity = 10, head_yaw="z", @@ -78,7 +78,6 @@ local axolotl = { attack_animals = true, specific_attack = { "extra_mobs_cod", - "mobs_mc:sheep", "extra_mobs_glow_squid", "extra_mobs_salmon", "extra_mobs_tropical_fish", diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index b5532e2ee..b8b650877 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -2,6 +2,18 @@ local S = minetest.get_translator("mobs_mc") +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + local date = os.date("*t") + local maxlight + if (date.month == 10 and date.day >= 20) or (date.month == 11 and date.day <= 3) then + maxlight = 6 + else + maxlight = 3 + end + + return artificial_light <= maxlight +end + mcl_mobs.register_mob("mobs_mc:bat", { description = S("Bat"), type = "animal", @@ -50,6 +62,7 @@ mcl_mobs.register_mob("mobs_mc:bat", { jump = false, fly = true, makes_footstep_sound = false, + spawn_check = spawn_check, }) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 6d92de210..98cf4728a 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -11,6 +11,9 @@ local mod_target = minetest.get_modpath("mcl_target") --################### BLAZE --################### +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + return artificial_light <= 11 +end mcl_mobs.register_mob("mobs_mc:blaze", { description = S("Blaze"), @@ -137,6 +140,7 @@ mcl_mobs.register_mob("mobs_mc:blaze", { }, }) end, + spawn_check = spawn_check, }) mcl_mobs:spawn_specific( diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index ca942d355..5702db4c7 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -23,7 +23,7 @@ mcl_mobs.register_mob("mobs_mc:chicken", { head_swivel = "head.control", bone_eye_height = 4, head_eye_height = 1.5, - horrizonatal_head_height = -.3, + horizontal_head_height = -.3, curiosity = 10, head_yaw="z", visual_size = {x=1,y=1}, diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 9d1aa1aaa..86b94eea3 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -24,7 +24,7 @@ local cow_def = { head_swivel = "head.control", bone_eye_height = 10, head_eye_height = 1.1, - horrizonatal_head_height=-1.8, + horizontal_head_height=-1.8, curiosity = 2, head_yaw="z", makes_footstep_sound = true, diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index fb92f51c4..d916596dd 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -127,7 +127,7 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", { minetest.set_node(vector.add(self._portal_pos, vector.new(0, 5, 0)), {name = "mcl_end:dragon_egg"}) end end - + -- Free The End Advancement for _,players in pairs(minetest.get_objects_inside_radius(pos,64)) do if players:is_player() then @@ -136,6 +136,7 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", { end end, fire_resistant = true, + is_boss = true, }) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 32bfc97ea..578e7c88a 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -62,7 +62,7 @@ mcl_mobs.register_mob("mobs_mc:llama", { head_swivel = "head.control", bone_eye_height = 11, head_eye_height = 3, - horrizonatal_head_height=0, + horizontal_head_height=0, curiosity = 60, head_yaw = "z", diff --git a/mods/ENTITIES/mobs_mc/mod.conf b/mods/ENTITIES/mobs_mc/mod.conf index 5b94879b2..ec7446505 100644 --- a/mods/ENTITIES/mobs_mc/mod.conf +++ b/mods/ENTITIES/mobs_mc/mod.conf @@ -2,4 +2,4 @@ name = mobs_mc author = maikerumine description = Adds Minecraft-like monsters and animals. depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core, mcl_util -optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, doc_items +optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, doc_items, mcl_worlds diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 65181a581..7aadda492 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -39,7 +39,7 @@ local ocelot = { head_swivel = "head.control", bone_eye_height = 6.2, head_eye_height = 0.4, - horrizonatal_head_height=-0, + horizontal_head_height=-0, head_yaw="z", curiosity = 4, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.69, 0.3}, diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index ed2892aca..7d4c50f1c 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -137,7 +137,7 @@ mcl_mobs.register_mob("mobs_mc:parrot", { xp_max = 3, head_swivel = "head.control", bone_eye_height = 1.1, - horrizonatal_head_height=0, + horizontal_head_height=0, curiosity = 10, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, visual = "mesh", diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 9084c5d4d..7b1f4e879 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -22,7 +22,7 @@ mcl_mobs.register_mob("mobs_mc:pig", { head_swivel = "head.control", bone_eye_height = 7.5, head_eye_height = 0.8, - horrizonatal_head_height=-1, + horizontal_head_height=-1, curiosity = 3, head_yaw="z", makes_footstep_sound = true, diff --git a/mods/ENTITIES/mobs_mc/piglin.lua b/mods/ENTITIES/mobs_mc/piglin.lua index 4f701b3e9..27f5a72f4 100644 --- a/mods/ENTITIES/mobs_mc/piglin.lua +++ b/mods/ENTITIES/mobs_mc/piglin.lua @@ -219,6 +219,10 @@ mcl_mobs.register_mob("mobs_mc:sword_piglin", sword_piglin) -- Zombified Piglin -- +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + return artificial_light <= 11 +end + local zombified_piglin = { description = S("Zombie Piglin"), -- type="animal", passive=false: This combination is needed for a neutral mob which becomes hostile, if attacked @@ -256,6 +260,7 @@ local zombified_piglin = { }, jump = true, makes_footstep_sound = true, + spawn_check = spawn_check, walk_velocity = .8, run_velocity = 2.6, pathfinding = 1, diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index d6667a256..18d6f3a13 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -27,7 +27,7 @@ mcl_mobs.register_mob("mobs_mc:polar_bear", { head_swivel = "head.control", bone_eye_height = 2.6, head_eye_height = 1, - horrizonatal_head_height = 0, + horizontal_head_height = 0, curiosity = 20, head_yaw="z", visual_size = {x=3.0, y=3.0}, diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index 6c4317519..38fae935f 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -18,7 +18,7 @@ local rabbit = { head_swivel = "head.control", bone_eye_height = 2, head_eye_height = 0.5, - horrizonatal_head_height = -.3, + horizontal_head_height = -.3, curiosity = 20, head_yaw="z", visual = "mesh", diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index af1222403..4a5e924d8 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -67,7 +67,7 @@ mcl_mobs.register_mob("mobs_mc:sheep", { head_swivel = "head.control", bone_eye_height = 3.3, head_eye_height = 1.1, - horrizonatal_head_height=-.7, + horizontal_head_height=-.7, curiosity = 6, head_yaw="z", visual = "mesh", diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index ab659a2a0..ec8ee19bb 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -4,6 +4,10 @@ local S = minetest.get_translator("mobs_mc") +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + return artificial_light <= 11 +end + mcl_mobs.register_mob("mobs_mc:silverfish", { description = S("Silverfish"), type = "monster", @@ -53,6 +57,7 @@ mcl_mobs.register_mob("mobs_mc:silverfish", { view_range = 16, attack_type = "dogfight", damage = 1, + spawn_check = spawn_check, }) mcl_mobs.register_egg("mobs_mc:silverfish", S("Silverfish"), "#6d6d6d", "#313131", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index 314260581..865fa13f0 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -96,6 +96,11 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", { fear_height = 4, harmed_by_heal = true, fire_resistant = true, + dealt_effect = { + name = "withering", + factor = 1, + dur = 10, + }, }) --spawn diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index c07afb6b1..321a9c1ce 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -161,6 +161,18 @@ local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed) end end +local swamp_light_max = 7 + +local function slime_spawn_check(pos, environmental_light, artificial_light, sky_light) + local maxlight = swamp_light_max + + if is_slime_chunk(pos) then + maxlight = minetest.LIGHT_MAX + 1 + end + + return artificial_light <= maxlight +end + -- Slime local slime_big = { description = S("Slime"), @@ -213,6 +225,7 @@ local slime_big = { spawn_small_alternative = "mobs_mc:slime_small", on_die = spawn_children_on_die("mobs_mc:slime_small", 1.0, 1.5), use_texture_alpha = true, + spawn_check = slime_spawn_check, } mcl_mobs.register_mob("mobs_mc:slime_big", slime_big) @@ -297,7 +310,6 @@ local cave_min = mcl_vars.mg_overworld_min local cave_max = water_level - 23 local swampy_biomes = {"Swampland", "MangroveSwamp"} -local swamp_light_max = 7 local swamp_min = water_level local swamp_max = water_level + 27 diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 65d3a2d21..38138a71c 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -114,9 +114,7 @@ mcl_mobs.register_mob("mobs_mc:spider", spider) local cave_spider = table.copy(spider) cave_spider.description = S("Cave Spider") cave_spider.textures = { {"mobs_mc_cave_spider.png^(mobs_mc_spider_eyes.png^[makealpha:0,0,0)"} } --- TODO: Poison damage --- TODO: Revert damage to 2 -cave_spider.damage = 3 -- damage increased to undo non-existing poison +cave_spider.damage = 2 cave_spider.hp_min = 1 cave_spider.hp_max = 12 cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.46, 0.35} @@ -138,6 +136,11 @@ 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 +cave_spider.dealt_effect = { + name = "poison", + factor = 2.5, + dur = 7, +} mcl_mobs.register_mob("mobs_mc:cave_spider", cave_spider) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index b00a68116..c9cc3c8ee 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -70,6 +70,11 @@ mcl_mobs.register_mob("mobs_mc:witch", { }, view_range = 16, fear_height = 4, + deal_damage = function(self, damage, mcl_reason) + local factor = 1 + if mcl_reason.type == "magic" then factor = 0.15 end + self.health = self.health - factor*damage + end, }) -- potion projectile (EXPERIMENTAL) diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 6b47d601a..cda3f0153 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -1,14 +1,72 @@ --MCmobs v0.4 --maikerumine +--updated by Herowl --made for MC like Survival game --License for code WTFPL and otherwise stated in readmes local S = minetest.get_translator("mobs_mc") +local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true) +local follow_spawner = minetest.settings:get_bool("wither_follow_spawner", false) +local w_strafes = minetest.settings:get_bool("wither_strafes", true) +local anti_troll = minetest.settings:get_bool("wither_anti_troll_measures", false) + +local WITHER_INIT_BOOM = 7 +local WITHER_MELEE_COOLDOWN = 3 + +local function atan(x) + if not x or x ~= x then + return 0 + else + return math.atan(x) + end +end --################### --################### WITHER --################### +local function wither_unstuck(self) + local pos = self.object:get_pos() + if mobs_griefing then -- destroy blocks very nearby (basically, colliding with) + local col = self.collisionbox + local pos1 = vector.offset(pos, col[1], col[2], col[3]) + local pos2 = vector.offset(pos, col[4], col[5], col[6]) + for z = pos1.z, pos2.z do for y = pos1.y, pos2.y do for x = pos1.x, pos2.x do + local npos = vector.new(x,y,z) + local name = minetest.get_node(npos).name + if name ~= "air" then + local ndef = minetest.registered_nodes[name] + if ndef and ndef._mcl_hardness and ndef._mcl_hardness >= 0 then + local drops = minetest.get_node_drops(name, "") + if minetest.dig_node(npos) then + for _, item in ipairs(drops) do + if type(item) ~= "string" then + item = item:get_name() .. item:get_count() + end + minetest.add_item(npos, item) + end + end + end + end + end end end + end + mcl_mobs.mob_class.safe_boom(self, pos, 2) +end + +local function get_dim_relative_y(pos) + if (pos.y >= mcl_vars.mg_realm_barrier_overworld_end_max) then + return pos.y + elseif (pos.y <= mcl_vars.mg_nether_max + 200) then + return (pos.y - mcl_vars.mg_nether_min - 20) + else + return (pos.y - mcl_vars.mg_end_min - 50) + end +end + +mobs_mc.wither_count_overworld = 0 +mobs_mc.wither_count_nether = 0 +mobs_mc.wither_count_end = 0 + mcl_mobs.register_mob("mobs_mc:wither", { description = S("Wither"), type = "monster", @@ -26,11 +84,11 @@ mcl_mobs.register_mob("mobs_mc:wither", { {"mobs_mc_wither.png"}, }, visual_size = {x=4, y=4}, - makes_footstep_sound = true, - view_range = 16, + view_range = 50, fear_height = 4, walk_velocity = 2, run_velocity = 4, + strafes = w_strafes, sounds = { shoot_attack = "mobs_mc_ender_dragon_shoot", attack = "mobs_mc_ender_dragon_attack", @@ -41,9 +99,8 @@ mcl_mobs.register_mob("mobs_mc:wither", { jump_height = 10, fly = true, makes_footstep_sound = false, - dogshoot_switch = 1, - dogshoot_count_max = 1, - attack_animals = true, + dogshoot_switch = 1, -- unused + dogshoot_count_max = 1, -- unused can_despawn = false, drops = { {name = "mcl_mobitems:nether_star", @@ -53,13 +110,13 @@ mcl_mobs.register_mob("mobs_mc:wither", { }, lava_damage = 0, fire_damage = 0, - attack_type = "dogshoot", + attack_type = "custom", explosion_strength = 8, dogshoot_stop = true, arrow = "mobs_mc:wither_skull", reach = 5, - shoot_interval = 0.5, - shoot_offset = -1, + shoot_interval = 1, + shoot_offset = -0.5, animation = { walk_speed = 12, run_speed = 12, stand_speed = 12, stand_start = 0, stand_end = 20, @@ -67,57 +124,377 @@ mcl_mobs.register_mob("mobs_mc:wither", { run_start = 0, run_end = 20, }, harmed_by_heal = true, - do_custom = function(self) + is_boss = true, + extra_hostile = true, + attack_exception = function(p) + local ent = p:get_luaentity() + if p:is_player() then return false end + if not ent or not ent.is_mob or ent.harmed_by_heal or string.find(ent.name, "ghast") then return true + else return false end + end, + + do_custom = function(self, dtime) + if self._spawning then + -- "loading" bar while spawning + if not self._spw_max then self._spw_max = self._spawning end + self._spawning = self._spawning - dtime + local bardef = { + color = "dark_purple", + text = "Wither spawning", + percentage = math.floor((self._spw_max - self._spawning) / self._spw_max * 100), + } + + local pos = self.object:get_pos() + for _, player in pairs(minetest.get_connected_players()) do + local d = vector.distance(pos, player:get_pos()) + if d <= 80 then + mcl_bossbars.add_bar(player, bardef, true, d) + end + end + + -- turn around and flash while spawning + self.object:set_yaw(self._spawning*10) + local factor = math.floor((math.sin(self._spawning*10)+1.5) * 85) + local str = minetest.colorspec_to_colorstring({r=factor, g=factor, b=factor}) + self.object:set_texture_mod("^[brighten^[multiply:"..str) + + -- when fully spawned, explode + if self._spawning <= 0 then + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, WITHER_INIT_BOOM, { drop_chance = 1.0 }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, WITHER_INIT_BOOM) + end + self.object:set_texture_mod("") + self._spawning = nil + self._spw_max = nil + else + return false + end + end + + -- passive regeneration + self._custom_timer = self._custom_timer + dtime + if self._custom_timer > 1 then + self.health = math.min(self.health + 1, self.hp_max) + self._custom_timer = self._custom_timer - 1 + end + + -- anti-troll measures + if anti_troll then + if self._spawner then + local spawner = minetest.get_player_by_name(self._spawner) + if follow_spawner and spawner then + self._death_timer = 0 + local pos = self.object:get_pos() + local spw = spawner:get_pos() + local dist = vector.distance(pos, spw) + if dist > 60 then -- teleport to the player who spawned the wither + local R = 10 + pos.x = spw.x + math.random(-R, R) + pos.y = spw.y + math.random(-R, R) + pos.z = spw.z + math.random(-R, R) + self.object:set_pos(pos) + end + else -- despawn automatically after set time + -- HP changes impact timer: taking damage sets it back + self._death_timer = self._death_timer + self.health - self._health_old + if self.health == self._health_old then self._death_timer = self._death_timer + dtime end + if self._death_timer > 100 then + self.object:remove() + return false + end + self._health_old = self.health + end + end + -- count withers per dimension + local dim = mcl_worlds.pos_to_dimension(self.object:get_pos()) + if dim == "overworld" then mobs_mc.wither_count_overworld = mobs_mc.wither_count_overworld + 1 + elseif dim == "nether" then mobs_mc.wither_count_nether = mobs_mc.wither_count_nether + 1 + elseif dim == "end" then mobs_mc.wither_count_end = mobs_mc.wither_count_end + 1 end + end + + -- update things dependent on HP + local rand_factor if self.health < (self.hp_max / 2) then self.base_texture = "mobs_mc_wither_half_health.png" self.fly = false - self.object:set_properties({textures={self.base_texture}}) - self.armor = {undead = 80, fleshy = 80} + self._arrow_resistant = true + rand_factor = 3 + else + self.base_texture = "mobs_mc_wither.png" + self.fly = true + self._arrow_resistant = false + rand_factor = 10 end + if not self.attack then + local y = get_dim_relative_y(self.object:get_pos()) + if y > 0 then + self.fly = false + else + self.fly = true + local vel = self.object:get_velocity() + self.object:set_velocity(vector.new(vel.x, self.walk_velocity, vel.z)) + end + end + self.object:set_properties({textures={self.base_texture}}) mcl_bossbars.update_boss(self.object, "Wither", "dark_purple") + if math.random(1, rand_factor) < 2 then + self.arrow = "mobs_mc:wither_skull_strong" + else + self.arrow = "mobs_mc:wither_skull" + end end, + + attack_state = function(self, dtime) + local s = self.object:get_pos() + local p = self.attack:get_pos() or s + + p.y = p.y - .5 + s.y = s.y + .5 + + local dist = vector.distance(p, s) + local vec = { + x = p.x - s.x, + y = p.y - s.y, + z = p.z - s.z + } + + local yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + if p.x > s.x then yaw = yaw +math.pi end + yaw = self:set_yaw( yaw, 0, dtime) + + local stay_away_from_player = vector.zero() + + --strafe back and fourth + + --stay away from player so as to shoot them + if dist < self.avoid_distance and self.shooter_avoid_enemy then + self:set_animation( "shoot") + stay_away_from_player=vector.multiply(vector.direction(p, s), 0.33) + end + + if self.fly then + local vel = self.object:get_velocity() + local diff = s.y - p.y + local FLY_FACTOR = self.walk_velocity + if diff < 10 then + self.object:set_velocity({x=vel.x, y= FLY_FACTOR, z=vel.z}) + elseif diff > 15 then + self.object:set_velocity({x=vel.x, y=-FLY_FACTOR, z=vel.z}) + end + for i=1, 15 do + if minetest.get_node(vector.offset(s, 0, -i, 0)).name ~= "air" then + self.object:set_velocity({x=vel.x, y= FLY_FACTOR, z=vel.z}) + break + elseif minetest.get_node(vector.offset(s, 0, i, 0)).name ~= "air" then + self.object:set_velocity({x=vel.x, y=-FLY_FACTOR/i, z=vel.z}) + break + end + end + end + + if self.strafes then + if not self.strafe_direction then + self.strafe_direction = 1.57 + end + if math.random(40) == 1 then + self.strafe_direction = self.strafe_direction*-1 + end + + local dir = vector.rotate_around_axis(vector.direction(s, p), vector.new(0,1,0), self.strafe_direction) + local dir2 = vector.multiply(dir, 0.3 * self.walk_velocity) + + if dir2 and stay_away_from_player then + self.acc = vector.add(dir2, stay_away_from_player) + end + else + self:set_velocity(0) + end + + if dist > 30 then self.acc = vector.add(self.acc, vector.direction(s, p)*0.01) end + + local side_cor = vector.new(0.7*math.cos(yaw), 0, 0.7*math.sin(yaw)) + local m = self.object:get_pos() -- position of the middle head + local sr = self.object:get_pos() + side_cor -- position of side right head + local sl = self.object:get_pos() - side_cor -- position of side left head + -- height corrections + m.y = m.y + self.collisionbox[5] + sr.y = sr.y + self.collisionbox[5] - 0.3 + sl.y = sl.y + self.collisionbox[5] - 0.3 + local rand_pos = math.random(1,3) + if rand_pos == 1 then m = sr + elseif rand_pos == 2 then m = sl end + + -- melee attack + if not self._melee_timer then + self._melee_timer = 0 + end + if self._melee_timer < WITHER_MELEE_COOLDOWN then + self._melee_timer = self._melee_timer + dtime + else + self._melee_timer = 0 + local pos = table.copy(s) + pos.y = pos.y + 2 + local objs = minetest.get_objects_inside_radius(pos, self.reach) + local obj_pos, dist + local hit_some = false + for n = 1, #objs do + objs[n]:punch(objs[n], 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 4}, + }, pos) + local ent = objs[n]:get_luaentity() + if objs[n]:is_player() or (ent and ent ~= self and (not ent._shooter or ent._shooter ~= self)) then + mcl_util.deal_damage(objs[n], 8, {type = "magic"}) + hit_some = true + end + mcl_mobs.effect_functions["withering"](objs[n], 0.5, 10) + end + if hit_some then + mcl_mobs.effect(pos, 32, "mcl_particles_soul_fire_flame.png", 5, 10, self.reach, 1, 0) + end + end + + if dist < self.reach then + self.shoot_interval = 3 + else + self.shoot_interval = 1 + end + + if self.shoot_interval + and self.timer > self.shoot_interval + and not minetest.raycast(vector.add(m, vector.new(0,self.shoot_offset,0)), vector.add(self.attack:get_pos(), vector.new(0,1.5,0)), false, false):next() + and math.random(1, 100) <= 60 then + + self.timer = 0 + self:set_animation( "shoot") + + -- play shoot attack sound + self:mob_sound("shoot_attack") + + -- Shoot arrow + if minetest.registered_entities[self.arrow] then + + local arrow, ent + local v = 1 + if not self.shoot_arrow then + self.firing = true + minetest.after(1, function() + self.firing = false + end) + arrow = minetest.add_entity(m, self.arrow) + ent = arrow:get_luaentity() + if ent.velocity then + v = ent.velocity + end + ent.switch = 1 + ent.owner_id = tostring(self.object) -- add unique owner id to arrow + + -- important for mcl_shields + ent._shooter = self.object + ent._saved_shooter_pos = self.object:get_pos() + end + + local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 + -- offset makes shoot aim accurate + vec.y = vec.y + self.shoot_offset + vec.x = vec.x * (v / amount) + vec.y = vec.y * (v / amount) + vec.z = vec.z * (v / amount) + if self.shoot_arrow then + vec = vector.normalize(vec) + self:shoot_arrow(m, vec) + else + arrow:set_velocity(vec) + end + end + end + end, + + do_punch = function(self, hitter, tflp, tool_capabilities, dir) + if self._spawning or hitter == self.object then return false end + local ent = hitter:get_luaentity() + if ent and self._arrow_resistant and (string.find(ent.name, "arrow") or string.find(ent.name, "rocket")) then return false end + wither_unstuck(self) + return true + end, + deal_damage = function(self, damage, mcl_reason) + if self._spawning then return end + if self._arrow_resistant and mcl_reason.type == "magic" then return end + wither_unstuck(self) + self.health = self.health - damage + end, + on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) + self._custom_timer = 0.0 + self._death_timer = 0.0 + self._health_old = self.hp_max + self._spawning = 10 + return true end, }) -local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local wither_rose_soil = { "group:grass_block", "mcl_core:dirt", "mcl_core:coarse_dirt", "mcl_nether:netherrack", "group:soul_block", "mcl_mud:mud", "mcl_moss:moss" } +local function spawn_wither_rose(obj) + local n = minetest.find_node_near(obj:get_pos(),2,wither_rose_soil) + if n then + local p = vector.offset(n,0,1,0) + if minetest.get_node(p).name == "air" then + if not ( mobs_griefing and minetest.place_node(p,{name="mcl_flowers:wither_rose"}) ) then + minetest.add_item(p,"mcl_flowers:wither_rose") + end + end + end +end mcl_mobs.register_arrow("mobs_mc:wither_skull", { - visual = "sprite", - visual_size = {x = 0.75, y = 0.75}, - -- TODO: 3D projectile, replace tetxture - textures = {"mobs_mc_TEMP_wither_projectile.png"}, - velocity = 6, + visual = "cube", + visual_size = {x = 0.3, y = 0.3}, + textures = { + "mobs_mc_wither_projectile.png^[verticalframe:6:0", -- top + "mobs_mc_wither_projectile.png^[verticalframe:6:1", -- bottom + "mobs_mc_wither_projectile.png^[verticalframe:6:2", -- left + "mobs_mc_wither_projectile.png^[verticalframe:6:3", -- right + "mobs_mc_wither_projectile.png^[verticalframe:6:4", -- back + "mobs_mc_wither_projectile.png^[verticalframe:6:5", -- front + }, + velocity = 7, + rotate = 90, + _lifetime = 350, + on_punch = function(self) end, -- direct hit hit_player = function(self, player) + local pos = vector.new(self.object:get_pos()) + mcl_mobs.effect_functions["withering"](player, 0.5, 10) player:punch(self.object, 1.0, { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self, pos, 1) + if player:get_hp() <= 0 then + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(player) + end end, hit_mob = function(self, mob) + local pos = vector.new(self.object:get_pos()) + mcl_mobs.effect_functions["withering"](mob, 0.5, 10) mob:punch(self.object, 1.0, { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self, pos, 1) local l = mob:get_luaentity() if l and l.health - 8 <= 0 then - local n = minetest.find_node_near(mob:get_pos(),2,wither_rose_soil) - if n then - local p = vector.offset(n,0,1,0) - if minetest.get_node(p).name == "air" then - if not ( mobs_griefing and minetest.place_node(p,{name="mcl_flowers:wither_rose"}) ) then - minetest.add_item(p,"mcl_flowers:wither_rose") - end - end - end + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(mob) end end, @@ -126,10 +503,75 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", { mcl_mobs.mob_class.boom(self,pos, 1) end }) --- TODO: Add blue wither skull +mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", { + visual = "cube", + visual_size = {x = 0.35, y = 0.35}, + textures = { + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:0", -- top + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:1", -- bottom + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:2", -- left + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:3", -- right + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:4", -- back + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:5", -- front + }, + velocity = 4, + rotate = 90, + _lifetime = 500, + on_punch = function(self) end, + + -- direct hit + hit_player = function(self, player) + local pos = vector.new(self.object:get_pos()) + mcl_mobs.effect_functions["withering"](player, 0.5, 10) + player:punch(self.object, 1.0, { + full_punch_interval = 0.5, + damage_groups = {fleshy = 12}, + }, nil) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here + end + if player:get_hp() <= 0 then + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(player) + end + end, + + hit_mob = function(self, mob) + local pos = vector.new(self.object:get_pos()) + mcl_mobs.effect_functions["withering"](mob, 0.5, 10) + mob:punch(self.object, 1.0, { + full_punch_interval = 0.5, + damage_groups = {fleshy = 12}, + }, nil) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here + end + local l = mob:get_luaentity() + if l and l.health - 8 <= 0 then + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(mob) + end + end, + + -- node hit, explode + hit_node = function(self, pos, node) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here + end + end +}) --Spawn egg mcl_mobs.register_egg("mobs_mc:wither", S("Wither"), "#4f4f4f", "#4f4f4f", 0, true) mcl_wip.register_wip_item("mobs_mc:wither") mcl_mobs:non_spawn_specific("mobs_mc:wither","overworld",0,minetest.LIGHT_MAX+1) + diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index 7b142086d..c52b5b1a3 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -29,7 +29,7 @@ local wolf = { head_swivel = "head.control", bone_eye_height = 3.5, head_eye_height = 1.1, - horrizonatal_head_height=0, + horizontal_head_height=0, curiosity = 3, head_yaw="z", sounds = { diff --git a/mods/HELP/mcl_craftguide/init.lua b/mods/HELP/mcl_craftguide/init.lua index 5e3686047..80df19b90 100644 --- a/mods/HELP/mcl_craftguide/init.lua +++ b/mods/HELP/mcl_craftguide/init.lua @@ -774,7 +774,7 @@ local function search(data) for i = 1, #data.items_raw do local item = data.items_raw[i] local def = reg_items[item] - local desc = lower(def.description) + local desc = string.lower(M.get_translated_string(data.lang_code, def.description)) local search_in = item .. desc local to_add @@ -838,6 +838,7 @@ local function init_data(name) iX = sfinv_only and 8 or DEFAULT_SIZE, items = init_items, items_raw = init_items, + lang_code = M.get_player_information(name).lang_code or 'en', } end diff --git a/mods/ITEMS/mcl_bamboo/bamboo_items.lua b/mods/ITEMS/mcl_bamboo/bamboo_items.lua index 412ec92cb..95d4999fc 100644 --- a/mods/ITEMS/mcl_bamboo/bamboo_items.lua +++ b/mods/ITEMS/mcl_bamboo/bamboo_items.lua @@ -192,10 +192,23 @@ if minetest.get_modpath("mcl_fences") then local wood_groups = { handy = 1, axey = 1, flammable = 2, fence_wood = 1, fire_encouragement = 5, fire_flammability = 20 } local wood_connect = { "group:fence_wood" } - local fence_id = mcl_fences.register_fence(id, S("Bamboo Fence"), "mcl_bamboo_fence_bamboo.png", wood_groups, - 2, 15, wood_connect, node_sound) - local gate_id = mcl_fences.register_fence_gate(id, S("Bamboo Fence Gate"), "mcl_bamboo_fence_gate_bamboo.png", - wood_groups, 2, 15, node_sound) -- note: about missing params.. will use defaults. + local fence_id = mcl_fences.register_fence( + id, + S("Bamboo Fence"), + "mcl_bamboo_fence_bamboo.png", + wood_groups, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + wood_connect, node_sound) + + local gate_id = mcl_fences.register_fence_gate( + id, + S("Bamboo Fence Gate"), + "mcl_bamboo_fence_gate_bamboo.png", + wood_groups, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + node_sound) -- note: about missing params.. will use defaults. mcl_bamboo.mcl_log(dump(fence_id)) mcl_bamboo.mcl_log(dump(gate_id)) diff --git a/mods/ITEMS/mcl_blackstone/init.lua b/mods/ITEMS/mcl_blackstone/init.lua index fd05465d3..138e02191 100644 --- a/mods/ITEMS/mcl_blackstone/init.lua +++ b/mods/ITEMS/mcl_blackstone/init.lua @@ -199,7 +199,11 @@ mcl_stairs.register_stair_and_slab_simple("blackstone_chiseled_polished", "mcl_b mcl_stairs.register_stair_and_slab_simple("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished", S("Polished Blackstone Brick Stair"), S("Polished Blackstone Brick Slab"), S("Double Polished Blackstone Brick Slab")) --Wall -mcl_walls.register_wall("mcl_blackstone:wall", S("Blackstone Wall"), "mcl_blackstone:blackstone") +mcl_walls.register_wall( + "mcl_blackstone:wall", + S("Blackstone Wall"), + "mcl_blackstone:blackstone" +) --lavacooling diff --git a/mods/ITEMS/mcl_cauldrons/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index c84e3bb88..0ba678583 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -67,12 +67,12 @@ local function register_filled_cauldron(water_level, description, liquid) local water_tex if liquid == "river_water" then id = id .. "r" - water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#0084FF" + water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#0084FF" elseif liquid == "lava" then id = id .. "_lava" - water_tex = "default_lava_source_animated.png^[verticalframe:16:0" + water_tex = "mcl_core_lava_source_animation.png^[verticalframe:16:0" else - water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#3F76E4" + water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#3F76E4" end minetest.register_node(id, { description = description, diff --git a/mods/ITEMS/mcl_cherry_blossom/nodes.lua b/mods/ITEMS/mcl_cherry_blossom/nodes.lua index 4b6803123..403982872 100644 --- a/mods/ITEMS/mcl_cherry_blossom/nodes.lua +++ b/mods/ITEMS/mcl_cherry_blossom/nodes.lua @@ -66,9 +66,16 @@ mcl_signs.register_sign_custom("mcl_cherry_blossom", "_cherrywood", "mcl_cherry_blossom_sign_inv.png", "mcl_cherry_blossom_sign_inv.png", S("Cherry Sign")) -- Fences & Gates -mcl_fences.register_fence_and_fence_gate("cherry_fence", S("Cherry Fence"), S("Cherry Gate"), - "mcl_cherry_blossom_planks.png", {handy=1, axey=1, flammable=2, fence_wood=1, fire_encouragement=5, fire_flammability=20}, 2, 15, - {"group:fence_wood"}, mcl_sounds.node_sound_wood_defaults()) +mcl_fences.register_fence_and_fence_gate( + "cherry_fence", + S("Cherry Fence"), + S("Cherry Gate"), + "mcl_cherry_blossom_planks.png", + {handy=1, axey=1, flammable=2, fence_wood=1, fire_encouragement=5, fire_flammability=20}, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults()) -- Redstone mesecon.register_pressure_plate( diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 59ed2ba09..6f3272149 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -532,9 +532,12 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) - if minetest.registered_nodes[minetest.get_node({ x = pos.x, y = pos.y + 1, z = pos.z }).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + local topnode = minetest.get_node({ x = pos.x, y = pos.y + 1, z = pos.z }) + if topnode and topnode.name and minetest.registered_nodes[topnode.name] then + if minetest.registered_nodes[topnode.name].groups.opaque == 1 then + -- won't open if there is no space from the top + return false + end end local name = minetest.get_meta(pos):get_string("name") if name == "" then diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 01de997d5..f36d5cabd 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -406,7 +406,7 @@ mcl_core.register_snowed_node("mcl_core:dirt_with_grass_snow", "mcl_core:dirt_wi minetest.register_node("mcl_core:grass_path", { tiles = {"mcl_core_grass_path_top.png", "default_dirt.png", "mcl_core_grass_path_side.png"}, description = S("Grass Path"), - _doc_items_longdesc = S("Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created with a shovel. A grass path turns into dirt when it is below a solid block."), + _doc_items_longdesc = S("Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created by right clicking with a shovel. A grass path turns into dirt when it is below a solid block or when shift+right clicked with a shovel."), drop = "mcl_core:dirt", is_ground_content = true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, @@ -419,7 +419,7 @@ minetest.register_node("mcl_core:grass_path", { {-0.5, -0.5, -0.5, 0.5, 0.4375, 0.5}, } }, - groups = {handy=1,shovely=1, cultivatable=2, dirtifies_below_solid=1, dirtifier=1, deco_block=1 }, + groups = {handy=1,shovely=1, cultivatable=2, dirtifies_below_solid=1, dirtifier=1, deco_block=1, path_remove_possible=1 }, sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, }), diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index e55664432..9a7318af7 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -18,17 +18,17 @@ end minetest.register_node("mcl_core:water_flowing", { description = S("Flowing Water"), _doc_items_create_entry = false, - wield_image = "default_water_flowing_animated.png^[verticalframe:64:0", + wield_image = "mcl_core_water_flow_animation.png^[verticalframe:64:0", drawtype = "flowingliquid", - tiles = {"default_water_flowing_animated.png^[verticalframe:64:0"}, + tiles = {"mcl_core_water_flow_animation.png^[verticalframe:64:0"}, special_tiles = { { - image="default_water_flowing_animated.png", + image="mcl_core_water_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1.5} }, { - image="default_water_flowing_animated.png", + image="mcl_core_water_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1.5} }, @@ -71,12 +71,12 @@ S("• When water is directly below lava, the water turns into stone."), drawtype = "liquid", waving = 3, tiles = { - {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} + {name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} }, special_tiles = { -- New-style water source material (mostly unused) { - name="default_water_source_animated.png", + name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}, backface_culling = false, } @@ -119,17 +119,17 @@ S("• When water is directly below lava, the water turns into stone."), minetest.register_node("mcl_core:lava_flowing", { description = S("Flowing Lava"), _doc_items_create_entry = false, - wield_image = "default_lava_flowing_animated.png^[verticalframe:64:0", + wield_image = "mcl_core_lava_flow_animation.png^[verticalframe:64:0", drawtype = "flowingliquid", - tiles = {"default_lava_flowing_animated.png^[verticalframe:64:0"}, + tiles = {"mcl_core_lava_flow_animation.png^[verticalframe:64:0"}, special_tiles = { { - image="default_lava_flowing_animated.png", + image="mcl_core_lava_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=6.6} }, { - image="default_lava_flowing_animated.png", + image="mcl_core_lava_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=6.6} }, @@ -182,12 +182,12 @@ S("• When flowing water touches flowing lava either from above or horizontally S("• When lava is directly above water, the water turns into stone."), drawtype = "liquid", tiles = { - {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} + {name="mcl_core_lava_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} }, special_tiles = { -- New-style lava source material (mostly unused) { - name="default_lava_source_animated.png", + name="mcl_core_lava_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}, backface_culling = false, } diff --git a/mods/ITEMS/mcl_deepslate/init.lua b/mods/ITEMS/mcl_deepslate/init.lua index a1182246a..b4549159f 100644 --- a/mods/ITEMS/mcl_deepslate/init.lua +++ b/mods/ITEMS/mcl_deepslate/init.lua @@ -218,7 +218,10 @@ local function register_deepslate_variant(item, desc, longdesc) end if item ~= "chiseled" then mcl_stairs.register_stair_and_slab_simple("deepslate_"..item, "mcl_deepslate:deepslate_"..item, S(desc.." Stairs"), S(desc.." Slab"), S("Double "..desc.." Slab")) - mcl_walls.register_wall("mcl_deepslate:deepslate"..item.."wall", S(desc.." Wall"), "mcl_deepslate:deepslate_"..item) + mcl_walls.register_wall( + "mcl_deepslate:deepslate"..item.."wall", + S(desc.." Wall"), + "mcl_deepslate:deepslate_"..item) end end diff --git a/mods/ITEMS/mcl_fences/init.lua b/mods/ITEMS/mcl_fences/init.lua index b14d103d2..5555fbfc0 100644 --- a/mods/ITEMS/mcl_fences/init.lua +++ b/mods/ITEMS/mcl_fences/init.lua @@ -269,7 +269,16 @@ for w=1, #woods do id = wood[1].."_fence" id_gate = wood[1].."_fence_gate" end - mcl_fences.register_fence_and_fence_gate(id, wood[2], wood[3], wood[4], wood_groups, 2, 15, wood_connect, wood_sounds) + mcl_fences.register_fence_and_fence_gate( + id, + wood[2], + wood[3], + wood[4], + wood_groups, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + wood_connect, + wood_sounds) minetest.register_craft({ output = "mcl_fences:"..id.." 3", @@ -289,7 +298,15 @@ end -- Nether Brick Fence (without fence gate!) -mcl_fences.register_fence("nether_brick_fence", S("Nether Brick Fence"), "mcl_fences_fence_nether_brick.png", {pickaxey=1, deco_block=1, fence_nether_brick=1}, 2, 30, {"group:fence_nether_brick"}, mcl_sounds.node_sound_stone_defaults()) +mcl_fences.register_fence( + "nether_brick_fence", + S("Nether Brick Fence"), + "mcl_fences_fence_nether_brick.png", + {pickaxey=1, deco_block=1, fence_nether_brick=1}, + minetest.registered_nodes["mcl_nether:nether_brick"]._mcl_hardness, + minetest.registered_nodes["mcl_nether:nether_brick"]._mcl_blast_resistance, + {"group:fence_nether_brick"}, + mcl_sounds.node_sound_stone_defaults()) minetest.register_craft({ output = "mcl_fences:nether_brick_fence 6", diff --git a/mods/ITEMS/mcl_mangrove/init.lua b/mods/ITEMS/mcl_mangrove/init.lua index 6e7767541..932e7851d 100644 --- a/mods/ITEMS/mcl_mangrove/init.lua +++ b/mods/ITEMS/mcl_mangrove/init.lua @@ -183,7 +183,7 @@ mcl_flowerpots.register_potted_flower("mcl_mangrove:propagule", { image = "mcl_mangrove_propagule.png", }) -local water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#3F76E4" +local water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#3F76E4" local wlroots = { description = S("water logged mangrove roots"), @@ -194,12 +194,12 @@ local wlroots = { S("These cannot be crafted yet only occure when get in contact of water."), _doc_items_hidden = false, tiles = { - {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} + {name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} }, special_tiles = { -- New-style water source material (mostly unused) { - name="default_water_source_animated.png", + name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, backface_culling = false, } @@ -221,7 +221,7 @@ local wlroots = { liquids_pointable = true, drop = "mcl_mangrove:mangrove_roots", groups = { - handy = 1, hoey = 1, water=3, liquid=3, puts_out_fire=1, dig_by_piston = 1, deco_block = 1, not_in_creative_inventory=1 }, + handy = 1, hoey = 1, water=3, liquid=3, puts_out_fire=1, dig_by_piston = 1, deco_block = 1, waterlogged = 1, not_in_creative_inventory=1 }, _mcl_blast_resistance = 100, _mcl_hardness = -1, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode on_construct = function(pos) @@ -245,7 +245,7 @@ local rwlroots = table.copy(wlroots) -- FIXME luacheck complains that this is a repeated definition of water_tex. -- Maybe the tiles definition below should be replaced with the animated tile -- definition as per above? -water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#0084FF" +water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#0084FF" rwlroots.tiles = { "("..water_tex..")^mcl_mangrove_roots_top.png", "("..water_tex..")^mcl_mangrove_roots_side.png", diff --git a/mods/ITEMS/mcl_maps/colors.json b/mods/ITEMS/mcl_maps/colors.json index 4929a2f66..ae09ab483 100644 --- a/mods/ITEMS/mcl_maps/colors.json +++ b/mods/ITEMS/mcl_maps/colors.json @@ -4664,7 +4664,7 @@ 126, 164 ], - "default_water_source_animated.png": [ + "mcl_core_water_source_animation.png": [ 37, 98, 129 @@ -4984,7 +4984,7 @@ 79, 64 ], - "default_water_flowing_animated.png": [ + "mcl_core_water_flow_animation.png": [ 38, 101, 129 @@ -5009,7 +5009,7 @@ 89, 86 ], - "default_lava_flowing_animated.png": [ + "mcl_core_lava_flow_animation.png": [ 177, 42, 16 @@ -5059,7 +5059,7 @@ 142, 123 ], - "default_lava_source_animated.png": [ + "mcl_core_lava_source_animation.png": [ 180, 45, 17 @@ -6604,16 +6604,6 @@ 56, 64 ], - "default_river_water_flowing_animated.png": [ - 38, - 123, - 130 - ], - "default_river_water_source_animated.png": [ - 37, - 120, - 130 - ], "mcl_armor_stand_item.png": [ 134, 114, @@ -9009,17 +8999,17 @@ 127, 113 ], - "bucket_river_water.png": [ + "mcl_buckets_river_water_bucket.png": [ 139, 152, 155 ], - "bucket_water.png": [ + "mcl_buckets_water_bucket.png": [ 139, 147, 155 ], - "bucket.png": [ + "mcl_buckets_bucket.png": [ 147, 143, 139 diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 1084dfa77..530d96093 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -267,7 +267,8 @@ function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flow -- Flowing liquid: Grow 1 step, but also turn the tip node into a liquid source. if downward_flowing then local alt_liq = mt_registered_nodes[node_tip.name].liquid_alternative_source - if alt_liq then + local alt_liq_accessible = mt_get_item_group(node_tip.name,"waterlogged") -- returns 0 if it isn't waterlogged. + if alt_liq and not alt_liq_accessible then mt_set_node(pos_tip, {name=alt_liq}) end end diff --git a/mods/ITEMS/mcl_ocean/prismarine.lua b/mods/ITEMS/mcl_ocean/prismarine.lua index 32d17538d..fff07cb7e 100644 --- a/mods/ITEMS/mcl_ocean/prismarine.lua +++ b/mods/ITEMS/mcl_ocean/prismarine.lua @@ -52,7 +52,7 @@ minetest.register_node("mcl_ocean:prismarine_brick", { tiles = {"mcl_ocean_prismarine_bricks.png"}, groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 1.5, + _mcl_blast_resistance = 6, _mcl_hardness = 1.5, }) @@ -64,7 +64,7 @@ minetest.register_node("mcl_ocean:prismarine_dark", { tiles = {"mcl_ocean_prismarine_dark.png"}, groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 1.5, + _mcl_blast_resistance = 6, _mcl_hardness = 1.5, }) diff --git a/mods/ITEMS/mcl_potions/commands.lua b/mods/ITEMS/mcl_potions/commands.lua index 76ac71e72..10bf86311 100644 --- a/mods/ITEMS/mcl_potions/commands.lua +++ b/mods/ITEMS/mcl_potions/commands.lua @@ -20,6 +20,7 @@ get_chat_function["leaping"] = mcl_potions.leaping_func get_chat_function["swiftness"] = mcl_potions.swiftness_func get_chat_function["heal"] = mcl_potions.healing_func get_chat_function["bad_omen"] = mcl_potions.bad_omen_func +get_chat_function["withering"] = mcl_potions.withering_func minetest.register_chatcommand("effect",{ params = S(" []"), diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 20608a7df..24aa2e402 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -10,6 +10,7 @@ EF.swift = {} -- for swiftness AND slowness EF.night_vision = {} EF.fire_proof = {} EF.bad_omen = {} +EF.withering = {} local EFFECT_TYPES = 0 for _,_ in pairs(EF) do @@ -19,8 +20,11 @@ end local icon_ids = {} local function potions_set_hudbar(player) - - if EF.poisoned[player] and EF.regenerating[player] then + if EF.withering[player] and EF.regenerating[player] then + hb.change_hudbar(player, "health", nil, nil, "mcl_potions_icon_regen_wither.png", nil, "hudbars_bar_health.png") + elseif EF.withering[player] then + hb.change_hudbar(player, "health", nil, nil, "mcl_potions_icon_wither.png", nil, "hudbars_bar_health.png") + elseif 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 EF.poisoned[player] then hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_health_poison.png", nil, "hudbars_bar_health.png") @@ -123,6 +127,33 @@ minetest.register_globalstep(function(dtime) end + -- Check for withering players + for player, vals in pairs(EF.withering) do + + is_player = player:is_player() + entity = player:get_luaentity() + + EF.withering[player].timer = EF.withering[player].timer + dtime + EF.withering[player].hit_timer = (EF.withering[player].hit_timer or 0) + dtime + + if player:get_pos() then mcl_potions._add_spawner(player, "#000000") end + + if EF.withering[player].hit_timer >= EF.withering[player].step then + if is_player or entity then mcl_util.deal_damage(player, 1, {type = "magic"}) end + if EF.withering[player] then EF.withering[player].hit_timer = 0 end + end + + if EF.withering[player] and EF.withering[player].timer >= EF.withering[player].dur then + EF.withering[player] = nil + if is_player then + meta = player:get_meta() + meta:set_string("_is_withering", minetest.serialize(EF.withering[player])) + potions_set_hud(player) + end + end + + end + -- Check for poisoned players for player, vals in pairs(EF.poisoned) do @@ -152,7 +183,7 @@ minetest.register_globalstep(function(dtime) end - -- Check for regnerating players + -- Check for regenerating players for player, vals in pairs(EF.regenerating) do is_player = player:is_player() @@ -408,6 +439,7 @@ function mcl_potions._clear_cached_player_data(player) EF.night_vision[player] = nil EF.fire_proof[player] = nil EF.bad_omen[player] = nil + EF.withering[player] = nil meta = player:get_meta() meta:set_int("night_vision", 0) @@ -452,6 +484,7 @@ function mcl_potions._save_player_effects(player) meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player])) meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player])) meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player])) + meta:set_string("_is_withering", minetest.serialize(EF.withering[player])) end @@ -507,6 +540,10 @@ function mcl_potions._load_player_effects(player) EF.bad_omen[player] = minetest.deserialize(meta:get_string("_has_bad_omen")) end + if minetest.deserialize(meta:get_string("_is_withering")) then + EF.withering[player] = minetest.deserialize(meta:get_string("_is_withering")) + end + end -- Returns true if player has given effect @@ -693,11 +730,9 @@ end function mcl_potions.healing_func(player, hp) - local obj = player:get_luaentity() + if not player or player:get_hp() <= 0 then return false end - if player:get_hp() == 0 then - return - end + local obj = player:get_luaentity() if obj and obj.harmed_by_heal then hp = -hp end @@ -725,6 +760,11 @@ end function mcl_potions.swiftness_func(player, factor, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not player:get_meta() then return false end @@ -753,6 +793,11 @@ end function mcl_potions.leaping_func(player, factor, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not player:get_meta() then return false end @@ -781,6 +826,11 @@ end function mcl_potions.weakness_func(player, factor, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not EF.weak[player] then EF.weak[player] = {dur = duration, timer = 0, factor = factor} @@ -804,6 +854,11 @@ end function mcl_potions.strength_func(player, factor, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not EF.strong[player] then EF.strong[player] = {dur = duration, timer = 0, factor = factor} @@ -825,8 +880,41 @@ function mcl_potions.strength_func(player, factor, duration) end +function mcl_potions.withering_func(player, factor, duration) + + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and (entity.is_boss or string.find(entity.name, "wither")) then return false end + + if not EF.withering[player] then + + EF.withering[player] = {step = factor, dur = duration, timer = 0} + + else + + local victim = EF.withering[player] + + victim.step = math.min(victim.step, factor) + victim.dur = math.max(duration, victim.dur - victim.timer) + victim.timer = 0 + + end + + if player:is_player() then + potions_set_hud(player) + end + +end + + function mcl_potions.poison_func(player, factor, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and (entity.is_boss or entity.harmed_by_heal or string.find(entity.name, "spider")) then return false end + if not EF.poisoned[player] then EF.poisoned[player] = {step = factor, dur = duration, timer = 0} @@ -850,6 +938,11 @@ end function mcl_potions.regeneration_func(player, factor, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and (entity.is_boss or entity.harmed_by_heal) then return false end + if not EF.regenerating[player] then EF.regenerating[player] = {step = factor, dur = duration, timer = 0} @@ -873,6 +966,11 @@ end function mcl_potions.invisiblility_func(player, null, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not EF.invisible[player] then EF.invisible[player] = {dur = duration, timer = 0} @@ -895,6 +993,11 @@ end function mcl_potions.water_breathing_func(player, null, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not EF.water_breathing[player] then EF.water_breathing[player] = {dur = duration, timer = 0} @@ -917,6 +1020,11 @@ end function mcl_potions.fire_resistance_func(player, null, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + if not EF.fire_proof[player] then EF.fire_proof[player] = {dur = duration, timer = 0} @@ -938,6 +1046,11 @@ end function mcl_potions.night_vision_func(player, null, duration) + if not player or player:get_hp() <= 0 then return false end + + local entity = player:get_luaentity() + if entity and entity.is_boss then return false end + meta = player:get_meta() if not EF.night_vision[player] then diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index 2ea7e2879..73fcdae16 100644 --- a/mods/ITEMS/mcl_potions/init.lua +++ b/mods/ITEMS/mcl_potions/init.lua @@ -190,7 +190,7 @@ local function set_node_empty_bottle(itemstack, placer, pointed_thing, newitemst -- play sound minetest.sound_play("mcl_potions_bottle_pour", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) - -- + -- if minetest.is_creative_enabled(placer:get_player_name()) then return itemstack else @@ -356,6 +356,7 @@ local awkward_table = { ["mcl_fishing:pufferfish_raw"] = "mcl_potions:water_breathing", ["mcl_mobitems:ghast_tear"] = "mcl_potions:regeneration", ["mcl_mobitems:spider_eye"] = "mcl_potions:poison", + ["mcl_flowers:wither_rose"] = "mcl_potions:withering", ["mcl_mobitems:rabbit_foot"] = "mcl_potions:leaping", } @@ -373,7 +374,7 @@ local potions = {} for i, potion in ipairs({"healing","harming","swiftness","slowness", "leaping","poison","regeneration","invisibility","fire_resistance", -- "weakness","strength", - "water_breathing","night_vision"}) do + "water_breathing","night_vision", "withering"}) do table.insert(potions, potion) @@ -461,6 +462,31 @@ function mcl_potions.get_alchemy(ingr, pot) return false end +mcl_mobs.effect_functions["poison"] = mcl_potions.poison_func +mcl_mobs.effect_functions["regeneration"] = mcl_potions.regeneration_func +mcl_mobs.effect_functions["invisibility"] = mcl_potions.invisiblility_func +mcl_mobs.effect_functions["fire_resistance"] = mcl_potions.fire_resistance_func +mcl_mobs.effect_functions["night_vision"] = mcl_potions.night_vision_func +mcl_mobs.effect_functions["water_breathing"] = mcl_potions.water_breathing_func +mcl_mobs.effect_functions["leaping"] = mcl_potions.leaping_func +mcl_mobs.effect_functions["swiftness"] = mcl_potions.swiftness_func +mcl_mobs.effect_functions["heal"] = mcl_potions.healing_func +mcl_mobs.effect_functions["bad_omen"] = mcl_potions.bad_omen_func +mcl_mobs.effect_functions["withering"] = mcl_potions.withering_func + +-- give withering to players in a wither rose +local etime = 0 +minetest.register_globalstep(function(dtime) + etime = dtime + etime + if etime < 0.5 then return end + etime = 0 + for _,pl in pairs(minetest.get_connected_players()) do + local npos = vector.offset(pl:get_pos(), 0, 0.2, 0) + local n = minetest.get_node(npos) + if n.name == "mcl_flowers:wither_rose" then mcl_potions.withering_func(pl, 1, 2) end + end +end) + mcl_wip.register_wip_item("mcl_potions:night_vision") mcl_wip.register_wip_item("mcl_potions:night_vision_plus") mcl_wip.register_wip_item("mcl_potions:night_vision_splash") @@ -468,4 +494,4 @@ mcl_wip.register_wip_item("mcl_potions:night_vision_plus_splash") mcl_wip.register_wip_item("mcl_potions:night_vision_lingering") mcl_wip.register_wip_item("mcl_potions:night_vision_plus_lingering") mcl_wip.register_wip_item("mcl_potions:night_vision_arrow") -mcl_wip.register_wip_item("mcl_potions:night_vision_plus_arrow") \ No newline at end of file +mcl_wip.register_wip_item("mcl_potions:night_vision_plus_arrow") diff --git a/mods/ITEMS/mcl_potions/mod.conf b/mods/ITEMS/mcl_potions/mod.conf index bcb6d8ad3..91280a607 100644 --- a/mods/ITEMS/mcl_potions/mod.conf +++ b/mods/ITEMS/mcl_potions/mod.conf @@ -1,2 +1,2 @@ name = mcl_potions -depends = mcl_core, mcl_farming, mcl_mobitems, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip +depends = mcl_core, mcl_farming, mcl_flowers, mcl_mobitems, mcl_mobs, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip diff --git a/mods/ITEMS/mcl_potions/potions.lua b/mods/ITEMS/mcl_potions/potions.lua index 3d89d1d40..57c06c29d 100644 --- a/mods/ITEMS/mcl_potions/potions.lua +++ b/mods/ITEMS/mcl_potions/potions.lua @@ -79,7 +79,7 @@ local function register_potion(def) if def.is_inv then dur = dur * mcl_potions.INV_FACTOR end - if def.name == "poison" or def.name == "regeneration" then + if def.name == "poison" or def.name == "regeneration" or def.name == "withering" then dur = 45 end @@ -93,7 +93,7 @@ local function register_potion(def) local _tt if effect and def.is_dur then _tt = perc_string(effect).." | "..time_string(dur) - if def.name == "poison" or def.name == "regeneration" then + if def.name == "poison" or def.name == "regeneration" or def.name == "withering" then _tt = S("1 HP/@1s | @2", effect, time_string(dur)) end elseif def.name == "healing" or def.name == "harming" then @@ -235,6 +235,8 @@ local function register_potion(def) effect_II = def.effect*mcl_potions.II_FACTOR elseif def.name == "poison" or def.name == "regeneration" then effect_II = 1.2 + elseif def.name == "withering" then + effect_II = 2 else effect_II = def.effect^mcl_potions.II_FACTOR end @@ -327,7 +329,7 @@ local function register_potion(def) if def.is_plus then local dur_pl = dur * mcl_potions.PLUS_FACTOR - if def.name == "poison" or def.name == "regeneration" then + if def.name == "poison" or def.name == "regeneration" or def.name == "withering" then dur_pl = 90 end @@ -533,6 +535,20 @@ local leaping_def = { is_plus = true, } +local withering_def = { + name = "withering", + description = S("Withering"), + _tt = nil, + _longdesc = S("Applies the withering effect which deals damage at a regular interval and can kill."), + color = "#000000", + effect = 4, + is_dur = true, + on_use = mcl_potions.withering_func, + is_II = true, + is_plus = true, + is_inv = true, +} + local poison_def = { name = "poison", description = S("Poison"), @@ -597,7 +613,7 @@ local fire_resistance_def = { local defs = { awkward_def, mundane_def, thick_def, dragon_breath_def, healing_def, harming_def, night_vision_def, swiftness_def, - slowness_def, leaping_def, poison_def, regeneration_def, + slowness_def, leaping_def, withering_def, poison_def, regeneration_def, invisibility_def, water_breathing_def, fire_resistance_def} for _, def in ipairs(defs) do diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua index 730796952..6b6238dbf 100644 --- a/mods/ITEMS/mcl_potions/splash.lua +++ b/mods/ITEMS/mcl_potions/splash.lua @@ -110,7 +110,7 @@ function mcl_potions.register_splash(name, descr, color, def) for _,obj in pairs(minetest.get_objects_inside_radius(pos, 4)) do local entity = obj:get_luaentity() - if obj:is_player() or entity.is_mob then + if obj:is_player() or entity and entity.is_mob then local pos2 = obj:get_pos() local rad = math.floor(math.sqrt((pos2.x-pos.x)^2 + (pos2.y-pos.y)^2 + (pos2.z-pos.z)^2)) diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index e9755479b..87f40e3ae 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -155,7 +155,7 @@ minetest.register_node("mcl_sponges:sponge_wet", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, hoey=1, building_block=1}, + groups = {handy=1, hoey=1, waterlogged = 1, building_block=1}, on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, @@ -175,7 +175,7 @@ if minetest.get_modpath("mclx_core") then buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, waterlogged = 1, building_block=1}, on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, diff --git a/mods/ITEMS/mcl_sus_stew/init.lua b/mods/ITEMS/mcl_sus_stew/init.lua index d3e03ae48..01c8d2d55 100644 --- a/mods/ITEMS/mcl_sus_stew/init.lua +++ b/mods/ITEMS/mcl_sus_stew/init.lua @@ -1,7 +1,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) -- ____________________________ ---_________________________________________/ Variables & Functions \_________ +--_________________________________________/ Variables & Functions \_________ local eat = minetest.item_eat(6, "mcl_core:bowl") --6 hunger points, player receives mcl_core:bowl after eating @@ -12,7 +12,7 @@ local flower_effect = { [ "mcl_flowers:dandelion" ] = "hunger", [ "mcl_flowers:cornflower" ] = "jump", [ "mcl_flowers:oxeye_daisy" ] = "regeneration", - [ "mcl_flowers:poppy" ] = "night_vision" + [ "mcl_flowers:poppy" ] = "night_vision" } local effects = { @@ -53,13 +53,27 @@ local function get_random_effect() return effects[keys[math.random(#keys)]] end -local function eat_stew(itemstack, placer, pointed_thing) +local function eat_stew(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + if user and not user:get_player_control().sneak then + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if user and not user:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + end + end + end + elseif pointed_thing.type == "object" then + return itemstack + end + local e = itemstack:get_meta():get_string("effect") local f = effects[e] if not f then f = get_random_effect() end - if f(itemstack,placer,pointed_thing) then + if f(itemstack, user, pointed_thing) then return "mcl_core:bowl" end end diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index e60fd11b2..6282da5c3 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -165,12 +165,36 @@ local make_grass_path = function(itemstack, placer, pointed_thing) end end - -- Only make grass path if tool used on side or top of target node + -- Only make or remove grass path if tool used on side or top of target node if pointed_thing.above.y < pointed_thing.under.y then return itemstack end - if (minetest.get_item_group(node.name, "path_creation_possible") == 1) then +-- Remove grass paths + if (minetest.get_item_group(node.name, "path_remove_possible") == 1) and placer:get_player_control().sneak then + local above = table.copy(pointed_thing.under) + above.y = above.y + 1 + if minetest.get_node(above).name == "air" then + if minetest.is_protected(pointed_thing.under, placer:get_player_name()) then + minetest.record_protection_violation(pointed_thing.under, placer:get_player_name()) + return itemstack + end + + if not minetest.is_creative_enabled(placer:get_player_name()) then + -- Add wear (as if digging a shovely node) + local toolname = itemstack:get_name() + local wear = mcl_autogroup.get_wear(toolname, "shovely") + if wear then + itemstack:add_wear(wear) + end + end + minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above, max_hear_distance = 16}, true) + minetest.swap_node(pointed_thing.under, {name="mcl_core:dirt"}) + end + end + +-- Make grass paths + if (minetest.get_item_group(node.name, "path_creation_possible") == 1) and not placer:get_player_control().sneak then local above = table.copy(pointed_thing.under) above.y = above.y + 1 if minetest.get_node(above).name == "air" then diff --git a/mods/ITEMS/mcl_walls/API.md b/mods/ITEMS/mcl_walls/API.md index e6956ac47..5c21ce98d 100644 --- a/mods/ITEMS/mcl_walls/API.md +++ b/mods/ITEMS/mcl_walls/API.md @@ -2,7 +2,7 @@ This API allows you to add more walls (like the cobblestone wall) to MineClone 2. -## `mcl_walls.register_wall(nodename, description, craft_material, tiles, invtex, groups, sounds)` +## `mcl_walls.register_wall(nodename, description, craft_material, tiles, invtex, groups, sounds, hardness, blast_resistance)` Adds a new wall type. This is optimized for stone-based walls, but other materials are theoretically possible, too. @@ -25,6 +25,8 @@ If `craft_material` is not `nil` it also adds a crafting recipe of the following * `inventory_image`: Inventory image (optional if `source` is set) * `groups`: Base group memberships (optional, default is `{pickaxey=1}`) * `sounds`: Sound table (optional, by default default uses stone sounds) +* `hardness`: Hardness of node (optional, default matches `source` node or fallback value 2) +* `blast_resistance`: Blast resistance of node (optional, default matches `source` node or fallback value 6) The following groups will automatically be added to the nodes (where applicable), you do not need to add them to the `groups` table: diff --git a/mods/ITEMS/mcl_walls/init.lua b/mods/ITEMS/mcl_walls/init.lua index 14b512ffd..caf8b34fe 100644 --- a/mods/ITEMS/mcl_walls/init.lua +++ b/mods/ITEMS/mcl_walls/init.lua @@ -97,8 +97,10 @@ local full_blocks = { * inventory_image: Inventory image (optional) * groups: Base group memberships (optional, default is {pickaxey=1}) * sounds: Sound table (optional, default is stone) +* hardness: Hardness of node (optional, default matches `source` node or fallback value 2) +* blast_resistance: Blast resistance of node (optional, default matches `source` node or fallback value 6) ]] -function mcl_walls.register_wall(nodename, description, source, tiles, inventory_image, groups, sounds) +function mcl_walls.register_wall(nodename, description, source, tiles, inventory_image, groups, sounds, hardness, blast_resistance) local base_groups = groups if not base_groups then @@ -112,15 +114,29 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory local main_node_groups = table.copy(base_groups) main_node_groups.deco_block = 1 - -- TODO: Stop hardcoding blast resistance - - if not sounds then - sounds = mcl_sounds.node_sound_stone_defaults() - end - - if (not tiles) and source then - if minetest.registered_nodes[source] then - tiles = minetest.registered_nodes[source].tiles + if source then + -- Default values from `source` node + if not hardness then + hardness = minetest.registered_nodes[source]._mcl_hardness + end + if not blast_resistance then + blast_resistance = minetest.registered_nodes[source]._mcl_blast_resistance + end + if not sounds then + sounds = minetest.registered_nodes[source].sounds + end + if not tiles then + if minetest.registered_nodes[source] then + tiles = minetest.registered_nodes[source].tiles + end + end + else + -- Fallback in case no `source` given + if not hardness then + hardness = 2 + end + if not blast_resistance then + blast_resistance = 6 end end @@ -169,8 +185,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = take }, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) -- Add entry alias for the Help @@ -197,8 +213,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = {pillar, full_blocks[1]} }, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) -- Add entry alias for the Help if minetest.get_modpath("doc") then @@ -223,8 +239,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = {pillar, full_blocks[2]} }, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) -- Add entry alias for the Help if minetest.get_modpath("doc") then @@ -255,8 +271,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory collisionbox = {-0.2, 0, -0.2, 0.2, 1.4, 0.2}, on_construct = update_wall, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) if source then minetest.register_craft({ diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 69cb00d07..99da0a01a 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -154,27 +154,27 @@ end local player_props_elytra = { collisionbox = { -0.35, 0, -0.35, 0.35, 0.8, 0.35 }, - eye_height = 0.5, + eye_height = 0.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } local player_props_riding = { collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, - eye_height = 1.5, + eye_height = 1.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } local player_props_sneaking = { collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, - eye_height = 1.35, + eye_height = 1.45, nametag_color = { r = 225, b = 225, a = 0, g = 225 } } local player_props_swimming = { collisionbox = { -0.312, 0, -0.312, 0.312, 0.8, 0.312 }, - eye_height = 0.5, + eye_height = 0.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } local player_props_normal = { collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, - eye_height = 1.5, + eye_height = 1.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } diff --git a/settingtypes.txt b/settingtypes.txt index 8123ca9d9..82086de14 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -166,6 +166,24 @@ mcl_mob_cap_axolotl (Mob cap axolotl) int 5 0 1024 #Maximum amount of ambient mobs that will spawn near a player (default:15) mcl_mob_cap_ambient (Mob cap ambient mobs) int 15 0 1024 +#Maximum amount of wither bosses on the loaded mapchunks in the overworld that allows spawning withers in the overworld (default:3) +wither_cap_overworld (Wither cap overworld) int 3 0 2048 + +#Maximum amount of wither bosses on the loaded mapchunks in the nether that allows spawning withers in the nether (default:10) +wither_cap_nether (Wither cap nether) int 10 0 2048 + +#Maximum amount of wither bosses on the loaded mapchunks in the end that allows spawning withers in the end (default:5) +wither_cap_end (Wither cap end) int 5 0 2048 + +#Should wither follow the player who spawned him around +wither_follow_spawner (Wither following his spawner) bool false + +#Should wither strafe while in combat +wither_strafes (Wither strafes) bool true + +#Wither anti-troll measures (escaping when stuck in a block, despawning when spawner goes offline, teleporting after the spawner). When this is OFF, wither_follow_spawner has no effect. +wither_anti_troll_measures (Wither anti-troll measures) bool false + #Display mob icons in inventory instead of mc-like spawn eggs mcl_old_spawn_icons (Old spawn icons instead of eggs) bool false @@ -176,6 +194,19 @@ mcl_mob_active_range (Active mob range) int 48 0 256 # Zombie siege raid (default:false) mcl_raids_zombie_siege (Zombie siege raid) bool false +# Use MC 1.18+ light levels to control monster spawning. +# Disable to use older mob specific light levels. +mcl_mobs_modern_lighting (Use MC 1.18+ light rules for spawning) bool true + +# These only take effect if mcl_mobs_modern_lighting is enabled +# Light levels greater than these block mobs spawning +# See https://minecraft.fandom.com/wiki/Light#Internal_light_level +mcl_mobs_nether_threshold (Artificial light threshold to stop spawns in the Nether) int 11 0 14 +mcl_mobs_end_threshold (Artificial light threshold to stop spawns in the End) int 0 0 14 +mcl_mobs_overworld_threshold (Artificial light threshold to stop monster spawns in the Overworld) int 0 0 14 +mcl_mobs_overworld_sky_threshold (Skylight threshold to stop monster spawns in the Overworld) int 7 0 14 +mcl_mobs_overworld_passive_threshold (Combined light threshold to stop animal and npc spawns in the Overworld) int 7 0 14 + [Audio] # Enable flame sound. flame_sound (Flame sound) bool true diff --git a/textures/default_lava_flowing_animated.png b/textures/mcl_core_lava_flow_animation.png similarity index 100% rename from textures/default_lava_flowing_animated.png rename to textures/mcl_core_lava_flow_animation.png diff --git a/textures/default_lava_source_animated.png b/textures/mcl_core_lava_source_animation.png similarity index 100% rename from textures/default_lava_source_animated.png rename to textures/mcl_core_lava_source_animation.png diff --git a/textures/default_water_flowing_animated.png b/textures/mcl_core_water_flow_animation.png similarity index 100% rename from textures/default_water_flowing_animated.png rename to textures/mcl_core_water_flow_animation.png diff --git a/textures/default_water_source_animated.png b/textures/mcl_core_water_source_animation.png similarity index 100% rename from textures/default_water_source_animated.png rename to textures/mcl_core_water_source_animation.png diff --git a/textures/mcl_potions_effect_withering.png b/textures/mcl_potions_effect_withering.png new file mode 100644 index 000000000..eed626c6b Binary files /dev/null and b/textures/mcl_potions_effect_withering.png differ diff --git a/textures/mcl_potions_icon_regen_wither.png b/textures/mcl_potions_icon_regen_wither.png new file mode 100644 index 000000000..14c6acdad Binary files /dev/null and b/textures/mcl_potions_icon_regen_wither.png differ diff --git a/textures/mcl_potions_icon_wither.png b/textures/mcl_potions_icon_wither.png new file mode 100644 index 000000000..7ccf394b9 Binary files /dev/null and b/textures/mcl_potions_icon_wither.png differ diff --git a/textures/mobs_mc_wither_projectile.png b/textures/mobs_mc_wither_projectile.png new file mode 100644 index 000000000..381a0ff8f Binary files /dev/null and b/textures/mobs_mc_wither_projectile.png differ diff --git a/textures/mobs_mc_wither_projectile_strong.png b/textures/mobs_mc_wither_projectile_strong.png new file mode 100644 index 000000000..4e4c38f73 Binary files /dev/null and b/textures/mobs_mc_wither_projectile_strong.png differ diff --git a/tools/Conversion_Table.csv b/tools/Conversion_Table.csv index 9dc50dc7a..72e8ac433 100644 --- a/tools/Conversion_Table.csv +++ b/tools/Conversion_Table.csv @@ -7,9 +7,9 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? /assets/minecraft/textures/gui,icons.png,/mods/HUD/hudbars/textures,hudbars_icon_breath.png,16,18,9,9,0,0,y /assets/minecraft/textures/gui,icons.png,/mods/HUD/mcl_base_textures/textures,heart.png,52,0,9,9,0,0,y /assets/minecraft/textures/gui,icons.png,/mods/HUD/mcl_base_textures/textures,bubble.png,16,18,9,9,0,0,y -/assets/minecraft/textures/items,bucket_empty.png,/mods/ITEMS/mcl_buckets/textures,bucket.png,,,,,,, -/assets/minecraft/textures/items,bucket_water.png,/mods/ITEMS/mcl_buckets/textures,bucket_water.png,,,,,,, -/assets/minecraft/textures/items,bucket_water.png,/mods/ITEMS/mcl_buckets/textures,bucket_river_water.png,,,,,,, +/assets/minecraft/textures/items,bucket_empty.png,/mods/ITEMS/mcl_buckets/textures,mcl_buckets_bucket.png,,,,,,, +/assets/minecraft/textures/items,bucket_water.png,/mods/ITEMS/mcl_buckets/textures,mcl_buckets_water_bucket.png,,,,,,, +/assets/minecraft/textures/items,bucket_water.png,/mods/ITEMS/mcl_buckets/textures,mcl_buckets_river_water_bucket.png,,,,,,, /assets/minecraft/textures/items,bucket_lava.png,/mods/ITEMS/mcl_buckets/textures,mcl_buckets_lava_bucket.png,,,,,,, /assets/minecraft/textures/items,item_frame.png,/mods/ITEMS/mcl_itemframes/textures,mcl_itemframes_item_frame.png,,,,,,, /assets/minecraft/textures/blocks,anvil_base.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_base.png,,,,,,, @@ -171,8 +171,8 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? /assets/minecraft/textures/blocks,log_jungle_top.png,/mods/ITEMS/mcl_core/textures,default_jungletree_top.png,,,,,,, /assets/minecraft/textures/blocks,planks_jungle.png,/mods/ITEMS/mcl_core/textures,default_junglewood.png,,,,,,, /assets/minecraft/textures/blocks,ladder.png,/mods/ITEMS/mcl_core/textures,default_ladder.png,,,,,,, -/assets/minecraft/textures/blocks,lava_still.png,/mods/ITEMS/mcl_core/textures,default_lava_source_animated.png,,,,,,, -/assets/minecraft/textures/blocks,lava_flow.png,/mods/ITEMS/mcl_core/textures,default_lava_flowing_animated.png,,,,,,, +/assets/minecraft/textures/blocks,lava_still.png,/mods/ITEMS/mcl_core/textures,mcl_core_lava_source_animation.png,,,,,,, +/assets/minecraft/textures/blocks,lava_flow.png,/mods/ITEMS/mcl_core/textures,mcl_core_lava_flow_animation.png,,,,,,, /assets/minecraft/textures/blocks,cobblestone_mossy.png,/mods/ITEMS/mcl_core/textures,default_mossycobble.png,,,,,,, /assets/minecraft/textures/blocks,obsidian.png,/mods/ITEMS/mcl_core/textures,default_obsidian.png,,,,,,, /assets/minecraft/textures/items,paper.png,/mods/ITEMS/mcl_core/textures,default_paper.png,,,,,,, @@ -187,10 +187,8 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? /assets/minecraft/textures/blocks,stone.png,/mods/ITEMS/mcl_core/textures,default_stone.png,,,,,,, /assets/minecraft/textures/blocks,log_oak.png,/mods/ITEMS/mcl_core/textures,default_tree.png,,,,,,, /assets/minecraft/textures/blocks,log_oak_top.png,/mods/ITEMS/mcl_core/textures,default_tree_top.png,,,,,,, -/assets/minecraft/textures/blocks,water_still.png,/mods/ITEMS/mcl_core/textures,default_water_source_animated.png,,,,,,, -/assets/minecraft/textures/blocks,water_flow.png,/mods/ITEMS/mcl_core/textures,default_water_flowing_animated.png,,,,,,, -/assets/minecraft/textures/blocks,water_still.png,/mods/ITEMS/mcl_core/textures,default_river_water_source_animated.png,,,,,,, -/assets/minecraft/textures/blocks,water_flow.png,/mods/ITEMS/mcl_core/textures,default_river_water_flowing_animated.png,,,,,,, +/assets/minecraft/textures/blocks,water_still.png,/mods/ITEMS/mcl_core/textures,mcl_core_water_source_animation.png,,,,,,, +/assets/minecraft/textures/blocks,water_flow.png,/mods/ITEMS/mcl_core/textures,mcl_core_water_flow_animation.png,,,,,,, /assets/minecraft/textures/blocks,planks_oak.png,/mods/ITEMS/mcl_core/textures,default_wood.png,,,,,,, /assets/minecraft/textures/blocks,stone_andesite.png,/mods/ITEMS/mcl_core/textures,mcl_core_andesite.png,,,,,,, /assets/minecraft/textures/blocks,stone_andesite_smooth.png,/mods/ITEMS/mcl_core/textures,mcl_core_andesite_smooth.png,,,,,,,