From ce123d4676e5aabf6a878509dc7f933b346a2b22 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:02:35 +0100 Subject: [PATCH 001/164] add API documentation to mcl_autogroup --- mods/CORE/mcl_autogroup/API.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 mods/CORE/mcl_autogroup/API.md diff --git a/mods/CORE/mcl_autogroup/API.md b/mods/CORE/mcl_autogroup/API.md new file mode 100644 index 000000000..79b9770b5 --- /dev/null +++ b/mods/CORE/mcl_autogroup/API.md @@ -0,0 +1,27 @@ +# mcl_autogroup +This mod emulate digging times from mc. + +## mcl_autogroup.can_harvest(nodename, toolname) +Return true if can be dig with . +* nodename: string, valid nodename +* toolname: (optional) string, valid toolname + +## mcl_autogroup.get_groupcaps(toolname, efficiency) +This function is used to calculate diggroups for tools. +WARNING: This function can only be called after mod initialization. +* toolname: string, name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") +* efficiency: (optional) integer, the efficiency level the tool is enchanted with (default 0) + +## mcl_autogroup.get_wear(toolname, diggroup) +Return the max wear of with +WARNING: This function can only be called after mod initialization. +* toolname: string, name of the tool used +* diggroup: string, the name of the diggroup the tool is used on + +## mcl_autogroup.register_diggroup(group, def) +* group: string, name of the group to register as a digging group +* def: (optional) table, table with information about the diggroup (defaults to {} if unspecified) + * level: (optional) string, if specified it is an array containing the names of the different digging levels the digging group supports + +## mcl_autogroup.registered_diggroups +List of registered diggroups, indexed by name. \ No newline at end of file From fb50b256ed6c2e0451e950c33114c51507c08618 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:12:41 +0100 Subject: [PATCH 002/164] add API documentation to flowlib (part 1) --- mods/CORE/flowlib/API.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 mods/CORE/flowlib/API.md diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md new file mode 100644 index 000000000..d9f54e4bd --- /dev/null +++ b/mods/CORE/flowlib/API.md @@ -0,0 +1,35 @@ +# flowlib +Simple flow functions. + +## flowlib.is_touching() + + +## flowlib.is_water(pos) +Return true if node at is water, false overwise. +* pos: position + +## flowlib.node_is_water(node) +Return true if is water, false overwise. +* node: node + +## flowlib.is_lava(pos) +Return true if node at is lava, false overwise. +* pos: position + +## flowlib.node_is_lava(node) +Return true if is lava, false overwise. +* node: node + +## flowlib.is_liquid(pos) +Return true if node at is liquid, false overwise. +* pos: position + +## flowlib.node_is_liquid(node) +Return true if is liquid, false overwise. +* node: node + +## flowlib.quick_flow(pos, node) +* pos: position +* node: node + +## flowlib.move_centre(pos, realpos, node, radius) \ No newline at end of file From 19db2a479f702a9fa1f2fb44e6b4253c5e27a9e7 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:18:19 +0100 Subject: [PATCH 003/164] add API documentation to flowlib (part 2) --- mods/CORE/flowlib/API.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md index d9f54e4bd..7ebb4cc87 100644 --- a/mods/CORE/flowlib/API.md +++ b/mods/CORE/flowlib/API.md @@ -1,7 +1,11 @@ # flowlib Simple flow functions. -## flowlib.is_touching() +## flowlib.is_touching(realpos, nodepos, radius) +Return true if a sphere of at collide with node at . +* realpos: position +* nodepos: position +* radius: number ## flowlib.is_water(pos) From 2a5dcd1634c8d546636b7725308efd3705f1e0f9 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:23:57 +0100 Subject: [PATCH 004/164] add API documentation to flowlib (part 3) --- mods/CORE/flowlib/API.md | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md index 7ebb4cc87..0542e4519 100644 --- a/mods/CORE/flowlib/API.md +++ b/mods/CORE/flowlib/API.md @@ -33,6 +33,7 @@ Return true if is liquid, false overwise. * node: node ## flowlib.quick_flow(pos, node) +Return direction where the water is flowing (to be use to push mobs, items...). * pos: position * node: node From 39ac3f208d003f77ad3fcec1a79d6b1c4e4799a3 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:25:54 +0100 Subject: [PATCH 005/164] add API documentation to flowlib (part 4) --- mods/CORE/flowlib/API.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md index 0542e4519..f3282c975 100644 --- a/mods/CORE/flowlib/API.md +++ b/mods/CORE/flowlib/API.md @@ -37,4 +37,8 @@ Return direction where the water is flowing (to be use to push mobs, items...). * pos: position * node: node -## flowlib.move_centre(pos, realpos, node, radius) \ No newline at end of file +## flowlib.move_centre(pos, realpos, node, radius) +* pos: position +* realpos: position +* node: node +* radius: number \ No newline at end of file From 52939ff6a409e777106b82d87c34d917cb0c9fd4 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:32:52 +0100 Subject: [PATCH 006/164] add API documentation to flowlib (part 5) --- mods/CORE/flowlib/API.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md index f3282c975..20e85036b 100644 --- a/mods/CORE/flowlib/API.md +++ b/mods/CORE/flowlib/API.md @@ -7,7 +7,6 @@ Return true if a sphere of at collide with node at . * nodepos: position * radius: number - ## flowlib.is_water(pos) Return true if node at is water, false overwise. * pos: position @@ -38,7 +37,9 @@ Return direction where the water is flowing (to be use to push mobs, items...). * node: node ## flowlib.move_centre(pos, realpos, node, radius) +Return the pos of the nearest not water block near from in a sphere of at . +WARNING: This function is never used in mcl2, use at your own risk. The informations described here may be wrong. * pos: position -* realpos: position +* realpos: position, position of the entity * node: node * radius: number \ No newline at end of file From e56d9d2ab805250221ab0d3fed54bac3f8e03444 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:44:36 +0100 Subject: [PATCH 007/164] add API documentation to controls --- mods/CORE/controls/API.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 mods/CORE/controls/API.md diff --git a/mods/CORE/controls/API.md b/mods/CORE/controls/API.md new file mode 100644 index 000000000..8d9df6ca5 --- /dev/null +++ b/mods/CORE/controls/API.md @@ -0,0 +1,23 @@ +# controls + +## controls.players +Table containing player controls at runtime. +WARNING: Never use this table in writing + +## controls.register_on_press(func) +Register a function that will be executed with (player, keyname) every time a player press a key. + +## controls.registered_on_press +Table containing functions registered with controls.register_on_press(). + +## controls.register_on_release(func) +Register a function that will be executed with (player, keyname, clock_from_last_press) every time a player release a key. + +## controls.registered_on_release +Table containing functions registered with controls.register_on_release(). + +## controls.register_on_hold(func) +Register a function that will be executed with (player, keyname, clock_from_start_hold) every time a player hold a key. + +## controls.registered_on_hold +Table containing functions registered with controls.register_on_hold(). \ No newline at end of file From 6f9c1856b8bae6b7293ead323ab291aa482a0b81 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:48:24 +0100 Subject: [PATCH 008/164] add API documentation to mcl_colors (!) --- mods/CORE/mcl_colors/API.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 mods/CORE/mcl_colors/API.md diff --git a/mods/CORE/mcl_colors/API.md b/mods/CORE/mcl_colors/API.md new file mode 100644 index 000000000..71cad335b --- /dev/null +++ b/mods/CORE/mcl_colors/API.md @@ -0,0 +1,8 @@ +# mcl_colors +Mod providing global table containing legacity minecraft colors to be used in mods. + +## mcl_colors.* +Colors by upper name, in hex value. + +## mcl_colors.background.* +Background colors by upper name, in hex value. From cdb67d96a6cf4a72a94b98ff9f0b5055af0cd977 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 01:00:18 +0100 Subject: [PATCH 009/164] add API documentation to mcl_explosions --- mods/CORE/mcl_explosions/API.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 mods/CORE/mcl_explosions/API.md diff --git a/mods/CORE/mcl_explosions/API.md b/mods/CORE/mcl_explosions/API.md new file mode 100644 index 000000000..cb0e9252d --- /dev/null +++ b/mods/CORE/mcl_explosions/API.md @@ -0,0 +1,15 @@ +# mcl_explosions +This mod provide helper functions to create explosions. + +## mcl_explosions.explode(pos, strength, info, puncher) +* pos: position, initial position of the explosion +* strenght: number, radius of the explosion +* info: table, explosion informations: + * drop_chance: number, if specified becomes the drop chance of all nodes in the explosion (default: 1.0 / strength) + * max_blast_resistance: int, if specified the explosion will treat all non-indestructible nodes as having a blast resistance of no more than this value + * sound: bool, if true, the explosion will play a sound (default: true) + * particles: bool, if true, the explosion will create particles (default: true) + * fire: bool, if true, 1/3 nodes become fire (default: false) + * griefing: bool, if true, the explosion will destroy nodes (default: true) + * grief_protected: bool, if true, the explosion will also destroy nodes which have been protected (default: false) +* puncher: (optional) entity, will be used as source for damage done by the explosion \ No newline at end of file From 890a569b13cf0a9c9925dc545df740e201a6a2fb Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 07:40:36 +0200 Subject: [PATCH 010/164] add API documentation to mcl_worlds --- mods/CORE/mcl_worlds/API.md | 80 +++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 mods/CORE/mcl_worlds/API.md diff --git a/mods/CORE/mcl_worlds/API.md b/mods/CORE/mcl_worlds/API.md new file mode 100644 index 000000000..a5509431c --- /dev/null +++ b/mods/CORE/mcl_worlds/API.md @@ -0,0 +1,80 @@ +# mcl_worlds +This mod provides utility functions about positions and dimensions. + +## mcl_worlds.is_in_void(pos) +This function returns: + +* true, true: if pos is in deep void (deadly) +* true, false: if the pos is in void (non deadly) +* false, false: owerwise + +Params: + +* pos: position + +## mcl_worlds.y_to_layer(y) +This function is used to calculate the minetest y layer and dimension of the given minecraft layer. +Mainly used for ore generation. +Takes an Y coordinate as input and returns: + +* The corresponding Minecraft layer (can be nil if void) +* The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if is in the void +If the Y coordinate is not located in any dimension, it will return: nil, "void" + +Params: + +* y: int + +## mcl_worlds.pos_to_dimension(pos) +This function return the Minecraft dimension of ("overworld", "nether" or "end") or "void" if is in the void. + +* pos: position + +## mcl_worlds.layer_to_y(layer, mc_dimension) +Takes a Minecraft layer and a “dimension” name and returns the corresponding Y coordinate for MineClone 2. +mc_dimension can be "overworld", "nether", "end" (default: "overworld"). + +* layer: int +* mc_dimension: string + +## mcl_worlds.has_weather(pos) +Returns true if can have weather, false owerwise. +Weather can be only in the overworld. + +* pos: position + +## mcl_worlds.has_dust(pos) +Returns true if can have nether dust, false owerwise. +Nether dust can be only in the nether. + +* pos: position + +## mcl_worlds.compass_works(pos) +Returns true if compasses are working at , false owerwise. +In mc, you cant use compass in the nether and the end. + +* pos: position + +## mcl_worlds.compass_works(pos) +Returns true if clock are working at , false owerwise. +In mc, you cant use clock in the nether and the end. + +* pos: position + +## mcl_worlds.register_on_dimension_change(function(player, dimension)) +Register a callback function func(player, dimension). +It will be called whenever a player changes between dimensions. +The void counts as dimension. + +* player: player, the player who changed the dimension +* dimension: position, The new dimension of the player ("overworld", "nether", "end", "void"). + + +## mcl_worlds.registered_on_dimension_change +Table containing all function registered with mcl_worlds.register_on_dimension_change() + +## mcl_worlds.dimension_change(player, dimension) +Notify this mod of a dimmension change of to + +* player: player, player who changed the dimension +* dimension: string, new dimension ("overworld", "nether", "end", "void") \ No newline at end of file From 0dbe66f3b43bb2134b1dc1920539627bc4aaf9a0 Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 1 Apr 2021 14:12:07 -0700 Subject: [PATCH 011/164] make mob drops similar to MC --- mods/ENTITIES/mcl_mobs/api.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index f1df87e8b..1ef0712e8 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -735,7 +735,9 @@ local item_drop = function(self, cooked, looting_level) end -- add item if it exists - obj = minetest.add_item(pos, ItemStack(item .. " " .. num)) + for x = 1, num do + obj = minetest.add_item(pos, ItemStack(item .. " " .. 1)) + end if obj and obj:get_luaentity() then From 2f272b3dff16c642bd0e8f02dd1b0878bac3188c Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 1 Apr 2021 23:48:00 -0400 Subject: [PATCH 012/164] Fix item drop on laggy servers --- mods/ENTITIES/mcl_item_entity/init.lua | 156 ++++++++++--------------- 1 file changed, 61 insertions(+), 95 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 95b90e546..df08291b4 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -1,6 +1,6 @@ local has_awards = minetest.get_modpath("awards") -mcl_item_entity = {} +local mcl_item_entity = {} --basic settings local item_drop_settings = {} --settings table @@ -74,114 +74,70 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement end end +--this is a 0.2 second tick globally across all players +local item_check_ticker = 0 + minetest.register_globalstep(function(dtime) - for _,player in pairs(minetest.get_connected_players()) do - if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then - local pos = player:get_pos() - local inv = player:get_inventory() - local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} + item_check_ticker = item_check_ticker + dtime + if item_check_ticker >= 0.2 then + item_check_ticker = 0 + print(dtime) - --magnet and collection - for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do - if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then - object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime - local collected = false - if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + for _,player in pairs(minetest.get_connected_players()) do + if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then + local pos = player:get_pos() + local inv = player:get_inventory() + local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} - -- Collection - if vector.distance(checkpos, object:get_pos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then - -- Ignore if itemstring is not set yet - if object:get_luaentity().itemstring ~= "" then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - minetest.sound_play("item_drop_pickup", { - pos = pos, - max_hear_distance = 16, - gain = 1.0, - }, true) - check_pickup_achievements(object, player) + --magnet and collection + for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do + if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then + object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime + local collected = false + if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + + -- Collection + if not object:get_luaentity()._removed then + -- Ignore if itemstring is not set yet + if object:get_luaentity().itemstring ~= "" then + inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) + minetest.sound_play("item_drop_pickup", { + pos = pos, + max_hear_distance = 16, + gain = 1.0, + }, true) + check_pickup_achievements(object, player) - -- Destroy entity - -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. - object:get_luaentity()._removed = true - object:remove() - collected = true - end + object:move_to(checkpos, false) - -- Magnet - else + -- Destroy entity + -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. + object:get_luaentity()._removed = true - object:get_luaentity()._magnet_active = true - object:get_luaentity()._collector_timer = 0 - - -- Move object to player - disable_physics(object, object:get_luaentity()) - - local opos = object:get_pos() - local vec = vector.subtract(checkpos, opos) - vec = vector.add(opos, vector.divide(vec, 2)) - object:move_to(vec) - - - --fix eternally falling items - minetest.after(0, function(object) - local lua = object:get_luaentity() - if lua then - object:set_acceleration({x=0, y=0, z=0}) - end - end, object) - - - --this is a safety to prevent items flying away on laggy servers - if item_drop_settings.collection_safety == true then - if object:get_luaentity().init ~= true then - object:get_luaentity().init = true - minetest.after(1, function(args) - local playername = args[1] - local player = minetest.get_player_by_name(playername) - local object = args[2] - local lua = object:get_luaentity() - if player == nil or not player:is_player() or object == nil or lua == nil or lua.itemstring == nil then - return - end - if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - if not object:get_luaentity()._removed then - minetest.sound_play("item_drop_pickup", { - pos = pos, - max_hear_distance = 16, - gain = 1.0, - }, true) - end - check_pickup_achievements(object, player) - object:get_luaentity()._removed = true - object:remove() - else - enable_physics(object, object:get_luaentity()) - end - end, {player:get_player_name(), object}) + collected = true end end end - end - if not collected then - if object:get_luaentity()._magnet_timer > 1 then - object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time - object:get_luaentity()._magnet_active = false - elseif object:get_luaentity()._magnet_timer < 0 then - object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime + if not collected then + if object:get_luaentity()._magnet_timer > 1 then + object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time + object:get_luaentity()._magnet_active = false + elseif object:get_luaentity()._magnet_timer < 0 then + object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime + end end + + elseif not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mcl_experience:orb" then + local entity = object:get_luaentity() + entity.collector = player:get_player_name() + entity.collected = true + end - - elseif not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mcl_experience:orb" then - local entity = object:get_luaentity() - entity.collector = player:get_player_name() - entity.collected = true - end - end + end end end end) @@ -230,12 +186,13 @@ local function get_fortune_drops(fortune_drops, fortune_level) return drop or {} end +local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true) + function minetest.handle_node_drops(pos, drops, digger) -- NOTE: This function override allows digger to be nil. -- This means there is no digger. This is a special case which allows this function to be called -- by hand. Creative Mode is intentionally ignored in this case. - local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true) if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then return end @@ -401,6 +358,9 @@ minetest.register_entity(":__builtin:item", { -- Number of seconds this item entity has existed so far age = 0, + -- How old it has become in the collection animation + collection_age = 0, + set_item = function(self, itemstring) self.itemstring = itemstring if self.itemstring == "" then @@ -566,6 +526,12 @@ minetest.register_entity(":__builtin:item", { on_step = function(self, dtime) if self._removed then + self.object:set_acceleration({x=0,y=0,z=0}) + self.object:set_velocity({x=0,y=0,z=0}) + self.collection_age = self.collection_age + dtime + if self.collection_age > 0.15 then + self.object:remove() + end return end self.age = self.age + dtime From 1e3676c391a8588236e4f7871c382a4b28f6f9b3 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Fri, 2 Apr 2021 05:38:53 +0000 Subject: [PATCH 013/164] Remove debug info from item magnet --- mods/ENTITIES/mcl_item_entity/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index df08291b4..a05bb1ffd 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -81,7 +81,6 @@ minetest.register_globalstep(function(dtime) item_check_ticker = item_check_ticker + dtime if item_check_ticker >= 0.2 then item_check_ticker = 0 - print(dtime) for _,player in pairs(minetest.get_connected_players()) do if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then From 39aaf0f21faac88ba1f249e7324e7e4296861f50 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 2 Apr 2021 11:09:45 +0000 Subject: [PATCH 014/164] Fix #1391 --- mods/ITEMS/mcl_end/end_crystal.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index b6b9fdd6a..d089c3cdf 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -70,7 +70,7 @@ minetest.register_entity("mcl_end:crystal", { collisionbox = {-1, 0.5, -1, 1, 2.5, 1}, mesh = "mcl_end_crystal.b3d", textures = {"mcl_end_crystal.png"}, - collide_with_objects = true, + collide_with_objects = false, }, on_punch = crystal_explode, on_activate = set_crystal_animation, From 695ad9120bf42f4b5ce62027a393fc2d65dd86aa Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 14:12:44 +0200 Subject: [PATCH 015/164] remove backward compatibility for water --- mods/ITEMS/mcl_core/nodes_liquid.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 0479c7f72..4696a629a 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -7,10 +7,10 @@ local WATER_ALPHA = 179 local WATER_VISC = 1 local LAVA_VISC = 7 local LIGHT_LAVA = minetest.LIGHT_MAX -local USE_TEXTURE_ALPHA +local USE_TEXTURE_ALPHA = true + if minetest.features.use_texture_alpha_string_modes then USE_TEXTURE_ALPHA = "blend" - WATER_ALPHA = nil end local lava_death_messages = { @@ -40,7 +40,6 @@ minetest.register_node("mcl_core:water_flowing", { }, sounds = mcl_sounds.node_sound_water_defaults(), is_ground_content = false, - alpha = WATER_ALPHA, use_texture_alpha = USE_TEXTURE_ALPHA, paramtype = "light", paramtype2 = "flowingliquid", @@ -86,7 +85,6 @@ S("• When water is directly below lava, the water turns into stone."), }, sounds = mcl_sounds.node_sound_water_defaults(), is_ground_content = false, - alpha = WATER_ALPHA, use_texture_alpha = USE_TEXTURE_ALPHA, paramtype = "light", walkable = false, From e20e0fab7164fee0a7cd495817d4a5a8dcd60c1a Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 14:16:14 +0200 Subject: [PATCH 016/164] remobe backward compatibility for portals --- mods/ITEMS/mcl_portals/portal_end.lua | 6 ------ mods/ITEMS/mcl_portals/portal_nether.lua | 2 -- 2 files changed, 8 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 0bc0ce57e..ab09c5966 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -4,11 +4,6 @@ local S = minetest.get_translator("mcl_portals") local SPAWN_MIN = mcl_vars.mg_end_min+70 local SPAWN_MAX = mcl_vars.mg_end_min+98 -local PORTAL_ALPHA = 192 -if minetest.features.use_texture_alpha_string_modes then - PORTAL_ALPHA = nil -end - local mg_name = minetest.get_mapgen_setting("mg_name") local destroy_portal = function(pos) @@ -81,7 +76,6 @@ minetest.register_node("mcl_portals:portal_end", { -- This is 15 in MC. light_source = 14, post_effect_color = {a = 192, r = 0, g = 0, b = 0}, - alpha = PORTAL_ALPHA, after_destruct = destroy_portal, -- This prevents “falling through” collision_box = { diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index e842edf81..50a3bde39 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -30,7 +30,6 @@ local N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_be local O_DY, N_DY = O_Y_MAX - O_Y_MIN + 1, N_Y_MAX - N_Y_MIN + 1 -- Alpha and particles -local ALPHA = minetest.features.use_texture_alpha_string_modes and 192 local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" local node_particles_levels = { none=0, low=1, medium=2, high=3 } local PARTICLES = node_particles_levels[node_particles_allowed] @@ -263,7 +262,6 @@ minetest.register_node(PORTAL, { drop = "", light_source = 11, post_effect_color = {a = 180, r = 51, g = 7, b = 89}, - alpha = ALPHA, node_box = { type = "fixed", fixed = { From ead33e3520dd923f36f137614464f281b4d0ee43 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 14:27:35 +0200 Subject: [PATCH 017/164] fix undeacleared vars in mcl_throwing --- mods/ITEMS/mcl_throwing/init.lua | 4 ++-- mods/ITEMS/mcl_throwing/register.lua | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua index 4d6dcfe5c..09a34c12f 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -58,7 +58,7 @@ function mcl_throwing.dispense_function(stack, dispenserpos, droppos, dropnode, end -- Staticdata handling because objects may want to be reloaded -local get_staticdata = function(self) +function mcl_throwing.get_staticdata(self) local thrower -- Only save thrower if it's a player name if type(self._thrower) == "string" then @@ -71,7 +71,7 @@ local get_staticdata = function(self) return minetest.serialize(data) end -local on_activate = function(self, staticdata, dtime_s) +function mcl_throwing.on_activate(self, staticdata, dtime_s) local data = minetest.deserialize(staticdata) if data then self._lastpos = data._lastpos diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua index 027ff4e93..8ef1c73bf 100644 --- a/mods/ITEMS/mcl_throwing/register.lua +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -9,8 +9,8 @@ local snowball_ENTITY={ collisionbox = {0,0,0,0,0,0}, pointable = false, - get_staticdata = get_staticdata, - on_activate = on_activate, + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, _thrower = nil, _lastpos={}, @@ -23,8 +23,8 @@ local egg_ENTITY={ collisionbox = {0,0,0,0,0,0}, pointable = false, - get_staticdata = get_staticdata, - on_activate = on_activate, + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, _thrower = nil, _lastpos={}, @@ -38,8 +38,8 @@ local pearl_ENTITY={ collisionbox = {0,0,0,0,0,0}, pointable = false, - get_staticdata = get_staticdata, - on_activate = on_activate, + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, _lastpos={}, _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl From c457c4ce3c833bd564af5d0c4aa6a1fe62cdc653 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 14:28:43 +0200 Subject: [PATCH 018/164] fix undeacleared vars in mcl_fishing --- mods/ITEMS/mcl_fishing/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 228d490ea..2bd0ed515 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -303,8 +303,8 @@ local flying_bobber_ENTITY={ collisionbox = {0,0,0,0,0,0}, pointable = false, - get_staticdata = get_staticdata, - on_activate = on_activate, + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, _lastpos={}, _thrower = nil, From 59d687c57960c0817e59b35f05b5019b36591d79 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 14:30:46 +0200 Subject: [PATCH 019/164] fix API.md --- mods/ITEMS/mcl_throwing/API.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ITEMS/mcl_throwing/API.md b/mods/ITEMS/mcl_throwing/API.md index f2b1c7374..41a47223a 100644 --- a/mods/ITEMS/mcl_throwing/API.md +++ b/mods/ITEMS/mcl_throwing/API.md @@ -33,3 +33,9 @@ Handle creative mode, and throw params. * entity_name: the name of the entity to throw * velocity: (optional) velocity overide (can be nil) + +## mcl_throwing.get_staticdata(self) +Must be used in entity def if you want the entity to be saved after unloading mapblock. + +## mcl_throwing.on_activate(self, staticdata, dtime_s) +Must be used in entity def if you want the entity to be saved after unloading mapblock. From ca01b3641bb332e11afe26a45fa88a5dc6a0e29d Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 15:04:21 +0200 Subject: [PATCH 020/164] make endermen not teleport everytime when hitted --- mods/ENTITIES/mobs_mc/enderman.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index efc789344..22599dd9e 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -534,9 +534,11 @@ mobs:register_mob("mobs_mc:enderman", { --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then -- self:teleport(nil) --else + if pr:next(1, 8) == 8 then --FIXME: real mc rate self:teleport(hitter) - self.attack=hitter - self.state="attack" + end + self.attack=hitter + self.state="attack" --end end end, From b68c4b07c135a5e2a46225cf3c90cb8a2ac52252 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 2 Apr 2021 17:20:19 +0200 Subject: [PATCH 021/164] tweak hudbars --- mods/HUD/hudbars/default_settings.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/HUD/hudbars/default_settings.lua b/mods/HUD/hudbars/default_settings.lua index 0bd267d0e..ce43cc8be 100644 --- a/mods/HUD/hudbars/default_settings.lua +++ b/mods/HUD/hudbars/default_settings.lua @@ -20,9 +20,9 @@ if hb.settings.bar_type == "progress_bar" then hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15) hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86) else - hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -265) + hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -258) hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90) - hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 25) + hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 16) hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90) end -- Modified in MCL2! From 18d7be4a4f3b0215f306dc95da4486cf8b3fc288 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 00:42:20 -0400 Subject: [PATCH 022/164] More fixes to item collection on laggy servers --- mods/ENTITIES/mcl_item_entity/init.lua | 88 +++++++++++--------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index a05bb1ffd..cee2fda69 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -4,6 +4,7 @@ local mcl_item_entity = {} --basic settings local item_drop_settings = {} --settings table +item_drop_settings.dug_buffer = 0.65 -- the warm up period before a dug item can be collected item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect! @@ -74,69 +75,50 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement end end ---this is a 0.2 second tick globally across all players -local item_check_ticker = 0 minetest.register_globalstep(function(dtime) - item_check_ticker = item_check_ticker + dtime - if item_check_ticker >= 0.2 then - item_check_ticker = 0 + for _,player in pairs(minetest.get_connected_players()) do + if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then + local pos = player:get_pos() + local inv = player:get_inventory() + local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} - for _,player in pairs(minetest.get_connected_players()) do - if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then - local pos = player:get_pos() - local inv = player:get_inventory() - local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} + --magnet and collection + for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do + if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then - --magnet and collection - for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do - if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then - object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime - local collected = false - if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - -- Collection - if not object:get_luaentity()._removed then - -- Ignore if itemstring is not set yet - if object:get_luaentity().itemstring ~= "" then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - minetest.sound_play("item_drop_pickup", { - pos = pos, - max_hear_distance = 16, - gain = 1.0, - }, true) - check_pickup_achievements(object, player) + -- Collection + if not object:get_luaentity()._removed then + -- Ignore if itemstring is not set yet + if object:get_luaentity().itemstring ~= "" then + inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) + minetest.sound_play("item_drop_pickup", { + pos = pos, + max_hear_distance = 16, + gain = 1.0, + }, true) + check_pickup_achievements(object, player) - object:move_to(checkpos, false) + object:move_to(checkpos, true) - -- Destroy entity - -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. - object:get_luaentity()._removed = true - - collected = true - end + -- Destroy entity + -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. + object:get_luaentity()._removed = true end end - - if not collected then - if object:get_luaentity()._magnet_timer > 1 then - object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time - object:get_luaentity()._magnet_active = false - elseif object:get_luaentity()._magnet_timer < 0 then - object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime - end - end - - elseif not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mcl_experience:orb" then - local entity = object:get_luaentity() - entity.collector = player:get_player_name() - entity.collected = true - end - end + elseif not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mcl_experience:orb" then + local entity = object:get_luaentity() + entity.collector = player:get_player_name() + entity.collected = true + + end end + end end end) @@ -291,6 +273,12 @@ function minetest.handle_node_drops(pos, drops, digger) z = -z end obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z}) + + obj:get_luaentity().age = item_drop_settings.dug_buffer + + obj:get_luaentity()._insta_collect = false + + print(obj:get_luaentity().age) end end end From 61e812e40a963bcc4492be4df02957891629931a Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Fri, 2 Apr 2021 21:40:04 -0400 Subject: [PATCH 023/164] Add in manual interpolation into the item magnet --- mods/ENTITIES/mcl_item_entity/init.lua | 27 +++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index cee2fda69..a955f928b 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -9,7 +9,7 @@ item_drop_settings.age = 1.0 --how old a dropped item (_insta_ item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.radius_collect = 0.2 --radius of collection -item_drop_settings.player_collect_height = 1.0 --added to their pos y value +item_drop_settings.player_collect_height = 1.1 --added to their pos y value item_drop_settings.collection_safety = false --do this to prevent items from flying away on laggy servers item_drop_settings.random_item_velocity = true --this sets random item velocity if velocity is 0 item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack @@ -101,12 +101,13 @@ minetest.register_globalstep(function(dtime) }, true) check_pickup_achievements(object, player) - - object:move_to(checkpos, true) - -- Destroy entity -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. + object:get_luaentity().target = checkpos object:get_luaentity()._removed = true + + object:set_velocity(vector.multiply(vector.subtract(checkpos, object:get_pos()), 10)) + object:set_acceleration(vector.multiply(vector.subtract(checkpos, object:get_pos()), 20)) end end end @@ -513,12 +514,24 @@ minetest.register_entity(":__builtin:item", { on_step = function(self, dtime) if self._removed then - self.object:set_acceleration({x=0,y=0,z=0}) - self.object:set_velocity({x=0,y=0,z=0}) + + self.object:set_properties({ + physical = false + }) self.collection_age = self.collection_age + dtime - if self.collection_age > 0.15 then + if not self.target then self.object:remove() + else + local pos = self.object:get_pos() + + self.object:set_acceleration(vector.multiply(vector.subtract(self.target, pos), 20)) + self.object:set_velocity(vector.multiply(vector.subtract(self.target, pos), 10)) + + if self.collection_age >= 0.3 or vector.distance(pos, self.target) <= 0.08 then + self.object:remove() + end end + return end self.age = self.age + dtime From 1cbd3a998da0014cf14fd746f3e37980f5c93272 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Fri, 2 Apr 2021 21:50:47 -0400 Subject: [PATCH 024/164] Use manual move_to to account for move_to interpolation issues --- mods/ENTITIES/mcl_item_entity/init.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index a955f928b..582690ea7 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -106,8 +106,8 @@ minetest.register_globalstep(function(dtime) object:get_luaentity().target = checkpos object:get_luaentity()._removed = true - object:set_velocity(vector.multiply(vector.subtract(checkpos, object:get_pos()), 10)) - object:set_acceleration(vector.multiply(vector.subtract(checkpos, object:get_pos()), 20)) + object:set_velocity({x=0,y=0,z=0}) + object:set_acceleration({x=0,y=0,z=0}) end end end @@ -278,8 +278,6 @@ function minetest.handle_node_drops(pos, drops, digger) obj:get_luaentity().age = item_drop_settings.dug_buffer obj:get_luaentity()._insta_collect = false - - print(obj:get_luaentity().age) end end end @@ -518,16 +516,20 @@ minetest.register_entity(":__builtin:item", { self.object:set_properties({ physical = false }) + + self.object:set_velocity({x=0,y=0,z=0}) + self.object:set_acceleration({x=0,y=0,z=0}) + self.collection_age = self.collection_age + dtime + if not self.target then self.object:remove() else local pos = self.object:get_pos() - self.object:set_acceleration(vector.multiply(vector.subtract(self.target, pos), 20)) - self.object:set_velocity(vector.multiply(vector.subtract(self.target, pos), 10)) + self.object:move_to(vector.add(pos, vector.multiply(vector.subtract(self.target, pos), 0.5))) - if self.collection_age >= 0.3 or vector.distance(pos, self.target) <= 0.08 then + if self.collection_age >= 1 or vector.distance(pos, self.target) <= 0.06 then self.object:remove() end end From 0840ad98a2f5521599efce69eecdf0003be796be Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Fri, 2 Apr 2021 21:57:38 -0400 Subject: [PATCH 025/164] Adjust the item collection magnet even more --- mods/ENTITIES/mcl_item_entity/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 582690ea7..acd714d19 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -9,7 +9,7 @@ item_drop_settings.age = 1.0 --how old a dropped item (_insta_ item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.radius_collect = 0.2 --radius of collection -item_drop_settings.player_collect_height = 1.1 --added to their pos y value +item_drop_settings.player_collect_height = 0.8 --added to their pos y value item_drop_settings.collection_safety = false --do this to prevent items from flying away on laggy servers item_drop_settings.random_item_velocity = true --this sets random item velocity if velocity is 0 item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack @@ -527,9 +527,9 @@ minetest.register_entity(":__builtin:item", { else local pos = self.object:get_pos() - self.object:move_to(vector.add(pos, vector.multiply(vector.subtract(self.target, pos), 0.5))) + self.object:move_to(vector.add(pos, vector.multiply(vector.subtract(self.target, pos), 0.75))) - if self.collection_age >= 1 or vector.distance(pos, self.target) <= 0.06 then + if self.collection_age >= 1 or vector.distance(pos, self.target) <= 0.07 then self.object:remove() end end From 844db8aa7b6fb745a5c9040e4c0b2b7a2b65cb64 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Fri, 2 Apr 2021 22:02:19 -0400 Subject: [PATCH 026/164] Revert to previous style of interpolated move_to with tweaks --- mods/ENTITIES/mcl_item_entity/init.lua | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index acd714d19..9184b50bd 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -108,6 +108,15 @@ minetest.register_globalstep(function(dtime) object:set_velocity({x=0,y=0,z=0}) object:set_acceleration({x=0,y=0,z=0}) + + object:move_to(checkpos) + + minetest.after(0.25, function() + --safety check + if object and object:get_luaentity() then + object:remove() + end + end) end end end @@ -512,28 +521,11 @@ minetest.register_entity(":__builtin:item", { on_step = function(self, dtime) if self._removed then - self.object:set_properties({ physical = false }) - self.object:set_velocity({x=0,y=0,z=0}) self.object:set_acceleration({x=0,y=0,z=0}) - - self.collection_age = self.collection_age + dtime - - if not self.target then - self.object:remove() - else - local pos = self.object:get_pos() - - self.object:move_to(vector.add(pos, vector.multiply(vector.subtract(self.target, pos), 0.75))) - - if self.collection_age >= 1 or vector.distance(pos, self.target) <= 0.07 then - self.object:remove() - end - end - return end self.age = self.age + dtime From da3d5025a8a1d37ca6fb5eebc2d414a0c1639f45 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 01:22:13 -0400 Subject: [PATCH 027/164] Update tick rate to 0.05 ticks per second (20 tps) --- minetest.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/minetest.conf b/minetest.conf index e122db7b3..1788cf992 100644 --- a/minetest.conf +++ b/minetest.conf @@ -1,5 +1,8 @@ # This is a game specific minetest.conf file, do not edit +# If any of these settings are set in your minetest.conf file in .minetest (Linux) or in the root directory of the game (Run in place/Windows) +# They will override these settings + # Basic game rules time_speed = 72 @@ -33,7 +36,7 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de keepInventory = false # Performance settings -# dedicated_server_step = 0.001 +dedicated_server_step = 0.05 #tick rate # abm_interval = 0.25 # max_objects_per_block = 4096 # max_packets_per_iteration = 10096 From b14bc2182946cfdab4716afd7ed46904611629b0 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 05:26:08 +0000 Subject: [PATCH 028/164] Minor update to home directory warning in minetest.conf --- minetest.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minetest.conf b/minetest.conf index 1788cf992..223587f4d 100644 --- a/minetest.conf +++ b/minetest.conf @@ -1,6 +1,6 @@ # This is a game specific minetest.conf file, do not edit -# If any of these settings are set in your minetest.conf file in .minetest (Linux) or in the root directory of the game (Run in place/Windows) +# If any of these settings are set in your minetest.conf file in ~/.minetest (Linux) or in the root directory of the game (Run in place/Windows) # They will override these settings # Basic game rules From c572db92aad6d95cb719b4d9ca1e224d28a636a7 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 20:39:08 -0400 Subject: [PATCH 029/164] Add sound buffer and different item collection sound --- mods/ENTITIES/mcl_item_entity/init.lua | 51 ++++++++++++++++-- .../mcl_item_entity/sounds/Attributes.txt | 1 + .../sounds/item_drop_pickup.1.ogg | Bin 5965 -> 0 bytes .../sounds/item_drop_pickup.2.ogg | Bin 6151 -> 0 bytes .../sounds/item_drop_pickup.3.ogg | Bin 5690 -> 0 bytes .../sounds/item_drop_pickup.4.ogg | Bin 5822 -> 0 bytes .../sounds/item_drop_pickup.ogg | Bin 0 -> 5625 bytes 7 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt delete mode 100644 mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.1.ogg delete mode 100644 mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.2.ogg delete mode 100644 mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.3.ogg delete mode 100644 mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.4.ogg create mode 100644 mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 9184b50bd..4028f5a15 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -1,3 +1,24 @@ +--these are lua locals, used for higher performance +local minetest,math,vector,ipairs = minetest,math,vector,ipairs + +--this is used for the player pool in the sound buffer +local pool = {} + +local tick = false + +local name +minetest.register_on_joinplayer(function(player) + name = player:get_player_name() + pool[name] = 0 +end) + +local name +minetest.register_on_leaveplayer(function(player) + name = player:get_player_name() + pool[name] = nil +end) + + local has_awards = minetest.get_modpath("awards") local mcl_item_entity = {} @@ -77,8 +98,30 @@ end minetest.register_globalstep(function(dtime) + + tick = not tick + for _,player in pairs(minetest.get_connected_players()) do if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then + + + local name = player:get_player_name() + + if tick == true and pool[name] > 0 then + minetest.sound_play("item_drop_pickup", { + pos = pos, + gain = 1, + max_hear_distance = 16, + pitch = math.random(60,100)/100 + }) + if pool[name] > 6 then + pool[name] = 6 + else + pool[name] = pool[name] - 1 + end + end + + local pos = player:get_pos() local inv = player:get_inventory() local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} @@ -94,11 +137,7 @@ minetest.register_globalstep(function(dtime) -- Ignore if itemstring is not set yet if object:get_luaentity().itemstring ~= "" then inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - minetest.sound_play("item_drop_pickup", { - pos = pos, - max_hear_distance = 16, - gain = 1.0, - }, true) + check_pickup_achievements(object, player) -- Destroy entity @@ -111,6 +150,8 @@ minetest.register_globalstep(function(dtime) object:move_to(checkpos) + pool[name] = pool[name] + 1 + minetest.after(0.25, function() --safety check if object and object:get_luaentity() then diff --git a/mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt b/mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt new file mode 100644 index 000000000..781759352 --- /dev/null +++ b/mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt @@ -0,0 +1 @@ + Item_Drop_Pickup - https://freesound.org/people/benniknop/sounds/317848/ (License: CC0) diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.1.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.1.ogg deleted file mode 100644 index 8010ff0a296be3df24018ee787d7663e31762245..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5965 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 A6aWAK diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.3.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.3.ogg deleted file mode 100644 index f234a482cff9830ff772e316207957d26d666b04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5690 zcmahtc|6nM|Bsnl%-JwSkxi6o%Azt6hA`%A$+4u-#Y%@#8_AW{oJ}DUqEaZ5RIZRh z=1Phjl}?K8-?Mdmzu&)p&+FOqc|Y&#d7k(4em~FqnM+8BJ3xRxMK|A#DFoY)wvl2B z#P;so6BrsHM2Ojx3O@kEn2U+NH^f|olK+ZOQb_qxozkpe`Rl*RQSskuj3CuJbl0|J zE_*_B!a@T*Map#?bWBa~W+r$OGac;68TP-56RH-I_$|B0dcCI@umV6Y0&Tc~AEC}h zX$3INcym|= zYakR)gt$;44rTqfu_bPURFbqdd(^~So;7AZhhf_iy-^T1sl!&ZzLCu;B|>IBGkaH- zBykeMzH5X{IM!ftL!FH@!zLYjVbb!LC1)L<&2liC(`1K`qSSwnp+~Y$Wl54+(CiH) zI0H%I4OMmY3?L2p>=O#?Q(o9}^n5t_qB?$}#Hj76sG5qz?E!FglegWiDkYK&20%L3Jb~|> zz~7cI5uYN>jw?lg7yyuP7{YpYOFOR3Ll0_iRruh4Rljt)hDaRR5Y-jBwOBIVL|j8s zv=49^F-i$04KaU>9D^n+L+2uYNMrer&oL&&~*Kjn<0 z5Emg-C2C$ZzQpiUgx#WB)#+y*HA2Xx>E%-%>K}`UPh@1cUMo~wa=;Uubl1c-oefHX znx-#Fvy&z=nk=66tIo-71>Dur`f0lKxhBG5L^>FqMbOY$3^{JCfrc4OVv)~ zZw^=W9J}-$bQ!r!6I@i*xT)H96R4ePG`CgZZY$~CW;FMeG^%H~S9-W#6>~6yJ~$ga z{9lzOC0e2~0INBRahyds&Zv2co`co47DHeqDU8U35p2q+IY-ZdqaVr%*`HpNmHjg7 ztYL|W1)zj1!je!Jl~5d&P!yFi8PD04m0nbwy|lG(s^-$`|F6o499$28NIknfdUg~& zTM7h3){T)DS{HKMOB`TJK?+d47M%KAMNW2(Dx z55=~}o%;V3=Wc?t3N);YFkm0~Mzoh@q>v^{Gg`0(xxE{S;|0C#*kim26h0`knSx(0 z-;_>bb0whBkiZSb6}|=EfZ5aG@Ji3NgJ`JDZz9?ipMUH|E-&=8AoHs{7^6JcZN>6^ z9WQG0Js2hBPzXrDpIqLfR5dXxRRE64Q)F?m+`tapL@K3~IF1QSAYR}Fbr7*R+*YDN z&S_;FA9isQJZ^`>IPY|q0~Y#6y%_viV+p~w0A&E4?ZP;pCOE6=JFD2bsM2~>Yo17DTU1iBqxI6Ii&sm(U0wFA=FMxaL${M~LOnKa zRA;ZsaCc_7pNeg-8nq|g)}0BpMEf)8{k=AwOj~LiT{vVKowkqebsdU?Q};#>N785+ zOq%yrzuDMsCX<#%ANHdA%+hJi0_O0nQ+JhfZx6GZ${ZFj$Fjl)=b#vqnjY&9`FdlY z@82;r|EwF8ImD&;L$Ucg{8tUs?XbKY9yGZ2>gC1qc6C>bXoD+j>YOu~Lz7zTpRbA| zbXSB!eM6Bn{|x5Pw%0YT9#onay?>VK^*I_&;`!(3VKlXO7MeV+Cp{-%Hk$udE{$3h z3uiEq8BX&)JUaQk&NPzg2W89K>n>T|+#MOW7RJ0J1^|Q;Ry;PYR2qyR0h-NQ??j4M zWx=BW$4;d*pxNz2oJIu28dn@kp(LVNsl+Av5gWI@ex)lpv6!#v$1vNFL~7xk<`50|ToIw2Xqdx-M<_h#e2s98-b4d^Rti~4m(L+P z>GRR+4a?KGfsoMW8&=(z8G+?Da>!x&d~ZJ|Vih_fML4*DXmEZdg~CXSpg>i01+pPj zMJD6nte`3dYcf>jPKL7zT#D=QCT}l?svPkGS4tuzIFj*D)sFHp0co3YfpQR5zezpl zQdyM^ zC43^@-eNt1D{piqCzVzD`Xv#M{~0`?5~^a9e})98%8_hVg=VCfea`m12nmes<>T2A z@9^V&?hLc*Xa*d^7pfW;1i?H>Tmc>rOSng2+#`f>kJKgOCG$w}_=y67G=7}NO~6m+ z6j1Qv7&gUpLWj$t2qB6rzkowwu=Jl&;YF;HnenxDBxezgqFEQu(Y$K^sx1tj66`2~-C z9n&IEWQXF)zQ9r*%auYdYt#&aJ|*xiEf-{4K)+RIloI(? z?pB5%u+(hg2@7?%LN(}8_2*{?-{Go!84uRX>9AePdwe6_3zNx2{Ol9fdzfHuN+M1y zV86d36#&3KmN>9Emb{`=FGnp!a=vi2(lS5?6$m$&2jdVf8**dd<&4#*h;Rzl()z)F zaeQvlZ$245m-B}Y<`Je7xlk73C}feWv=Dmv4~G+GwjwG{{~yF>qsUkxAG9sX8a98d z{1?ahhoeyb;^0>O;p0*qUAq8$8`lP;p$SZ^TusD*yaH;i6v@D9R|U*& zt%Kw22}a1{QfWX5uLks%U|%4tVjFD-8YLn%o*i5Eb~VZxbqv)o0%Yy$@5rpO{19jG z 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�f5#;*eaK)&O;QfH5bvjVb@WI!Ps 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 UjuChK@}jF_ji#EJ<#7Q14-TB@yZ`_I diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6ca412d96cfa7037788371c0b70f39314d42b3a7 GIT binary patch literal 5625 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 Date: Sat, 3 Apr 2021 20:53:34 -0400 Subject: [PATCH 030/164] Adjust volume of item collection sound --- mods/ENTITIES/mcl_item_entity/init.lua | 2 +- .../sounds/item_drop_pickup.ogg | Bin 5625 -> 4834 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 4028f5a15..7b566d8f4 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -112,7 +112,7 @@ minetest.register_globalstep(function(dtime) pos = pos, gain = 1, max_hear_distance = 16, - pitch = math.random(60,100)/100 + pitch = math.random(70,110)/100 }) if pool[name] > 6 then pool[name] = 6 diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg index 6ca412d96cfa7037788371c0b70f39314d42b3a7..e7f5df09490b6e5ba110d540d4d064fa8c681bb1 100644 GIT binary patch delta 3456 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 delta 4252 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 From a807ee6372b0a597f45f6d05a3a073566768dbdf Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 20:55:46 -0400 Subject: [PATCH 031/164] Adjust the volume even more to perfectly match the gameplay --- mods/ENTITIES/mcl_item_entity/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 7b566d8f4..b63c17c2b 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -110,7 +110,7 @@ minetest.register_globalstep(function(dtime) if tick == true and pool[name] > 0 then minetest.sound_play("item_drop_pickup", { pos = pos, - gain = 1, + gain = 0.7, max_hear_distance = 16, pitch = math.random(70,110)/100 }) From 1b511936f5d287ce4a3592a71ec27e01a724da47 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 21:05:31 -0400 Subject: [PATCH 032/164] Fix local name memory leak --- mods/ENTITIES/mcl_item_entity/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index b63c17c2b..cc7672b7a 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -6,14 +6,14 @@ local pool = {} local tick = false -local name minetest.register_on_joinplayer(function(player) + local name name = player:get_player_name() pool[name] = 0 end) -local name minetest.register_on_leaveplayer(function(player) + local name name = player:get_player_name() pool[name] = nil end) From 40b07e466b6f934a61e88224e8993ac163300bd0 Mon Sep 17 00:00:00 2001 From: epCode Date: Sat, 3 Apr 2021 18:07:51 -0700 Subject: [PATCH 033/164] make ghast fireballs deflectible --- mods/ENTITIES/mcl_mobs/api.lua | 7 ++++++- mods/ENTITIES/mobs_mc/ghast.lua | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 1ef0712e8..fac8bbeec 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -4223,6 +4223,11 @@ function mobs:register_arrow(name, def) switch = 0, owner_id = def.owner_id, rotate = def.rotate, + on_punch = 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, + collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0}, automatic_face_movement_dir = def.rotate and (def.rotate - (pi / 180)) or false, @@ -4285,7 +4290,7 @@ function mobs:register_arrow(name, def) if self.hit_player or self.hit_mob or self.hit_object then - for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do + for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do if self.hit_player and player:is_player() then diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 679a28c13..39af10add 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -74,6 +74,7 @@ mobs:register_arrow("mobs_mc:fireball", { visual_size = {x = 1, y = 1}, textures = {"mcl_fire_fire_charge.png"}, velocity = 15, + collisionbox = {-.5, -.5, -.5, .5, .5, .5}, hit_player = function(self, player) if rawget(_G, "armor") and armor.last_damage_types then From 90fd65ac665600d6f31bad18f7b5b0a5c53629f4 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Sat, 3 Apr 2021 21:09:43 -0400 Subject: [PATCH 034/164] Fix locationless playing --- mods/ENTITIES/mcl_item_entity/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index cc7672b7a..b65585a15 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -106,6 +106,8 @@ minetest.register_globalstep(function(dtime) local name = player:get_player_name() + + local pos = player:get_pos() if tick == true and pool[name] > 0 then minetest.sound_play("item_drop_pickup", { @@ -122,7 +124,7 @@ minetest.register_globalstep(function(dtime) end - local pos = player:get_pos() + local inv = player:get_inventory() local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} From ac87e0604ee673e8b13036fafd1c91d46fbbbcdf Mon Sep 17 00:00:00 2001 From: epCode Date: Sat, 3 Apr 2021 18:39:20 -0700 Subject: [PATCH 035/164] make ghast firing more MC-like --- mods/ENTITIES/mcl_mobs/api.lua | 4 ++++ mods/ENTITIES/mobs_mc/ghast.lua | 9 +++++++++ .../mobs_mc/textures/mobs_mc_ghast_firing.png | Bin 0 -> 1532 bytes 3 files changed, 13 insertions(+) create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index fac8bbeec..0a038ba13 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2819,6 +2819,10 @@ local do_states = function(self, dtime) 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(p, self.arrow) ent = arrow:get_luaentity() if ent.velocity then diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 39af10add..7aed9395e 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -63,6 +63,15 @@ mobs:register_mob("mobs_mc:ghast", { makes_footstep_sound = false, instant_death = true, fire_resistant = true, + do_custom = function(self) + if self.firing == true then + self.base_texture = {"mobs_mc_ghast_firing.png"} + self.object:set_properties({textures=self.base_texture}) + else + self.base_texture = {"mobs_mc_ghast.png"} + self.object:set_properties({textures=self.base_texture}) + end + end, }) diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png new file mode 100644 index 0000000000000000000000000000000000000000..3e5b41c32710a811ff75aa6a349bf4944294aaf0 GIT binary patch literal 1532 zcmVGj!2SAnoeDME4ikJU}4pA#amKA0nNSU0>ruVUlH< zMG@oNK%42{*j6_^;#ihEnn`-V$hIUOonL)N7WhNg*VhIBlu`hIqoX5%2>SNzn*o5^ z+gpssVt# zlyY@-Wy-RIloDlG0szXgwC@#Z_5@H}i{Jj4AyS%2I3 zj-5wF_O*&zdoUQ-#KiCWXn%jdHI7@qsw!kz2CcPsZjvOZ>-t3!T!?mech`FWS&$17 zBYceJdEAFQWZMwfWF0{dP)ea`8b~Qyt!vG7nLi|8D96-w9h~=)Ibd&ZuipczszTE= zpq3U*_c0hCNfP9FZe5*#4|&$%;bEsQNfMhFxAlOS&>>kumkNQJZNh+*K&X!^koqQ* zNyjVxb`p%<1qOqG_r8y4oQwLn_I>fl!)seXVmzm+s@_Y!l=UAT9$G?i!Pn)Izlj5A zs}8j!A3ki11Ck{1wu%x}nx&F2i_uwEamoBmZum=WQI2 zWm#+c3MI49;y7cs@bHas`E0{~JRY|cA3A%8LV|sjo4dD@ra7(#fYZ}cOsCV%-05_R z)6-M0)%*DKQrgEq=HR6dAINnFAX;n7lrNeWGg3+{77Lu6onbf};^WsZm`=K|4mRN?NVH!Vm_Z662!NKaSP;m?gcRJ)@Quaa&0E5IEb! z?OoXvkIA~OE#xG3bGHqb(lo_#xr9;*qtOUeRoPfRIXM9UTwY#UbVov^Y3faoLWq{& zS(f4E=EkdxSTsm;eR)Um4xjsT_u-!4V{(6gkI7`xDP~SiPH=g72`MGMfB$YVL1>|z zZf7GPvOdSW8Wc$8$-T@)^*)sa&_<@@B{c){9|KxJRale>8S-x zN%5S&n|nfT9|}p1Irw~fCM+UDh>SGMt<=CVu;6hnx^>m>sO~J i+LS-9Kx4y&huCj4GoCz*uaG4G0000 Date: Sat, 3 Apr 2021 20:12:24 +0300 Subject: [PATCH 036/164] Fix passive mobs despawning According to the wiki most passive mobs do not despawn. The ones that do have already been explicity marked as despawning. --- mods/ENTITIES/mcl_mobs/api.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 0a038ba13..6a8646bd5 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3741,6 +3741,8 @@ function mobs:register_mob(name, def) local can_despawn if def.can_despawn ~= nil then can_despawn = def.can_despawn +elseif def.spawn_class == "passive" then + can_despawn = false else can_despawn = true end From 49446bbb7b615e75f56e75a9bd2b507f81d6e214 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 4 Apr 2021 12:01:45 +0200 Subject: [PATCH 037/164] Make enderdragon spawn upon exit portal generation --- mods/MAPGEN/mcl_structures/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index f6317bdeb..6a7f44dfb 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -313,6 +313,7 @@ mcl_structures.generate_fossil = function(pos, rotation, pr) end mcl_structures.generate_end_exit_portal = function(pos, rot) + minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon") local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end From 598692cf8c2fcbe94c21ab82ef3432665eb74e76 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 4 Apr 2021 12:10:21 +0200 Subject: [PATCH 038/164] Add nil check to prevent crashes with mcl_throwing --- mods/ITEMS/mcl_throwing/register.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua index 8ef1c73bf..3d8cc94cf 100644 --- a/mods/ITEMS/mcl_throwing/register.lua +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -99,7 +99,7 @@ local snowball_on_step = function(self, dtime) local vel = self.object:get_velocity() local node = minetest.get_node(pos) local def = minetest.registered_nodes[node.name] - + -- Destroy when hitting a solid node if self._lastpos.x~=nil then @@ -203,7 +203,7 @@ local pearl_on_step = function(self, dtime) self.object:remove() -- Activate when hitting a solid node or a plant elseif walkable or nn == "mcl_core:vine" or nn == "mcl_core:deadbush" or minetest.get_item_group(nn, "flower") ~= 0 or minetest.get_item_group(nn, "sapling") ~= 0 or minetest.get_item_group(nn, "plant") ~= 0 or minetest.get_item_group(nn, "mushroom") ~= 0 or not def then - local player = minetest.get_player_by_name(self._thrower) + local player = self._thrower and minetest.get_player_by_name(self._thrower) if player then -- Teleport and hurt player From 1144006cdd77993daf8a1f37e8775d2f077ba06a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 4 Apr 2021 15:16:06 +0200 Subject: [PATCH 039/164] Add End main island generation --- mods/MAPGEN/mcl_end_island/init.lua | 36 +++++++++++++++++++++++++++++ mods/MAPGEN/mcl_end_island/mod.conf | 4 ++++ 2 files changed, 40 insertions(+) create mode 100644 mods/MAPGEN/mcl_end_island/init.lua create mode 100644 mods/MAPGEN/mcl_end_island/mod.conf diff --git a/mods/MAPGEN/mcl_end_island/init.lua b/mods/MAPGEN/mcl_end_island/init.lua new file mode 100644 index 000000000..fb062bf77 --- /dev/null +++ b/mods/MAPGEN/mcl_end_island/init.lua @@ -0,0 +1,36 @@ +local noisemap = PerlinNoiseMap({ + offset = 0.5, + scale = 0.5, + spread = {x = 84, y = 84, z = 84}, + seed = minetest.get_mapgen_setting("seed") + 99999, + octaves = 4, + persist = 0.85, +}, {x = 151, y = 30, z = 151}):get_3d_map({x = 0, y = 0, z = 0}) + +local c_end_stone = minetest.get_content_id("mcl_end:end_stone") + +local x_offset = mcl_vars.mg_end_platform_pos.x - 27 +local y_offset = -2 + +minetest.register_on_generated(function(minp, maxp) + if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < (-75 + x_offset) or minp.x > (75 + x_offset) or maxp.z < -75 or minp.z > 75 then + return + end + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local data = vm:get_data() + local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + + for idx in area:iter(math.max(minp.x, -75 + x_offset), math.max(minp.y, -27025 + y_offset + 4), math.max(minp.z, -75), math.min(maxp.x, 75 + x_offset), math.min(maxp.y, -27000 + y_offset), math.min(maxp.z, 75)) do + local pos = area:position(idx) + local y = 27025 + pos.y - y_offset + if noisemap[pos.x + 75 - x_offset + 1][y + 1][pos.z + 75 + 1] > (math.abs(1 - y / 25) ^ 2 + math.abs((pos.x - x_offset) / 75) ^ 2 + math.abs(pos.z / 75) ^ 2) then + data[idx] = c_end_stone + end + end + + vm:set_data(data) + vm:calc_lighting() + vm:update_liquids() + vm:write_to_map() +end) diff --git a/mods/MAPGEN/mcl_end_island/mod.conf b/mods/MAPGEN/mcl_end_island/mod.conf new file mode 100644 index 000000000..90432792c --- /dev/null +++ b/mods/MAPGEN/mcl_end_island/mod.conf @@ -0,0 +1,4 @@ +name = mcl_end_island +author = Fleckenstein +depends = mcl_mapgen_core, mcl_end +description = Generate the end main island for MCL2 From 90f312f77278c93e7c1d0e5603263b0a7830565d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 4 Apr 2021 19:13:46 +0200 Subject: [PATCH 040/164] Add credits overlay prototype --- mods/HUD/mcl_credits/init.lua | 105 ++++++++++++++++++ mods/HUD/mcl_credits/mod.conf | 4 + .../mcl_credits/textures/mineclone2_logo.png | Bin 0 -> 77528 bytes mods/ITEMS/mcl_portals/portal_end.lua | 4 + 4 files changed, 113 insertions(+) create mode 100644 mods/HUD/mcl_credits/init.lua create mode 100644 mods/HUD/mcl_credits/mod.conf create mode 100644 mods/HUD/mcl_credits/textures/mineclone2_logo.png diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua new file mode 100644 index 000000000..05e7aeff4 --- /dev/null +++ b/mods/HUD/mcl_credits/init.lua @@ -0,0 +1,105 @@ +mcl_credits = { + players = {}, +} + +mcl_credits.description = "A faithful Open Source imitation of Minecraft" + +-- Sub-lists are sorted by number of commits +mcl_credits.people = { + {"Creator of MineClone", { + "davedevils", + }}, + {"Creator of MineClone2", { + "Wuzzy", + }}, + {"Maintainers", { + "Fleckenstein", + "kay27", + "oilboi", + }}, + {"Developers", { + "bzoss", + "AFCMS", + "epCode", + "ryvnf", + "iliekprogrammar", + "MysticTempest", + "Rootyjr", + "Nicu", + "aligator", + }}, + {"Contributors", { + "Code-Sploit", + "Laurent Rocher", + "HimbeerserverDE", + "TechDudie", + "Alexander Minges", + "ArTee3", + "ZeDique la Ruleta", + "pitchum", + "wuniversales", + "Bu-Gee", + "David McMackins II", + "Nicholas Niro", + "Wouters Dorian", + "Blue Blancmange", + "Jared Moody", + "Li0n", + "Midgard", + "NO11", + "Saku Laesvuori", + "Yukitty", + "ZedekThePD", + "aldum", + "dBeans", + "nickolas360", + "yutyo", + }}, + {"3D Models", { + "22i", + "tobyplowy", + }}, + {"Textures", { + "XSSheep", + "kingoscargames", + "leorockway", + "xMrVizzy", + }}, +} + +function mcl_credits.show(player) + local name = player:get_player_name() + if mcl_credits.players[name] then + return + end + local hud_list = { + player:hud_add({ + hud_elem_type = "image", + text = "menu_bg.png", + position = {x = 0, y = 0}, + alignment = {x = 1, y = 1}, + scale = {x = -100, y = -100}, + z_index = 1000, + }) + } + mcl_credits.players[name] = hud_list +end + +function mcl_credits.hide(player) + local name = player:get_player_name() + local list = mcl_credits.players[name] + if list then + for _, id in pairs(list) do + player:hud_remove(id) + end + end + mcl_credits.players[name] = nil +end + +controls.register_on_press(function(player, key) + if key == "sneak" then + mcl_credits.hide(player) + elseif key == "aux1" then + mcl_credits.show(player) + end +end) diff --git a/mods/HUD/mcl_credits/mod.conf b/mods/HUD/mcl_credits/mod.conf new file mode 100644 index 000000000..b5532cd30 --- /dev/null +++ b/mods/HUD/mcl_credits/mod.conf @@ -0,0 +1,4 @@ +name = mcl_credits +author = Fleckenstein +description = Show a HUD containing the credits +depends = controls diff --git a/mods/HUD/mcl_credits/textures/mineclone2_logo.png b/mods/HUD/mcl_credits/textures/mineclone2_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..11435df51033b13cdeba49326b6eabe72ba320a8 GIT binary patch literal 77528 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 aYyTg9*d2kzhi~x!0000 Date: Sun, 4 Apr 2021 23:24:28 +0300 Subject: [PATCH 041/164] Make horse taming more similar to minecraft (#1249) In minecraft horses are tamed by trying to ride them and they can also be fed to speed up taming. This commit implements both of those features and disables the old and broken taming system for horses. --- mods/ENTITIES/mobs_mc/horse.lua | 74 +++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 4e588855f..1c2df41f3 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -157,8 +157,29 @@ local horse = { self._regentimer = 0 end - -- if driver present allow control of horse - if self.driver then + -- Some weird human is riding. Buck them off? + if self.driver and not self.tamed and self.buck_off_time <= 0 then + if math.random() < 0.2 then + mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + -- TODO bucking animation + else + -- Nah, can't be bothered. Think about it again in one second + self.buck_off_time = 20 + end + end + + -- Tick the timer for trying to buck the player off + if self.buck_off_time then + if self.driver then + self.buck_off_time = self.buck_off_time - 1 + else + -- Player isn't riding anymore so no need to count + self.buck_off_time = nil + end + end + + -- if driver present and horse has a saddle allow control of horse + if self.driver and self._saddle then mobs.drive(self, "walk", "stand", false, dtime) @@ -191,6 +212,50 @@ local horse = { local item = clicker:get_wielded_item() local iname = item:get_name() local heal = 0 + + -- Taming + self.temper = self.temper or (math.random(1,100)) + + if not self.tamed then + local temper_increase = 0 + + -- Feeding, intentionally not using mobs:feed_tame because horse taming is + -- different and more complicated + if (iname == mobs_mc.items.sugar) then + temper_increase = 3 + elseif (iname == mobs_mc.items.wheat) then + temper_increase = 3 + elseif (iname == mobs_mc.items.apple) then + temper_increase = 3 + elseif (iname == mobs_mc.items.golden_carrot) then + temper_increase = 5 + elseif (iname == mobs_mc.items.golden_apple) then + temper_increase = 10 + + -- Trying to ride + elseif not self.driver then + self.object:set_properties({stepheight = 1.1}) + mobs.attach(self, clicker) + self.buck_off_time = 40 -- TODO how long does it take in minecraft? + if self.temper > 100 then + self.tamed = true -- NOTE taming can only be finished by riding the horse + if not self.owner or self.owner == "" then + self.owner = clicker:get_player_name() + end + end + temper_increase = 5 + + -- Clicking on the horse while riding ==> unmount + elseif self.driver and self.driver == clicker then + mobs.detach(clicker, {x = 1, y = 0, z = 1}) + end + + -- If nothing happened temper_increase = 0 and addition does nothing + self.temper = self.temper + temper_increase + + return + end + if can_breed(self.name) then -- Breed horse with golden apple or golden carrot if (iname == mobs_mc.items.golden_apple) then @@ -202,7 +267,8 @@ local horse = { return end end - -- Feed/tame with anything else + -- Feed with anything else + -- TODO heal amounts don't work if (iname == mobs_mc.items.sugar) then heal = 1 elseif (iname == mobs_mc.items.wheat) then @@ -212,7 +278,7 @@ local horse = { elseif (iname == mobs_mc.items.hay_bale) then heal = 20 end - if heal > 0 and mobs:feed_tame(self, clicker, heal, false, true) then + if heal > 0 and mobs:feed_tame(self, clicker, heal, false, false) then return end From 8bb8a0e3b29d2779d8c811a8a549608941fde345 Mon Sep 17 00:00:00 2001 From: Tianyang Zhang Date: Sun, 4 Apr 2021 15:40:10 -0700 Subject: [PATCH 042/164] Fix large and small slimes and magma cubes not dropping xp and loot --- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 7c21fb812..fd1f92bb4 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -51,7 +51,6 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance end end, children, self.attack) end - return true end end From 93684baa86adcdf3db4b0a13e219428b6bf1a344 Mon Sep 17 00:00:00 2001 From: epCode Date: Sun, 4 Apr 2021 16:32:58 -0700 Subject: [PATCH 043/164] Make Blazes have more Mc-likeness ;) --- mods/ENTITIES/mobs_mc/blaze.lua | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 20fa86a1f..30255612a 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -75,6 +75,59 @@ mobs:register_mob("mobs_mc:blaze", { fear_height = 0, glow = 14, fire_resistant = true, + do_custom = function(self) + for _,obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.2)) do + if obj:is_player() or not obj:is_player() and obj:get_luaentity()._cmi_is_mob then + mcl_burning.set_on_fire(obj, 5) + end + end + local pos = self.object:get_pos() + minetest.add_particle({ + pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2}, + velocity = {x=0, y=math.random(1,1), z=0}, + expirationtime = math.random(), + size = math.random(1, 4), + collisiondetection = true, + vertical = false, + texture = "mcl_particles_smoke_anim.png^[colorize:#2c2c2c:255", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }) + minetest.add_particle({ + pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2}, + velocity = {x=0, y=math.random(1,1), z=0}, + expirationtime = math.random(), + size = math.random(1, 4), + collisiondetection = true, + vertical = false, + texture = "mcl_particles_smoke_anim.png^[colorize:#424242:255", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }) + minetest.add_particle({ + pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2}, + velocity = {x=0, y=math.random(1,1), z=0}, + expirationtime = math.random(), + size = math.random(1, 4), + collisiondetection = true, + vertical = false, + texture = "mcl_particles_smoke_anim.png^[colorize:#0f0f0f:255", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }) + end, }) mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) From a6f0ad13a0592277a86d3ce3301f57751771c63b Mon Sep 17 00:00:00 2001 From: epCode Date: Sun, 4 Apr 2021 16:46:44 -0700 Subject: [PATCH 044/164] Make blaze burning better --- mods/ENTITIES/mobs_mc/blaze.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 30255612a..fbffa7920 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -76,10 +76,8 @@ mobs:register_mob("mobs_mc:blaze", { glow = 14, fire_resistant = true, do_custom = function(self) - for _,obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.2)) do - if obj:is_player() or not obj:is_player() and obj:get_luaentity()._cmi_is_mob then - mcl_burning.set_on_fire(obj, 5) - end + if self.state == "attack" and vector.distance(self.object:get_pos(), self.attack:get_pos()) < 1.2 then + mcl_burning.set_on_fire(self.attack, 5) end local pos = self.object:get_pos() minetest.add_particle({ From 5fc3bb11ef9f8ea7d3198ba7a776f5b742b196f8 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 5 Apr 2021 04:54:58 +0400 Subject: [PATCH 045/164] [tools] Add simple python script to entirely reset End dimension generated before and get fresh one, improved (but please stop server & backup world before) --- tools/remove_end.py | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tools/remove_end.py diff --git a/tools/remove_end.py b/tools/remove_end.py new file mode 100644 index 000000000..3b73e5575 --- /dev/null +++ b/tools/remove_end.py @@ -0,0 +1,46 @@ +world_name = "world" +path_to_map_sqlite = "../../../worlds/" + world_name + "/map.sqlite" + +import sqlite3, sys + +try: + conn = sqlite3.connect(path_to_map_sqlite) +except Error as e: + print(e) + sys.exit() + +def unsignedToSigned(i, max_positive): + if i < max_positive: + return i + else: + return i - 2*max_positive + +cursor = conn.cursor() +cursor.execute("SELECT pos FROM blocks") +poses = cursor.fetchall() +end_blocks = [] +for i0 in (poses): + i = int(i0[0]) + blockpos = i + x = unsignedToSigned(i % 4096, 2048) + i = int((i - x) / 4096) + y = unsignedToSigned(i % 4096, 2048) + i = int((i - y) / 4096) + z = unsignedToSigned(i % 4096, 2048) + + node_pos_y = y * 16 + if node_pos_y > -28811 and node_pos_y + 15 < -67: + end_blocks.append(blockpos) + +if len(end_blocks) < 1: + print ("End blocks not found") + sys.exit() + +counter = 0 +for blockpos in end_blocks: + print("Deleting ", blockpos) + cursor.execute("DELETE FROM blocks WHERE pos=" + str(blockpos)) + counter += 1 +conn.commit() + +print(counter, " block(s) deleted") From e407ad2254fc2159bc5364480e2f802670d1ab05 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 5 Apr 2021 09:25:03 +0200 Subject: [PATCH 046/164] Fix #1447 --- mods/PLAYER/mcl_playerplus/init.lua | 44 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 767b275e4..52c87a514 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -86,17 +86,23 @@ minetest.register_globalstep(function(dtime) time = time + dtime - -- Update jump status immediately since we need this info in real time. - -- WARNING: This section is HACKY as hell since it is all just based on heuristics. for _,player in pairs(get_connected_players()) do + + --[[ + _ _ _ + __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ + / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| + | (_| | | | | | | | | | | (_| | |_| | (_) | | | \__ \ + \__,_|_| |_|_|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/ + + ]]-- + local controls = player:get_player_control() - name = player:get_player_name() - + local name = player:get_player_name() local meta = player:get_meta() - - local player_velocity = player:get_velocity() or player:get_player_velocity() - + local parent = player:get_attach() local wielded = player:get_wielded_item() + local player_velocity = player:get_velocity() or player:get_player_velocity() -- controls head bone local pitch = - degrees(player:get_look_vertical()) @@ -114,7 +120,7 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) -- when punching - elseif controls.LMB and player:get_attach() == nil then + elseif controls.LMB and not parent then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) -- when holding an item. @@ -127,38 +133,40 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) end - if controls.sneak and player:get_attach() == nil then + if parent then + local parent_yaw = degrees(parent:get_yaw()) + player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) + elseif controls.sneak then -- controls head pitch when sneaking player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0)) -- sets eye height, and nametag color accordingly player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) -- sneaking body conrols player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) - elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and player:get_attach() == nil and is_sprinting(name) == true then + elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then -- set head pitch and yaw when swimming player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) -- control body bone when swimming player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) - - elseif player:get_attach() == nil then + else -- sets eye height, and nametag color accordingly player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) - else - local attached = player:get_attach(parent) - local attached_yaw = degrees(attached:get_yaw()) - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, attached_yaw) + attached_yaw, 0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) end + -- Update jump status immediately since we need this info in real time. + -- WARNING: This section is HACKY as hell since it is all just based on heuristics. + if mcl_playerplus_internal[name].jump_cooldown > 0 then mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime end + if controls.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then pos = player:get_pos() From 28402ca6637118e2a86207899d28ffc0634aba26 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 5 Apr 2021 10:16:56 +0200 Subject: [PATCH 047/164] store tool wield scale in a global var --- mods/CORE/mcl_init/init.lua | 3 +++ mods/ITEMS/mcl_tools/init.lua | 2 +- mods/ITEMS/mcl_tools/mod.conf | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index 014a30d1e..066e555df 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -21,6 +21,9 @@ mcl_vars.gui_bg_img = "background9[1,1;1,1;mcl_base_textures_background9.png;tru -- Legacy mcl_vars.inventory_header = "" +-- Tool wield size +mcl_vars.tool_wield_scale = { x = 1.8, y = 1.8, z = 1 } + -- Mapgen variables local mg_name = minetest.get_mapgen_setting("mg_name") local minecraft_height_limit = 256 diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index bc6bed09f..b50782ec4 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -70,7 +70,7 @@ local shovel_use = S("To turn a grass block into a grass path, hold the shovel i local shears_longdesc = S("Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.") local shears_use = S("To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.") -local wield_scale = { x = 1.8, y = 1.8, z = 1 } +local wield_scale = mcl_vars.tool_wield_scale -- Picks minetest.register_tool("mcl_tools:pick_wood", { diff --git a/mods/ITEMS/mcl_tools/mod.conf b/mods/ITEMS/mcl_tools/mod.conf index f40547c26..d2d93197b 100644 --- a/mods/ITEMS/mcl_tools/mod.conf +++ b/mods/ITEMS/mcl_tools/mod.conf @@ -1,2 +1,2 @@ name = mcl_tools -depends = mcl_sounds +depends = mcl_sounds, mcl_init From beb2484224e346390c4db9708df207a5101eb918 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 5 Apr 2021 13:50:26 +0400 Subject: [PATCH 048/164] Merge https://git.minetest.land/MineClone2/MineClone2/pulls/1366 --- mods/ENTITIES/mcl_mobs/api.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 6a8646bd5..6e932ed5e 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -4351,7 +4351,7 @@ end -- make explosion with protection and tnt mod check function mobs:boom(self, pos, strength, fire) - + self.object:remove() if mod_explosions then if mobs_griefing and not minetest.is_protected(pos, "") then mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object) From 339e3e2792972f2b0c120e20326b714f4b15d801 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Mon, 5 Apr 2021 14:32:48 +0200 Subject: [PATCH 049/164] fix some tools not using right var --- mods/ITEMS/mcl_bows/bow.lua | 4 ++-- mods/ITEMS/mcl_bows/mod.conf | 2 +- mods/ITEMS/mcl_farming/hoes.lua | 10 +++++----- mods/ITEMS/mcl_farming/mod.conf | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 87820071d..45912384e 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -133,7 +133,7 @@ S("The speed and damage of the arrow increases the longer you charge. The regula _doc_items_usagehelp = S("To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot."), _doc_items_durability = BOW_DURABILITY, inventory_image = "mcl_bows_bow.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, stack_max = 1, range = 4, -- Trick to disable digging as well @@ -198,7 +198,7 @@ for level=0, 2 do description = S("Bow"), _doc_items_create_entry = false, inventory_image = "mcl_bows_bow_"..level..".png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, stack_max = 1, range = 0, -- Pointing range to 0 to prevent punching with bow :D groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1}, diff --git a/mods/ITEMS/mcl_bows/mod.conf b/mods/ITEMS/mcl_bows/mod.conf index cfb423474..79ae42436 100644 --- a/mods/ITEMS/mcl_bows/mod.conf +++ b/mods/ITEMS/mcl_bows/mod.conf @@ -1,6 +1,6 @@ name = mcl_bows author = Arcelmi description = This mod adds bows and arrows for MineClone 2. -depends = controls, mcl_particles, mcl_enchanting +depends = controls, mcl_particles, mcl_enchanting, mcl_init optional_depends = awards, mcl_achievements, mcl_core, mcl_mobitems, playerphysics, doc, doc_identifier, mesecons_button diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index a45b382ed..db470b999 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -68,7 +68,7 @@ minetest.register_tool("mcl_farming:hoe_wood", { _doc_items_usagehelp = hoe_usagehelp, _doc_items_hidden = false, inventory_image = "farming_tool_woodhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, on_place = hoe_on_place_function(uses.wood), groups = { tool=1, hoe=1, enchantability=15 }, tool_capabilities = { @@ -111,7 +111,7 @@ minetest.register_tool("mcl_farming:hoe_stone", { _doc_items_longdesc = hoe_longdesc, _doc_items_usagehelp = hoe_usagehelp, inventory_image = "farming_tool_stonehoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, on_place = hoe_on_place_function(uses.stone), groups = { tool=1, hoe=1, enchantability=5 }, tool_capabilities = { @@ -149,7 +149,7 @@ minetest.register_tool("mcl_farming:hoe_iron", { _doc_items_longdesc = hoe_longdesc, _doc_items_usagehelp = hoe_usagehelp, inventory_image = "farming_tool_steelhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, on_place = hoe_on_place_function(uses.iron), groups = { tool=1, hoe=1, enchantability=14 }, tool_capabilities = { @@ -195,7 +195,7 @@ minetest.register_tool("mcl_farming:hoe_gold", { _doc_items_longdesc = hoe_longdesc, _doc_items_usagehelp = hoe_usagehelp, inventory_image = "farming_tool_goldhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, on_place = hoe_on_place_function(uses.gold), groups = { tool=1, hoe=1, enchantability=22 }, tool_capabilities = { @@ -242,7 +242,7 @@ minetest.register_tool("mcl_farming:hoe_diamond", { _doc_items_longdesc = hoe_longdesc, _doc_items_usagehelp = hoe_usagehelp, inventory_image = "farming_tool_diamondhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, on_place = hoe_on_place_function(uses.diamond), groups = { tool=1, hoe=1, enchantability=10 }, tool_capabilities = { diff --git a/mods/ITEMS/mcl_farming/mod.conf b/mods/ITEMS/mcl_farming/mod.conf index 9ab36c39f..fe4bc1564 100644 --- a/mods/ITEMS/mcl_farming/mod.conf +++ b/mods/ITEMS/mcl_farming/mod.conf @@ -1,3 +1,3 @@ name = mcl_farming -depends = mcl_core, mcl_sounds, mcl_wool, mcl_torches, mcl_weather, mobs_mc, mcl_colors +depends = mcl_core, mcl_sounds, mcl_wool, mcl_torches, mcl_weather, mobs_mc, mcl_colors, mcl_init optional_depends = mcl_armor, doc From d07e415b3752c2e96a2a1fe27b023ca23abebd51 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 11:55:21 +0200 Subject: [PATCH 050/164] Add credits screen --- mods/HUD/mcl_credits/init.lua | 140 ++++++++++++++---- mods/HUD/mcl_credits/mod.conf | 1 - .../mcl_credits/textures/mineclone2_icon.png | Bin 0 -> 3961 bytes 3 files changed, 113 insertions(+), 28 deletions(-) create mode 100644 mods/HUD/mcl_credits/textures/mineclone2_icon.png diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 05e7aeff4..a53ebbba9 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -2,22 +2,22 @@ mcl_credits = { players = {}, } -mcl_credits.description = "A faithful Open Source imitation of Minecraft" +mcl_credits.description = "A faithful Open Source clone of Minecraft" --- Sub-lists are sorted by number of commits +-- Sub-lists are sorted by number of commits, but the list should not be rearranged (-> new contributors are just added at the end of the list) mcl_credits.people = { - {"Creator of MineClone", { + {"Creator of MineClone", 0x0A9400, { "davedevils", }}, - {"Creator of MineClone2", { + {"Creator of MineClone2", 0xFBF837, { "Wuzzy", }}, - {"Maintainers", { + {"Maintainers", 0xFF51D5, { "Fleckenstein", "kay27", "oilboi", }}, - {"Developers", { + {"Developers", 0xF84355, { "bzoss", "AFCMS", "epCode", @@ -28,7 +28,7 @@ mcl_credits.people = { "Nicu", "aligator", }}, - {"Contributors", { + {"Contributors", 0x52FF00, { "Code-Sploit", "Laurent Rocher", "HimbeerserverDE", @@ -55,11 +55,11 @@ mcl_credits.people = { "nickolas360", "yutyo", }}, - {"3D Models", { + {"3D Models", 0x0019FF, { "22i", "tobyplowy", }}, - {"Textures", { + {"Textures", 0xFF9705, { "XSSheep", "kingoscargames", "leorockway", @@ -67,39 +67,125 @@ mcl_credits.people = { }}, } +local function add_hud_element(def, huds, y) + def.alignment = {x = 0, y = 0} + def.position = {x = 0.5, y = 0} + def.offset = {x = 0, y = y} + def.z_index = 1001 + local id = huds.player:hud_add(def) + table.insert(huds.ids, id) + huds.moving[id] = y + return id +end + function mcl_credits.show(player) local name = player:get_player_name() if mcl_credits.players[name] then return end - local hud_list = { - player:hud_add({ - hud_elem_type = "image", - text = "menu_bg.png", - position = {x = 0, y = 0}, - alignment = {x = 1, y = 1}, - scale = {x = -100, y = -100}, - z_index = 1000, - }) + local huds = { + new = true, -- workaround for MT < 5.5 (sending hud_add and hud_remove in the same tick) + player = player, + moving = {}, + ids = { + player:hud_add({ + hud_elem_type = "image", + text = "menu_bg.png", + position = {x = 0, y = 0}, + alignment = {x = 1, y = 1}, + scale = {x = -100, y = -100}, + z_index = 1000, + }), + player:hud_add({ + hud_elem_type = "text", + text = "Sneak to skip", + position = {x = 1, y = 1}, + alignment = {x = -1, y = -1}, + offset = {x = -5, y = -5}, + z_index = 1001, + number = 0xFFFFFF, + }) + }, } - mcl_credits.players[name] = hud_list + add_hud_element({ + hud_elem_type = "image", + text = "mineclone2_logo.png", + scale = {x = 1, y = 1}, + }, huds, 300, 0) + add_hud_element({ + hud_elem_type = "text", + text = mcl_credits.description, + number = 0x757575, + scale = {x = 5, y = 5}, + }, huds, 350, 0) + local y = 450 + for _, group in ipairs(mcl_credits.people) do + add_hud_element({ + hud_elem_type = "text", + text = group[1], + number = group[2], + scale = {x = 3, y = 3}, + }, huds, y, 0) + y = y + 25 + for _, name in ipairs(group[3]) do + y = y + 25 + add_hud_element({ + hud_elem_type = "text", + text = name, + number = 0xFFFFFF, + scale = {x = 1, y = 1}, + }, huds, y, 0) + end + y = y + 200 + end + huds.icon = add_hud_element({ + hud_elem_type = "image", + text = "mineclone2_icon.png", + scale = {x = 1, y = 1}, + }, huds, y) + mcl_credits.players[name] = huds end function mcl_credits.hide(player) local name = player:get_player_name() - local list = mcl_credits.players[name] - if list then - for _, id in pairs(list) do + local huds = mcl_credits.players[name] + if huds then + for _, id in pairs(huds.ids) do player:hud_remove(id) end end mcl_credits.players[name] = nil end -controls.register_on_press(function(player, key) - if key == "sneak" then - mcl_credits.hide(player) - elseif key == "aux1" then - mcl_credits.show(player) +minetest.register_on_leaveplayer(function(player) + mcl_credits.players[player:get_player_name()] = nil +end) + +minetest.register_globalstep(function(dtime) + for _, huds in pairs(mcl_credits.players) do + local player = huds.player + if not huds.new and player:get_player_control().sneak then + mcl_credits.hide(player) + else + local moving = {} + local any + for id, y in pairs(huds.moving) do + y = y - 1 + if y > -100 then + if id == huds.icon then + y = math.max(400, y) + else + any = true + end + player:hud_change(id, "offset", {x = 0, y = y}) + moving[id] = y + end + end + if not any then + mcl_credits.hide(player) + end + huds.moving = moving + end + huds.new = false end end) diff --git a/mods/HUD/mcl_credits/mod.conf b/mods/HUD/mcl_credits/mod.conf index b5532cd30..3df6370af 100644 --- a/mods/HUD/mcl_credits/mod.conf +++ b/mods/HUD/mcl_credits/mod.conf @@ -1,4 +1,3 @@ name = mcl_credits author = Fleckenstein description = Show a HUD containing the credits -depends = controls diff --git a/mods/HUD/mcl_credits/textures/mineclone2_icon.png b/mods/HUD/mcl_credits/textures/mineclone2_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e479dfff5a55bf28d90056e968246e803aad0297 GIT binary patch literal 3961 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 Tj70 Date: Tue, 6 Apr 2021 11:59:22 +0200 Subject: [PATCH 051/164] Remove empty line from mcl_portals --- mods/ITEMS/mcl_portals/portal_end.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index bf93b4c1f..192f5001c 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -170,7 +170,6 @@ function mcl_portals.end_teleport(obj, pos) -- Teleport back to the player's spawn or world spawn in the Overworld. if obj:is_player() then target = mcl_spawn.get_player_spawn_pos(obj) - end target = target or mcl_spawn.get_world_spawn_pos(obj) From ba15f01ca9f2b6652bac50ebb3caeeb096dbb2c1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 12:08:25 +0200 Subject: [PATCH 052/164] Add translations; Duplicate listing of people --- mods/HUD/mcl_credits/init.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index a53ebbba9..ba30d2408 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -58,12 +58,22 @@ mcl_credits.people = { {"3D Models", 0x0019FF, { "22i", "tobyplowy", + "epCode", }}, {"Textures", 0xFF9705, { "XSSheep", + "Wuzzy", "kingoscargames", "leorockway", "xMrVizzy", + "yutyo" + }}, + {"Translations", 0x00FF60, { + "Wuzzy", + "Rocher Laurent", + "wuniversales", + "kay27", + "pitchum", }}, } From 5bdb3bc274be63ef0633ad1815ae2a447d15c52c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 12:14:43 +0200 Subject: [PATCH 053/164] Add MineClone5 section to credits --- mods/HUD/mcl_credits/init.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index ba30d2408..40bafa19e 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -55,6 +55,13 @@ mcl_credits.people = { "nickolas360", "yutyo", }}, + {"MineClone5", 0xA60014, { + "kay27", + "Debiankaios", + "epCode", + "NO11", + "j45", + }}, {"3D Models", 0x0019FF, { "22i", "tobyplowy", From a348909ba3cb8d274e313e9f6fff56d933c3dda9 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 12:50:36 +0200 Subject: [PATCH 054/164] Enderdragon: Proper Egg and XP spawning --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 16 ++++++---------- mods/ITEMS/mcl_end/end_crystal.lua | 3 +-- mods/MAPGEN/mcl_structures/init.lua | 2 +- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index e62b0d16b..ddaea360f 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -50,8 +50,8 @@ mobs:register_mob("mobs_mc:enderdragon", { arrow = "mobs_mc:dragon_fireball", shoot_interval = 0.5, shoot_offset = -1.0, - xp_min = 12000, - xp_max = 12000, + xp_min = 500, + xp_max = 500, animation = { fly_speed = 8, stand_speed = 8, stand_start = 0, stand_end = 20, @@ -59,15 +59,11 @@ mobs:register_mob("mobs_mc:enderdragon", { run_start = 0, run_end = 20, }, ignores_nametag = true, - on_die = function(self, own_pos) - if self._egg_spawn_pos then - local pos = minetest.string_to_pos(self._egg_spawn_pos) - --if minetest.get_node(pos).buildable_to then - minetest.set_node(pos, {name = mobs_mc.items.dragon_egg}) - return - --end + on_die = function(self, pos) + if not self._respawned then + mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 + minetest.set_node(self._portal_pos and minetest.string_to_pos(self._portal_pos) or vector.add(mcl_vars.mg_end_platform_pos, vector.new(-27, 2, 0)), {name = mobs_mc.items.dragon_egg}) end - minetest.add_item(own_pos, mobs_mc.items.dragon_egg) end, fire_resistant = true, }) diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index d089c3cdf..8fcf67a1d 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -58,8 +58,7 @@ local function spawn_crystal(pos) for _, crystal in pairs(crystals) do crystal_explode(crystal) end - local dragon = minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon") - dragon:get_luaentity()._egg_spawn_pos = minetest.pos_to_string(vector.add(portal_center, {x = 0, y = 4, z = 0})) + minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon"):get_luaentity()._respawned = true end minetest.register_entity("mcl_end:crystal", { diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 6a7f44dfb..4294215a9 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -313,7 +313,7 @@ mcl_structures.generate_fossil = function(pos, rotation, pr) end mcl_structures.generate_end_exit_portal = function(pos, rot) - minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon") + minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = minetest.pos_to_string(vector.add(pos, vector.new(3, 5, 3))) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end From 055c406d7a02b01724eb0f952e9ab4f5d0a4c6f5 Mon Sep 17 00:00:00 2001 From: Doloment Date: Tue, 6 Apr 2021 18:57:06 +0700 Subject: [PATCH 055/164] Fix chest entity textures (trapped chests were lighter) --- .../mcl_chests/textures/mcl_chests_normal.png | Bin 689 -> 672 bytes .../textures/mcl_chests_normal_double.png | Bin 1031 -> 961 bytes .../mcl_chests/textures/mcl_chests_trapped.png | Bin 1209 -> 674 bytes .../textures/mcl_chests_trapped_double.png | Bin 2011 -> 965 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png index 5133f53ff7ea3f44e51d8c339f7efa67f967eefe..9974f60d5733ae946cab3be3f6e805b284eaa235 100644 GIT binary patch delta 642 zcmV-|0)73l1)v3xDSt5kFc}#cI1&&eBO@#yC0WyMH2)#9bMNF?oibdv9=* z9@}+c&cdI={Wv-P=Py07AD6Jq1_M5@+!kY=%St;{Ij$?9DMUK3+Ox}bHv7H@*b135}$+l?yK>7Y;8M~ zv7W$uV0^@nnqQokgW9%38R!Y7Bg?8(-a60f^=*g0^?&;At}X-Mo(mjja7O&i_UsO` zHoeF(d1*`mDr?h;K*y6g0i0H4O@kDZCk_Kkxd~o_0D`K#5lIL(Bbz2du?EIWMFXosuH7!RALa?3?xyH+VIq+?%ppuO3Xe zLi}@lvyVWD5AB!0mzVkFF?{nC9*L&~RQW`Ls#`%4>uEaw zz6XdL5H%epEiw49TrPj@0nbWD`G!@NWlgL9Q=(=JAWmE*>wt)c1o2LZ88 zl5s~6aLaFqb$@5G;f4cNFwHtn{~#b%c+eDm_9rMw9h#v2aY=x%BTgec_h;;eG@+=| zyEzX?*F2Vo&*cU8Pr9yD5@dOe*0J`d9O%Voiztkaf4f>;Rkst`RW%11Njr|tq5SrP z{kUaqC$tuAkS<8oP{*~8&Z~NLJE7HSL)kI1ip4k1i+@UGJK=W)i?UN70hAYjk}iIj zzd4xSVb^9C88$D87=XGqYimqA9x}k`(rD%<*gSn0n3$VLDH*_Dns>Zy=ur&em;ugm z;3fwE7~l&5?MrMPyP;3Od4|nPql3Uix+W<$C;}QL2R^882>2KjK*$Gmou+dWH8xLk z8)T4o4S!JkkM;lOEe0000o88{LUBO@a$EG$GdC_Ozr zPChV6Nl95oH)2aWaaKfkTS40Uv!_>Z&VK*|Q4at7!|Wg872H%1KuyPop$J0>a2MqT;@aO~UBJ>=WQ}Ab$ff0N zEPyWN=~6_<lp&)a0&vpkdk>iv`#nQ!a0WesUkuxFVW@# z^(LQ#lPs!zV4mazW|fLa*mMCtfJ*Qo>c=bdz3VC~Xn!riv=JgH^j)(b+=8K`vhp$r zDhV`+vJl(_s6^Mq*j6_Q+P1n+WivndPShi~{u#rAV|=5&6JDBY>?C6g1v)mJUq&=t})5jCj`bYG^w`+!V_PO_dJpDcQeNxBR^vc1)Kpwzzthg1Nu1x{uZy)ioM9_7ROnSuNKx3=Tvk9GFv`4X$vEC&5oC zl?NcmAj3w=1<{B_D&b@mE3ai3Rr8YZf+=T6fk$Z6e{7^<^r)!HifLO zAmAOW-oIFfGmBs+5Kug+AaJ@Sz;(hAsssqxTz`N{op4kq+;dhil5h&@C{@BO%8;IFpRf5x-$$*w~s%6v&JJ^7OI%4_*97m@k#w0>$sDQ zEq@DDhq;NHs7wrLI8Ihr2vv8Mu}_BTj3*sF5F>%H&mUwweaNxi_&#F`1>89mF(Dm( zwjk6S!!Q}~D8~-Q_ZeF(kP;H7Q71hWZt6`RSVEP+Dm&mw#uf{3FNvq2JMS=8j(Egi z4J<5Xiv?IGfpWP5h6>6iEMzeV6tcw@^f23`ckDa9jUC@{dTn@w54J+Kw#61(Y_Y}v Z#V-QG-H{0gf6V{@002ovPDHLkV1oaNq&ENn delta 1021 zcmV^AB0gjv7r-)aG~#p08KqYDnQYBeXp%PBn)}&O`kHaeJ}xk&ypme; zp*_dnN;|ca4K~?_1-9&Ox=60eWWXy3PXFT1UH%F_5r_x?4uff=KarBaTeP_9$ z;3$E;O&1*~AZztN4f_}YT;A_;0o3pUVKXmaQ)ABeA}@7&HsO9~S7}vMjJsY?WF~ zvR`z$nB<6XCtF$TCi{dyt!xN!t&IAx3U5V)VMmPYnz0SgiZR|8fpw&57E zOj}q)jAydX2)I}rH~jJj3P_YfVkrRh8olA@h-b2=<9PA*2&Y4N r3A_aU{w7`mFM;3kDR}YX#fyIcKpwkkCH7o88{LUBO@a$EG$GdC_Ozr zPChV6Nl95oH*r=(cUwt(UrdQ=PLXg@_=nP>00001bW%=J06^y0W&i*JBS}O-R7l6| zlEI4FP!xt;^Z_a@eStnf8yVFI#{)PrGLv}ycsi_7VAAYvy~#V z?kG32D-ucEm0=i@XXv^221n_!T^Hso{5jl@ljDE>(j)6}39C|P!271xWX$(iX{V~k zjshA&qsuOF zmi{caCj<=K@P8m+_0n`Twlr`g;Yt11ylo^6^~0xBJoz7-zsLJ(RJz-zlJ-oNeMLKKc|0epTCc zC|5NF4AV&xpF`#SSL4md+;%7dnpzPPXYwSR4g($^Czt}L@!edj)NoNb4{ zj5D1D%f`gtO= zHW8RS+JC6aESpKIF?oWTz&w>TkhOoTf1bPi#4wB(WfWJ7aW6WwJXrX^n*6!@QcBS& zDMA}=enj(j^4WMTrRbCtz{O@6t=b8LZ&Hd*iB9zz0}Oy7v?TYUfgB*t7o=z)3Rm&< woD>a+_6qkQMO(<5;D6wxlpgA#{>Sr~F000DMK}|sb0I`n?{9y$E000SaNLh0L01mzY z01mzZ>O!%=00007bV*G`2iyt~2@*72tl>rg000)d0vx3}B)`}_ON z$G4Ba`117T7y5`HmYffduYV(Rdor$-J-;bJ@s8W{(6RxD{r2hIZ+!p!ehWhS24s`K z*dJe?wlL25zkk+%9JlGAWjvd##49A%ry=+d`uOU_PRu8#l|8?4>THZ>j@$Imya5jn z58DlTdOge$Lo7MGBMgCg#Yarr0OEktWrM(G-EfjO08z&@fLPXOW#=(O0jG=T`~)DI zL5%T=I;H_UTiJQc6SV=aY?$8GC8S!jo=YO%$4M1Ff6Y>W9lMO(Wr;WJ$ z5&UNxke>jec0tUad;;XOvh!H}A;bpr+9ObyBZgT28RS+R^CLKA13Xbq*Xy6y2*!B> z5QUGqUTlx~7jXl)s%*HYzX1rdNkW|Y{%#}}(SRg34t)b4jXXAEwPF)_s2 z0M|0_)Ow@5tk-0YtuLks#KOxXZ7bxZ>gYXi*f$@!jEb{=C>h)R*%iV>WuV)AqW@vP+-7<)^2 zZ+~UyF@zxMxf;;Z%Fbh_HUKdS$LH7vB-7sjHg`$`$m1P6;q-|OAg`63#}IW)1Bm5` z7*Txs(w}p!>^z1THh4?}6w_aI@x*(kZU7tH*8pNXO`a*5_aqx(%+w74HtRR*GewCx z`JEfzqj<*CHlT-%_Vh7*Q+AQ-w6f>7<$wP>%tnPmyU5riW86ggsvO9eiYf=H*d$|{ z%&~cO^U5*i`_q?K*O)%<<@NQpcs2mvzC6dr)^ofsugM%6N&eXIB#ALUPP{`EQ~A8E z!1&O-Q|ld)*JO^ZPojJNI_u9EAf_q?o)!p;+m|5Ear%(1yJxCl?kg)PpL_e;rZGRKw+Lw-jr-1~Tv zb18XE=Ga`EMR>A^@9Bf|$?SPe=6@U7X0utE(zz0)b0tdWN|er(D4i=&I#;4}u0-iv ziPE_erE?`p=Sq~$l_;GnQ94(mbSkby>0F7@xe}#wMxM>8Vl(nQc6Id=*tZtL<|9;J P00000NkvXXu0mjf?&D5S diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png index 95f768f97c0e7f1243b73df472b10174c7e69246..88ff45825f872490246c2b5eb81f18bb907d887b 100644 GIT binary patch delta 955 zcmV;s14R7W55)(N7=Hu<0000W_+m@|001yhOjJdG000>o88{LUBO@a$EG$GdC_Ozr zPChV6Nl95oH)2aWaaKfkTSt3&X@Ae9?6i?oICkEmixEnW zr4V{tW{i|m3C5FhE+z4P$z_X!>p2~}}A;J_jdRRQteeWdvrWib&XW0X~3A@B!*YEAzdpGJh**EWxxPA_?>zvp2p0LrG=j z<#=35piY#9;4VNVIwr=px=GMB)qN_O`N?;}F2U8$7#7N)w2}L{e9Jav|g#MR?DytsMU&Uxt3vYAS&U&oa$_FiDPVy ze@dx506_*BHdHPMhb&YHC(BrQEyJjq7mpT9Ia>rJ1bPRnxb~!gxuc~}3CA`Uh;*_k zqQ0#xdRqdMW9vVx(6Q&2~#5^fo7 zE|AtwHOf(?jFb_WxeST`mJ+I%rHs_OJzUK&C_f~ee%ldV&Pd}M*z8=tjv>SP+SQUx zRnN+-U@gP+H3ADc>1`?u!+*WbJ1-2wc(bEB!?1Mw@bfooJg`Nfim8gv*VbDVpVZH= zj(avX%EW*Mqj-gdP<3Z1`)H`nc--cFF%%g4{9Z=W`wZ)i?ou{az@1YO z5z^+T3qrjS43i-bGi-l!m$LZ+2_aDuwv!X#Cf@X(#Z(EbvV9(>Y`y^Z;%FMU^EPwk zkcSM`z=C`>Ux2k^D3>c>sGw}Z0v3TlE;O5OLBC15$G+p+*zp~w+k{8>V9RAITWqn# d7F+yZ`~s_X-5jfjq&NTo002ovPDHLkV1jaqv%LTS literal 2011 zcmZuydpy(o8~?5y#2QJogC#|j>nhVG3^}Z54pOQacE)j=%eHW0l*2iSKcDye^?9D>^}If*Zs(k!N}5Ul z06?+Mr`=^SQD&H(@-ja#n2;a~-v!#a+5te-ZOAu2IoVk;!r7Yw0LsnV1`^v>wa7pP zD%RCeVN^*~QB6)gsNY%!!KjWGsUG10)M&pb5)k1RM5daONz?-;OwCO#NXf@YGS&~+ z({`RQKA-bn-qa`UP7!J%qmKKjC8eM5mjkP6>^r1-!rXk1Tx)-er}=KP7Atd!(uJau zqEF1~hB9IQ7)4rO8Z)yc7H&K#uj~_xq07tD-F3^~)+KdyuN9^`Ztbhvs`PpJ%SN|l z`212Qj=(z<_R3CN&iOeII(Trt)3PWni{gb&$emp)8V&6V@K-fyUPy}dtOgkl+9qsK zZ*vkhw(fE0o2x!{&q43O^wg!{U@#RS9g3gwS>DvmeMe(G0xidz-##M^L^S-A=WNc9 zH-F?#q$D7LT1y=c=O`=TEwtsCLDeaV?AA>};!q_4r{NI{USyd-e8SDH4j$l|0cfRH z8zXFuzDvc7HD0_>uc2PxY&oPo-}MCQt6R@JfuRq;qhZ3~T)oW_I;b`j$jb^eadXO< zLs2O`nPe8q_~2f-7tFos51e^3?(V_fG4|tzfl9*4PVi1-}0y zumVZ!ZF`zJEAh#0H1Nv&wj-mo=`&mdrPXp$G+`J+2N|YRA#qY+9Idy?0+UZ^Ae_`J z&XlV8R-@UFNcw9lLRanxfR(0;DxOJ1b68h#VeVe#wK1X2*je-f56Jd_5W$PFTuY+F zTKFjlyg1(^%8q1gDzZU^{+t=y$At`ml}PDNWOiH0a8r@3^0+}Jf@-79$nWxVO|eOH zy-Cb=@K0PL`^0^pL>%-r861t`q@{v+|HpJ!=>RzkF4}{1l$~@@j}^Q5KXRp3t6s3b zduFY6CowJ3#)3I-uInItU6@1BGpkmm>*pGFJnJcC2PwC4txM4>V)wpJCk=}Y{Jekv z5?z4M@Mx5v&*8aK1*a%*S@NIZO@9Tg;t}Rhq&SM>khf53)IZ{)ls}b7mg>%h68Ech z^N(F!P{|AltLJ-k)uf!@V=olfcsn-f@^*Em*1p!}Bd+n9zEsxs^46);$o4ASJ$}O1 z3G7$tbCs>mgZ4kVz=~|?;P}JzfRd5&my&LrQS$ix)vDn%im_OC#WybM1m+MDP@Eui zvlK(v_d*6Aq^tKH{97A;#eMRF4zzz~#{m?+buh8!+Yy+NrxOyh(uewzSwJL%sR=7b z@sYK@HS!0J=#?1_YP#uZ0Zn76wWw1_`pMN&YH|+i!@D-`|dt>sAbN`5q+N%s68Z}WnKHj($ z0^GDKF|JPT_Ge_$GdL@>{WQ#6#2i+nWF~vT_(83fHjIfEX>N9WSdhC+8vCDYheeCS zMK@8L@9VPX(9Xg;ti=KKK!{fuK<3?pw!EXMg$KWEeSi;c^0Y;17OQ5pL3QmyEP)WV z#=@z_34M*`=jWS5H+tJ5>ztf#w`1A$6xiGg7Vq|GvYggw>fKn zfHaq`dO3SNl$_l^Nr(?)FvLd8a3}7rP8;v-8k3+A-)M`=QM%fi)L-^ztI&Axu9mHF2S0&EGEwja6mKJGqLRid#;2GuEs!DKEWep*WQB%f0 zvH>56Yj#(e2D$uf{X)T`tg!uBgz#+)O;WynkEC$#Ay9<)L z^KOjzi6omRiln*Lw-3!G^W20T0ouqfle9n(qY zGb#sNc>ff&Ubz$=g*Q(zD43-GChJGcP6Xm`i8y9Yw&GcxC#!kduv^z%B1S6aN7rOq z7nkh1LqX7`3olc4w-o&GYy>VmPAuoYzX-lgt=T69k_~F^t7Lh9h`qOzYei3C=E6}&Z?{1MiL|Kgr4X^M@ z`Db!Qt^4)o-G@CJrsl7kM&`6V8qkkcp{6$OMcy^7A9}T|V;%9A{Whvyok8sy1OH~M ohmTro(S=}T Date: Tue, 6 Apr 2021 14:50:34 +0200 Subject: [PATCH 056/164] Add bossbars --- mods/CORE/mcl_util/init.lua | 2 +- mods/ENTITIES/mcl_mobs/api.lua | 16 +-- mods/ENTITIES/mobs_mc/ender_dragon.lua | 3 + mods/ENTITIES/mobs_mc/wither.lua | 3 +- mods/HUD/mcl_bossbars/init.lua | 124 ++++++++++++++++++ mods/HUD/mcl_bossbars/mod.conf | 4 + .../mcl_bossbars/textures/mcl_bossbars.png | Bin 0 -> 3689 bytes .../textures/mcl_bossbars_empty.png | Bin 0 -> 3369 bytes 8 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 mods/HUD/mcl_bossbars/init.lua create mode 100644 mods/HUD/mcl_bossbars/mod.conf create mode 100644 mods/HUD/mcl_bossbars/textures/mcl_bossbars.png create mode 100644 mods/HUD/mcl_bossbars/textures/mcl_bossbars_empty.png diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a43c3d5d0..ac913de39 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -410,7 +410,7 @@ function mcl_util.get_color(colorstr) local mc_color = mcl_colors[colorstr:upper()] if mc_color then colorstr = mc_color - elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then + elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#" then return end local hex = tonumber(colorstr:sub(2, 7), 16) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 6e932ed5e..e599f2127 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3526,14 +3526,6 @@ local mob_step = function(self, dtime) -- end rotation - -- knockback timer - if self.pause_timer > 0 then - - self.pause_timer = self.pause_timer - dtime - - return - end - -- run custom function (defined in mob lua file) if self.do_custom then @@ -3543,6 +3535,14 @@ local mob_step = function(self, dtime) end end + -- knockback timer + if self.pause_timer > 0 then + + self.pause_timer = self.pause_timer - dtime + + return + end + -- attack timer self.timer = self.timer + dtime diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index ddaea360f..509409a2e 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -59,6 +59,9 @@ mobs:register_mob("mobs_mc:enderdragon", { run_start = 0, run_end = 20, }, ignores_nametag = true, + do_custom = function(self) + mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple") + end, on_die = function(self, pos) if not self._respawned then mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index caf5a248d..8e7f7eb95 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -73,6 +73,7 @@ mobs:register_mob("mobs_mc:wither", { self.object:set_properties({textures={self.base_texture}}) self.armor = {undead = 80, fleshy = 80} end + mcl_bossbars.update_boss(self, "Wither", "dark_purple") end, on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) @@ -115,4 +116,4 @@ mobs:register_arrow("mobs_mc:wither_skull", { --Spawn egg mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true) -mcl_wip.register_wip_item("mobs_mc:wither") \ No newline at end of file +mcl_wip.register_wip_item("mobs_mc:wither") diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua new file mode 100644 index 000000000..38dbbe376 --- /dev/null +++ b/mods/HUD/mcl_bossbars/init.lua @@ -0,0 +1,124 @@ +mcl_bossbars = { + bars = {}, + huds = {}, + colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"}, +} + +function mcl_bossbars.recalculate_colors() + local sorted = {} + local colors = mcl_bossbars.colors + local color_count = #colors + local frame_count = color_count * 2 + for i, color in ipairs(colors) do + local idx = i * 2 - 1 + local image = "mcl_bossbars.png" + .. "^[transformR270" + .. "^[verticalframe:" .. frame_count .. ":" .. (idx - 1) + .. "^(mcl_bossbars_empty.png" + .. "^[lowpart:%d:mcl_bossbars.png" + .. "^[transformR270" + .. "^[verticalframe:" .. frame_count .. ":" .. idx .. ")" + local _, hex = mcl_util.get_color(color) + sorted[color] = { + image = image, + hex = hex, + } + end + mcl_bossbars.colors_sorted = sorted +end + +function mcl_bossbars.update_bar(player, text, color, percentage) + local cdef = mcl_bossbars.colors_sorted[color] + table.insert(mcl_bossbars.bars[player:get_player_name()], {color = cdef.hex, text = text, image = string.format(cdef.image, percentage)}) +end + +function mcl_bossbars.update_boss(luaentity, name, color) + local object = luaentity.object + local text = luaentity.nametag + if not text or text == "" then + text = name + end + local percentage = math.floor(luaentity.health / luaentity.hp_max * 100) + for _, obj in pairs(minetest.get_objects_inside_radius(object:get_pos(), 128)) do + if obj:is_player() then + mcl_bossbars.update_bar(obj, text, color, percentage) + end + end +end + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + mcl_bossbars.huds[name] = {} + mcl_bossbars.bars[name] = {} +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + mcl_bossbars.huds[name] = nil + mcl_bossbars.bars[name] = nil +end) + +minetest.register_globalstep(function() + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local bars = mcl_bossbars.bars[name] + local huds = mcl_bossbars.huds[name] + local huds_new = {} + local i = 0 + + while #huds > 0 or #bars > 0 do + local bar = table.remove(bars, 1) + local hud = table.remove(huds, 1) + + if bar and not hud then + hud = { + color = bar.color, + image = bar.image, + text = bar.text, + text_id = player:hud_add({ + hud_elem_type = "text", + text = bar.text, + number = bar.color, + position = {x = 0.5, y = 0}, + alignment = {x = 0, y = 1}, + offset = {x = 0, y = i * 40}, + }), + image_id = player:hud_add({ + hud_elem_type = "image", + text = bar.image, + position = {x = 0.5, y = 0}, + alignment = {x = 0, y = 1}, + offset = {x = 0, y = i * 40 + 25}, + scale = {x = 3, y = 3}, + }), + } + elseif hud and not bar then + player:hud_remove(hud.text_id) + player:hud_remove(hud.image_id) + hud = nil + else + if bar.text ~= hud.text then + player:hud_change(hud.text_id, "text", bar.text) + hud.text = bar.text + end + + if bar.color ~= hud.color then + player:hud_change(hud.text_id, "number", bar.color) + hud.color = bar.color + end + + if bar.image ~= hud.image then + player:hud_change(hud.image_id, "text", bar.image) + hud.image = bar.image + end + end + + table.insert(huds_new, hud) + i = i + 1 + end + + mcl_bossbars.huds[name] = huds_new + end +end) + +mcl_bossbars.recalculate_colors() diff --git a/mods/HUD/mcl_bossbars/mod.conf b/mods/HUD/mcl_bossbars/mod.conf new file mode 100644 index 000000000..64cbd4c9f --- /dev/null +++ b/mods/HUD/mcl_bossbars/mod.conf @@ -0,0 +1,4 @@ +name = mcl_bossbars +author = Fleckenstein +description = Show enderdragon & wither boss bars. Also allows custom bars. +depends = mcl_util, mcl_colors diff --git a/mods/HUD/mcl_bossbars/textures/mcl_bossbars.png b/mods/HUD/mcl_bossbars/textures/mcl_bossbars.png new file mode 100644 index 0000000000000000000000000000000000000000..55bf36dc288f271d12228a67a6a39c98c6ca18e9 GIT binary patch literal 3689 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 literal 0 HcmV?d00001 diff --git a/mods/HUD/mcl_bossbars/textures/mcl_bossbars_empty.png b/mods/HUD/mcl_bossbars/textures/mcl_bossbars_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..1e50b6afc2a8dddc0748ae7763a5975ef6956b24 GIT binary patch literal 3369 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 SEo%JRzk$BCkyed{6ZSuzSwWZp literal 0 HcmV?d00001 From 962a13847e64613e53f1a2542860d3439a9a6d4f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 14:57:29 +0200 Subject: [PATCH 057/164] Fix dragons summoned using commands spawning an egg on the exit portal --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 4 ++-- mods/ITEMS/mcl_end/end_crystal.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index 509409a2e..01c346579 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -63,9 +63,9 @@ mobs:register_mob("mobs_mc:enderdragon", { mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple") end, on_die = function(self, pos) - if not self._respawned then + if self._portal_pos then mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 - minetest.set_node(self._portal_pos and minetest.string_to_pos(self._portal_pos) or vector.add(mcl_vars.mg_end_platform_pos, vector.new(-27, 2, 0)), {name = mobs_mc.items.dragon_egg}) + minetest.set_node(minetest.string_to_pos(self._portal_pos), {name = mobs_mc.items.dragon_egg}) end end, fire_resistant = true, diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index 8fcf67a1d..9e4fa13fd 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -58,7 +58,7 @@ local function spawn_crystal(pos) for _, crystal in pairs(crystals) do crystal_explode(crystal) end - minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon"):get_luaentity()._respawned = true + minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon") end minetest.register_entity("mcl_end:crystal", { From 83b9cf3ad258620ff3b89bc9c1ce01b02220b82e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 15:48:17 +0200 Subject: [PATCH 058/164] End exit portal openng / closing on dragon death / spawn --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 8 ++++++-- mods/ITEMS/mcl_end/end_crystal.lua | 4 +++- mods/MAPGEN/mcl_mapgen_core/init.lua | 14 ++++++++++---- mods/MAPGEN/mcl_structures/init.lua | 12 ++++++++++-- .../mcl_structures_end_exit_portal.mts | Bin 222 -> 193 bytes .../mcl_structures_end_exit_portal_open.mts | Bin 0 -> 222 bytes 6 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal_open.mts diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index 01c346579..50aaacd4b 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -64,8 +64,12 @@ mobs:register_mob("mobs_mc:enderdragon", { end, on_die = function(self, pos) if self._portal_pos then - mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 - minetest.set_node(minetest.string_to_pos(self._portal_pos), {name = mobs_mc.items.dragon_egg}) + local portal_pos = minetest.string_to_pos(self._portal_pos) + mcl_structures.call_struct(portal_pos, "end_exit_portal_open") + if self._initial then + mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 + minetest.set_node(vector.add(portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg}) + end end end, fire_resistant = true, diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index 9e4fa13fd..63a37d3c6 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -58,7 +58,9 @@ local function spawn_crystal(pos) for _, crystal in pairs(crystals) do crystal_explode(crystal) end - minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon") + local portal_pos = vector.add(portal_center, vector.new(-3, -1, -3)) + mcl_structures.call_struct(portal_pos, "end_exit_portal") + minetest.add_entity(vector.add(portal_pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = minetest.pos_to_string(portal_pos) end minetest.register_entity("mcl_end:crystal", { diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index e08b55ba3..237579dbe 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -54,8 +54,7 @@ local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superfl local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor --- End exit portal position. This is temporary. --- TODO: Remove the exit portal generation when the ender dragon has been implemented. +-- End exit portal position local END_EXIT_PORTAL_POS = table.copy(mcl_vars.mg_end_platform_pos) END_EXIT_PORTAL_POS.x = END_EXIT_PORTAL_POS.x - 30 END_EXIT_PORTAL_POS.z = END_EXIT_PORTAL_POS.z - 3 @@ -1251,6 +1250,13 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_ return lvm_used end +local function generate_end_exit_portal(pos) + local dragon_entity = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity() + dragon_entity._initial = true + dragon_entity._portal_pos = minetest.pos_to_string(pos) + mcl_structures.call_struct(pos, "end_exit_portal") +end + -- TODO: Try to use more efficient structure generating code local function generate_structures(minp, maxp, blockseed, biomemap) local chunk_has_desert_well = false @@ -1490,11 +1496,11 @@ local function generate_structures(minp, maxp, blockseed, biomemap) for y=maxp.y, minp.y, -1 do local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z} if minetest.get_node(p).name == "mcl_end:end_stone" then - mcl_structures.call_struct(p, "end_exit_portal") + generate_end_exit_portal(p) return end end - mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal") + generate_end_exit_portal(END_EXIT_PORTAL_POS) end end diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 4294215a9..d75854352 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -87,6 +87,8 @@ mcl_structures.call_struct = function(pos, struct_style, rotation, pr) return mcl_structures.generate_fossil(pos, rotation, pr) elseif struct_style == "end_exit_portal" then return mcl_structures.generate_end_exit_portal(pos, rotation) + elseif struct_style == "end_exit_portal_open" then + return mcl_structures.generate_end_exit_portal_open(pos, rotation) elseif struct_style == "end_portal_shrine" then return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) end @@ -313,11 +315,15 @@ mcl_structures.generate_fossil = function(pos, rotation, pr) end mcl_structures.generate_end_exit_portal = function(pos, rot) - minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = minetest.pos_to_string(vector.add(pos, vector.new(3, 5, 3))) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end +mcl_structures.generate_end_exit_portal_open = function(pos, rot) + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal_open.mts" + return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) +end + local function shrine_placement_callback(p1, p2, size, rotation, pr) -- Find and setup spawner with silverfish local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") @@ -535,7 +541,7 @@ end -- Debug command minetest.register_chatcommand("spawnstruct", { - params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | nether_portal | dungeon", + params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_opens | end_portal_shrine | nether_portal | dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) @@ -567,6 +573,8 @@ minetest.register_chatcommand("spawnstruct", { mcl_structures.generate_ice_spike_large(pos, rot, pr) elseif param == "end_exit_portal" then mcl_structures.generate_end_exit_portal(pos, rot, pr) + elseif param == "end_exit_portal_open" then + mcl_structures.generate_end_exit_portal_open(pos, rot, pr) elseif param == "end_portal_shrine" then mcl_structures.generate_end_portal_shrine(pos, rot, pr) elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts index bc24f800a6de0e4265fdbe08808c9720061b8490..30d145bd7fdc822259191c918696b74769628d72 100644 GIT binary patch delta 154 zcmcb|c#u)pHze4XfrWvcft7*19t0RzCJGzWmE;#CXQUQef$8}2#GIUpIa?=n^ED`N zxH`Vx{qw7j;reJ1ys)}uDrD>;&p_i$xl%M#|4o_Hb;dWRuj`fdDjvh*7QKNMy&unx^$sU)L+^RXm2rEqVhjdOw~yd0eDy%Dic&uPyg1I8yyH zO~3W?FE<7=#tl0-et5I*%~5yCuvOaK+coXSeq%5FGkVh6GdgztnH3o08erZh5UT|M Dl|EWe literal 0 HcmV?d00001 From 1d587b88955fc1de22e78e8dc64c9d440725ed8d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 15:59:59 +0200 Subject: [PATCH 059/164] Fix crash in wieldview --- mods/PLAYER/wieldview/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua index 48f3f99bd..6021dd369 100644 --- a/mods/PLAYER/wieldview/init.lua +++ b/mods/PLAYER/wieldview/init.lua @@ -70,6 +70,10 @@ minetest.register_on_joinplayer(function(player) local name = player:get_player_name() wieldview.wielded_item[name] = "" minetest.after(0, function(player) + -- if the player left :is_player() will return nil + if not player:is_player() then + return + end wieldview:update_wielded_item(player) local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode") itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) From 38a12e59daebe9efc9f797db4c12e8ab2263d5b1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 16:02:18 +0200 Subject: [PATCH 060/164] Fix comment indentation in wieldview --- mods/PLAYER/wieldview/init.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua index 6021dd369..7a349f2f3 100644 --- a/mods/PLAYER/wieldview/init.lua +++ b/mods/PLAYER/wieldview/init.lua @@ -115,10 +115,11 @@ minetest.register_entity("wieldview:wieldnode", { local def = minetest.registered_items[itemstring] self.object:set_properties({glow = def and def.light_source or 0}) - -- wield item as cubic + -- wield item as cubic if armor.textures[self.wielder].wielditem == "blank.png" then self.object:set_properties({textures = {itemstring}}) - else -- wield item as flat + -- wield item as flat + else self.object:set_properties({textures = {""}}) end From 3c73ad3b9866543c7c42356a49aa15f9ce938f76 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 16:06:44 +0200 Subject: [PATCH 061/164] Add ztianyang to credits --- mods/HUD/mcl_credits/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 40bafa19e..1e8138ab4 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -54,6 +54,7 @@ mcl_credits.people = { "dBeans", "nickolas360", "yutyo", + "ztianyang", }}, {"MineClone5", 0xA60014, { "kay27", From ea08fee9ba572287f4aad42b0afa07a7ace7369b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 16:38:23 +0200 Subject: [PATCH 062/164] Make the dragon stay within a 50 blocks range of the portal --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 18 +++++++++++++++--- mods/ITEMS/mcl_end/end_crystal.lua | 2 +- mods/MAPGEN/mcl_mapgen_core/init.lua | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index 50aaacd4b..fbdaf2bc9 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -61,14 +61,26 @@ mobs:register_mob("mobs_mc:enderdragon", { ignores_nametag = true, do_custom = function(self) mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple") + if self._portal_pos then + -- migrate old format + if type(self._portal_pos) == "string" then + self._portal_pos = minetest.string_to_pos(self._portal_pos) + end + local portal_center = vector.add(self._portal_pos, vector.new(3, 11, 3)) + local pos = self.object:get_pos() + if vector.distance(pos, portal_center) > 50 then + self.object:set_pos(self._last_good_pos or portal_center) + else + self._last_good_pos = pos + end + end end, on_die = function(self, pos) if self._portal_pos then - local portal_pos = minetest.string_to_pos(self._portal_pos) - mcl_structures.call_struct(portal_pos, "end_exit_portal_open") + mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open") if self._initial then mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 - minetest.set_node(vector.add(portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg}) + minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg}) end end end, diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index 63a37d3c6..772776a1c 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -60,7 +60,7 @@ local function spawn_crystal(pos) end local portal_pos = vector.add(portal_center, vector.new(-3, -1, -3)) mcl_structures.call_struct(portal_pos, "end_exit_portal") - minetest.add_entity(vector.add(portal_pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = minetest.pos_to_string(portal_pos) + minetest.add_entity(vector.add(portal_pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = portal_pos end minetest.register_entity("mcl_end:crystal", { diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 237579dbe..e9d9368ad 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1253,7 +1253,7 @@ end local function generate_end_exit_portal(pos) local dragon_entity = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity() dragon_entity._initial = true - dragon_entity._portal_pos = minetest.pos_to_string(pos) + dragon_entity._portal_pos = pos mcl_structures.call_struct(pos, "end_exit_portal") end From 8e2493dd9a3cb9f13ffbf1dd31356e95056d646a Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 10:40:16 -0400 Subject: [PATCH 063/164] Remove 47 node object check from mobs --- mods/ENTITIES/mcl_mobs/api.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index e599f2127..d81d3766d 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -4632,6 +4632,7 @@ function mobs:alias_mob(old_name, new_name) end +--[[ local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime @@ -4648,3 +4649,4 @@ minetest.register_globalstep(function(dtime) end timer = 0 end) +]]-- \ No newline at end of file From f65c40f805a7d9311519755a22725c5f4bfb38c9 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 17:20:11 +0200 Subject: [PATCH 064/164] Make dragon egg teleport on punching --- mods/ITEMS/mcl_end/building.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_end/building.lua b/mods/ITEMS/mcl_end/building.lua index 3dcf0671e..94fd26434 100644 --- a/mods/ITEMS/mcl_end/building.lua +++ b/mods/ITEMS/mcl_end/building.lua @@ -169,7 +169,16 @@ minetest.register_node("mcl_end:dragon_egg", { sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 9, _mcl_hardness = 3, - -- TODO: Make dragon egg teleport on punching + on_punch = function(pos, node) + local max_dist = vector.new(15, 7, 15) + local positions = minetest.find_nodes_in_area(vector.subtract(pos, max_dist), vector.add(pos, max_dist), "air", false) + if #positions > 0 then + local tpos = positions[math.random(#positions)] + minetest.remove_node(pos) + minetest.set_node(tpos, node) + minetest.check_for_falling(tpos) + end + end, }) From 430f958faee13f9b9750f37b9a5189fe10a4f309 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 6 Apr 2021 20:08:20 +0200 Subject: [PATCH 065/164] Move end exit portal to 0, 0; Add end gateway portals (WIP) --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 1 + mods/ITEMS/mcl_portals/init.lua | 6 ++- mods/ITEMS/mcl_portals/portal_gateway.lua | 45 ++++++++++++++++++ mods/ITEMS/mcl_portals/portal_nether.lua | 4 +- mods/MAPGEN/mcl_end_island/init.lua | 8 ++-- mods/MAPGEN/mcl_mapgen_core/init.lua | 5 +- mods/MAPGEN/mcl_structures/init.lua | 9 ++++ .../mcl_structures_end_gateway_portal.mts | Bin 0 -> 109 bytes 8 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 mods/ITEMS/mcl_portals/portal_gateway.lua create mode 100644 mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_gateway_portal.mts diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index fbdaf2bc9..92806d878 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -77,6 +77,7 @@ mobs:register_mob("mobs_mc:enderdragon", { end, on_die = function(self, pos) if self._portal_pos then + mcl_portals.spawn_gateway_portal() mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open") if self._initial then mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 diff --git a/mods/ITEMS/mcl_portals/init.lua b/mods/ITEMS/mcl_portals/init.lua index 2fd96afad..080051ffa 100644 --- a/mods/ITEMS/mcl_portals/init.lua +++ b/mods/ITEMS/mcl_portals/init.lua @@ -1,6 +1,8 @@ -- Load files -mcl_portals = {} +mcl_portals = { + storage = minetest.get_mod_storage(), +} -- Nether portal: -- Obsidian frame, activated by flint and steel @@ -10,3 +12,5 @@ dofile(minetest.get_modpath("mcl_portals").."/portal_nether.lua") -- Red nether brick block frame, activated by an eye of ender dofile(minetest.get_modpath("mcl_portals").."/portal_end.lua") +dofile(minetest.get_modpath("mcl_portals").."/portal_gateway.lua") + diff --git a/mods/ITEMS/mcl_portals/portal_gateway.lua b/mods/ITEMS/mcl_portals/portal_gateway.lua new file mode 100644 index 000000000..cae6fce43 --- /dev/null +++ b/mods/ITEMS/mcl_portals/portal_gateway.lua @@ -0,0 +1,45 @@ +local S = minetest.get_translator("mcl_portals") +local storage = mcl_portals.storage + +local gateway_positions = { + {x = 96, y = -26925, z = 0}, + {x = 91, y = -26925, z = 29}, + {x = 77, y = -26925, z = 56}, + {x = 56, y = -26925, z = 77}, + {x = 29, y = -26925, z = 91}, + {x = 0, y = -26925, z = 96}, + {x = -29, y = -26925, z = 91}, + {x = -56, y = -26925, z = 77}, + {x = -77, y = -26925, z = 56}, + {x = -91, y = -26925, z = 29}, + {x = -96, y = -26925, z = 0}, + {x = -91, y = -26925, z = -29}, + {x = -77, y = -26925, z = -56}, + {x = -56, y = -26925, z = -77}, + {x = -29, y = -26925, z = -91}, + {x = 0, y = -26925, z = -96}, + {x = 29, y = -26925, z = -91}, + {x = 56, y = -26925, z = -77}, + {x = 77, y = -26925, z = -56}, + {x = 91, y = -26925, z = -29}, +} + +function mcl_portals.spawn_gateway_portal() + local id = storage:get_int("gateway_last_id") + 1 + local pos = gateway_positions[id] + if not pos then return end + storage:set_int("gateway_last_id", id) + mcl_structures.call_struct(vector.add(pos, vector.new(-1, -2, -1)), "end_gateway_portal") +end + +local gateway_def = table.copy(minetest.registered_nodes["mcl_portals:portal_end"]) +gateway_def.description = S("End Gateway Portal") +gateway_def._tt_help = S("Used to construct end gateway portals") +gateway_def._doc_items_longdesc = S("An End gateway portal teleports creatures and objects to the outer End (and back!).") +gateway_def._doc_items_usagehelp = S("Throw an ender pearl into the portal to teleport. Entering an Gateway portal near the Overworld teleports you to the outer End. At this destination another gateway portal will be constructed, which you can use to get back.") +gateway_def.after_destruct = nil +gateway_def.drawtype = "normal" +gateway_def.node_box = nil +gateway_def.walkable = true +gateway_def.tiles[3] = nil +minetest.register_node("mcl_portals:portal_gateway", gateway_def) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 50a3bde39..9ac569dd7 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -47,7 +47,7 @@ local chatter = {} local queue = {} local chunks = {} -local storage = minetest.get_mod_storage() +local storage = mcl_portals.storage local exits = {} local keys = minetest.deserialize(storage:get_string("nether_exits_keys") or "return {}") or {} for _, key in pairs(keys) do @@ -193,7 +193,7 @@ end local function destroy_nether_portal(pos, node) if not node then return end local nn, orientation = node.name, node.param2 - local obsidian = nn == OBSIDIAN + local obsidian = nn == OBSIDIAN local check_remove = function(pos, orientation) local node = get_node(pos) diff --git a/mods/MAPGEN/mcl_end_island/init.lua b/mods/MAPGEN/mcl_end_island/init.lua index fb062bf77..730176257 100644 --- a/mods/MAPGEN/mcl_end_island/init.lua +++ b/mods/MAPGEN/mcl_end_island/init.lua @@ -8,12 +8,10 @@ local noisemap = PerlinNoiseMap({ }, {x = 151, y = 30, z = 151}):get_3d_map({x = 0, y = 0, z = 0}) local c_end_stone = minetest.get_content_id("mcl_end:end_stone") - -local x_offset = mcl_vars.mg_end_platform_pos.x - 27 local y_offset = -2 minetest.register_on_generated(function(minp, maxp) - if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < (-75 + x_offset) or minp.x > (75 + x_offset) or maxp.z < -75 or minp.z > 75 then + if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -75 or minp.x > 75 or maxp.z < -75 or minp.z > 75 then return end @@ -21,10 +19,10 @@ minetest.register_on_generated(function(minp, maxp) local data = vm:get_data() local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) - for idx in area:iter(math.max(minp.x, -75 + x_offset), math.max(minp.y, -27025 + y_offset + 4), math.max(minp.z, -75), math.min(maxp.x, 75 + x_offset), math.min(maxp.y, -27000 + y_offset), math.min(maxp.z, 75)) do + for idx in area:iter(math.max(minp.x, -75), math.max(minp.y, -27025 + y_offset + 4), math.max(minp.z, -75), math.min(maxp.x, 75), math.min(maxp.y, -27000 + y_offset), math.min(maxp.z, 75)) do local pos = area:position(idx) local y = 27025 + pos.y - y_offset - if noisemap[pos.x + 75 - x_offset + 1][y + 1][pos.z + 75 + 1] > (math.abs(1 - y / 25) ^ 2 + math.abs((pos.x - x_offset) / 75) ^ 2 + math.abs(pos.z / 75) ^ 2) then + if noisemap[pos.x + 75 + 1][y + 1][pos.z + 75 + 1] > (math.abs(1 - y / 25) ^ 2 + math.abs(pos.x / 75) ^ 2 + math.abs(pos.z / 75) ^ 2) then data[idx] = c_end_stone end end diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index e9d9368ad..1ee861e4a 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -55,10 +55,7 @@ local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superfl local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor -- End exit portal position -local END_EXIT_PORTAL_POS = table.copy(mcl_vars.mg_end_platform_pos) -END_EXIT_PORTAL_POS.x = END_EXIT_PORTAL_POS.x - 30 -END_EXIT_PORTAL_POS.z = END_EXIT_PORTAL_POS.z - 3 -END_EXIT_PORTAL_POS.y = END_EXIT_PORTAL_POS.y - 3 +local END_EXIT_PORTAL_POS = vector.new(-3, -27003, -3) -- Content IDs local c_bedrock = minetest.get_content_id("mcl_core:bedrock") diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index d75854352..00efeca14 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -89,6 +89,8 @@ mcl_structures.call_struct = function(pos, struct_style, rotation, pr) return mcl_structures.generate_end_exit_portal(pos, rotation) elseif struct_style == "end_exit_portal_open" then return mcl_structures.generate_end_exit_portal_open(pos, rotation) + elseif struct_style == "end_gateway_portal" then + return mcl_structures.generate_end_gateway_portal(pos, rotation) elseif struct_style == "end_portal_shrine" then return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) end @@ -324,6 +326,11 @@ mcl_structures.generate_end_exit_portal_open = function(pos, rot) return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end +mcl_structures.generate_end_gateway_portal = function(pos, rot) + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts" + return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) +end + local function shrine_placement_callback(p1, p2, size, rotation, pr) -- Find and setup spawner with silverfish local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") @@ -575,6 +582,8 @@ minetest.register_chatcommand("spawnstruct", { mcl_structures.generate_end_exit_portal(pos, rot, pr) elseif param == "end_exit_portal_open" then mcl_structures.generate_end_exit_portal_open(pos, rot, pr) + elseif param == "end_gateway_portal" then + mcl_structures.generate_end_gateway_portal(pos, rot, pr) elseif param == "end_portal_shrine" then mcl_structures.generate_end_portal_shrine(pos, rot, pr) elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_gateway_portal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_gateway_portal.mts new file mode 100644 index 0000000000000000000000000000000000000000..24b06a1c8feb879c7480ccaacebb07c0fa405ac6 GIT binary patch literal 109 zcmeYb3HD`RVPIxpWniuc0U(n(F|&w4AU8QDJ~_WA)ha19r6@l+n?VXBQjlL%l9*F$ z1)<~96H8Ld6Dup`Bqua5xv{Z0q#HLWGBXPcNzbpcSmCbt`t|FFD!X(v85s6$WNQKd D{xKuw literal 0 HcmV?d00001 From 069e089ae4c6446a0de3d9740664221a6a7ebb9d Mon Sep 17 00:00:00 2001 From: kay27 Date: Wed, 7 Apr 2021 03:34:15 +0400 Subject: [PATCH 066/164] [mcl_portals, mcl_structures] Add End gateways W-I-P by Elias Fleckenstein with minor portals improvements and fixes --- mods/ITEMS/mcl_portals/portal_gateway.lua | 78 ++++++++++++++++++++++- mods/ITEMS/mcl_portals/portal_nether.lua | 33 +++++++++- mods/MAPGEN/mcl_biomes/init.lua | 2 + mods/MAPGEN/mcl_structures/init.lua | 10 +-- 4 files changed, 115 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_gateway.lua b/mods/ITEMS/mcl_portals/portal_gateway.lua index cae6fce43..9fa35a36f 100644 --- a/mods/ITEMS/mcl_portals/portal_gateway.lua +++ b/mods/ITEMS/mcl_portals/portal_gateway.lua @@ -24,12 +24,21 @@ local gateway_positions = { {x = 91, y = -26925, z = -29}, } +local function spawn_gateway_portal(pos, dest_str) + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts" + return mcl_structures.place_schematic(vector.add(pos, vector.new(-1, -2, -1)), path, "0", nil, true, nil, dest_str and function(p1, p2, size, orientation, pr, param) + -- minetest.get_voxel_manip():read_from_map(pos, pos) + minetest.get_meta(vector.add(p1, {x=1,y=2,z=1})):set_string("mcl_portals:gateway_destination", param.dest_str) + print(param.dest_str) + end, nil, {dest_str=dest_str}) +end + function mcl_portals.spawn_gateway_portal() local id = storage:get_int("gateway_last_id") + 1 local pos = gateway_positions[id] if not pos then return end storage:set_int("gateway_last_id", id) - mcl_structures.call_struct(vector.add(pos, vector.new(-1, -2, -1)), "end_gateway_portal") + spawn_gateway_portal(pos) end local gateway_def = table.copy(minetest.registered_nodes["mcl_portals:portal_end"]) @@ -43,3 +52,70 @@ gateway_def.node_box = nil gateway_def.walkable = true gateway_def.tiles[3] = nil minetest.register_node("mcl_portals:portal_gateway", gateway_def) + +local function find_destination_pos(minp, maxp) + for y = maxp.y, minp.y, -1 do + for x = maxp.x, minp.x, -1 do + for z = maxp.z, minp.z, -1 do + local pos = vector.new(x, y, z) + local nn = minetest.get_node(pos).name + if nn ~= "ignore" and nn ~= "mcl_portals:portal_gateway" and nn ~= "mcl_core:bedrock" then + local def = minetest.registered_nodes[nn] + if def and def.walkable then + return vector.add(pos, vector.new(0, 1.5, 0)) + end + end + end + end + end +end + +local preparing = {} + +local function teleport(pos, obj) + local meta = minetest.get_meta(pos) + local dest_portal + local dest_str = meta:get_string("mcl_portals:gateway_destination") + local pos_str = minetest.pos_to_string(pos) + if dest_str == "" then + dest_portal = vector.multiply(vector.direction(vector.new(0, pos.y, 0), pos), math.random(768, 1024)) + dest_portal.y = -26970 + spawn_gateway_portal(dest_portal, pos_str) + meta:set_string("mcl_portals:gateway_destination", minetest.pos_to_string(dest_portal)) + else + dest_portal = minetest.string_to_pos(dest_str) + end + local minp = vector.subtract(dest_portal, vector.new(5, 40, 5)) + local maxp = vector.add(dest_portal, vector.new(5, 10, 5)) + preparing[pos_str] = true + minetest.emerge_area( + minp, + maxp, + function(blockpos, action, calls_remaining, param) + if calls_remaining < 1 then + local minp, maxp, dest_portal, obj, pos_str = param.minp, param.maxp, param.dest_portal, param.obj, param.pos_str + if obj and obj:is_player() or obj:get_luaentity() then + obj:set_pos(find_destination_pos(minp, maxp) or vector.add(dest_portal, vector.new(0, 3.5, 0))) + end + preparing[pos_str] = false + end + end, + {minp=vector.new(minp), maxp=vector.new(maxp), dest_portal=vector.new(dest_portal), obj=obj, pos_str=pos_str} + ) +end + +minetest.register_abm({ + label = "End gateway portal teleportation", + nodenames = {"mcl_portals:portal_gateway"}, + interval = 0.1, + chance = 1, + action = function(pos) + if preparing[minetest.pos_to_string(pos)] then return end + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do + if obj:get_hp() > 0 then + teleport(pos, obj) + return + end + end + end, +}) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 9ac569dd7..825c95e05 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -1,5 +1,7 @@ local S = minetest.get_translator("mcl_portals") +local SCAN_2_MAP_CHUNKS = true -- slower but helps to find more suitable places + -- Localize functions for better performance local abs = math.abs local ceil = math.ceil @@ -26,7 +28,7 @@ local DISTANCE_MAX = 128 local PORTAL = "mcl_portals:portal" local OBSIDIAN = "mcl_core:obsidian" local O_Y_MIN, O_Y_MAX = max(mcl_vars.mg_overworld_min, -31), min(mcl_vars.mg_overworld_max_official, 2048) -local N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_top_max +local N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_top_max - H_MIN local O_DY, N_DY = O_Y_MAX - O_Y_MIN + 1, N_Y_MAX - N_Y_MIN + 1 -- Alpha and particles @@ -486,6 +488,14 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param) create_portal_2(pos0, name, obj) return end + + if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then + local pos1, pos2, pos = param.next_chunk_1, param.next_chunk_2, param.next_pos + log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(pos)) + minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = pos, pos1 = pos1, pos2 = pos2, name=name, obj=obj}) + return + end + log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal") if pos.y < lava then pos.y = lava + 1 @@ -507,18 +517,35 @@ local function create_portal(pos, limit1, limit2, name, obj) -- we need to emerge the area here, but currently (mt5.4/mcl20.71) map generation is slow -- so we'll emerge single chunk only: 5x5x5 blocks, 80x80x80 nodes maximum + -- and maybe one more chunk from below if (SCAN_2_MAP_CHUNKS = true) local pos1 = add(mul(mcl_vars.pos_to_chunk(pos), mcl_vars.chunk_size_in_nodes), mcl_vars.central_chunk_offset_in_nodes) local pos2 = add(pos1, mcl_vars.chunk_size_in_nodes - 1) + if not SCAN_2_MAP_CHUNKS then + if limit1 and limit1.x and limit1.y and limit1.z then + pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} + end + if limit2 and limit2.x and limit2.y and limit2.z then + pos2 = {x = min(max(limit2.x, pos.x), pos2.x), y = min(max(limit2.y, pos.y), pos2.y), z = min(max(limit2.z, pos.z), pos2.z)} + end + minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = vector.new(pos), pos1 = pos1, pos2 = pos2, name=name, obj=obj}) + return + end + + -- Basically the copy of code above, with minor additions to continue the search in single additional chunk below: + local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z} + local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1) + local next_pos = {x = pos.x, y=next_chunk_2.y, z = pos.z} if limit1 and limit1.x and limit1.y and limit1.z then pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} + next_chunk_1 = {x = max(min(limit1.x, next_pos.x), next_chunk_1.x), y = max(min(limit1.y, next_pos.y), next_chunk_1.y), z = max(min(limit1.z, next_pos.z), next_chunk_1.z)} end if limit2 and limit2.x and limit2.y and limit2.z then pos2 = {x = min(max(limit2.x, pos.x), pos2.x), y = min(max(limit2.y, pos.y), pos2.y), z = min(max(limit2.z, pos.z), pos2.z)} + next_chunk_2 = {x = min(max(limit2.x, next_pos.x), next_chunk_2.x), y = min(max(limit2.y, next_pos.y), next_chunk_2.y), z = min(max(limit2.z, next_pos.z), next_chunk_2.z)} end - - minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = vector.new(pos), pos1 = pos1, pos2 = pos2, name=name, obj=obj}) + minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = vector.new(pos), pos1 = pos1, pos2 = pos2, name=name, obj=obj, next_chunk_1 = next_chunk_1, next_chunk_2 = next_chunk_2, next_pos = next_pos}) end local function available_for_nether_portal(p) diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 66de6c13a..5f0510344 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1484,6 +1484,7 @@ local function register_dimension_biomes() node_stone = "mcl_nether:netherrack", node_water = "air", node_river_water = "air", + node_cave_liquid = "air", y_min = mcl_vars.mg_nether_min, -- FIXME: For some reason the Nether stops generating early if this constant is not added. -- Figure out why. @@ -1501,6 +1502,7 @@ local function register_dimension_biomes() node_filler = "air", node_water = "air", node_river_water = "air", + node_cave_liquid = "air", -- FIXME: For some reason the End stops generating early if this constant is not added. -- Figure out why. y_min = mcl_vars.mg_end_min, diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 00efeca14..2ce5d94b5 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -11,10 +11,10 @@ local function ecb_place(blockpos, action, calls_remaining, param) if calls_remaining >= 1 then return end minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) if param.after_placement_callback and param.p1 and param.p2 then - param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr) + param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) end end -mcl_structures.place_schematic = function(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr) +mcl_structures.place_schematic = function(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return(schematic)")() if s and s.size then local x, z = s.size.x, s.size.z @@ -32,7 +32,7 @@ mcl_structures.place_schematic = function(pos, schematic, rotation, replacements local p1 = {x=pos.x , y=pos.y , z=pos.z } local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} minetest.log("verbose","[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) - local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr} + local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} minetest.emerge_area(p1, p2, ecb_place, param) end end @@ -548,7 +548,7 @@ end -- Debug command minetest.register_chatcommand("spawnstruct", { - params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_opens | end_portal_shrine | nether_portal | dungeon", + params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_opens | end_portal_shrine | nether_portal | gateway_portal | dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) @@ -590,6 +590,8 @@ minetest.register_chatcommand("spawnstruct", { mcl_dungeons.spawn_dungeon(pos, rot, pr) elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then mcl_portals.spawn_nether_portal(pos, rot, pr, name) + elseif param == "gateway_portal" and mcl_portals.spawn_gateway_portal then + mcl_portals.spawn_gateway_portal(pos, rot, pr, name) elseif param == "" then message = S("Error: No structure type given. Please use “/spawnstruct ”.") errord = true From 00db03320bf6f8b59d29e3d0ce5bf5c787b319d8 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 20:24:46 -0400 Subject: [PATCH 067/164] Fix insane enderman 64 node radius check for players --- mods/ENTITIES/mobs_mc/enderman.lua | 51 +++++++++++++----------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 22599dd9e..40d859f97 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -328,37 +328,30 @@ mobs:register_mob("mobs_mc:enderman", { --end end -- Check to see if people are near by enough to look at us. - local objs = minetest.get_objects_inside_radius(enderpos, 64) - local obj - for n = 1, #objs do - obj = objs[n] - if obj then - if minetest.is_player(obj) then - -- Check if they are looking at us. - local player_pos = obj:get_pos() - local look_dir_not_normalized = obj:get_look_dir() - local look_dir = vector.normalize(look_dir_not_normalized) - local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. - -- Cast up to 64 to see if player is looking at enderman. - for n = 1,64,.25 do - local node = minetest.get_node(look_pos) - if node.name ~= "air" then - break - end - if look_pos.x-1enderpos.x and look_pos.y-2.89enderpos.y and look_pos.z-1enderpos.z then - self.provoked = "staring" - self.attack = minetest.get_player_by_name(obj:get_player_name()) - break - else - if self.provoked == "staring" then - self.provoked = "broke_contact" - end - end - look_pos.x = look_pos.x + (.25 * look_dir.x) - look_pos.y = look_pos.y + (.25 * look_dir.y) - look_pos.z = look_pos.z + (.25 * look_dir.z) + for _,obj in pairs(minetest.get_connected_players()) do + -- Check if they are looking at us. + local player_pos = obj:get_pos() + local look_dir_not_normalized = obj:get_look_dir() + local look_dir = vector.normalize(look_dir_not_normalized) + local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. + -- Cast up to 64 to see if player is looking at enderman. + for n = 1,64,.25 do + local node = minetest.get_node(look_pos) + if node.name ~= "air" then + break + end + if look_pos.x-1enderpos.x and look_pos.y-2.89enderpos.y and look_pos.z-1enderpos.z then + self.provoked = "staring" + self.attack = minetest.get_player_by_name(obj:get_player_name()) + break + else + if self.provoked == "staring" then + self.provoked = "broke_contact" end end + look_pos.x = look_pos.x + (.25 * look_dir.x) + look_pos.y = look_pos.y + (.25 * look_dir.y) + look_pos.z = look_pos.z + (.25 * look_dir.z) end end -- TAKE AND PLACE STUFF BEHAVIOUR BELOW. From 9f7899c01ab7cb1d1b9e5b026e82c3a77a5656ab Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 20:37:48 -0400 Subject: [PATCH 068/164] Enderman use vectors to check distance between player and self --- mods/ENTITIES/mobs_mc/enderman.lua | 41 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 40d859f97..5b228a9af 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -331,27 +331,30 @@ mobs:register_mob("mobs_mc:enderman", { for _,obj in pairs(minetest.get_connected_players()) do -- Check if they are looking at us. local player_pos = obj:get_pos() - local look_dir_not_normalized = obj:get_look_dir() - local look_dir = vector.normalize(look_dir_not_normalized) - local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. - -- Cast up to 64 to see if player is looking at enderman. - for n = 1,64,.25 do - local node = minetest.get_node(look_pos) - if node.name ~= "air" then - break - end - if look_pos.x-1enderpos.x and look_pos.y-2.89enderpos.y and look_pos.z-1enderpos.z then - self.provoked = "staring" - self.attack = minetest.get_player_by_name(obj:get_player_name()) - break - else - if self.provoked == "staring" then - self.provoked = "broke_contact" + if vector.distance(enderpos, player_pos) <= 64 then + + local look_dir_not_normalized = obj:get_look_dir() + local look_dir = vector.normalize(look_dir_not_normalized) + local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. + -- Cast up to 64 to see if player is looking at enderman. + for n = 1,64,.25 do + local node = minetest.get_node(look_pos) + if node.name ~= "air" then + break end + if look_pos.x-1enderpos.x and look_pos.y-2.89enderpos.y and look_pos.z-1enderpos.z then + self.provoked = "staring" + self.attack = minetest.get_player_by_name(obj:get_player_name()) + break + else + if self.provoked == "staring" then + self.provoked = "broke_contact" + end + end + look_pos.x = look_pos.x + (.25 * look_dir.x) + look_pos.y = look_pos.y + (.25 * look_dir.y) + look_pos.z = look_pos.z + (.25 * look_dir.z) end - look_pos.x = look_pos.x + (.25 * look_dir.x) - look_pos.y = look_pos.y + (.25 * look_dir.y) - look_pos.z = look_pos.z + (.25 * look_dir.z) end end -- TAKE AND PLACE STUFF BEHAVIOUR BELOW. From 56f94af6ce95f69ab5e96cd5a498ff7425c83f5a Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 21:13:20 -0400 Subject: [PATCH 069/164] Massively overhaul enderman sight calculations --- mods/ENTITIES/mobs_mc/enderman.lua | 45 +++++++++++++++++++----------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 5b228a9af..e3f2c8e48 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -329,31 +329,44 @@ mobs:register_mob("mobs_mc:enderman", { end -- Check to see if people are near by enough to look at us. for _,obj in pairs(minetest.get_connected_players()) do - -- Check if they are looking at us. + + --check if they are within radius local player_pos = obj:get_pos() - if vector.distance(enderpos, player_pos) <= 64 then + if player_pos then -- prevent crashing in 1 in a million scenario - local look_dir_not_normalized = obj:get_look_dir() - local look_dir = vector.normalize(look_dir_not_normalized) - local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. - -- Cast up to 64 to see if player is looking at enderman. - for n = 1,64,.25 do - local node = minetest.get_node(look_pos) - if node.name ~= "air" then - break + local ender_distance = vector.distance(enderpos, player_pos) + if ender_distance <= 64 then + + -- Check if they are looking at us. + local look_dir_not_normalized = obj:get_look_dir() + local look_dir = vector.normalize(look_dir_not_normalized) + local player_eye_height = obj:get_properties().eye_height + + --skip player if they have no data - log it + if not player_eye_height then + minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!") + goto continue end - if look_pos.x-1enderpos.x and look_pos.y-2.89enderpos.y and look_pos.z-1enderpos.z then + + --calculate very quickly the exact location the player is looking + --within the distance between the two "heads" (player and enderman) + local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) + local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) + local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) + look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) + + --if looking in general head position, turn hostile + if vector.distance(look_pos, ender_eye_pos) <= 0.4 then self.provoked = "staring" self.attack = minetest.get_player_by_name(obj:get_player_name()) break - else + else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez if self.provoked == "staring" then self.provoked = "broke_contact" - end + end end - look_pos.x = look_pos.x + (.25 * look_dir.x) - look_pos.y = look_pos.y + (.25 * look_dir.y) - look_pos.z = look_pos.z + (.25 * look_dir.z) + + ::continue:: -- this is a sweep over statement, this can be used to continue even when errors occurred end end end From acd2b8e691c2fc5a19e288e4865fd8fd46487f58 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 21:29:52 -0400 Subject: [PATCH 070/164] Add line of sight calculations to the enderman --- mods/ENTITIES/mobs_mc/enderman.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index e3f2c8e48..cd8986aad 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -351,12 +351,13 @@ mobs:register_mob("mobs_mc:enderman", { --calculate very quickly the exact location the player is looking --within the distance between the two "heads" (player and enderman) local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) + local look_pos_base = look_pos local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) --if looking in general head position, turn hostile - if vector.distance(look_pos, ender_eye_pos) <= 0.4 then + if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then self.provoked = "staring" self.attack = minetest.get_player_by_name(obj:get_player_name()) break From 4a1faa44de4c107f9ed7e016e6d53789234249e9 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 21:59:51 -0400 Subject: [PATCH 071/164] Make unmounting a mob less of a jolt --- mods/ENTITIES/mcl_mobs/mount.lua | 8 ++++++-- mods/ENTITIES/mobs_mc/horse.lua | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index d8ce484c3..3d093a123 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -168,16 +168,20 @@ function mobs.detach(player, offset) mcl_player.player_set_animation(player, "stand" , 30) - local pos = player:get_pos() + --local pos = player:get_pos() - pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} + --pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} + player:add_velocity(vector.new(math.random(-5,5),math.random(3,6),math.random(-5,5))) --throw the rider off + + --[[ minetest.after(0.1, function(name, pos) local player = minetest.get_player_by_name(name) if player then player:set_pos(pos) end end, player:get_player_name(), pos) + ]]-- end diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 1c2df41f3..3da63831e 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -231,7 +231,6 @@ local horse = { temper_increase = 5 elseif (iname == mobs_mc.items.golden_apple) then temper_increase = 10 - -- Trying to ride elseif not self.driver then self.object:set_properties({stepheight = 1.1}) From 6aaf25bbc949c2aa5aefbfc70a6593073d0e48c4 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 22:02:52 -0400 Subject: [PATCH 072/164] Increase unmounting force --- mods/ENTITIES/mcl_mobs/mount.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index 3d093a123..9383ee067 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -172,7 +172,7 @@ function mobs.detach(player, offset) --pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} - player:add_velocity(vector.new(math.random(-5,5),math.random(3,6),math.random(-5,5))) --throw the rider off + player:add_velocity(vector.new(math.random(-6,6),math.random(5,8),math.random(-6,6))) --throw the rider off --[[ minetest.after(0.1, function(name, pos) From 7cecc71b91db42fbe11506c1a2720237a191816e Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 22:08:10 -0400 Subject: [PATCH 073/164] Make mobs not collide with objects to stop weird glitches --- mods/ENTITIES/mcl_mobs/api.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index d81d3766d..94d6340ea 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3418,6 +3418,7 @@ local mob_activate = function(self, staticdata, def, dtime) self.timer = 0 self.blinktimer = 0 self.blinkstatus = false + self.collide_with_objects = false -- check existing nametag if not self.nametag then From 6c4c22e3b9bd75c864a676adb8892b2af38b0478 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 6 Apr 2021 22:22:05 -0400 Subject: [PATCH 074/164] Adjust enderman projectile behavior, add snowballs to avoidance --- mods/ENTITIES/mobs_mc/enderman.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index cd8986aad..f93f131cb 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -295,7 +295,8 @@ mobs:register_mob("mobs_mc:enderman", { -- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE. -- Check for arrows and people nearby. local enderpos = self.object:get_pos() - local objs = minetest.get_objects_inside_radius(enderpos, 4) + enderpos.y = enderpos.y + 1.5 + local objs = minetest.get_objects_inside_radius(enderpos, 2) for n = 1, #objs do local obj = objs[n] if obj then @@ -307,7 +308,7 @@ mobs:register_mob("mobs_mc:enderman", { else local lua = obj:get_luaentity() if lua then - if lua.name == "mcl_bows:arrow_entity" then + if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then self:teleport(nil) end end From 6cdf7c98c2cc53e3a530fe99fbc8451742a54a3c Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Wed, 7 Apr 2021 00:55:57 -0400 Subject: [PATCH 075/164] Rework all mobs spawning - preprototype stage --- mods/ENTITIES/mcl_mobs/api.lua | 109 ++++++++++++++++++++- mods/ENTITIES/mobs_mc/agent.lua | 2 +- mods/ENTITIES/mobs_mc/bat.lua | 2 +- mods/ENTITIES/mobs_mc/blaze.lua | 4 +- mods/ENTITIES/mobs_mc/chicken.lua | 2 +- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 5 +- mods/ENTITIES/mobs_mc/creeper.lua | 7 +- mods/ENTITIES/mobs_mc/enderman.lua | 6 +- mods/ENTITIES/mobs_mc/ghast.lua | 2 +- mods/ENTITIES/mobs_mc/guardian_elder.lua | 2 +- mods/ENTITIES/mobs_mc/horse.lua | 4 +- mods/ENTITIES/mobs_mc/llama.lua | 2 +- mods/ENTITIES/mobs_mc/ocelot.lua | 8 +- mods/ENTITIES/mobs_mc/parrot.lua | 4 +- mods/ENTITIES/mobs_mc/pig.lua | 2 +- mods/ENTITIES/mobs_mc/polar_bear.lua | 2 +- mods/ENTITIES/mobs_mc/rabbit.lua | 6 +- mods/ENTITIES/mobs_mc/sheep.lua | 2 +- mods/ENTITIES/mobs_mc/shulker.lua | 2 +- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 6 +- mods/ENTITIES/mobs_mc/skeleton_wither.lua | 2 +- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 18 ++-- mods/ENTITIES/mobs_mc/spider.lua | 2 +- mods/ENTITIES/mobs_mc/squid.lua | 2 +- mods/ENTITIES/mobs_mc/villager.lua | 2 +- mods/ENTITIES/mobs_mc/villager_zombie.lua | 4 +- mods/ENTITIES/mobs_mc/witch.lua | 2 +- mods/ENTITIES/mobs_mc/wolf.lua | 2 +- mods/ENTITIES/mobs_mc/zombie.lua | 8 +- mods/ENTITIES/mobs_mc/zombiepig.lua | 6 +- 30 files changed, 171 insertions(+), 56 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 94d6340ea..49c8edeaf 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3562,7 +3562,7 @@ local mob_step = function(self, dtime) end -- mob plays random sound at times - if random(1, 100) == 1 then + if random(1, 70) == 1 then mob_sound(self, "random", true) end @@ -3925,7 +3925,35 @@ end end -- END mobs:register_mob function + + + + + + + + + + + +--BEGIN SPAWNING ALGORITHM + + + + + + + + + + + + + + + -- count how many mobs of one type are inside an area +--[[ local count_mobs = function(pos, mobtype) local num = 0 @@ -3969,7 +3997,7 @@ local count_mobs = function(pos, mobtype) return num end - +]]-- -- global functions @@ -3979,8 +4007,45 @@ function mobs:spawn_abm_check(pos, node, name) end -function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, - interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) +--[[ + Custom elements changed: +name: +the mobs name + +dimension: +"overworld" +"nether" +"end" + +types of spawning: +"air" +"water" +"ground" +"lava" + +what is aoc??? + +WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? + ]]-- + +function mobs:spawn_specific( + name, + dimension, + type_of_spawning, + min_light, + max_light, + interval, + chance, + aoc, + min_height, + max_height, + day_toggle, + on_spawn) + + + + + print(name, dump(nodes)) -- Do mobs spawn at all? if not mobs_spawn then @@ -4207,6 +4272,42 @@ function mobs:spawn(def) chance, active_object_count, min_height, max_height, day_toggle, on_spawn) end + + + + + + + + + + + + + + + +--END SPAWNING ALGORITHM + + + + + + + + + + + + + + + + + + + + -- register arrow for shoot attack function mobs:register_arrow(name, def) diff --git a/mods/ENTITIES/mobs_mc/agent.lua b/mods/ENTITIES/mobs_mc/agent.lua index 8fa7314cf..cc9910ee6 100644 --- a/mods/ENTITIES/mobs_mc/agent.lua +++ b/mods/ENTITIES/mobs_mc/agent.lua @@ -1,5 +1,5 @@ --################### ---################### AGENT +--################### AGENT - seemingly unused --################### local S = minetest.get_translator("mobs_mc") diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index 103579b67..b6825bbbf 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -64,7 +64,7 @@ else end -- Spawn on solid blocks at or below Sea level and the selected light level -mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) +mobs:spawn_specific("mobs_mc:bat", "overworld", "air", 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index fbffa7920..d56acdf38 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -1,6 +1,6 @@ -- daufinsyd -- My work is under the LGPL terms --- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models +-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez -- blaze.lua partial copy of mobs_mc/ghast.lua local S = minetest.get_translator("mobs_mc") @@ -128,7 +128,7 @@ mobs:register_mob("mobs_mc:blaze", { end, }) -mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:blaze", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Blaze fireball mobs:register_arrow("mobs_mc:blaze_fireball", { diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 325371e2b..397b6b8da 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -100,7 +100,7 @@ mobs:register_mob("mobs_mc:chicken", { }) --spawn -mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:chicken", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 005af2980..a094d6d35 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -145,8 +145,9 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning -mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:cow", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +--WARNING: THIS NEEDS A BIOME INTEGRATION +mobs:spawn_specific("mobs_mc:mooshroom", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 9ee9e9d24..f283fac18 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -39,6 +39,8 @@ mobs:register_mob("mobs_mc:creeper", { runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, attack_type = "explode", + --hssssssssssss + explosion_strength = 3, explosion_radius = 3.5, explosion_damage_radius = 3.5, @@ -139,6 +141,9 @@ mobs:register_mob("mobs_mc:creeper_charged", { pathfinding = 1, visual = "mesh", mesh = "mobs_mc_creeper.b3d", + + --BOOM + textures = { {"mobs_mc_creeper.png", "mobs_mc_creeper_charge.png"}, @@ -250,7 +255,7 @@ mobs:register_mob("mobs_mc:creeper_charged", { glow = 3, }) -mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:creeper", "overworld", "ground", 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index f93f131cb..ca3bc84ce 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -562,11 +562,11 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:enderman", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) -- Overworld spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:enderman", "overworld", "ground", 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn (rare) -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:enderman", "nether", "ground", 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 7aed9395e..e2f6b1369 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -75,7 +75,7 @@ mobs:register_mob("mobs_mc:ghast", { }) -mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:ghast", "nether", "air", 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- fireball (projectile) mobs:register_arrow("mobs_mc:fireball", { diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index a58a4a5b7..089f6e38f 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -106,7 +106,7 @@ mobs:register_mob("mobs_mc:guardian_elder", { view_range = 16, }) --- Spawning disabled due to size issues +-- Spawning disabled due to size issues <- what do you mean? -j4i -- TODO: Re-enable spawning -- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 3da63831e..00c292c1d 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -510,8 +510,8 @@ mobs:register_mob("mobs_mc:mule", mule) --=========================== --Spawn Function -mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:horse", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:donkey", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 36d020a65..0efb8e0ab 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -217,7 +217,7 @@ mobs:register_mob("mobs_mc:llama", { }) --spawn -mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:llama", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index eca74d3ba..3b5273185 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -152,6 +152,9 @@ mobs:register_mob("mobs_mc:cat", cat) local base_spawn_chance = 5000 -- Spawn ocelot +--they get the same as the llama because I'm trying to rework so much of this code right now -j4i +mobs:spawn_specific("mobs_mc:ocelot", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +--[[ mobs:spawn({ name = "mobs_mc:ocelot", nodes = mobs_mc.spawn.jungle, @@ -163,8 +166,8 @@ mobs:spawn({ min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level max_height = mobs_mc.spawn_height.overworld_max, on_spawn = function(self, pos) - --[[ Note: Minecraft has a 1/3 spawn failure rate. - In this mod it is emulated by reducing the spawn rate accordingly (see above). ]] + Note: Minecraft has a 1/3 spawn failure rate. + In this mod it is emulated by reducing the spawn rate accordingly (see above). -- 1/7 chance to spawn 2 ocelot kittens if pr:next(1,7) == 1 then @@ -207,6 +210,7 @@ mobs:spawn({ end end, }) +]]-- -- spawn eggs -- FIXME: The spawn icon shows a cat texture, not an ocelot texture diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 407cb4466..c67263fb9 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -90,8 +90,8 @@ mobs:register_mob("mobs_mc:parrot", { }) --- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* -mobs:spawn_specific("mobs_mc:parrot", {"mcl_core:jungletree", "mcl_core:jungleleaves"}, {"air"}, 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) +-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i +mobs:spawn_specific("mobs_mc:parrot","overworld", "air", 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 38700b6ca..143fcb495 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -182,7 +182,7 @@ mobs:register_mob("mobs_mc:pig", { end, }) -mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:pig", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 459ca29b4..745c13a26 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -67,7 +67,7 @@ mobs:register_mob("mobs_mc:polar_bear", { }) -mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:polar_bear", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index e167649f6..f09a70584 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -107,8 +107,11 @@ end mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) -- Mob spawning rules. --- Different skins depending on spawn location +-- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out +mobs:spawn_specific("mobs_mc:rabbit", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) + +--[[ local spawn = { name = "mobs_mc:rabbit", neighbors = {"air"}, @@ -165,6 +168,7 @@ spawn_grass.on_spawn = function(self, pos) self.object:set_properties({textures = self.base_texture}) end mobs:spawn(spawn_grass) +]]-- -- Spawn egg mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 84650b4dd..b3400ab5f 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -303,7 +303,7 @@ mobs:register_mob("mobs_mc:sheep", { end end, }) -mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:sheep", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index faaf2ac40..583c5eed1 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -81,4 +81,4 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) -mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:shulker", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index cb12e905d..84e51c517 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -139,13 +139,13 @@ table.insert(stray.drops, { mobs:register_mob("mobs_mc:stray", stray) -- Overworld spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:skeleton", "overworld", "ground", 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:skeleton", "nether", "ground", 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Stray spawn -- TODO: Spawn directly under the sky -mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:stray", "overworld", "ground", 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index e4a1f86fc..d9de90d84 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -94,7 +94,7 @@ mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn -mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:witherskeleton", "nether", "ground", 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index fd1f92bb4..2f9e8c8a9 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -157,9 +157,9 @@ mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) local smin = mobs_mc.spawn_height.overworld_min local smax = mobs_mc.spawn_height.water - 23 -mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_tiny", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_small", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_big", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) -- Magma cube local magma_cube_big = { @@ -272,13 +272,13 @@ mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) local mmin = mobs_mc.spawn_height.nether_min local mmax = mobs_mc.spawn_height.nether_max -mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_tiny", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_small", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_big", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) +--mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) +--mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) +--mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 0bb03a9c7..1361e6a3a 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -87,7 +87,7 @@ cave_spider.sounds.base_pitch = 1.25 mobs:register_mob("mobs_mc:cave_spider", cave_spider) -mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:spider", "overworld", "ground", 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 1877a2104..2dbb7c557 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -62,7 +62,7 @@ mobs:register_mob("mobs_mc:squid", { local water = mobs_mc.spawn_height.water --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height -mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) +mobs:spawn_specific("mobs_mc:squid", "overworld", "water", 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) -- spawn eggs mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 68644266f..0b53d8015 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1074,7 +1074,7 @@ mobs:register_mob("mobs_mc:villager", { -mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index 09539fa76..bcede2183 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -146,8 +146,8 @@ mobs:register_mob("mobs_mc:villager_zombie", { harmed_by_heal = true, }) -mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index 383cbd36f..f9f9b8d1f 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:potion_arrow", { end }) --- TODO: Spawn when witch works properly +-- TODO: Spawn when witch works properly <- eventually -j4i --mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index fe3031895..953c2df72 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -232,6 +232,6 @@ end mobs:register_mob("mobs_mc:dog", dog) -- Spawn -mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:wolf", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index df9727d34..64f99d34d 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -135,11 +135,11 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning -mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:zombie", "overworld", "ground", 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:husk", "overworld", "ground", 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_husk", "overworld", "ground", 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Spawn eggs mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index 8c29a4bff..e996425c8 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -111,12 +111,12 @@ baby_pigman.child = 1 mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) -- Regular spawning in the Nether -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:baby_pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Spawning in Nether portals in the Overworld -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +--mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0) From ec6eb517262793c7f0d589be5406b9a7071e5bc1 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Wed, 7 Apr 2021 02:39:15 -0400 Subject: [PATCH 076/164] Massively overhaul spawning algorithm for mobs --- mods/ENTITIES/mcl_mobs/api.lua | 156 +++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 6 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 49c8edeaf..d85633421 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -4026,7 +4026,14 @@ types of spawning: what is aoc??? WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? - ]]-- +]]-- + +--this is where all of the spawning information is kept +local spawn_dictionary = { + ["overworld"] = {}, + ["nether"] = {}, + ["end"] = {} +} function mobs:spawn_specific( name, @@ -4043,10 +4050,6 @@ function mobs:spawn_specific( on_spawn) - - - print(name, dump(nodes)) - -- Do mobs spawn at all? if not mobs_spawn then return @@ -4067,7 +4070,6 @@ function mobs:spawn_specific( minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) - end local spawn_action @@ -4232,6 +4234,24 @@ function mobs:spawn_specific( spawn_action(pos, node, active_object_count, active_object_count_wider, name) end + + --load information into the spawn dictionary + local key = #spawn_dictionary[dimension] + 1 + + spawn_dictionary[dimension][key] = {} + spawn_dictionary[dimension][key]["name"] = name + spawn_dictionary[dimension][key]["type"] = type_of_spawning + spawn_dictionary[dimension][key]["min_light"] = min_light + spawn_dictionary[dimension][key]["max_light"] = max_light + spawn_dictionary[dimension][key]["interval"] = interval + spawn_dictionary[dimension][key]["chance"] = chance + spawn_dictionary[dimension][key]["aoc"] = aoc + spawn_dictionary[dimension][key]["min_height"] = min_height + spawn_dictionary[dimension][key]["max_height"] = max_height + spawn_dictionary[dimension][key]["day_toggle"] = day_toggle + spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action + + --[[ minetest.register_abm({ label = name .. " spawning", nodenames = nodes, @@ -4241,18 +4261,24 @@ function mobs:spawn_specific( catch_up = false, action = spawn_abm_action, }) + ]]-- end -- compatibility with older mob registration +-- we're going to forget about this for now -j4i +--[[ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, chance, active_object_count, -31000, max_height, day_toggle) end +]]-- +--I'm not sure what this does but disabling it doesn't cause a crash -j4i -- MarkBu's spawn function +--[[ function mobs:spawn(def) local name = def.name @@ -4271,9 +4297,127 @@ function mobs:spawn(def) mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, day_toggle, on_spawn) end +]]-- +local axis +--inner and outer part of square donut radius +local inner = 1 +local outer = 70 +local int = {-1,1} +local position_calculation = function(pos) + pos = vector.floor(pos) + + --this is used to determine the axis buffer from the player + axis = math.random(0,1) + + --cast towards the direction + if axis == 0 then --x + pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)] + pos.z = pos.z + math.random(-outer,outer) + else --z + pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)] + pos.x = pos.x + math.random(-outer,outer) + end + return(pos) +end + +--[[ +local decypher_limits_dictionary = { + ["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max}, + ["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max}, + ["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max} +} +]]-- + +local function decypher_limits(posy) + --local min_max_table = decypher_limits_dictionary[dimension] + --return min_max_table[1],min_max_table[2] + posy = math.floor(posy) + return posy - 32, posy + 32 +end + + +--todo mob limiting +--MAIN LOOP +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 15 then + timer = 0 + for _,player in ipairs(minetest.get_connected_players()) do + for i = 1,math.random(5) do + local player_pos = player:get_pos() + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + local min,max = decypher_limits(player_pos.y) + + local goal_pos = position_calculation(player_pos) + + + local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] + + if not mob_def then --to catch a crazy error if it ever happens + minetest.log("error", "WARNING!! mob spawning attempted to index a NIL mob!") + goto continue + end + + if mob_def.type == "ground" then + + local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + spawning_position.y = spawning_position.y + 1 + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + elseif mob_def.type == "air" then + local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + elseif mob_def.type == "water" then + local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + --elseif mob_def.type == "lava" then + --implement later + end + --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) + + + ::continue:: --this is a safety catch + end + end + end +end) From b2c09c8ba058aaa7b9f4a2295925f1cc11b62fb6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 09:17:13 +0200 Subject: [PATCH 077/164] Add gateway portals --- mods/ITEMS/mcl_portals/portal_gateway.lua | 70 +++++++++++++++++- mods/MAPGEN/mcl_structures/init.lua | 4 +- .../mcl_structures_end_exit_portal.mts | Bin 193 -> 222 bytes .../mcl_structures_end_exit_portal_open.mts | Bin 222 -> 0 bytes 4 files changed, 71 insertions(+), 3 deletions(-) delete mode 100644 mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal_open.mts diff --git a/mods/ITEMS/mcl_portals/portal_gateway.lua b/mods/ITEMS/mcl_portals/portal_gateway.lua index cae6fce43..6d491433c 100644 --- a/mods/ITEMS/mcl_portals/portal_gateway.lua +++ b/mods/ITEMS/mcl_portals/portal_gateway.lua @@ -24,12 +24,21 @@ local gateway_positions = { {x = 91, y = -26925, z = -29}, } +local function spawn_gateway_portal(pos, dest_str) + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts" + return mcl_structures.place_schematic(vector.add(pos, vector.new(-1, -2, -1)), path, "0", nil, true, dest_str and function() + minetest.get_voxel_manip():read_from_map(pos, pos) + minetest.get_meta(pos):set_string("mcl_portals:gateway_destination", dest_str) + print(dest_str) + end) +end + function mcl_portals.spawn_gateway_portal() local id = storage:get_int("gateway_last_id") + 1 local pos = gateway_positions[id] if not pos then return end storage:set_int("gateway_last_id", id) - mcl_structures.call_struct(vector.add(pos, vector.new(-1, -2, -1)), "end_gateway_portal") + spawn_gateway_portal(pos) end local gateway_def = table.copy(minetest.registered_nodes["mcl_portals:portal_end"]) @@ -43,3 +52,62 @@ gateway_def.node_box = nil gateway_def.walkable = true gateway_def.tiles[3] = nil minetest.register_node("mcl_portals:portal_gateway", gateway_def) + +local function find_destination_pos(minp, maxp) + for y = maxp.y, minp.y, -1 do + for x = maxp.x, minp.x, -1 do + for z = maxp.z, minp.z, -1 do + local pos = vector.new(x, y, z) + local nn = minetest.get_node(pos).name + if nn ~= "ignore" and nn ~= "mcl_portals:portal_gateway" and nn ~= "mcl_core:bedrock" then + local def = minetest.registered_nodes[nn] + if def and def.walkable then + return vector.add(pos, vector.new(0, 1.5, 0)) + end + end + end + end + end +end + +local preparing = {} + +local function teleport(pos, obj) + local meta = minetest.get_meta(pos) + local dest_portal + local dest_str = meta:get_string("mcl_portals:gateway_destination") + local pos_str = minetest.pos_to_string(pos) + if dest_str == "" then + dest_portal = vector.multiply(vector.direction(vector.new(0, pos.y, 0), pos), math.random(768, 1024)) + dest_portal.y = -26970 + spawn_gateway_portal(dest_portal, pos_str) + meta:set_string("mcl_portals:gateway_destination", minetest.pos_to_string(dest_portal)) + else + dest_portal = minetest.string_to_pos(dest_str) + end + local minp = vector.subtract(dest_portal, vector.new(5, 40, 5)) + local maxp = vector.add(dest_portal, vector.new(5, 10, 5)) + preparing[pos_str] = true + minetest.emerge_area(minp, maxp, function() + if obj:is_player() or obj:get_luaentity() then + obj:set_pos(find_destination_pos(minp, maxp) or vector.add(dest_portal, vector.new(0, 3.5, 0))) + end + preparing[pos_str] = false + end) +end + +minetest.register_abm({ + label = "End gateway portal teleportation", + nodenames = {"mcl_portals:portal_gateway"}, + interval = 0.1, + chance = 1, + action = function(pos) + if preparing[minetest.pos_to_string(pos)] then return end + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do + if obj:get_hp() > 0 then + teleport(pos, obj) + return + end + end + end, +}) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 00efeca14..4ba369e01 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -318,11 +318,11 @@ end mcl_structures.generate_end_exit_portal = function(pos, rot) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" - return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) + return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true) end mcl_structures.generate_end_exit_portal_open = function(pos, rot) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal_open.mts" + local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts index 30d145bd7fdc822259191c918696b74769628d72..bc24f800a6de0e4265fdbe08808c9720061b8490 100644 GIT binary patch delta 161 zcmX@ec#l!oHze4XfrWvcft7*19t0RzCkh(~733F{B<2)bLFo9@yp)NyQu%u)-Q_x< zz|k6fyLf*1{0PUO)hWr(V>%M#|4o_Hb;dWRuj`fdDjvh*7QKNMy&uns)}uDrD>;&p_i$xlx^$sU)L+^RXm2rEqVhjdOw~yd0eDy%Dic&uPyg1I8yyH zO~3W?FE<7=#tl0-et5I*%~5yCuvOaK+coXSeq%5FGkVh6GdgztnH3o08erZh5UT|M Dl|EWe From c451866a36a4cb6c58928dbcd1379a62500484df Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 09:56:00 +0200 Subject: [PATCH 078/164] Fix #1426 --- mods/ITEMS/mcl_sponges/init.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index b832c01c6..75a99b0f1 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -94,6 +94,35 @@ minetest.register_node("mcl_sponges:sponge", { _mcl_hardness = 0.6, }) +function place_wet_sponge(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if placer and not placer: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, placer, itemstack) or itemstack + end + end + + local name = placer:get_player_name() + + if minetest.is_protected(pointed_thing.above, name) then + return itemstack + end + + if mcl_worlds.pos_to_dimension(pointed_thing.above) == "nether" then + minetest.item_place_node(ItemStack("mcl_sponges:sponge"), placer, pointed_thing) + if not minetest.is_creative_enabled(name) then + itemstack:take_item() + end + return itemstack + end + + return minetest.item_place_node(itemstack, placer, pointed_thing) +end + minetest.register_node("mcl_sponges:sponge_wet", { description = S("Waterlogged Sponge"), _tt_help = S("Can be dried in furnace"), @@ -108,6 +137,7 @@ minetest.register_node("mcl_sponges:sponge_wet", { stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), groups = {handy=1, hoey=1, building_block=1}, + on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, }) @@ -127,6 +157,7 @@ if minetest.get_modpath("mclx_core") then stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), groups = {handy=1, building_block=1}, + on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, }) From 6e2a7c8a7eda6ddca3af7bb23efa13233c7764c7 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 13:47:48 +0200 Subject: [PATCH 079/164] Make gateway enderpearl teleports easier --- mods/ITEMS/mcl_portals/portal_gateway.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mods/ITEMS/mcl_portals/portal_gateway.lua b/mods/ITEMS/mcl_portals/portal_gateway.lua index fd455ee76..c738da1a4 100644 --- a/mods/ITEMS/mcl_portals/portal_gateway.lua +++ b/mods/ITEMS/mcl_portals/portal_gateway.lua @@ -105,6 +105,11 @@ minetest.register_abm({ if preparing[minetest.pos_to_string(pos)] then return end for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do if obj:get_hp() > 0 then + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_throwing:ender_pearl" then + obj:remove() + obj = luaentity._thrower + end teleport(pos, obj) return end From f664a87dac0f64f8fed1847fbbf1c39da5873efb Mon Sep 17 00:00:00 2001 From: TechDudie Date: Mon, 5 Apr 2021 18:45:02 +0000 Subject: [PATCH 080/164] Update 'mods/ENTITIES/mobs_mc/creeper.lua' --- mods/ENTITIES/mobs_mc/creeper.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index f283fac18..ce07e4146 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -200,7 +200,6 @@ mobs:register_mob("mobs_mc:creeper_charged", { self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) - self.object:remove() end end end, From db9e8d23d96bcef23b94b84c4193bc0b523d9d7d Mon Sep 17 00:00:00 2001 From: TechDudie Date: Mon, 5 Apr 2021 18:51:35 +0000 Subject: [PATCH 081/164] Update 'mods/ENTITIES/mobs_mc/creeper.lua' --- mods/ENTITIES/mobs_mc/creeper.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index ce07e4146..f1f0a3ef6 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -78,7 +78,6 @@ mobs:register_mob("mobs_mc:creeper", { self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) - self.object:remove() end end end, From 61cef21cd11f5c187eae908ce57a774c954dbfb1 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Wed, 7 Apr 2021 20:39:49 +0800 Subject: [PATCH 082/164] Add right-to-left statbars, for hunger and air. --- mods/HUD/hudbars/API.md | 5 +++-- mods/HUD/hudbars/init.lua | 33 +++++++++++++++++++++------------ mods/HUD/mcl_hbarmor/init.lua | 2 +- mods/PLAYER/mcl_hunger/init.lua | 6 +++--- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/mods/HUD/hudbars/API.md b/mods/HUD/hudbars/API.md index ca6144ad1..ee112eceb 100644 --- a/mods/HUD/hudbars/API.md +++ b/mods/HUD/hudbars/API.md @@ -17,7 +17,7 @@ To give you a *very* brief overview over this API, here is the basic workflow on In order to use this API, you should be aware of a few basic rules in order to understand it: * A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%. -* The current value must always be equal to or smaller then the maximum +* The current value must always be equal to or smaller then the maximum * Both current value and maximum must not be smaller than 0 * Both current value and maximum must be real numbers. So no NaN, infinity, etc. * The HUD bar will be hidden if the maximum equals 0. This is intentional. @@ -45,7 +45,7 @@ a vertical gradient. ### Icon A 16×16 image shown left of the HUD bar. This is optional. -### `hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)` +### `hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)` This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden and unhidden on a per-player basis. Note this does not yet display the HUD bar. @@ -63,6 +63,7 @@ for more information. * `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section). * `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used. * `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode. +* `direction`: Either left to right(0), or right to left(1). * `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value * `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value * `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it. diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index e1ff3f5f1..6f90aa03d 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -124,7 +124,7 @@ function hb.get_hudbar_position_index(identifier) end end -function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config) +function hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config) minetest.log("action", "hb.register_hudbar: "..tostring(identifier)) local hudtable = {} local pos, offset @@ -133,30 +133,33 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta if hb.settings.alignment_pattern == "stack_up" then pos = hb.settings.pos_left offset = { - x = hb.settings.start_offset_left.x, + x = direction == 0 and hb.settings.start_offset_left.x or -hb.settings.start_offset_right.x, y = hb.settings.start_offset_left.y - hb.settings.vmargin * index } elseif hb.settings.alignment_pattern == "stack_down" then pos = hb.settings.pos_left offset = { - x = hb.settings.start_offset_left.x, + x = direction == 0 and hb.settings.start_offset_right.x or -hb.settings.start_offset_left.x, y = hb.settings.start_offset_left.y + hb.settings.vmargin * index } - else + else -- zigzag if index % 2 == 0 then pos = hb.settings.pos_left offset = { - x = hb.settings.start_offset_left.x, + -- -(24+18) = -42. using linear eq, -42 = -258m - 24. + x = direction == 0 and hb.settings.start_offset_left.x or (-42+24)/(-258.0) * hb.settings.start_offset_left.x - 24, y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2) } else pos = hb.settings.pos_right offset = { - x = hb.settings.start_offset_right.x, + -- 24*10+30 - 24 = 234. using linear eq, 234 = 16m - 24. + x = direction == 0 and hb.settings.start_offset_right.x or (234+24)/(16) * hb.settings.start_offset_right.x - 24, y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2) } end end + if format_string == nil then format_string = N("@1: @2/@3") end @@ -181,6 +184,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta local state = {} local name = player:get_player_name() local bgscale, iconscale, text, barnumber, bgiconnumber + if start_max == 0 or start_hidden then bgscale = { x=0, y=0 } else @@ -197,6 +201,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta bgiconnumber = hb.settings.statbar_length text = make_label(format_string, format_string_config, label, start_value, start_max) end + if hb.settings.bar_type == "progress_bar" then ids.bg = player:hud_add({ hud_elem_type = "image", @@ -219,6 +224,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta }) end end + local bar_image, bgicon, bar_size if hb.settings.bar_type == "progress_bar" then bar_image = textures.bar @@ -234,10 +240,12 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta bgicon = textures.bgicon bar_size = {x=24, y=24} end + local text2 if hb.settings.bar_type == "statbar_modern" then text2 = bgicon end + ids.bar = player:hud_add({ hud_elem_type = "statbar", position = pos, @@ -247,7 +255,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta item = bgiconnumber, alignment = {x=-1,y=-1}, offset = offset, - direction = 0, + direction = direction, size = bar_size, z_index = 1, }) @@ -258,7 +266,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta text = text, alignment = {x=1,y=1}, number = text_color, - direction = 0, + direction = direction, offset = { x = offset.x + 2, y = offset.y - 1}, z_index = 2, }) @@ -298,7 +306,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta hudtable.default_start_max = default_start_max hb.hudbars_count= hb.hudbars_count + 1 - + hb.hudtables[identifier] = hudtable end @@ -359,6 +367,7 @@ function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon if new_text_color ~= nil then player:hud_change(hudtable.hudids[name].text, "number", new_text_color) end + else if new_icon ~= nil and hudtable.hudids[name].bar ~= nil then player:hud_change(hudtable.hudids[name].bar, "text", new_icon) @@ -474,8 +483,8 @@ end --register built-in HUD bars if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then - hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false) - hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 10, 10, true) + hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 0, 20, 20, false) + hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 1, 10, 10, true) end local function hide_builtin(player) @@ -520,7 +529,7 @@ local function update_hud(player, has_damage) --air local breath_max = player:get_properties().breath_max local breath = player:get_breath() - + if breath >= breath_max and hb.settings.autohide_breath == true then hb.hide_hudbar(player, "breath") else diff --git a/mods/HUD/mcl_hbarmor/init.lua b/mods/HUD/mcl_hbarmor/init.lua index 4434f5dad..89b2db7a8 100644 --- a/mods/HUD/mcl_hbarmor/init.lua +++ b/mods/HUD/mcl_hbarmor/init.lua @@ -57,7 +57,7 @@ local function custom_hud(player) end --register and define armor HUD bar -hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 20, mcl_hbarmor.autohide) +hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 0, 20, mcl_hbarmor.autohide) function mcl_hbarmor.get_armor(player) if not player or not armor.def then diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 5ae45591c..b640dfdc9 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -89,10 +89,10 @@ function mcl_hunger.update_exhaustion_hud(player, exhaustion) end -- register saturation hudbar -hb.register_hudbar("hunger", 0xFFFFFF, S("Food"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 20, 20, false) +hb.register_hudbar("hunger", 0xFFFFFF, S("Food"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 1, 20, 20, false) if mcl_hunger.debug then - hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, mcl_hunger.SATURATION_INIT, 200, false, S("%s: %.1f/%d")) - hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 0, mcl_hunger.EXHAUST_LVL, false, S("%s: %d/%d")) + hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, 1, mcl_hunger.SATURATION_INIT, 200, false, S("%s: %.1f/%d")) + hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 1, 0, mcl_hunger.EXHAUST_LVL, false, S("%s: %d/%d")) end minetest.register_on_joinplayer(function(player) From 3449b3eb7c9dbb49ca4ecfc207d5038091ed4197 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 16:47:14 +0200 Subject: [PATCH 083/164] Improve bossbars API --- mods/HUD/mcl_bossbars/init.lua | 57 +++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 38dbbe376..6a3352338 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -1,6 +1,7 @@ mcl_bossbars = { bars = {}, huds = {}, + static = {}, colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"}, } @@ -27,21 +28,52 @@ function mcl_bossbars.recalculate_colors() mcl_bossbars.colors_sorted = sorted end -function mcl_bossbars.update_bar(player, text, color, percentage) +local function get_color_info(color, percentage) local cdef = mcl_bossbars.colors_sorted[color] - table.insert(mcl_bossbars.bars[player:get_player_name()], {color = cdef.hex, text = text, image = string.format(cdef.image, percentage)}) + return cdef.hex, string.format(cdef.image, percentage) +end + +local last_id = 0 + +function mcl_bossbars.add_bar(player, def) + local name = player:get_player_name() + local bar = {text = def.text} + bar.color, bar.image = get_color_info(def.color, def.percentage) + table.insert(mcl_bossbars.bars[name], bar) + if not def.dynamic then + bar.raw_color = def.color + bar.id = last_id + 1 + last_id = bar.id + mcl_bossbars.static[bar.id] = bar + return id + end +end + +function mcl_bossbars.remove_bar(id) + mcl_bossbars.static[id].bar.static = false + mcl_bossbars.static[id] = nil +end + +function mcl_bossbars.update_bar(id, def) + local old = mcl_bossbars.static[id] + old.color = get_color_info(def.color or old.raw_color, def.percentage or old.percentage) + old.text = def.text or old.text end function mcl_bossbars.update_boss(luaentity, name, color) local object = luaentity.object - local text = luaentity.nametag - if not text or text == "" then - text = name + local bardef = { + text = luaentity.nametag, + percentage = math.floor(luaentity.health / luaentity.hp_max * 100), + color = color, + dynamic = true, + } + if not bardef.text or bardef.text == "" then + bardef.text = name end - local percentage = math.floor(luaentity.health / luaentity.hp_max * 100) for _, obj in pairs(minetest.get_objects_inside_radius(object:get_pos(), 128)) do if obj:is_player() then - mcl_bossbars.update_bar(obj, text, color, percentage) + mcl_bossbars.add_bar(obj, bardef) end end end @@ -55,6 +87,11 @@ end) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() mcl_bossbars.huds[name] = nil + for _, bar in pairs(mcl_bossbars.bars[name]) do + if bar.id then + mcl_bossbars.static[bar.id] = nil + end + end mcl_bossbars.bars[name] = nil end) @@ -64,12 +101,17 @@ minetest.register_globalstep(function() local bars = mcl_bossbars.bars[name] local huds = mcl_bossbars.huds[name] local huds_new = {} + local bars_new = {} local i = 0 while #huds > 0 or #bars > 0 do local bar = table.remove(bars, 1) local hud = table.remove(huds, 1) + if bar and bar.id then + table.insert(bars_new, bar) + end + if bar and not hud then hud = { color = bar.color, @@ -118,6 +160,7 @@ minetest.register_globalstep(function() end mcl_bossbars.huds[name] = huds_new + mcl_bossbars.bars[name] = bars_new end end) From f282cd0c4dacb56c2b578d4d6d26e0214602fe5c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 16:56:21 +0200 Subject: [PATCH 084/164] Allow bossbars to be grouped --- mods/HUD/mcl_bossbars/init.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 6a3352338..504fc3aef 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -37,9 +37,23 @@ local last_id = 0 function mcl_bossbars.add_bar(player, def) local name = player:get_player_name() + local bars = mcl_bossbars.bars[name] local bar = {text = def.text} bar.color, bar.image = get_color_info(def.color, def.percentage) - table.insert(mcl_bossbars.bars[name], bar) + if def.dynamic then + for _, other in pairs(bars) do + if not other.id and other.color == bar.color and (other.original_text or other.text) == bar.text and other.image == bar.image then + if not other.count then + other.count = 1 + other.original_text = other.text + end + other.count = other.count + 1 + other.text = other.original_text .. " x" .. other.count + return + end + end + end + table.insert(bars, bar) if not def.dynamic then bar.raw_color = def.color bar.id = last_id + 1 From 567f157541973b3034e44ae1bbb730177b652539 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 17:02:03 +0200 Subject: [PATCH 085/164] Add a bossbar limit setting --- mods/HUD/mcl_bossbars/init.lua | 43 ++++++++++++++++++---------------- settingtypes.txt | 3 +++ 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 504fc3aef..3ba0bd755 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -3,6 +3,7 @@ mcl_bossbars = { huds = {}, static = {}, colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"}, + max_bars = tonumber(minetest.settings:get("max_bossbars")) or 6 } function mcl_bossbars.recalculate_colors() @@ -127,27 +128,29 @@ minetest.register_globalstep(function() end if bar and not hud then - hud = { - color = bar.color, - image = bar.image, - text = bar.text, - text_id = player:hud_add({ - hud_elem_type = "text", + if i < mcl_bossbars.max_bars then + hud = { + color = bar.color, + image = bar.image, text = bar.text, - number = bar.color, - position = {x = 0.5, y = 0}, - alignment = {x = 0, y = 1}, - offset = {x = 0, y = i * 40}, - }), - image_id = player:hud_add({ - hud_elem_type = "image", - text = bar.image, - position = {x = 0.5, y = 0}, - alignment = {x = 0, y = 1}, - offset = {x = 0, y = i * 40 + 25}, - scale = {x = 3, y = 3}, - }), - } + text_id = player:hud_add({ + hud_elem_type = "text", + text = bar.text, + number = bar.color, + position = {x = 0.5, y = 0}, + alignment = {x = 0, y = 1}, + offset = {x = 0, y = i * 40}, + }), + image_id = player:hud_add({ + hud_elem_type = "image", + text = bar.image, + position = {x = 0.5, y = 0}, + alignment = {x = 0, y = 1}, + offset = {x = 0, y = i * 40 + 25}, + scale = {x = 3, y = 3}, + }), + } + end elseif hud and not bar then player:hud_remove(hud.text_id) player:hud_remove(hud.image_id) diff --git a/settingtypes.txt b/settingtypes.txt index 67e686d1e..4ba6034eb 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -97,6 +97,9 @@ animated_chests (Animated chests) bool true # Whether to preview the player in inventory in 3D (requires Minetest 5.4) 3d_player_preview (3D Player preview) bool true +# The maximum number of boss bars to simultaniously display on the screen +max_bossbars (Maximum Boss bars) int 6 + [Experimental] # Whether ice is translucent. If disabled, ice is fully opaque. # From 6a1a634cba4e0530a4cb72cf319f203f4a770d7f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 17:20:56 +0200 Subject: [PATCH 086/164] Revert "Merge pull request 'Massively overhaul spawning algorithm for mobs' (#1487) from jordan4ibanez/MineClone2-MobTweaks:master into master" This reverts commit 4f2a6b2db001b98abd99e32e531aedc243118161, reversing changes made to 0970981252e32901b18ce00fa7498507818c0245. --- mods/ENTITIES/mcl_mobs/api.lua | 255 +-------------------- mods/ENTITIES/mobs_mc/agent.lua | 2 +- mods/ENTITIES/mobs_mc/bat.lua | 2 +- mods/ENTITIES/mobs_mc/blaze.lua | 4 +- mods/ENTITIES/mobs_mc/chicken.lua | 2 +- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 5 +- mods/ENTITIES/mobs_mc/creeper.lua | 7 +- mods/ENTITIES/mobs_mc/enderman.lua | 6 +- mods/ENTITIES/mobs_mc/ghast.lua | 2 +- mods/ENTITIES/mobs_mc/guardian_elder.lua | 2 +- mods/ENTITIES/mobs_mc/horse.lua | 4 +- mods/ENTITIES/mobs_mc/llama.lua | 2 +- mods/ENTITIES/mobs_mc/ocelot.lua | 8 +- mods/ENTITIES/mobs_mc/parrot.lua | 4 +- mods/ENTITIES/mobs_mc/pig.lua | 2 +- mods/ENTITIES/mobs_mc/polar_bear.lua | 2 +- mods/ENTITIES/mobs_mc/rabbit.lua | 6 +- mods/ENTITIES/mobs_mc/sheep.lua | 2 +- mods/ENTITIES/mobs_mc/shulker.lua | 2 +- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 6 +- mods/ENTITIES/mobs_mc/skeleton_wither.lua | 2 +- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 18 +- mods/ENTITIES/mobs_mc/spider.lua | 2 +- mods/ENTITIES/mobs_mc/squid.lua | 2 +- mods/ENTITIES/mobs_mc/villager.lua | 2 +- mods/ENTITIES/mobs_mc/villager_zombie.lua | 4 +- mods/ENTITIES/mobs_mc/witch.lua | 2 +- mods/ENTITIES/mobs_mc/wolf.lua | 2 +- mods/ENTITIES/mobs_mc/zombie.lua | 8 +- mods/ENTITIES/mobs_mc/zombiepig.lua | 6 +- 30 files changed, 57 insertions(+), 316 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index d85633421..94d6340ea 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3562,7 +3562,7 @@ local mob_step = function(self, dtime) end -- mob plays random sound at times - if random(1, 70) == 1 then + if random(1, 100) == 1 then mob_sound(self, "random", true) end @@ -3925,35 +3925,7 @@ end end -- END mobs:register_mob function - - - - - - - - - - - ---BEGIN SPAWNING ALGORITHM - - - - - - - - - - - - - - - -- count how many mobs of one type are inside an area ---[[ local count_mobs = function(pos, mobtype) local num = 0 @@ -3997,7 +3969,7 @@ local count_mobs = function(pos, mobtype) return num end -]]-- + -- global functions @@ -4007,49 +3979,9 @@ function mobs:spawn_abm_check(pos, node, name) end ---[[ - Custom elements changed: -name: -the mobs name +function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, + interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) -dimension: -"overworld" -"nether" -"end" - -types of spawning: -"air" -"water" -"ground" -"lava" - -what is aoc??? - -WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? -]]-- - ---this is where all of the spawning information is kept -local spawn_dictionary = { - ["overworld"] = {}, - ["nether"] = {}, - ["end"] = {} -} - -function mobs:spawn_specific( - name, - dimension, - type_of_spawning, - min_light, - max_light, - interval, - chance, - aoc, - min_height, - max_height, - day_toggle, - on_spawn) - - -- Do mobs spawn at all? if not mobs_spawn then return @@ -4070,6 +4002,7 @@ function mobs:spawn_specific( minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) + end local spawn_action @@ -4234,24 +4167,6 @@ function mobs:spawn_specific( spawn_action(pos, node, active_object_count, active_object_count_wider, name) end - - --load information into the spawn dictionary - local key = #spawn_dictionary[dimension] + 1 - - spawn_dictionary[dimension][key] = {} - spawn_dictionary[dimension][key]["name"] = name - spawn_dictionary[dimension][key]["type"] = type_of_spawning - spawn_dictionary[dimension][key]["min_light"] = min_light - spawn_dictionary[dimension][key]["max_light"] = max_light - spawn_dictionary[dimension][key]["interval"] = interval - spawn_dictionary[dimension][key]["chance"] = chance - spawn_dictionary[dimension][key]["aoc"] = aoc - spawn_dictionary[dimension][key]["min_height"] = min_height - spawn_dictionary[dimension][key]["max_height"] = max_height - spawn_dictionary[dimension][key]["day_toggle"] = day_toggle - spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action - - --[[ minetest.register_abm({ label = name .. " spawning", nodenames = nodes, @@ -4261,24 +4176,18 @@ function mobs:spawn_specific( catch_up = false, action = spawn_abm_action, }) - ]]-- end -- compatibility with older mob registration --- we're going to forget about this for now -j4i ---[[ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, chance, active_object_count, -31000, max_height, day_toggle) end -]]-- ---I'm not sure what this does but disabling it doesn't cause a crash -j4i -- MarkBu's spawn function ---[[ function mobs:spawn(def) local name = def.name @@ -4297,160 +4206,6 @@ function mobs:spawn(def) mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, day_toggle, on_spawn) end -]]-- - - -local axis ---inner and outer part of square donut radius -local inner = 1 -local outer = 70 -local int = {-1,1} -local position_calculation = function(pos) - - pos = vector.floor(pos) - - --this is used to determine the axis buffer from the player - axis = math.random(0,1) - - --cast towards the direction - if axis == 0 then --x - pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)] - pos.z = pos.z + math.random(-outer,outer) - else --z - pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)] - pos.x = pos.x + math.random(-outer,outer) - end - return(pos) -end - ---[[ -local decypher_limits_dictionary = { - ["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max}, - ["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max}, - ["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max} -} -]]-- - -local function decypher_limits(posy) - --local min_max_table = decypher_limits_dictionary[dimension] - --return min_max_table[1],min_max_table[2] - posy = math.floor(posy) - return posy - 32, posy + 32 -end - - ---todo mob limiting ---MAIN LOOP -local timer = 0 -minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer >= 15 then - timer = 0 - for _,player in ipairs(minetest.get_connected_players()) do - for i = 1,math.random(5) do - local player_pos = player:get_pos() - local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - local min,max = decypher_limits(player_pos.y) - - local goal_pos = position_calculation(player_pos) - - - local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] - - if not mob_def then --to catch a crazy error if it ever happens - minetest.log("error", "WARNING!! mob spawning attempted to index a NIL mob!") - goto continue - end - - if mob_def.type == "ground" then - - local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - spawning_position.y = spawning_position.y + 1 - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - elseif mob_def.type == "air" then - local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - elseif mob_def.type == "water" then - local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - --elseif mob_def.type == "lava" then - --implement later - end - --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) - - - ::continue:: --this is a safety catch - end - end - end -end) - - - - - - - - - - - - - ---END SPAWNING ALGORITHM - - - - - - - - - - - - - - - - - - - -- register arrow for shoot attack diff --git a/mods/ENTITIES/mobs_mc/agent.lua b/mods/ENTITIES/mobs_mc/agent.lua index cc9910ee6..8fa7314cf 100644 --- a/mods/ENTITIES/mobs_mc/agent.lua +++ b/mods/ENTITIES/mobs_mc/agent.lua @@ -1,5 +1,5 @@ --################### ---################### AGENT - seemingly unused +--################### AGENT --################### local S = minetest.get_translator("mobs_mc") diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index b6825bbbf..103579b67 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -64,7 +64,7 @@ else end -- Spawn on solid blocks at or below Sea level and the selected light level -mobs:spawn_specific("mobs_mc:bat", "overworld", "air", 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) +mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index d56acdf38..fbffa7920 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -1,6 +1,6 @@ -- daufinsyd -- My work is under the LGPL terms --- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez +-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -- blaze.lua partial copy of mobs_mc/ghast.lua local S = minetest.get_translator("mobs_mc") @@ -128,7 +128,7 @@ mobs:register_mob("mobs_mc:blaze", { end, }) -mobs:spawn_specific("mobs_mc:blaze", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Blaze fireball mobs:register_arrow("mobs_mc:blaze_fireball", { diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 397b6b8da..325371e2b 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -100,7 +100,7 @@ mobs:register_mob("mobs_mc:chicken", { }) --spawn -mobs:spawn_specific("mobs_mc:chicken", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index a094d6d35..005af2980 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -145,9 +145,8 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning -mobs:spawn_specific("mobs_mc:cow", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) ---WARNING: THIS NEEDS A BIOME INTEGRATION -mobs:spawn_specific("mobs_mc:mooshroom", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index f1f0a3ef6..de44ba8c6 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -39,8 +39,6 @@ mobs:register_mob("mobs_mc:creeper", { runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, attack_type = "explode", - --hssssssssssss - explosion_strength = 3, explosion_radius = 3.5, explosion_damage_radius = 3.5, @@ -140,9 +138,6 @@ mobs:register_mob("mobs_mc:creeper_charged", { pathfinding = 1, visual = "mesh", mesh = "mobs_mc_creeper.b3d", - - --BOOM - textures = { {"mobs_mc_creeper.png", "mobs_mc_creeper_charge.png"}, @@ -253,7 +248,7 @@ mobs:register_mob("mobs_mc:creeper_charged", { glow = 3, }) -mobs:spawn_specific("mobs_mc:creeper", "overworld", "ground", 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index ca3bc84ce..f93f131cb 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -562,11 +562,11 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn -mobs:spawn_specific("mobs_mc:enderman", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) -- Overworld spawn -mobs:spawn_specific("mobs_mc:enderman", "overworld", "ground", 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn (rare) -mobs:spawn_specific("mobs_mc:enderman", "nether", "ground", 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index e2f6b1369..7aed9395e 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -75,7 +75,7 @@ mobs:register_mob("mobs_mc:ghast", { }) -mobs:spawn_specific("mobs_mc:ghast", "nether", "air", 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- fireball (projectile) mobs:register_arrow("mobs_mc:fireball", { diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index 089f6e38f..a58a4a5b7 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -106,7 +106,7 @@ mobs:register_mob("mobs_mc:guardian_elder", { view_range = 16, }) --- Spawning disabled due to size issues <- what do you mean? -j4i +-- Spawning disabled due to size issues -- TODO: Re-enable spawning -- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 00c292c1d..3da63831e 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -510,8 +510,8 @@ mobs:register_mob("mobs_mc:mule", mule) --=========================== --Spawn Function -mobs:spawn_specific("mobs_mc:horse", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:donkey", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 0efb8e0ab..36d020a65 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -217,7 +217,7 @@ mobs:register_mob("mobs_mc:llama", { }) --spawn -mobs:spawn_specific("mobs_mc:llama", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 3b5273185..eca74d3ba 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -152,9 +152,6 @@ mobs:register_mob("mobs_mc:cat", cat) local base_spawn_chance = 5000 -- Spawn ocelot ---they get the same as the llama because I'm trying to rework so much of this code right now -j4i -mobs:spawn_specific("mobs_mc:ocelot", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) ---[[ mobs:spawn({ name = "mobs_mc:ocelot", nodes = mobs_mc.spawn.jungle, @@ -166,8 +163,8 @@ mobs:spawn({ min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level max_height = mobs_mc.spawn_height.overworld_max, on_spawn = function(self, pos) - Note: Minecraft has a 1/3 spawn failure rate. - In this mod it is emulated by reducing the spawn rate accordingly (see above). + --[[ Note: Minecraft has a 1/3 spawn failure rate. + In this mod it is emulated by reducing the spawn rate accordingly (see above). ]] -- 1/7 chance to spawn 2 ocelot kittens if pr:next(1,7) == 1 then @@ -210,7 +207,6 @@ mobs:spawn({ end end, }) -]]-- -- spawn eggs -- FIXME: The spawn icon shows a cat texture, not an ocelot texture diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index c67263fb9..407cb4466 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -90,8 +90,8 @@ mobs:register_mob("mobs_mc:parrot", { }) --- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i -mobs:spawn_specific("mobs_mc:parrot","overworld", "air", 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) +-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* +mobs:spawn_specific("mobs_mc:parrot", {"mcl_core:jungletree", "mcl_core:jungleleaves"}, {"air"}, 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 143fcb495..38700b6ca 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -182,7 +182,7 @@ mobs:register_mob("mobs_mc:pig", { end, }) -mobs:spawn_specific("mobs_mc:pig", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 745c13a26..459ca29b4 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -67,7 +67,7 @@ mobs:register_mob("mobs_mc:polar_bear", { }) -mobs:spawn_specific("mobs_mc:polar_bear", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index f09a70584..e167649f6 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -107,11 +107,8 @@ end mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) -- Mob spawning rules. --- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out +-- Different skins depending on spawn location -mobs:spawn_specific("mobs_mc:rabbit", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) - ---[[ local spawn = { name = "mobs_mc:rabbit", neighbors = {"air"}, @@ -168,7 +165,6 @@ spawn_grass.on_spawn = function(self, pos) self.object:set_properties({textures = self.base_texture}) end mobs:spawn(spawn_grass) -]]-- -- Spawn egg mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index b3400ab5f..84650b4dd 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -303,7 +303,7 @@ mobs:register_mob("mobs_mc:sheep", { end end, }) -mobs:spawn_specific("mobs_mc:sheep", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index 583c5eed1..faaf2ac40 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -81,4 +81,4 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) -mobs:spawn_specific("mobs_mc:shulker", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index 84e51c517..cb12e905d 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -139,13 +139,13 @@ table.insert(stray.drops, { mobs:register_mob("mobs_mc:stray", stray) -- Overworld spawn -mobs:spawn_specific("mobs_mc:skeleton", "overworld", "ground", 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn -mobs:spawn_specific("mobs_mc:skeleton", "nether", "ground", 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Stray spawn -- TODO: Spawn directly under the sky -mobs:spawn_specific("mobs_mc:stray", "overworld", "ground", 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index d9de90d84..e4a1f86fc 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -94,7 +94,7 @@ mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn -mobs:spawn_specific("mobs_mc:witherskeleton", "nether", "ground", 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 2f9e8c8a9..fd1f92bb4 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -157,9 +157,9 @@ mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) local smin = mobs_mc.spawn_height.overworld_min local smax = mobs_mc.spawn_height.water - 23 -mobs:spawn_specific("mobs_mc:slime_tiny", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_small", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_big", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) -- Magma cube local magma_cube_big = { @@ -272,13 +272,13 @@ mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) local mmin = mobs_mc.spawn_height.nether_min local mmax = mobs_mc.spawn_height.nether_max -mobs:spawn_specific("mobs_mc:magma_cube_tiny", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) ---mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) ---mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) ---mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 1361e6a3a..0bb03a9c7 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -87,7 +87,7 @@ cave_spider.sounds.base_pitch = 1.25 mobs:register_mob("mobs_mc:cave_spider", cave_spider) -mobs:spawn_specific("mobs_mc:spider", "overworld", "ground", 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 2dbb7c557..1877a2104 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -62,7 +62,7 @@ mobs:register_mob("mobs_mc:squid", { local water = mobs_mc.spawn_height.water --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height -mobs:spawn_specific("mobs_mc:squid", "overworld", "water", 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) +mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) -- spawn eggs mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 0b53d8015..68644266f 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1074,7 +1074,7 @@ mobs:register_mob("mobs_mc:villager", { -mobs:spawn_specific("mobs_mc:villager", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index bcede2183..09539fa76 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -146,8 +146,8 @@ mobs:register_mob("mobs_mc:villager_zombie", { harmed_by_heal = true, }) -mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index f9f9b8d1f..383cbd36f 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:potion_arrow", { end }) --- TODO: Spawn when witch works properly <- eventually -j4i +-- TODO: Spawn when witch works properly --mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index 953c2df72..fe3031895 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -232,6 +232,6 @@ end mobs:register_mob("mobs_mc:dog", dog) -- Spawn -mobs:spawn_specific("mobs_mc:wolf", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 64f99d34d..df9727d34 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -135,11 +135,11 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning -mobs:spawn_specific("mobs_mc:zombie", "overworld", "ground", 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:husk", "overworld", "ground", 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:baby_husk", "overworld", "ground", 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Spawn eggs mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index e996425c8..8c29a4bff 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -111,12 +111,12 @@ baby_pigman.child = 1 mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) -- Regular spawning in the Nether -mobs:spawn_specific("mobs_mc:pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Spawning in Nether portals in the Overworld ---mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0) From d77affca91be1b17462851d3559ee32038ea5bf0 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 7 Apr 2021 17:39:13 +0200 Subject: [PATCH 087/164] Change max_bossbars default to 4 --- mods/HUD/mcl_bossbars/init.lua | 2 +- settingtypes.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 3ba0bd755..3a144aac4 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -3,7 +3,7 @@ mcl_bossbars = { huds = {}, static = {}, colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"}, - max_bars = tonumber(minetest.settings:get("max_bossbars")) or 6 + max_bars = tonumber(minetest.settings:get("max_bossbars")) or 4 } function mcl_bossbars.recalculate_colors() diff --git a/settingtypes.txt b/settingtypes.txt index 4ba6034eb..bfda9b3ba 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -98,7 +98,7 @@ animated_chests (Animated chests) bool true 3d_player_preview (3D Player preview) bool true # The maximum number of boss bars to simultaniously display on the screen -max_bossbars (Maximum Boss bars) int 6 +max_bossbars (Maximum Boss bars) int 4 [Experimental] # Whether ice is translucent. If disabled, ice is fully opaque. From 11114c6847ed1eb90da964026395d24f559aba03 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 7 Apr 2021 23:54:36 +0200 Subject: [PATCH 088/164] fix add_bar function returning nil value --- mods/HUD/mcl_bossbars/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 3a144aac4..5c6a883d9 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -60,7 +60,7 @@ function mcl_bossbars.add_bar(player, def) bar.id = last_id + 1 last_id = bar.id mcl_bossbars.static[bar.id] = bar - return id + return bar.id end end From f7ddfe289178064ba36b3f1b2e88b7c83a33c0e8 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Wed, 7 Apr 2021 23:54:40 +0200 Subject: [PATCH 089/164] Revert "fix add_bar function returning nil value" This reverts commit 11114c6847ed1eb90da964026395d24f559aba03. --- mods/HUD/mcl_bossbars/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 5c6a883d9..3a144aac4 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -60,7 +60,7 @@ function mcl_bossbars.add_bar(player, def) bar.id = last_id + 1 last_id = bar.id mcl_bossbars.static[bar.id] = bar - return bar.id + return id end end From 8e30bc8dbd41082df63699c8f786ebedc04b1e0c Mon Sep 17 00:00:00 2001 From: kay27 Date: Thu, 8 Apr 2021 02:54:33 +0400 Subject: [PATCH 090/164] [mcl_portals] Prevent from spawning Nether portals in Undertale when not enough air space in Nether --- mods/ITEMS/mcl_portals/portal_nether.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 825c95e05..1d9fe2efb 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -490,10 +490,12 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param) end if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then - local pos1, pos2, pos = param.next_chunk_1, param.next_chunk_2, param.next_pos - log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(pos)) - minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = pos, pos1 = pos1, pos2 = pos2, name=name, obj=obj}) - return + local pos1, pos2, p = param.next_chunk_1, param.next_chunk_2, param.next_pos + if p.x >= pos1.x and p.x <= pos2.x and p.y >= pos1.y and p.y <= pos2.y and p.z >= pos1.z and p.z <= pos2.z then + log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(p)) + minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = p, pos1 = pos1, pos2 = pos2, name=name, obj=obj}) + return + end end log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal") @@ -536,7 +538,7 @@ local function create_portal(pos, limit1, limit2, name, obj) -- Basically the copy of code above, with minor additions to continue the search in single additional chunk below: local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z} local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1) - local next_pos = {x = pos.x, y=next_chunk_2.y, z = pos.z} + local next_pos = {x = pos.x, y=max(next_chunk_2.y, limit1.y), z = pos.z} if limit1 and limit1.x and limit1.y and limit1.z then pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} next_chunk_1 = {x = max(min(limit1.x, next_pos.x), next_chunk_1.x), y = max(min(limit1.y, next_pos.y), next_chunk_1.y), z = max(min(limit1.z, next_pos.z), next_chunk_1.z)} From 2db0e176b315968363998f6c655920a174840a76 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Thu, 8 Apr 2021 12:04:29 +0800 Subject: [PATCH 091/164] Prevent param2 overflow when adding stems. Fix #1490 --- mods/ITEMS/mcl_ocean/kelp.lua | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 3aefe85f8..bbdae64ee 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -1,6 +1,9 @@ -- TODO: whenever it becomes possible to fully implement kelp without the -- plantlike_rooted limitation, please update accordingly. -- +-- TODO: whenever it becomes possible to make kelp grow infinitely without +-- resorting to making intermediate kelp stem node, please update accordingly. +-- -- TODO: In MC, you can't actually destroy kelp by bucket'ing water in the middle. -- However, because of the plantlike_rooted hack, we'll just allow it for now. @@ -191,17 +194,18 @@ end -- Converts param2 to kelp height. +-- For the special case where the max param2 is reached, interpret that as the +-- 16th kelp stem. function kelp.get_height(param2) - return math_floor(param2 / 16) + return param2 ~= 255 and math_floor(param2 / 16) or 16 -- 256/16 end -- Obtain pos and node of the tip of kelp. -function kelp.get_tip(pos, param2) - -- Optional params: param2 - local height = kelp.get_height(param2 or mt_get_node(pos).param2) - local pos_tip = {x=pos.x, y=pos.y, z=pos.z} - pos_tip.y = pos_tip.y + height + 1 +function kelp.get_tip(pos, height) + -- Optional params: height + local height = height or kelp.get_height(mt_get_node(pos).param2) + local pos_tip = {x=pos.x, y=pos.y+height+1, z=pos.z} return pos_tip, mt_get_node(pos_tip), height end @@ -227,7 +231,8 @@ end -- Obtain next param2. function kelp.next_param2(param2) - return param2+16 - param2 % 16 + -- param2 max value is 255, so adding to 256 causes overflow. + return math_min(param2+16 - param2 % 16, 255); end @@ -526,7 +531,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) -- When placed on kelp. if mt_get_item_group(nu_name, "kelp") == 1 then - pos_tip,node_tip = kelp.get_tip(pos_under, node_under.param2) + pos_tip,node_tip = kelp.get_tip(pos_under, kelp.get_height(node_under.param2)) def_tip = mt_registered_nodes[node_tip.name] -- When placed on surface. From 5ccb12586dd09405f42ca7c824a817cde8fdf435 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Thu, 8 Apr 2021 13:34:04 +0800 Subject: [PATCH 092/164] Fix bug where incorrect number of items are dropped. --- mods/ITEMS/mcl_ocean/kelp.lua | 46 ++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index bbdae64ee..3d4c6b4b3 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -214,7 +214,7 @@ end function kelp.find_unsubmerged(pos, node, height) -- Optional params: node, height local node = node or mt_get_node(pos) - local height = height or kelp.get_height(node.param2) + local height = height or ((node.param2 >= 0 and node.param2 < 16) and 1) or kelp.get_height(node.param2) local walk_pos = {x=pos.x, z=pos.z} local y = pos.y @@ -316,7 +316,7 @@ function kelp.init_timer(pos, pos_hash) end --- Apply next kelp height. +-- Apply next kelp height. The surface is swapped. so on_construct is skipped. function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing) -- Modified params: node -- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing @@ -372,9 +372,9 @@ end -- Drops the items for detached kelps. -function kelp.detach_drop(pos, param2) - -- Optional params: param2 - local height = kelp.get_height(param2 or mt_get_node(pos).param2) +function kelp.detach_drop(pos, height) + -- Optional params: height + local height = height or kelp.get_height(mt_get_node(pos).param2) local y = pos.y local walk_pos = {x=pos.x, z=pos.z} for i=1,height do @@ -389,17 +389,18 @@ end -- Synonymous to digging the kelp. -- NOTE: this is intended for whenever kelp truly becomes segmented plants -- instead of rooted to the floor. Don't try to remove dig_pos. -function kelp.detach_dig(dig_pos, pos, node, drop) - -- Optional params: drop +function kelp.detach_dig(dig_pos, pos, drop, node, height) + -- Optional params: drop, node, height - local param2 = node.param2 + local node = node or mt_get_node(pos) + local height = height or kelp.get_height(node.param2) -- pos.y points to the surface, offset needed to point to the first kelp. local new_height = dig_pos.y - (pos.y+1) -- Digs the entire kelp. if new_height <= 0 then if drop then - kelp.detach_drop(dig_pos, param2) + kelp.detach_drop(dig_pos, height) end mt_set_node(pos, { name=mt_registered_nodes[node.name].node_dig_prediction, @@ -409,7 +410,8 @@ function kelp.detach_dig(dig_pos, pos, node, drop) -- Digs the kelp beginning at a height. else if drop then - kelp.detach_drop(dig_pos, param2 - new_height) + kelp.detach_drop(dig_pos, height - new_height) + minetest.chat_send_all(node.param2 - new_height) end mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height}) end @@ -421,7 +423,7 @@ end -------------------------------------------------------------------------------- function kelp.surface_on_dig(pos, node, digger) - kelp.detach_dig(pos, pos, node, true) + kelp.detach_dig(pos, pos, true, node) end @@ -435,11 +437,11 @@ function kelp.surface_on_timer(pos) local pos_hash -- Update detahed kelps - local dig_pos = kelp.find_unsubmerged(pos, node) + local dig_pos,_, height = kelp.find_unsubmerged(pos, node) if dig_pos then pos_hash = mt_hash_node_position(pos) mt_sound_play(mt_registered_nodes[node.name].sounds.dug, { gain = 0.5, pos = dig_pos }, true) - kelp.detach_dig(dig_pos, pos, node, true) + kelp.detach_dig(dig_pos, pos, true, node, height) kelp.store_age(kelp.roll_init_age(), pos, pos_hash) end @@ -468,7 +470,7 @@ function kelp.surface_on_destruct(pos) -- on_falling callback. Activated by pistons for falling nodes too. if kelp.is_falling(pos, node) then - kelp.detach_drop(pos, node.param2) + kelp.detach_drop(pos, kelp.get_height(node.param2)) end -- Removes position from queue @@ -479,7 +481,7 @@ end function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta) -- Pistons moving falling nodes will have already activated on_falling callback. - kelp.detach_dig(pos, pos, node, mt_get_item_group(node.name, "falling_node") ~= 1) + kelp.detach_dig(pos, pos, mt_get_item_group(node.name, "falling_node") ~= 1, node) end @@ -523,7 +525,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) end - local pos_tip, node_tip, def_tip, new_kelp + local pos_tip, node_tip, def_tip, new_surface -- Kelp must also be placed on the top/tip side of the surface/kelp if pos_under.y >= pos_above.y then return itemstack @@ -536,17 +538,17 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) -- When placed on surface. else - new_kelp = false + new_surface = false for _,surface in pairs(kelp.surfaces) do if nu_name == surface.nodename then node_under.name = "mcl_ocean:kelp_" ..surface.name node_under.param2 = 0 - new_kelp = true + new_surface = true break end end -- Surface must support kelp - if not new_kelp then + if not new_surface then return itemstack end @@ -555,7 +557,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) def_tip = mt_registered_nodes[node_tip.name] end - -- New kelp must also be submerged in water. + -- Next kelp must also be submerged in water. local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip) local submerged = kelp.is_submerged(node_tip) if not submerged then @@ -572,9 +574,9 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) itemstack:take_item() end - -- Initialize age and timer when it's a new kelp + -- Initialize age and timer when it's planted on a new surface. local pos_hash = mt_hash_node_position(pos_under) - if new_kelp then + if new_surface then kelp.init_age(pos_under, nil, pos_hash) kelp.init_timer(pos_under, pos_hash) else From d50665d2d5e49d58317cffdaed50fd165e5d2315 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Thu, 8 Apr 2021 19:25:19 +0800 Subject: [PATCH 093/164] Allow kelp stems at half height to be treated like full-sized ones. Remove debug information --- mods/ITEMS/mcl_ocean/kelp.lua | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 3d4c6b4b3..9670943da 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -197,7 +197,7 @@ end -- For the special case where the max param2 is reached, interpret that as the -- 16th kelp stem. function kelp.get_height(param2) - return param2 ~= 255 and math_floor(param2 / 16) or 16 -- 256/16 + return math_floor(param2 / 16) + math_floor(param2 % 16 / 8) end @@ -411,7 +411,6 @@ function kelp.detach_dig(dig_pos, pos, drop, node, height) else if drop then kelp.detach_drop(dig_pos, height - new_height) - minetest.chat_send_all(node.param2 - new_height) end mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height}) end @@ -525,7 +524,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) end - local pos_tip, node_tip, def_tip, new_surface + local pos_tip, node_tip, def_tip, new_surface, height -- Kelp must also be placed on the top/tip side of the surface/kelp if pos_under.y >= pos_above.y then return itemstack @@ -533,7 +532,8 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) -- When placed on kelp. if mt_get_item_group(nu_name, "kelp") == 1 then - pos_tip,node_tip = kelp.get_tip(pos_under, kelp.get_height(node_under.param2)) + height = kelp.get_height(node_under.param2) + pos_tip,node_tip = kelp.get_tip(pos_under, height) def_tip = mt_registered_nodes[node_tip.name] -- When placed on surface. @@ -555,6 +555,7 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) pos_tip = pos_above node_tip = mt_get_node(pos_above) def_tip = mt_registered_nodes[node_tip.name] + height = 0 end -- Next kelp must also be submerged in water. @@ -569,7 +570,12 @@ function kelp.kelp_on_place(itemstack, placer, pointed_thing) if def_node.sounds then mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing) + -- TODO: get rid of rooted plantlike hack + if height < 16 then + kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing) + else + mt_add_item(pos_tip, "mcl_ocean:kelp") + end if not mt_is_creative_enabled(player_name) then itemstack:take_item() end From 0842a36aa6f4a45a10a3ec1182dedcec1d4aac61 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 14:28:07 -0400 Subject: [PATCH 094/164] Fix extreme mesecons/redstone crashing at world border --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 7986c2908..78d675e47 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -483,6 +483,12 @@ function mesecon.turnoff(pos, link) for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) + + if not n then + mcl_explosions.explode(f.pos, 10) + return + end + if mesecon.is_receptor_on(n.name) then local receptorrules = mesecon.receptor_get_rules(n) for _, rr in pairs(receptorrules) do From b9d175e6a5d6654b19098c7943a4e14ca8e43eb1 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 15:16:38 -0400 Subject: [PATCH 095/164] Add erlehmann fix to redstone world border crash --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 78d675e47..3a8e68f95 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -484,16 +484,13 @@ function mesecon.turnoff(pos, link) local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) - if not n then - mcl_explosions.explode(f.pos, 10) - return - end - - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) - for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then - return false + if not (mesecon.get_node_force(np) == nil) then + if mesecon.is_receptor_on(n.name) then + local receptorrules = mesecon.receptor_get_rules(n) + for _, rr in pairs(receptorrules) do + if rr.spread and vector.equals(mesecon.invertRule(rr), r) then + return false + end end end end From 18f73ba31f3669b49a573fe6cc15050c81fe31db Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 15:48:53 -0400 Subject: [PATCH 096/164] Revert fixes to crash world border --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 3a8e68f95..d17a3acd2 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -483,14 +483,12 @@ function mesecon.turnoff(pos, link) for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) - - if not (mesecon.get_node_force(np) == nil) then - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) - for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then - return false - end + + if mesecon.is_receptor_on(n.name) then + local receptorrules = mesecon.receptor_get_rules(n) + for _, rr in pairs(receptorrules) do + if rr.spread and vector.equals(mesecon.invertRule(rr), r) then + return false end end end From 5e0bd2281c6546d6f9ef672263adabccb91badc0 Mon Sep 17 00:00:00 2001 From: kay27 Date: Wed, 7 Apr 2021 20:47:40 +0400 Subject: [PATCH 097/164] Revert "Revert "Merge pull request 'Massively overhaul spawning algorithm for mobs' (#1487) from jordan4ibanez/MineClone2-MobTweaks:master into master"" This reverts commit 6a1a634cba4e0530a4cb72cf319f203f4a770d7f. --- mods/ENTITIES/mcl_mobs/api.lua | 255 ++++++++++++++++++++- mods/ENTITIES/mobs_mc/agent.lua | 2 +- mods/ENTITIES/mobs_mc/bat.lua | 2 +- mods/ENTITIES/mobs_mc/blaze.lua | 4 +- mods/ENTITIES/mobs_mc/chicken.lua | 2 +- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 5 +- mods/ENTITIES/mobs_mc/creeper.lua | 7 +- mods/ENTITIES/mobs_mc/enderman.lua | 6 +- mods/ENTITIES/mobs_mc/ghast.lua | 2 +- mods/ENTITIES/mobs_mc/guardian_elder.lua | 2 +- mods/ENTITIES/mobs_mc/horse.lua | 4 +- mods/ENTITIES/mobs_mc/llama.lua | 2 +- mods/ENTITIES/mobs_mc/ocelot.lua | 8 +- mods/ENTITIES/mobs_mc/parrot.lua | 4 +- mods/ENTITIES/mobs_mc/pig.lua | 2 +- mods/ENTITIES/mobs_mc/polar_bear.lua | 2 +- mods/ENTITIES/mobs_mc/rabbit.lua | 6 +- mods/ENTITIES/mobs_mc/sheep.lua | 2 +- mods/ENTITIES/mobs_mc/shulker.lua | 2 +- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 6 +- mods/ENTITIES/mobs_mc/skeleton_wither.lua | 2 +- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 18 +- mods/ENTITIES/mobs_mc/spider.lua | 2 +- mods/ENTITIES/mobs_mc/squid.lua | 2 +- mods/ENTITIES/mobs_mc/villager.lua | 2 +- mods/ENTITIES/mobs_mc/villager_zombie.lua | 4 +- mods/ENTITIES/mobs_mc/witch.lua | 2 +- mods/ENTITIES/mobs_mc/wolf.lua | 2 +- mods/ENTITIES/mobs_mc/zombie.lua | 8 +- mods/ENTITIES/mobs_mc/zombiepig.lua | 6 +- 30 files changed, 316 insertions(+), 57 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 94d6340ea..d85633421 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3562,7 +3562,7 @@ local mob_step = function(self, dtime) end -- mob plays random sound at times - if random(1, 100) == 1 then + if random(1, 70) == 1 then mob_sound(self, "random", true) end @@ -3925,7 +3925,35 @@ end end -- END mobs:register_mob function + + + + + + + + + + + +--BEGIN SPAWNING ALGORITHM + + + + + + + + + + + + + + + -- count how many mobs of one type are inside an area +--[[ local count_mobs = function(pos, mobtype) local num = 0 @@ -3969,7 +3997,7 @@ local count_mobs = function(pos, mobtype) return num end - +]]-- -- global functions @@ -3979,9 +4007,49 @@ function mobs:spawn_abm_check(pos, node, name) end -function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, - interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) +--[[ + Custom elements changed: +name: +the mobs name +dimension: +"overworld" +"nether" +"end" + +types of spawning: +"air" +"water" +"ground" +"lava" + +what is aoc??? + +WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? +]]-- + +--this is where all of the spawning information is kept +local spawn_dictionary = { + ["overworld"] = {}, + ["nether"] = {}, + ["end"] = {} +} + +function mobs:spawn_specific( + name, + dimension, + type_of_spawning, + min_light, + max_light, + interval, + chance, + aoc, + min_height, + max_height, + day_toggle, + on_spawn) + + -- Do mobs spawn at all? if not mobs_spawn then return @@ -4002,7 +4070,6 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) - end local spawn_action @@ -4167,6 +4234,24 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, spawn_action(pos, node, active_object_count, active_object_count_wider, name) end + + --load information into the spawn dictionary + local key = #spawn_dictionary[dimension] + 1 + + spawn_dictionary[dimension][key] = {} + spawn_dictionary[dimension][key]["name"] = name + spawn_dictionary[dimension][key]["type"] = type_of_spawning + spawn_dictionary[dimension][key]["min_light"] = min_light + spawn_dictionary[dimension][key]["max_light"] = max_light + spawn_dictionary[dimension][key]["interval"] = interval + spawn_dictionary[dimension][key]["chance"] = chance + spawn_dictionary[dimension][key]["aoc"] = aoc + spawn_dictionary[dimension][key]["min_height"] = min_height + spawn_dictionary[dimension][key]["max_height"] = max_height + spawn_dictionary[dimension][key]["day_toggle"] = day_toggle + spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action + + --[[ minetest.register_abm({ label = name .. " spawning", nodenames = nodes, @@ -4176,18 +4261,24 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, catch_up = false, action = spawn_abm_action, }) + ]]-- end -- compatibility with older mob registration +-- we're going to forget about this for now -j4i +--[[ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, chance, active_object_count, -31000, max_height, day_toggle) end +]]-- +--I'm not sure what this does but disabling it doesn't cause a crash -j4i -- MarkBu's spawn function +--[[ function mobs:spawn(def) local name = def.name @@ -4206,6 +4297,160 @@ function mobs:spawn(def) mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, day_toggle, on_spawn) end +]]-- + + +local axis +--inner and outer part of square donut radius +local inner = 1 +local outer = 70 +local int = {-1,1} +local position_calculation = function(pos) + + pos = vector.floor(pos) + + --this is used to determine the axis buffer from the player + axis = math.random(0,1) + + --cast towards the direction + if axis == 0 then --x + pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)] + pos.z = pos.z + math.random(-outer,outer) + else --z + pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)] + pos.x = pos.x + math.random(-outer,outer) + end + return(pos) +end + +--[[ +local decypher_limits_dictionary = { + ["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max}, + ["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max}, + ["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max} +} +]]-- + +local function decypher_limits(posy) + --local min_max_table = decypher_limits_dictionary[dimension] + --return min_max_table[1],min_max_table[2] + posy = math.floor(posy) + return posy - 32, posy + 32 +end + + +--todo mob limiting +--MAIN LOOP +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 15 then + timer = 0 + for _,player in ipairs(minetest.get_connected_players()) do + for i = 1,math.random(5) do + local player_pos = player:get_pos() + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + local min,max = decypher_limits(player_pos.y) + + local goal_pos = position_calculation(player_pos) + + + local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] + + if not mob_def then --to catch a crazy error if it ever happens + minetest.log("error", "WARNING!! mob spawning attempted to index a NIL mob!") + goto continue + end + + if mob_def.type == "ground" then + + local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + spawning_position.y = spawning_position.y + 1 + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + elseif mob_def.type == "air" then + local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + elseif mob_def.type == "water" then + local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + --elseif mob_def.type == "lava" then + --implement later + end + --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) + + + ::continue:: --this is a safety catch + end + end + end +end) + + + + + + + + + + + + + +--END SPAWNING ALGORITHM + + + + + + + + + + + + + + + + + + + -- register arrow for shoot attack diff --git a/mods/ENTITIES/mobs_mc/agent.lua b/mods/ENTITIES/mobs_mc/agent.lua index 8fa7314cf..cc9910ee6 100644 --- a/mods/ENTITIES/mobs_mc/agent.lua +++ b/mods/ENTITIES/mobs_mc/agent.lua @@ -1,5 +1,5 @@ --################### ---################### AGENT +--################### AGENT - seemingly unused --################### local S = minetest.get_translator("mobs_mc") diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index 103579b67..b6825bbbf 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -64,7 +64,7 @@ else end -- Spawn on solid blocks at or below Sea level and the selected light level -mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) +mobs:spawn_specific("mobs_mc:bat", "overworld", "air", 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index fbffa7920..d56acdf38 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -1,6 +1,6 @@ -- daufinsyd -- My work is under the LGPL terms --- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models +-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez -- blaze.lua partial copy of mobs_mc/ghast.lua local S = minetest.get_translator("mobs_mc") @@ -128,7 +128,7 @@ mobs:register_mob("mobs_mc:blaze", { end, }) -mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:blaze", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Blaze fireball mobs:register_arrow("mobs_mc:blaze_fireball", { diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 325371e2b..397b6b8da 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -100,7 +100,7 @@ mobs:register_mob("mobs_mc:chicken", { }) --spawn -mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:chicken", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 005af2980..a094d6d35 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -145,8 +145,9 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning -mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:cow", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +--WARNING: THIS NEEDS A BIOME INTEGRATION +mobs:spawn_specific("mobs_mc:mooshroom", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index de44ba8c6..f1f0a3ef6 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -39,6 +39,8 @@ mobs:register_mob("mobs_mc:creeper", { runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, attack_type = "explode", + --hssssssssssss + explosion_strength = 3, explosion_radius = 3.5, explosion_damage_radius = 3.5, @@ -138,6 +140,9 @@ mobs:register_mob("mobs_mc:creeper_charged", { pathfinding = 1, visual = "mesh", mesh = "mobs_mc_creeper.b3d", + + --BOOM + textures = { {"mobs_mc_creeper.png", "mobs_mc_creeper_charge.png"}, @@ -248,7 +253,7 @@ mobs:register_mob("mobs_mc:creeper_charged", { glow = 3, }) -mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:creeper", "overworld", "ground", 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index f93f131cb..ca3bc84ce 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -562,11 +562,11 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:enderman", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) -- Overworld spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:enderman", "overworld", "ground", 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn (rare) -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:enderman", "nether", "ground", 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 7aed9395e..e2f6b1369 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -75,7 +75,7 @@ mobs:register_mob("mobs_mc:ghast", { }) -mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:ghast", "nether", "air", 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- fireball (projectile) mobs:register_arrow("mobs_mc:fireball", { diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index a58a4a5b7..089f6e38f 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -106,7 +106,7 @@ mobs:register_mob("mobs_mc:guardian_elder", { view_range = 16, }) --- Spawning disabled due to size issues +-- Spawning disabled due to size issues <- what do you mean? -j4i -- TODO: Re-enable spawning -- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 3da63831e..00c292c1d 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -510,8 +510,8 @@ mobs:register_mob("mobs_mc:mule", mule) --=========================== --Spawn Function -mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:horse", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:donkey", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 36d020a65..0efb8e0ab 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -217,7 +217,7 @@ mobs:register_mob("mobs_mc:llama", { }) --spawn -mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:llama", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index eca74d3ba..3b5273185 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -152,6 +152,9 @@ mobs:register_mob("mobs_mc:cat", cat) local base_spawn_chance = 5000 -- Spawn ocelot +--they get the same as the llama because I'm trying to rework so much of this code right now -j4i +mobs:spawn_specific("mobs_mc:ocelot", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +--[[ mobs:spawn({ name = "mobs_mc:ocelot", nodes = mobs_mc.spawn.jungle, @@ -163,8 +166,8 @@ mobs:spawn({ min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level max_height = mobs_mc.spawn_height.overworld_max, on_spawn = function(self, pos) - --[[ Note: Minecraft has a 1/3 spawn failure rate. - In this mod it is emulated by reducing the spawn rate accordingly (see above). ]] + Note: Minecraft has a 1/3 spawn failure rate. + In this mod it is emulated by reducing the spawn rate accordingly (see above). -- 1/7 chance to spawn 2 ocelot kittens if pr:next(1,7) == 1 then @@ -207,6 +210,7 @@ mobs:spawn({ end end, }) +]]-- -- spawn eggs -- FIXME: The spawn icon shows a cat texture, not an ocelot texture diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 407cb4466..c67263fb9 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -90,8 +90,8 @@ mobs:register_mob("mobs_mc:parrot", { }) --- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* -mobs:spawn_specific("mobs_mc:parrot", {"mcl_core:jungletree", "mcl_core:jungleleaves"}, {"air"}, 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) +-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i +mobs:spawn_specific("mobs_mc:parrot","overworld", "air", 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 38700b6ca..143fcb495 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -182,7 +182,7 @@ mobs:register_mob("mobs_mc:pig", { end, }) -mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:pig", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 459ca29b4..745c13a26 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -67,7 +67,7 @@ mobs:register_mob("mobs_mc:polar_bear", { }) -mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:polar_bear", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index e167649f6..f09a70584 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -107,8 +107,11 @@ end mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) -- Mob spawning rules. --- Different skins depending on spawn location +-- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out +mobs:spawn_specific("mobs_mc:rabbit", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) + +--[[ local spawn = { name = "mobs_mc:rabbit", neighbors = {"air"}, @@ -165,6 +168,7 @@ spawn_grass.on_spawn = function(self, pos) self.object:set_properties({textures = self.base_texture}) end mobs:spawn(spawn_grass) +]]-- -- Spawn egg mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 84650b4dd..b3400ab5f 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -303,7 +303,7 @@ mobs:register_mob("mobs_mc:sheep", { end end, }) -mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:sheep", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index faaf2ac40..583c5eed1 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -81,4 +81,4 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) -mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:shulker", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index cb12e905d..84e51c517 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -139,13 +139,13 @@ table.insert(stray.drops, { mobs:register_mob("mobs_mc:stray", stray) -- Overworld spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:skeleton", "overworld", "ground", 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:skeleton", "nether", "ground", 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Stray spawn -- TODO: Spawn directly under the sky -mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:stray", "overworld", "ground", 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index e4a1f86fc..d9de90d84 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -94,7 +94,7 @@ mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn -mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:witherskeleton", "nether", "ground", 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index fd1f92bb4..2f9e8c8a9 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -157,9 +157,9 @@ mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) local smin = mobs_mc.spawn_height.overworld_min local smax = mobs_mc.spawn_height.water - 23 -mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_tiny", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_small", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) +mobs:spawn_specific("mobs_mc:slime_big", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) -- Magma cube local magma_cube_big = { @@ -272,13 +272,13 @@ mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) local mmin = mobs_mc.spawn_height.nether_min local mmax = mobs_mc.spawn_height.nether_max -mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_tiny", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_small", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) +mobs:spawn_specific("mobs_mc:magma_cube_big", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) +--mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) +--mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) +--mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 0bb03a9c7..1361e6a3a 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -87,7 +87,7 @@ cave_spider.sounds.base_pitch = 1.25 mobs:register_mob("mobs_mc:cave_spider", cave_spider) -mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:spider", "overworld", "ground", 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 1877a2104..2dbb7c557 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -62,7 +62,7 @@ mobs:register_mob("mobs_mc:squid", { local water = mobs_mc.spawn_height.water --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height -mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) +mobs:spawn_specific("mobs_mc:squid", "overworld", "water", 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) -- spawn eggs mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 68644266f..0b53d8015 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1074,7 +1074,7 @@ mobs:register_mob("mobs_mc:villager", { -mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index 09539fa76..bcede2183 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -146,8 +146,8 @@ mobs:register_mob("mobs_mc:villager_zombie", { harmed_by_heal = true, }) -mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index 383cbd36f..f9f9b8d1f 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:potion_arrow", { end }) --- TODO: Spawn when witch works properly +-- TODO: Spawn when witch works properly <- eventually -j4i --mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index fe3031895..953c2df72 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -232,6 +232,6 @@ end mobs:register_mob("mobs_mc:dog", dog) -- Spawn -mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:wolf", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index df9727d34..64f99d34d 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -135,11 +135,11 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning -mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:zombie", "overworld", "ground", 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:husk", "overworld", "ground", 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific("mobs_mc:baby_husk", "overworld", "ground", 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Spawn eggs mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index 8c29a4bff..e996425c8 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -111,12 +111,12 @@ baby_pigman.child = 1 mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) -- Regular spawning in the Nether -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific("mobs_mc:baby_pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Spawning in Nether portals in the Overworld -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +--mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0) From de41a4c26ba4d72091a26f969a435d4456a55ce0 Mon Sep 17 00:00:00 2001 From: kay27 Date: Thu, 8 Apr 2021 00:44:20 +0400 Subject: [PATCH 098/164] merge --- mods/ENTITIES/mcl_mobs/api.lua | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index d85633421..bf4880231 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -4277,13 +4277,14 @@ end --I'm not sure what this does but disabling it doesn't cause a crash -j4i +-- Just compatibility problem with outer mob mods currently, so adding a warning and temporarily enabling back -kay27 2021-04-08 -- MarkBu's spawn function ---[[ -function mobs:spawn(def) +function mobs:spawn(def) + minetest.log("warning", "[mcl_mobs] Deprecated function call: `mobs:spawn()`. Please use mobs:spawn_specific() instead!") local name = def.name local nodes = def.nodes or {"group:soil", "group:stone"} - local neighbors = def.neighbors or {"air"} +-- local neighbors = def.neighbors or {"air"} local min_light = def.min_light or 0 local max_light = def.max_light or 15 local interval = def.interval or 30 @@ -4294,10 +4295,16 @@ function mobs:spawn(def) local day_toggle = def.day_toggle local on_spawn = def.on_spawn - mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, + --mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, + -- chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + mobs:spawn_specific(name, "overworld", nodes, min_light, max_light, interval, + chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + mobs:spawn_specific(name, "end", nodes, min_light, max_light, interval, + chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + mobs:spawn_specific(name, "nether", nodes, min_light, max_light, interval, chance, active_object_count, min_height, max_height, day_toggle, on_spawn) end -]]-- + local axis @@ -4409,6 +4416,22 @@ minetest.register_globalstep(function(dtime) end --elseif mob_def.type == "lava" then --implement later + else -- mob_def.type is specific node name or group name + local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), mob_def.type) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + spawning_position.y = spawning_position.y + 1 + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end end --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) From d65a5e3be0a27f2c03ecc7a27e0032ec4e6e5fba Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Wed, 7 Apr 2021 23:07:04 -0400 Subject: [PATCH 099/164] Fix mobs colliding with objects --- mods/ENTITIES/mcl_mobs/api.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index bf4880231..8ab342ac5 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -866,10 +866,12 @@ local check_for_death = function(self, cause, cmi_cause) remove_texture_mod(self, "^[colorize:#FF000040") remove_texture_mod(self, "^[brighten") self.passive = true + self.object:set_properties({ pointable = false, collide_with_objects = false, }) + set_velocity(self, 0) local acc = self.object:get_acceleration() acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0 @@ -3418,7 +3420,6 @@ local mob_activate = function(self, staticdata, def, dtime) self.timer = 0 self.blinktimer = 0 self.blinkstatus = false - self.collide_with_objects = false -- check existing nametag if not self.nametag then @@ -3907,6 +3908,12 @@ minetest.register_entity(name, { on_detach_child = mob_detach_child, on_activate = function(self, staticdata, dtime) + --this is a temporary hack so mobs stop + --glitching and acting really weird with the + --default built in engine collision detection + self.object:set_properties({ + collide_with_objects = false, + }) return mob_activate(self, staticdata, def, dtime) end, @@ -4348,11 +4355,11 @@ end --todo mob limiting --MAIN LOOP -local timer = 0 +local timer = 15 --0 minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 0 + timer = 15--0 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(5) do local player_pos = player:get_pos() @@ -4361,6 +4368,7 @@ minetest.register_globalstep(function(dtime) local goal_pos = position_calculation(player_pos) + print(dump(minetest.get_biome_data(goal_pos))) local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] From 38dcbcb3d4d75bd4596d508e1a3b398bbb7ecf90 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Wed, 7 Apr 2021 23:16:03 -0400 Subject: [PATCH 100/164] Fix mobs colliding with other mobs/players --- mods/ENTITIES/mcl_mobs/api.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 8ab342ac5..7ec86a332 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -4359,7 +4359,7 @@ local timer = 15 --0 minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 15--0 + timer = 0--15--0 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(5) do local player_pos = player:get_pos() From abc68f4dc6a58b9c2e28d85771888fb955ed8c7e Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 02:07:15 -0400 Subject: [PATCH 101/164] Refactor spawning into it's own file --- mods/ENTITIES/mcl_mobs/api.lua | 554 ---------------------------- mods/ENTITIES/mcl_mobs/init.lua | 5 +- mods/ENTITIES/mcl_mobs/spawning.lua | 470 +++++++++++++++++++++++ mods/ENTITIES/mobs_mc/depends.txt | 1 + 4 files changed, 475 insertions(+), 555 deletions(-) create mode 100644 mods/ENTITIES/mcl_mobs/spawning.lua create mode 100644 mods/ENTITIES/mobs_mc/depends.txt diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 7ec86a332..daa209e9e 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -61,8 +61,6 @@ end -- Load settings local damage_enabled = minetest.settings:get_bool("enable_damage") -local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false - local disable_blood = minetest.settings:get_bool("mobs_disable_blood") local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false @@ -3931,558 +3929,6 @@ end end -- END mobs:register_mob function - - - - - - - - - - - - ---BEGIN SPAWNING ALGORITHM - - - - - - - - - - - - - - - --- count how many mobs of one type are inside an area ---[[ -local count_mobs = function(pos, mobtype) - - local num = 0 - local objs = minetest.get_objects_inside_radius(pos, aoc_range) - - for n = 1, #objs do - - local obj = objs[n]:get_luaentity() - - if obj and obj.name and obj._cmi_is_mob then - - -- count passive mobs only - if mobtype == "!passive" then - if obj.spawn_class == "passive" then - num = num + 1 - end - -- count hostile mobs only - elseif mobtype == "!hostile" then - if obj.spawn_class == "hostile" then - num = num + 1 - end - -- count ambient mobs only - elseif mobtype == "!ambient" then - if obj.spawn_class == "ambient" then - num = num + 1 - end - -- count water mobs only - elseif mobtype == "!water" then - if obj.spawn_class == "water" then - num = num + 1 - end - -- count mob type - elseif mobtype and obj.name == mobtype then - num = num + 1 - -- count total mobs - elseif not mobtype then - num = num + 1 - end - end - end - - return num -end -]]-- - --- global functions - -function mobs:spawn_abm_check(pos, node, name) - -- global function to add additional spawn checks - -- return true to stop spawning mob -end - - ---[[ - Custom elements changed: -name: -the mobs name - -dimension: -"overworld" -"nether" -"end" - -types of spawning: -"air" -"water" -"ground" -"lava" - -what is aoc??? - -WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? -]]-- - ---this is where all of the spawning information is kept -local spawn_dictionary = { - ["overworld"] = {}, - ["nether"] = {}, - ["end"] = {} -} - -function mobs:spawn_specific( - name, - dimension, - type_of_spawning, - min_light, - max_light, - interval, - chance, - aoc, - min_height, - max_height, - day_toggle, - on_spawn) - - - -- Do mobs spawn at all? - if not mobs_spawn then - return - end - - -- chance/spawn number override in minetest.conf for registered mob - local numbers = minetest.settings:get(name) - - if numbers then - numbers = numbers:split(",") - chance = tonumber(numbers[1]) or chance - aoc = tonumber(numbers[2]) or aoc - - if chance == 0 then - minetest.log("warning", string.format("[mobs] %s has spawning disabled", name)) - return - end - - minetest.log("action", - string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) - end - - local spawn_action - spawn_action = function(pos, node, active_object_count, active_object_count_wider, name) - - local orig_pos = table.copy(pos) - -- is mob actually registered? - if not mobs.spawning_mobs[name] - or not minetest.registered_entities[name] then - minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!") - return - end - - -- additional custom checks for spawning mob - if mobs:spawn_abm_check(pos, node, name) == true then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!") - return - end - - -- count nearby mobs in same spawn class - local entdef = minetest.registered_entities[name] - local spawn_class = entdef and entdef.spawn_class - if not spawn_class then - if entdef.type == "monster" then - spawn_class = "hostile" - else - spawn_class = "passive" - end - end - local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class] - -- do not spawn if too many of same mob in area - if active_object_count_wider >= max_per_block -- large-range mob cap - or (not in_class_cap) -- spawn class mob cap - or count_mobs(pos, name) >= aoc then -- per-mob mob cap - -- too many entities - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!") - return - end - - -- if toggle set to nil then ignore day/night check - if day_toggle ~= nil then - - local tod = (minetest.get_timeofday() or 0) * 24000 - - if tod > 4500 and tod < 19500 then - -- daylight, but mob wants night - if day_toggle == false then - -- mob needs night - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!") - return - end - else - -- night time but mob wants day - if day_toggle == true then - -- mob needs day - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!") - return - end - end - end - - -- spawn above node - pos.y = pos.y + 1 - - -- only spawn away from player - local objs = minetest.get_objects_inside_radius(pos, 24) - - for n = 1, #objs do - - if objs[n]:is_player() then - -- player too close - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!") - return - end - end - - -- mobs cannot spawn in protected areas when enabled - if not spawn_protected - and minetest.is_protected(pos, "") then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!") - return - end - - -- are we spawning within height limits? - if pos.y > max_height - or pos.y < min_height then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!") - return - end - - -- are light levels ok? - local light = minetest.get_node_light(pos) - if not light - or light > max_light - or light < min_light then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!") - return - end - - -- do we have enough space to spawn mob? - local ent = minetest.registered_entities[name] - local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1])) - local min_x, max_x - if width_x % 2 == 0 then - max_x = math.floor(width_x/2) - min_x = -(max_x-1) - else - max_x = math.floor(width_x/2) - min_x = -max_x - end - - local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3])) - local min_z, max_z - if width_z % 2 == 0 then - max_z = math.floor(width_z/2) - min_z = -(max_z-1) - else - max_z = math.floor(width_z/2) - min_z = -max_z - end - - local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1) - - for y = 0, max_y do - for x = min_x, max_x do - for z = min_z, max_z do - local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z} - if minetest.registered_nodes[node_ok(pos2).name].walkable == true then - -- inside block - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!") - if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then - minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative) - spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative) - end - return - end - end - end - end - - -- tweak X/Y/Z spawn pos - if width_x % 2 == 0 then - pos.x = pos.x + 0.5 - end - if width_z % 2 == 0 then - pos.z = pos.z + 0.5 - end - pos.y = pos.y - 0.5 - - local mob = minetest.add_entity(pos, name) - minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos)) - - if on_spawn then - - local ent = mob:get_luaentity() - - on_spawn(ent, pos) - end - end - - local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider) - spawn_action(pos, node, active_object_count, active_object_count_wider, name) - end - - - --load information into the spawn dictionary - local key = #spawn_dictionary[dimension] + 1 - - spawn_dictionary[dimension][key] = {} - spawn_dictionary[dimension][key]["name"] = name - spawn_dictionary[dimension][key]["type"] = type_of_spawning - spawn_dictionary[dimension][key]["min_light"] = min_light - spawn_dictionary[dimension][key]["max_light"] = max_light - spawn_dictionary[dimension][key]["interval"] = interval - spawn_dictionary[dimension][key]["chance"] = chance - spawn_dictionary[dimension][key]["aoc"] = aoc - spawn_dictionary[dimension][key]["min_height"] = min_height - spawn_dictionary[dimension][key]["max_height"] = max_height - spawn_dictionary[dimension][key]["day_toggle"] = day_toggle - spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action - - --[[ - minetest.register_abm({ - label = name .. " spawning", - nodenames = nodes, - neighbors = neighbors, - interval = interval, - chance = floor(max(1, chance * mobs_spawn_chance)), - catch_up = false, - action = spawn_abm_action, - }) - ]]-- -end - - --- compatibility with older mob registration --- we're going to forget about this for now -j4i ---[[ -function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) - - mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, - chance, active_object_count, -31000, max_height, day_toggle) -end -]]-- - - ---I'm not sure what this does but disabling it doesn't cause a crash -j4i --- Just compatibility problem with outer mob mods currently, so adding a warning and temporarily enabling back -kay27 2021-04-08 --- MarkBu's spawn function - -function mobs:spawn(def) - minetest.log("warning", "[mcl_mobs] Deprecated function call: `mobs:spawn()`. Please use mobs:spawn_specific() instead!") - local name = def.name - local nodes = def.nodes or {"group:soil", "group:stone"} --- local neighbors = def.neighbors or {"air"} - local min_light = def.min_light or 0 - local max_light = def.max_light or 15 - local interval = def.interval or 30 - local chance = def.chance or 5000 - local active_object_count = def.active_object_count or 1 - local min_height = def.min_height or -31000 - local max_height = def.max_height or 31000 - local day_toggle = def.day_toggle - local on_spawn = def.on_spawn - - --mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, - -- chance, active_object_count, min_height, max_height, day_toggle, on_spawn) - mobs:spawn_specific(name, "overworld", nodes, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) - mobs:spawn_specific(name, "end", nodes, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) - mobs:spawn_specific(name, "nether", nodes, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) -end - - - -local axis ---inner and outer part of square donut radius -local inner = 1 -local outer = 70 -local int = {-1,1} -local position_calculation = function(pos) - - pos = vector.floor(pos) - - --this is used to determine the axis buffer from the player - axis = math.random(0,1) - - --cast towards the direction - if axis == 0 then --x - pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)] - pos.z = pos.z + math.random(-outer,outer) - else --z - pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)] - pos.x = pos.x + math.random(-outer,outer) - end - return(pos) -end - ---[[ -local decypher_limits_dictionary = { - ["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max}, - ["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max}, - ["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max} -} -]]-- - -local function decypher_limits(posy) - --local min_max_table = decypher_limits_dictionary[dimension] - --return min_max_table[1],min_max_table[2] - posy = math.floor(posy) - return posy - 32, posy + 32 -end - - ---todo mob limiting ---MAIN LOOP -local timer = 15 --0 -minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer >= 15 then - timer = 0--15--0 - for _,player in ipairs(minetest.get_connected_players()) do - for i = 1,math.random(5) do - local player_pos = player:get_pos() - local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - local min,max = decypher_limits(player_pos.y) - - local goal_pos = position_calculation(player_pos) - - print(dump(minetest.get_biome_data(goal_pos))) - - local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] - - if not mob_def then --to catch a crazy error if it ever happens - minetest.log("error", "WARNING!! mob spawning attempted to index a NIL mob!") - goto continue - end - - if mob_def.type == "ground" then - - local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - spawning_position.y = spawning_position.y + 1 - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - elseif mob_def.type == "air" then - local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - elseif mob_def.type == "water" then - local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - --elseif mob_def.type == "lava" then - --implement later - else -- mob_def.type is specific node name or group name - local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), mob_def.type) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - spawning_position.y = spawning_position.y + 1 - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - end - --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) - - - ::continue:: --this is a safety catch - end - end - end -end) - - - - - - - - - - - - - ---END SPAWNING ALGORITHM - - - - - - - - - - - - - - - - - - - - -- register arrow for shoot attack function mobs:register_arrow(name, def) diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index c2d6cb21b..69246b470 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -4,8 +4,11 @@ local path = minetest.get_modpath(minetest.get_current_modname()) -- Mob API dofile(path .. "/api.lua") +-- Spawning Algorithm +dofile(path .. "/spawning.lua") + -- Rideable Mobs dofile(path .. "/mount.lua") -- Mob Items -dofile(path .. "/crafts.lua") +dofile(path .. "/crafts.lua") \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua new file mode 100644 index 000000000..b56fe1cee --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -0,0 +1,470 @@ +local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false +-- count how many mobs of one type are inside an area +--[[ +local count_mobs = function(pos, mobtype) + + local num = 0 + local objs = minetest.get_objects_inside_radius(pos, aoc_range) + + for n = 1, #objs do + + local obj = objs[n]:get_luaentity() + + if obj and obj.name and obj._cmi_is_mob then + + -- count passive mobs only + if mobtype == "!passive" then + if obj.spawn_class == "passive" then + num = num + 1 + end + -- count hostile mobs only + elseif mobtype == "!hostile" then + if obj.spawn_class == "hostile" then + num = num + 1 + end + -- count ambient mobs only + elseif mobtype == "!ambient" then + if obj.spawn_class == "ambient" then + num = num + 1 + end + -- count water mobs only + elseif mobtype == "!water" then + if obj.spawn_class == "water" then + num = num + 1 + end + -- count mob type + elseif mobtype and obj.name == mobtype then + num = num + 1 + -- count total mobs + elseif not mobtype then + num = num + 1 + end + end + end + + return num +end +]]-- + +-- global functions + +function mobs:spawn_abm_check(pos, node, name) + -- global function to add additional spawn checks + -- return true to stop spawning mob +end + + +--[[ + Custom elements changed: +name: +the mobs name + +dimension: +"overworld" +"nether" +"end" + +types of spawning: +"air" +"water" +"ground" +"lava" + +what is aoc??? + +WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? +]]-- + +--this is where all of the spawning information is kept +local spawn_dictionary = { + ["overworld"] = {}, + ["nether"] = {}, + ["end"] = {} +} + +function mobs:spawn_specific(name, dimension, type_of_spawning, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) + -- Do mobs spawn at all? + if not mobs_spawn then + return + end + + -- chance/spawn number override in minetest.conf for registered mob + local numbers = minetest.settings:get(name) + + if numbers then + numbers = numbers:split(",") + chance = tonumber(numbers[1]) or chance + aoc = tonumber(numbers[2]) or aoc + + if chance == 0 then + minetest.log("warning", string.format("[mobs] %s has spawning disabled", name)) + return + end + + minetest.log("action", + string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) + end + + local spawn_action + spawn_action = function(pos, node, active_object_count, active_object_count_wider, name) + + local orig_pos = table.copy(pos) + -- is mob actually registered? + if not mobs.spawning_mobs[name] + or not minetest.registered_entities[name] then + minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!") + return + end + + -- additional custom checks for spawning mob + if mobs:spawn_abm_check(pos, node, name) == true then + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!") + return + end + + -- count nearby mobs in same spawn class + local entdef = minetest.registered_entities[name] + local spawn_class = entdef and entdef.spawn_class + if not spawn_class then + if entdef.type == "monster" then + spawn_class = "hostile" + else + spawn_class = "passive" + end + end + local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class] + -- do not spawn if too many of same mob in area + if active_object_count_wider >= max_per_block -- large-range mob cap + or (not in_class_cap) -- spawn class mob cap + or count_mobs(pos, name) >= aoc then -- per-mob mob cap + -- too many entities + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!") + return + end + + -- if toggle set to nil then ignore day/night check + if day_toggle ~= nil then + + local tod = (minetest.get_timeofday() or 0) * 24000 + + if tod > 4500 and tod < 19500 then + -- daylight, but mob wants night + if day_toggle == false then + -- mob needs night + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!") + return + end + else + -- night time but mob wants day + if day_toggle == true then + -- mob needs day + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!") + return + end + end + end + + -- spawn above node + pos.y = pos.y + 1 + + -- only spawn away from player + local objs = minetest.get_objects_inside_radius(pos, 24) + + for n = 1, #objs do + + if objs[n]:is_player() then + -- player too close + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!") + return + end + end + + -- mobs cannot spawn in protected areas when enabled + if not spawn_protected + and minetest.is_protected(pos, "") then + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!") + return + end + + -- are we spawning within height limits? + if pos.y > max_height + or pos.y < min_height then + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!") + return + end + + -- are light levels ok? + local light = minetest.get_node_light(pos) + if not light + or light > max_light + or light < min_light then + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!") + return + end + + -- do we have enough space to spawn mob? + local ent = minetest.registered_entities[name] + local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1])) + local min_x, max_x + if width_x % 2 == 0 then + max_x = math.floor(width_x/2) + min_x = -(max_x-1) + else + max_x = math.floor(width_x/2) + min_x = -max_x + end + + local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3])) + local min_z, max_z + if width_z % 2 == 0 then + max_z = math.floor(width_z/2) + min_z = -(max_z-1) + else + max_z = math.floor(width_z/2) + min_z = -max_z + end + + local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1) + + for y = 0, max_y do + for x = min_x, max_x do + for z = min_z, max_z do + local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z} + if minetest.registered_nodes[node_ok(pos2).name].walkable == true then + -- inside block + minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!") + if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then + minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative) + spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative) + end + return + end + end + end + end + + -- tweak X/Y/Z spawn pos + if width_x % 2 == 0 then + pos.x = pos.x + 0.5 + end + if width_z % 2 == 0 then + pos.z = pos.z + 0.5 + end + pos.y = pos.y - 0.5 + + local mob = minetest.add_entity(pos, name) + minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos)) + + if on_spawn then + + local ent = mob:get_luaentity() + + on_spawn(ent, pos) + end + end + + local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider) + spawn_action(pos, node, active_object_count, active_object_count_wider, name) + end + + + --load information into the spawn dictionary + local key = #spawn_dictionary[dimension] + 1 + + spawn_dictionary[dimension][key] = {} + spawn_dictionary[dimension][key]["name"] = name + spawn_dictionary[dimension][key]["type"] = type_of_spawning + spawn_dictionary[dimension][key]["min_light"] = min_light + spawn_dictionary[dimension][key]["max_light"] = max_light + spawn_dictionary[dimension][key]["interval"] = interval + spawn_dictionary[dimension][key]["chance"] = chance + spawn_dictionary[dimension][key]["aoc"] = aoc + spawn_dictionary[dimension][key]["min_height"] = min_height + spawn_dictionary[dimension][key]["max_height"] = max_height + spawn_dictionary[dimension][key]["day_toggle"] = day_toggle + spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action + + --[[ + minetest.register_abm({ + label = name .. " spawning", + nodenames = nodes, + neighbors = neighbors, + interval = interval, + chance = floor(max(1, chance * mobs_spawn_chance)), + catch_up = false, + action = spawn_abm_action, + }) + ]]-- +end + + +-- compatibility with older mob registration +-- we're going to forget about this for now -j4i +--[[ +function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) + + mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, + chance, active_object_count, -31000, max_height, day_toggle) +end +]]-- + + +--I'm not sure what this does but disabling it doesn't cause a crash -j4i +-- MarkBu's spawn function + +function mobs:spawn(def) + --does nothing for now + --[[ + local name = def.name + local nodes = def.nodes or {"group:soil", "group:stone"} + local neighbors = def.neighbors or {"air"} + local min_light = def.min_light or 0 + local max_light = def.max_light or 15 + local interval = def.interval or 30 + local chance = def.chance or 5000 + local active_object_count = def.active_object_count or 1 + local min_height = def.min_height or -31000 + local max_height = def.max_height or 31000 + local day_toggle = def.day_toggle + local on_spawn = def.on_spawn + + mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, + chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + ]]-- +end + + + +local axis +--inner and outer part of square donut radius +local inner = 1 +local outer = 70 +local int = {-1,1} +local position_calculation = function(pos) + + pos = vector.floor(pos) + + --this is used to determine the axis buffer from the player + axis = math.random(0,1) + + --cast towards the direction + if axis == 0 then --x + pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)] + pos.z = pos.z + math.random(-outer,outer) + else --z + pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)] + pos.x = pos.x + math.random(-outer,outer) + end + return(pos) +end + +--[[ +local decypher_limits_dictionary = { + ["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max}, + ["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max}, + ["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max} +} +]]-- + +local function decypher_limits(posy) + --local min_max_table = decypher_limits_dictionary[dimension] + --return min_max_table[1],min_max_table[2] + posy = math.floor(posy) + return posy - 32, posy + 32 +end + +minetest.register_on_mods_loaded(function() + for _,data in pairs(minetest.registered_biomes) do + print(data.name) + end + + print(dump(spawn_dictionary)) +end) + +--todo mob limiting +--MAIN LOOP +if mobs_spawn then + local timer = 15 --0 + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 15 then + timer = 0--15--0 + for _,player in ipairs(minetest.get_connected_players()) do + for i = 1,math.random(5) do + local player_pos = player:get_pos() + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + local min,max = decypher_limits(player_pos.y) + + local goal_pos = position_calculation(player_pos) + + local gotten_biome = minetest.get_biome_data(goal_pos) + + if not gotten_biome then + goto continue --skip if in unloaded area + end + + --print(minetest.get_biome_name(gotten_biome.biome)) + + local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] + + if not mob_def then --to catch a crazy error if it ever happens + minetest.log("error", "WARNING!! Attempted to spawn a mob that doesn't exist! Please notify developers!\nThe game will continue to run though.") + goto continue + end + + if mob_def.type == "ground" then + + local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + spawning_position.y = spawning_position.y + 1 + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + elseif mob_def.type == "air" then + local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + elseif mob_def.type == "water" then + local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"}) + + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + + local gotten_light = minetest.get_node_light(spawning_position) + + if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + minetest.add_entity(spawning_position, mob_def.name) + end + --elseif mob_def.type == "lava" then + --implement later + end + --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) + + ::continue:: --this is a safety catch + end + end + end + end) +end \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/depends.txt b/mods/ENTITIES/mobs_mc/depends.txt new file mode 100644 index 000000000..674eb8094 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/depends.txt @@ -0,0 +1 @@ +mcl_mobs \ No newline at end of file From cb093b774ca946863e2ee09d49aec6d3d36300ac Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 06:04:36 -0400 Subject: [PATCH 102/164] Add biome list --- mods/ENTITIES/mcl_mobs/spawning.lua | 163 ++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index b56fe1cee..9ea774ba9 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -1,3 +1,166 @@ +--[[ + +THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs + +underground: +FlowerForest_underground +JungleEdge_underground +StoneBeach_underground +MesaBryce_underground +Mesa_underground +RoofedForest_underground +Jungle_underground +Swampland_underground +MushroomIsland_underground +BirchForest_underground +Plains_underground +MesaPlateauF_underground +ExtremeHills_underground +MegaSpruceTaiga_underground +BirchForestM_underground +SavannaM_underground +MesaPlateauFM_underground +Desert_underground +Savanna_underground +Forest_underground +SunflowerPlains_underground +ColdTaiga_underground +IcePlains_underground +IcePlainsSpikes_underground +MegaTaiga_underground +Taiga_underground +ExtremeHills+_underground +JungleM_underground +ExtremeHillsM_underground +JungleEdgeM_underground + +ocean: +RoofedForest_ocean +JungleEdgeM_ocean +BirchForestM_ocean +BirchForest_ocean +IcePlains_deep_ocean +Jungle_deep_ocean +Savanna_ocean +MesaPlateauF_ocean +ExtremeHillsM_deep_ocean +Savanna_deep_ocean +SunflowerPlains_ocean +Swampland_deep_ocean +Swampland_ocean +MegaSpruceTaiga_deep_ocean +ExtremeHillsM_ocean +JungleEdgeM_deep_ocean +SunflowerPlains_deep_ocean +BirchForest_deep_ocean +IcePlainsSpikes_ocean +Mesa_ocean +StoneBeach_ocean +Plains_deep_ocean +JungleEdge_deep_ocean +SavannaM_deep_ocean +Desert_deep_ocean +Mesa_deep_ocean +ColdTaiga_deep_ocean +Plains_ocean +MesaPlateauFM_ocean +Forest_deep_ocean +JungleM_deep_ocean +FlowerForest_deep_ocean +MushroomIsland_ocean +MegaTaiga_ocean +StoneBeach_deep_ocean +IcePlainsSpikes_deep_ocean +ColdTaiga_ocean +SavannaM_ocean +MesaPlateauF_deep_ocean +MesaBryce_deep_ocean +ExtremeHills+_deep_ocean +ExtremeHills_ocean +MushroomIsland_deep_ocean +Forest_ocean +MegaTaiga_deep_ocean +JungleEdge_ocean +MesaBryce_ocean +MegaSpruceTaiga_ocean +ExtremeHills+_ocean +Jungle_ocean +RoofedForest_deep_ocean +IcePlains_ocean +FlowerForest_ocean +ExtremeHills_deep_ocean +MesaPlateauFM_deep_ocean +Desert_ocean +Taiga_ocean +BirchForestM_deep_ocean +Taiga_deep_ocean +JungleM_ocean + +water or beach? +MesaPlateauFM_sandlevel +MesaPlateauF_sandlevel +MesaBryce_sandlevel +Mesa_sandlevel + +beach: +FlowerForest_beach +Forest_beach +StoneBeach +ColdTaiga_beach_water +Taiga_beach +Savanna_beach +Plains_beach +ExtremeHills_beach +ColdTaiga_beach +Swampland_shore +MushroomIslandShore +JungleM_shore +Jungle_shore + +dimension biome: +Nether +End + +Overworld regular: +Mesa +FlowerForest +Swampland +Taiga +ExtremeHills +Jungle +Savanna +BirchForest +MegaSpruceTaiga +MegaTaiga +ExtremeHills+ +Forest +Plains +Desert +ColdTaiga +MushroomIsland +IcePlainsSpikes +SunflowerPlains +IcePlains +RoofedForest + +I have no idea: +ExtremeHills+_snowtop +MesaPlateauFM_grasstop +JungleEdgeM +ExtremeHillsM +JungleM +BirchForestM +MesaPlateauF +MesaPlateauFM +MesaPlateauF_grasstop +MesaBryce +JungleEdge +SavannaM +]]-- + + + + local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false -- count how many mobs of one type are inside an area --[[ From 89f35c06af2e00150e90cfd8cb26552f99c9903e Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 06:10:07 -0400 Subject: [PATCH 103/164] Ignore default or void dimensions --- mods/ENTITIES/mcl_mobs/spawning.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 9ea774ba9..765c78ba0 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -551,11 +551,16 @@ if mobs_spawn then minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 0--15--0 + timer = 15--0 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(5) do local player_pos = player:get_pos() local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + + if dimension == "void" or dimension == "default" then + goto continue -- ignore void and unloaded area + end + local min,max = decypher_limits(player_pos.y) local goal_pos = position_calculation(player_pos) @@ -566,7 +571,7 @@ if mobs_spawn then goto continue --skip if in unloaded area end - --print(minetest.get_biome_name(gotten_biome.biome)) + print(minetest.get_biome_name(gotten_biome.biome)) local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] From 34b66acc9d2b9fcc54712d2cc603d52e3042ca69 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 06:48:25 -0400 Subject: [PATCH 104/164] Make reference list copy-pastable --- mods/ENTITIES/mcl_mobs/spawning.lua | 307 ++++++++++++++-------------- 1 file changed, 159 insertions(+), 148 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 765c78ba0..40c9ee7a9 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -3,159 +3,159 @@ THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs underground: -FlowerForest_underground -JungleEdge_underground -StoneBeach_underground -MesaBryce_underground -Mesa_underground -RoofedForest_underground -Jungle_underground -Swampland_underground -MushroomIsland_underground -BirchForest_underground -Plains_underground -MesaPlateauF_underground -ExtremeHills_underground -MegaSpruceTaiga_underground -BirchForestM_underground -SavannaM_underground -MesaPlateauFM_underground -Desert_underground -Savanna_underground -Forest_underground -SunflowerPlains_underground -ColdTaiga_underground -IcePlains_underground -IcePlainsSpikes_underground -MegaTaiga_underground -Taiga_underground -ExtremeHills+_underground -JungleM_underground -ExtremeHillsM_underground -JungleEdgeM_underground +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", ocean: -RoofedForest_ocean -JungleEdgeM_ocean -BirchForestM_ocean -BirchForest_ocean -IcePlains_deep_ocean -Jungle_deep_ocean -Savanna_ocean -MesaPlateauF_ocean -ExtremeHillsM_deep_ocean -Savanna_deep_ocean -SunflowerPlains_ocean -Swampland_deep_ocean -Swampland_ocean -MegaSpruceTaiga_deep_ocean -ExtremeHillsM_ocean -JungleEdgeM_deep_ocean -SunflowerPlains_deep_ocean -BirchForest_deep_ocean -IcePlainsSpikes_ocean -Mesa_ocean -StoneBeach_ocean -Plains_deep_ocean -JungleEdge_deep_ocean -SavannaM_deep_ocean -Desert_deep_ocean -Mesa_deep_ocean -ColdTaiga_deep_ocean -Plains_ocean -MesaPlateauFM_ocean -Forest_deep_ocean -JungleM_deep_ocean -FlowerForest_deep_ocean -MushroomIsland_ocean -MegaTaiga_ocean -StoneBeach_deep_ocean -IcePlainsSpikes_deep_ocean -ColdTaiga_ocean -SavannaM_ocean -MesaPlateauF_deep_ocean -MesaBryce_deep_ocean -ExtremeHills+_deep_ocean -ExtremeHills_ocean -MushroomIsland_deep_ocean -Forest_ocean -MegaTaiga_deep_ocean -JungleEdge_ocean -MesaBryce_ocean -MegaSpruceTaiga_ocean -ExtremeHills+_ocean -Jungle_ocean -RoofedForest_deep_ocean -IcePlains_ocean -FlowerForest_ocean -ExtremeHills_deep_ocean -MesaPlateauFM_deep_ocean -Desert_ocean -Taiga_ocean -BirchForestM_deep_ocean -Taiga_deep_ocean -JungleM_ocean +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", water or beach? -MesaPlateauFM_sandlevel -MesaPlateauF_sandlevel -MesaBryce_sandlevel -Mesa_sandlevel +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", beach: -FlowerForest_beach -Forest_beach -StoneBeach -ColdTaiga_beach_water -Taiga_beach -Savanna_beach -Plains_beach -ExtremeHills_beach -ColdTaiga_beach -Swampland_shore -MushroomIslandShore -JungleM_shore -Jungle_shore +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", dimension biome: -Nether -End +"Nether", +"End", Overworld regular: -Mesa -FlowerForest -Swampland -Taiga -ExtremeHills -Jungle -Savanna -BirchForest -MegaSpruceTaiga -MegaTaiga -ExtremeHills+ -Forest -Plains -Desert -ColdTaiga -MushroomIsland -IcePlainsSpikes -SunflowerPlains -IcePlains -RoofedForest +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", I have no idea: -ExtremeHills+_snowtop -MesaPlateauFM_grasstop -JungleEdgeM -ExtremeHillsM -JungleM -BirchForestM -MesaPlateauF -MesaPlateauFM -MesaPlateauF_grasstop -MesaBryce -JungleEdge -SavannaM +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", ]]-- @@ -219,6 +219,7 @@ end --[[ Custom elements changed: + name: the mobs name @@ -233,7 +234,11 @@ types of spawning: "ground" "lava" -what is aoc??? +biomes: tells the spawner to allow certain mobs to spawn in certain biomes +{"this", "that", "grasslands", "whatever"} + + +what is aoc??? objects in area WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? ]]-- @@ -245,7 +250,10 @@ local spawn_dictionary = { ["end"] = {} } -function mobs:spawn_specific(name, dimension, type_of_spawning, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) +function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) + + print(dump(bimoes)) + -- Do mobs spawn at all? if not mobs_spawn then return @@ -472,7 +480,7 @@ end ]]-- ---I'm not sure what this does but disabling it doesn't cause a crash -j4i +--Don't disable this yet-j4i -- MarkBu's spawn function function mobs:spawn(def) @@ -546,6 +554,7 @@ end) --todo mob limiting --MAIN LOOP +--[[ if mobs_spawn then local timer = 15 --0 minetest.register_globalstep(function(dtime) @@ -557,9 +566,10 @@ if mobs_spawn then local player_pos = player:get_pos() local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - if dimension == "void" or dimension == "default" then - goto continue -- ignore void and unloaded area - end + if dimension == "void" or dimension == "default" then + goto continue -- ignore void and unloaded area + end + local min,max = decypher_limits(player_pos.y) @@ -635,4 +645,5 @@ if mobs_spawn then end end end) -end \ No newline at end of file +end +]]-- \ No newline at end of file From 249a3c8891ed049f672bac6956c224a7488b4cf5 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 06:57:24 -0400 Subject: [PATCH 105/164] Add bats, chicken, and blaze spawn info --- mods/ENTITIES/mcl_mobs/spawning.lua | 7 ++- mods/ENTITIES/mobs_mc/bat.lua | 76 ++++++++++++++++++++++++++++- mods/ENTITIES/mobs_mc/blaze.lua | 13 ++++- mods/ENTITIES/mobs_mc/chicken.lua | 29 ++++++++++- 4 files changed, 118 insertions(+), 7 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 40c9ee7a9..515dbaf3d 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -142,8 +142,6 @@ Overworld regular: "SunflowerPlains", "IcePlains", "RoofedForest", - -I have no idea: "ExtremeHills+_snowtop", "MesaPlateauFM_grasstop", "JungleEdgeM", @@ -252,7 +250,7 @@ local spawn_dictionary = { function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) - print(dump(bimoes)) + print(dump(biomes)) -- Do mobs spawn at all? if not mobs_spawn then @@ -543,7 +541,7 @@ local function decypher_limits(posy) posy = math.floor(posy) return posy - 32, posy + 32 end - +--[[ minetest.register_on_mods_loaded(function() for _,data in pairs(minetest.registered_biomes) do print(data.name) @@ -551,6 +549,7 @@ minetest.register_on_mods_loaded(function() print(dump(spawn_dictionary)) end) +]]-- --todo mob limiting --MAIN LOOP diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index b6825bbbf..a525f5583 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -64,7 +64,81 @@ else end -- Spawn on solid blocks at or below Sea level and the selected light level -mobs:spawn_specific("mobs_mc:bat", "overworld", "air", 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) +mobs:spawn_specific( +"mobs_mc:bat", +"overworld", +"air", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +}, +0, +maxlight, +20, +5000, +2, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.water-1) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index d56acdf38..847e2f4a5 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -128,7 +128,18 @@ mobs:register_mob("mobs_mc:blaze", { end, }) -mobs:spawn_specific("mobs_mc:blaze", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:blaze", +"nether", +"ground", +{"Nether"}, +0, +minetest.LIGHT_MAX+1, +30, +5000, +3, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- Blaze fireball mobs:register_arrow("mobs_mc:blaze_fireball", { diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 397b6b8da..43044aae0 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -100,7 +100,34 @@ mobs:register_mob("mobs_mc:chicken", { }) --spawn -mobs:spawn_specific("mobs_mc:chicken", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:chicken", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +} +9, +minetest.LIGHT_MAX+1, +30, 17000, +3, +mobs_mc.spawn_height.spawn_height.water, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) From c259fc2a28af4e5020d21989955a89cf9d7f6eaf Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 07:39:18 -0400 Subject: [PATCH 106/164] Add in all biome information to mobs --- mods/ENTITIES/mobs_mc/chicken.lua | 4 +- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 49 ++++- mods/ENTITIES/mobs_mc/creeper.lua | 153 +++++++++++++- mods/ENTITIES/mobs_mc/enderman.lua | 184 ++++++++++++++++- mods/ENTITIES/mobs_mc/ghast.lua | 15 +- mods/ENTITIES/mobs_mc/horse.lua | 52 ++++- mods/ENTITIES/mobs_mc/llama.lua | 20 +- mods/ENTITIES/mobs_mc/ocelot.lua | 18 +- mods/ENTITIES/mobs_mc/parrot.lua | 18 +- mods/ENTITIES/mobs_mc/pig.lua | 30 ++- mods/ENTITIES/mobs_mc/polar_bear.lua | 18 +- mods/ENTITIES/mobs_mc/sheep.lua | 30 ++- mods/ENTITIES/mobs_mc/shulker.lua | 15 +- mods/ENTITIES/mobs_mc/silverfish.lua | 22 +- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 188 ++++++++++++++++- mods/ENTITIES/mobs_mc/skeleton_wither.lua | 17 +- mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 182 ++++++++++++++++- mods/ENTITIES/mobs_mc/spider.lua | 153 +++++++++++++- mods/ENTITIES/mobs_mc/squid.lua | 153 +++++++++++++- mods/ENTITIES/mobs_mc/villager.lua | 30 ++- mods/ENTITIES/mobs_mc/wolf.lua | 30 ++- mods/ENTITIES/mobs_mc/zombie.lua | 224 ++++++++++++++++++++- mods/ENTITIES/mobs_mc/zombiepig.lua | 30 ++- 23 files changed, 1589 insertions(+), 46 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 43044aae0..246bf216a 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -121,12 +121,12 @@ mobs:spawn_specific( "MesaPlateauFM_grasstop", "ExtremeHillsM", "BirchForestM", -} +}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, -mobs_mc.spawn_height.spawn_height.water, +mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index a094d6d35..656570a83 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -145,9 +145,52 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning -mobs:spawn_specific("mobs_mc:cow", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) ---WARNING: THIS NEEDS A BIOME INTEGRATION -mobs:spawn_specific("mobs_mc:mooshroom", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:cow", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +9, +minetest.LIGHT_MAX+1, +30, +17000, +10, +mobs_mc.spawn_height.water, +mobs_mc.spawn_height.overworld_max) + + +mobs:spawn_specific( +"mobs_mc:mooshroom", +"overworld", +"ground", +{ +"MushroomIslandShore", +"MushroomIsland" +}, +9, +minetest.LIGHT_MAX+1, +30, +17000, +5, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index f1f0a3ef6..0c884d569 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -253,7 +253,158 @@ mobs:register_mob("mobs_mc:creeper_charged", { glow = 3, }) -mobs:spawn_specific("mobs_mc:creeper", "overworld", "ground", 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:creeper", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +20, +16500, +2, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index ca3bc84ce..ba04f8b59 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -562,11 +562,189 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn -mobs:spawn_specific("mobs_mc:enderman", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific( +"mobs_mc:enderman", +"end", +"ground", +{ +"End" +}, +0, +minetest.LIGHT_MAX+1, +30, +3000, +12, +mobs_mc.spawn_height.end_min, +mobs_mc.spawn_height.end_max) -- Overworld spawn -mobs:spawn_specific("mobs_mc:enderman", "overworld", "ground", 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:enderman", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +30, +19000, +2, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) + -- Nether spawn (rare) -mobs:spawn_specific("mobs_mc:enderman", "nether", "ground", 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:enderman", +"nether", +"ground", +{ +"Nether" +}, +0, +7, +30, +27500, +4, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- spawn eggs mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index e2f6b1369..9c3e0cee1 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -75,7 +75,20 @@ mobs:register_mob("mobs_mc:ghast", { }) -mobs:spawn_specific("mobs_mc:ghast", "nether", "air", 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:ghast", +"nether", +"air", +{ +"Nether" +}, +0, +minetest.LIGHT_MAX+1, +30, +18000, +2, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- fireball (projectile) mobs:register_arrow("mobs_mc:fireball", { diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 00c292c1d..938a6b6ac 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -510,8 +510,56 @@ mobs:register_mob("mobs_mc:mule", mule) --=========================== --Spawn Function -mobs:spawn_specific("mobs_mc:horse", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:donkey", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:horse", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mobs_mc.spawn_height.water+3, +mobs_mc.spawn_height.overworld_max) + + +mobs:spawn_specific( +"mobs_mc:donkey", +"overworld", +"ground", +{ +"Mesa", +"MesaPlateauFM_grasstop", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mobs_mc.spawn_height.water+3, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 0efb8e0ab..8ff82b502 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -217,7 +217,25 @@ mobs:register_mob("mobs_mc:llama", { }) --spawn -mobs:spawn_specific("mobs_mc:llama", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:llama", +"overworld", +"ground", +{ +"Mesa", +"MesaPlateauFM_grasstop", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +5, +mobs_mc.spawn_height.water+15, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 3b5273185..f3c8c87ae 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -153,7 +153,23 @@ local base_spawn_chance = 5000 -- Spawn ocelot --they get the same as the llama because I'm trying to rework so much of this code right now -j4i -mobs:spawn_specific("mobs_mc:ocelot", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:ocelot", +"overworld", +"ground", +{ +"Jungle", +"JungleEdgeM", +"JungleM", +"JungleEdge", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +5, +mobs_mc.spawn_height.water+15, +mobs_mc.spawn_height.overworld_max) --[[ mobs:spawn({ name = "mobs_mc:ocelot", diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index c67263fb9..60329211e 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -91,7 +91,23 @@ mobs:register_mob("mobs_mc:parrot", { }) -- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i -mobs:spawn_specific("mobs_mc:parrot","overworld", "air", 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:parrot", +"overworld", +"air", +{ +"Jungle", +"JungleEdgeM", +"JungleM", +"JungleEdge", +}, +0, +minetest.LIGHT_MAX+1, +7, +30000, +1, +mobs_mc.spawn_height.water+7, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 143fcb495..b7cdf1afe 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -182,7 +182,35 @@ mobs:register_mob("mobs_mc:pig", { end, }) -mobs:spawn_specific("mobs_mc:pig", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:pig", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +9, +minetest.LIGHT_MAX+1, +30, +15000, +8, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 745c13a26..5d2853f6d 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -67,7 +67,23 @@ mobs:register_mob("mobs_mc:polar_bear", { }) -mobs:spawn_specific("mobs_mc:polar_bear", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:polar_bear", +"overworld", +"ground", +{ +"ColdTaiga", +"IcePlainsSpikes", +"IcePlains", +"ExtremeHills+_snowtop", +}, +0, +minetest.LIGHT_MAX+1, +30, +7000, +3, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- spawn egg mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index b3400ab5f..d82df8cf9 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -303,7 +303,35 @@ mobs:register_mob("mobs_mc:sheep", { end end, }) -mobs:spawn_specific("mobs_mc:sheep", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:sheep", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +3, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index 583c5eed1..8000d0937 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -81,4 +81,17 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) -mobs:spawn_specific("mobs_mc:shulker", "end", "ground", 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific( +"mobs_mc:shulker", +"end", +"ground", +{ +"End" +}, +0, +minetest.LIGHT_MAX+1, +30, +5000, +2, +mobs_mc.spawn_height.end_min, +mobs_mc.spawn_height.end_max) diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 433211503..9a6f3fc98 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -23,13 +23,23 @@ mobs:register_mob("mobs_mc:silverfish", { }, pathfinding = 1, visual_size = {x=3, y=3}, - sounds = { - random = "mobs_mc_silverfish_idle", - death = "mobs_mc_silverfish_death", - damage = "mobs_mc_silverfish_hurt", - distance = 16, + sounds = {"FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "ColdTaiga", + "SunflowerPlains", + "RoofedForest", + "MesaPlateauFM_grasstop", + "ExtremeHillsM", + "BirchForestM", }, - makes_footstep_sound = false, walk_velocity = 0.6, run_velocity = 2, jump = true, diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index 84e51c517..b43873b2a 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -139,13 +139,195 @@ table.insert(stray.drops, { mobs:register_mob("mobs_mc:stray", stray) -- Overworld spawn -mobs:spawn_specific("mobs_mc:skeleton", "overworld", "ground", 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:skeleton", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +20, +17000, +2, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) + + -- Nether spawn -mobs:spawn_specific("mobs_mc:skeleton", "nether", "ground", 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:skeleton", +"nether", +"ground", +{ +"Nether" +}, +0, +7, +30, +10000, +3, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- Stray spawn -- TODO: Spawn directly under the sky -mobs:spawn_specific("mobs_mc:stray", "overworld", "ground", 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:stray", +"overworld", +"ground", +{ +"ColdTaiga", +"IcePlainsSpikes", +"IcePlains", +"ExtremeHills+_snowtop", +}, +0, +7, +20, +19000, +2, +mobs_mc.spawn_height.water, +mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index d9de90d84..da472d605 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -94,7 +94,20 @@ mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn -mobs:spawn_specific("mobs_mc:witherskeleton", "nether", "ground", 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:witherskeleton", +"nether", +"ground", +{ +"Nether" +}, +0, +7, +30, +5000, +5, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- spawn eggs -mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) +mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 2f9e8c8a9..6c8000a50 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -157,9 +157,137 @@ mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) local smin = mobs_mc.spawn_height.overworld_min local smax = mobs_mc.spawn_height.water - 23 -mobs:spawn_specific("mobs_mc:slime_tiny", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_small", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_big", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) +mobs:spawn_specific( +"mobs_mc:slime_tiny", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +12000, +4, +smin, +smax) + +mobs:spawn_specific( +"mobs_mc:slime_small", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +8500, +4, +smin, +smax) + +mobs:spawn_specific( +"mobs_mc:slime_big", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +10000, +4, +smin, +smax) -- Magma cube local magma_cube_big = { @@ -272,9 +400,51 @@ mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) local mmin = mobs_mc.spawn_height.nether_min local mmax = mobs_mc.spawn_height.nether_max -mobs:spawn_specific("mobs_mc:magma_cube_tiny", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) +mobs:spawn_specific( +"mobs_mc:magma_cube_tiny", +"nether", +"ground", +{ +"Nether" +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mmin, +mmax) + + +mobs:spawn_specific( +"mobs_mc:magma_cube_small", +"nether", +"ground", +{ +"Nether" +}, +0, +minetest.LIGHT_MAX+1, +30, +15500, +4, +mmin, +mmax) + +mobs:spawn_specific( +"mobs_mc:magma_cube_big", +"nether", +"ground", +{ +"Nether" +}, +0, +minetest.LIGHT_MAX+1, +30, +16000, +4, +mmin, +mmax) --mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) --mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 1361e6a3a..bb5e29eb1 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -87,7 +87,158 @@ cave_spider.sounds.base_pitch = 1.25 mobs:register_mob("mobs_mc:cave_spider", cave_spider) -mobs:spawn_specific("mobs_mc:spider", "overworld", "ground", 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:spider", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +30, +17000, +2, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 2dbb7c557..cf794ea5b 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -62,7 +62,158 @@ mobs:register_mob("mobs_mc:squid", { local water = mobs_mc.spawn_height.water --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height -mobs:spawn_specific("mobs_mc:squid", "overworld", "water", 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) +mobs:spawn_specific( +"mobs_mc:squid", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +5500, +3, +water-16, +water+1) -- spawn eggs mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 0b53d8015..d251ba823 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1074,7 +1074,35 @@ mobs:register_mob("mobs_mc:villager", { -mobs:spawn_specific("mobs_mc:villager", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 20, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:villager", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +0, +minetest.LIGHT_MAX+1, +30, +20, +4, +mobs_mc.spawn_height.water+1, +mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index 953c2df72..b1c077d46 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -232,6 +232,34 @@ end mobs:register_mob("mobs_mc:dog", dog) -- Spawn -mobs:spawn_specific("mobs_mc:wolf", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:wolf", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +0, +minetest.LIGHT_MAX+1, +30, +9000, +7, +mobs_mc.spawn_height.water+3, +mobs_mc.spawn_height.overworld_max) mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 64f99d34d..fed83f233 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -135,11 +135,227 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning -mobs:spawn_specific("mobs_mc:zombie", "overworld", "ground", 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:zombie", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +}, +0, +7, +30, +6000, +4, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:husk", "overworld", "ground", 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:baby_husk", "overworld", "ground", 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:baby_zombie", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +}, +0, +7, +30, +60000, +4, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) + + +mobs:spawn_specific( +"mobs_mc:husk", +"overworld", +"ground", +{ +"Desert", +"SavannaM", +"Savanna", +"Savanna_beach", +}, +0, +7, +30, +6500, +4, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:baby_husk", +"overworld", +"ground", +{ +"Desert", +"SavannaM", +"Savanna", +"Savanna_beach", +}, +0, +7, +30, +65000, +4, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) -- Spawn eggs mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index e996425c8..ebd8ce485 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -111,9 +111,35 @@ baby_pigman.child = 1 mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) -- Regular spawning in the Nether -mobs:spawn_specific("mobs_mc:pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:pigman", +"nether", +"ground", +{ +"Nether" +}, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_pigman", "nether", "ground", 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mobs:spawn_specific( +"mobs_mc:baby_pigman", +"nether", +"ground", +{ +"Nether" +}, +0, +minetest.LIGHT_MAX+1, +30, +100000, +4, +mobs_mc.spawn_height.nether_min, +mobs_mc.spawn_height.nether_max) -- Spawning in Nether portals in the Overworld --mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) From 668b67158c3ddf778825d18e33c825481d4262df Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 08:09:43 -0400 Subject: [PATCH 107/164] merge --- mods/ENTITIES/mcl_mobs/spawning.lua | 24 ++++-- mods/ENTITIES/mobs_mc/rabbit.lua | 30 ++++++- mods/ENTITIES/mobs_mc/villager_zombie.lua | 95 ++++++++++++++++++++++- 3 files changed, 139 insertions(+), 10 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 515dbaf3d..f7220f1e0 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -242,15 +242,11 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? ]]-- --this is where all of the spawning information is kept -local spawn_dictionary = { - ["overworld"] = {}, - ["nether"] = {}, - ["end"] = {} -} +local spawn_dictionary = {} function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) - print(dump(biomes)) + --print(dump(biomes)) -- Do mobs spawn at all? if not mobs_spawn then @@ -438,6 +434,20 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh --load information into the spawn dictionary + + --allow for new dimensions to be auto added + --this will take extra time, a whole few nanoseconds + --but will allow modularity + if not spawn_dictionary[dimension] then + spawn_dictionary[dimension] = {} + end + + print("----") + print(name) + for _,added_biome in pairs(biomes) do + print(added_biome) + end + --[[ local key = #spawn_dictionary[dimension] + 1 spawn_dictionary[dimension][key] = {} @@ -452,7 +462,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh spawn_dictionary[dimension][key]["max_height"] = max_height spawn_dictionary[dimension][key]["day_toggle"] = day_toggle spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action - + ]]-- --[[ minetest.register_abm({ label = name .. " spawning", diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index f09a70584..74bdffcd8 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -109,7 +109,35 @@ mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) -- Mob spawning rules. -- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out -mobs:spawn_specific("mobs_mc:rabbit", "overworld", "ground", 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:rabbit", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +9, +minetest.LIGHT_MAX+1, +30, +15000, +8, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) --[[ local spawn = { diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index bcede2183..325cf5955 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -146,8 +146,99 @@ mobs:register_mob("mobs_mc:villager_zombie", { harmed_by_heal = true, }) -mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mobs:spawn_specific( +"mobs_mc:villager_zombie", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +}, +0, +7, +30, +4090, +4, +mobs_mc.spawn_height.overworld_min, +mobs_mc.spawn_height.overworld_max) +--mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) From ae0c235c1fd06acb7bd7296d137014c542128fc2 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 08:12:43 -0400 Subject: [PATCH 108/164] Combine air and ground type spawning into ground --- mods/ENTITIES/mcl_mobs/spawning.lua | 15 +++++++++++---- mods/ENTITIES/mobs_mc/bat.lua | 2 +- mods/ENTITIES/mobs_mc/ghast.lua | 2 +- mods/ENTITIES/mobs_mc/parrot.lua | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index f7220f1e0..829005a8c 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -227,7 +227,6 @@ dimension: "end" types of spawning: -"air" "water" "ground" "lava" @@ -438,15 +437,23 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh --allow for new dimensions to be auto added --this will take extra time, a whole few nanoseconds --but will allow modularity + + + if type_of_spawning == "air" then + print("---------------------------- HERE") + print(name) + print("---------------------------- sdfkhjsadfhjklsfsehjkfsdhjk") + end + if not spawn_dictionary[dimension] then spawn_dictionary[dimension] = {} end - print("----") - print(name) for _,added_biome in pairs(biomes) do - print(added_biome) + --print(added_biome) end + + --[[ local key = #spawn_dictionary[dimension] + 1 diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index a525f5583..a0aa8e4f5 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -66,7 +66,7 @@ end -- Spawn on solid blocks at or below Sea level and the selected light level mobs:spawn_specific( "mobs_mc:bat", -"overworld", +"ground", "air", { "FlowerForest_underground", diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 9c3e0cee1..83a10bfc4 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -78,7 +78,7 @@ mobs:register_mob("mobs_mc:ghast", { mobs:spawn_specific( "mobs_mc:ghast", "nether", -"air", +"ground", { "Nether" }, diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 60329211e..5efcb191b 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -94,7 +94,7 @@ mobs:register_mob("mobs_mc:parrot", { mobs:spawn_specific( "mobs_mc:parrot", "overworld", -"air", +"ground", { "Jungle", "JungleEdgeM", From 71c50042e67333fb0cbe7a66f101e5d167ee0b2e Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 08:13:46 -0400 Subject: [PATCH 109/164] Fix typo --- mods/ENTITIES/mobs_mc/bat.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index a0aa8e4f5..677b96aad 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -66,8 +66,8 @@ end -- Spawn on solid blocks at or below Sea level and the selected light level mobs:spawn_specific( "mobs_mc:bat", +"overworld", "ground", -"air", { "FlowerForest_underground", "JungleEdge_underground", From f5cc2bab099570507c25bb2b4bf89bfd7b7a8895 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 08:29:16 -0400 Subject: [PATCH 110/164] Readjust mobs internal settings to not cause insane memory usage --- mods/ENTITIES/mcl_mobs/spawning.lua | 30 +++++++++++++++++++------- mods/ENTITIES/mobs_mc/0_gameconfig.lua | 10 ++++----- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 829005a8c..d4d688085 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -438,21 +438,35 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh --this will take extra time, a whole few nanoseconds --but will allow modularity - - if type_of_spawning == "air" then - print("---------------------------- HERE") - print(name) - print("---------------------------- sdfkhjsadfhjklsfsehjkfsdhjk") - end - + --build dimensions modularly if not spawn_dictionary[dimension] then spawn_dictionary[dimension] = {} end + --build biome list modularly for _,added_biome in pairs(biomes) do - --print(added_biome) + if not spawn_dictionary[dimension][added_biome] then + spawn_dictionary[dimension][added_biome] = {} + end + + --build type of spawning per biome modularly + if not spawn_dictionary[dimension][added_biome][type_of_spawning] then + spawn_dictionary[dimension][added_biome][type_of_spawning] = {} + end + + --build light levels to spawn mob + for i = min_light,max_light do + if not spawn_dictionary[dimension][added_biome][type_of_spawning][i] then + spawn_dictionary[dimension][added_biome][type_of_spawning][i] = {} + end + + for y = min_height, max_height do + --print(y) + end + end end + --[[ local key = #spawn_dictionary[dimension] + 1 diff --git a/mods/ENTITIES/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua index 74c92d415..b979c7353 100644 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ b/mods/ENTITIES/mobs_mc/0_gameconfig.lua @@ -290,13 +290,13 @@ mobs_mc.spawn = { mobs_mc.spawn_height = { water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld - -- Overworld boundaries (inclusive) - overworld_min = -2999, - overworld_max = 31000, + -- Overworld boundaries (inclusive) --had to make this reasonable otherwise mob spawning would go nuts using data + overworld_min = -64,-- -2999, + overworld_max = 256,-- 31000, -- Nether boundaries (inclusive) - nether_min = -3369, - nether_max = -3000, + nether_min = -29067,-- -3369, + nether_max = -28939,-- -3000, -- End boundaries (inclusive) end_min = -6200, From 26ef8c26747ff78cc5e20f2e3546870b0af9e477 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 08:33:50 -0400 Subject: [PATCH 111/164] Fix silverfish typo --- mods/ENTITIES/mcl_mobs/spawning.lua | 2 +- mods/ENTITIES/mobs_mc/silverfish.lua | 21 ++++++--------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index d4d688085..01e2eb9e5 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -461,7 +461,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh end for y = min_height, max_height do - --print(y) + print(y) end end end diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 9a6f3fc98..9befe1905 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -24,22 +24,13 @@ mobs:register_mob("mobs_mc:silverfish", { pathfinding = 1, visual_size = {x=3, y=3}, sounds = {"FlowerForest", - "Swampland", - "Taiga", - "ExtremeHills", - "BirchForest", - "MegaSpruceTaiga", - "MegaTaiga", - "ExtremeHills+", - "Forest", - "Plains", - "ColdTaiga", - "SunflowerPlains", - "RoofedForest", - "MesaPlateauFM_grasstop", - "ExtremeHillsM", - "BirchForestM", + sounds = { + random = "mobs_mc_silverfish_idle", + death = "mobs_mc_silverfish_death", + damage = "mobs_mc_silverfish_hurt", + distance = 16, }, + makes_footstep_sound = false, walk_velocity = 0.6, run_velocity = 2, jump = true, From 282ba2614a259c834dcc71e225a90ec80c2cf873 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 08:42:57 -0400 Subject: [PATCH 112/164] merge --- mods/ENTITIES/mcl_mobs/spawning.lua | 4 +++- mods/ENTITIES/mobs_mc/silverfish.lua | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 01e2eb9e5..0b386390b 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -461,11 +461,13 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh end for y = min_height, max_height do - print(y) + --print(y) end end end + print("--") + print(min_height, max_height) --[[ diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 9befe1905..433211503 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -23,7 +23,6 @@ mobs:register_mob("mobs_mc:silverfish", { }, pathfinding = 1, visual_size = {x=3, y=3}, - sounds = {"FlowerForest", sounds = { random = "mobs_mc_silverfish_idle", death = "mobs_mc_silverfish_death", From ba9866db4916571039be1059855e40d4904ff1ef Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 09:52:50 -0400 Subject: [PATCH 113/164] merge --- mods/ENTITIES/mcl_mobs/spawning.lua | 226 ++++++++++--------------- mods/ENTITIES/mobs_mc/0_gameconfig.lua | 4 +- 2 files changed, 96 insertions(+), 134 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 0b386390b..866591194 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -1,29 +1,18 @@ +--lua locals +local get_node = minetest.get_node +local get_item_group = minetest.get_item_group +local get_node_light = minetest.get_node_light +local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air +local new_vector = vector.new +local math_random = math.random +local get_biome_name = minetest.get_biome_name --[[ THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs underground: "FlowerForest_underground", -"JungleEdge_underground", -"StoneBeach_underground", -"MesaBryce_underground", -"Mesa_underground", -"RoofedForest_underground", -"Jungle_underground", -"Swampland_underground", -"MushroomIsland_underground", -"BirchForest_underground", -"Plains_underground", -"MesaPlateauF_underground", -"ExtremeHills_underground", -"MegaSpruceTaiga_underground", -"BirchForestM_underground", -"SavannaM_underground", -"MesaPlateauFM_underground", -"Desert_underground", -"Savanna_underground", -"Forest_underground", -"SunflowerPlains_underground", +"JungleEdge_underground",local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] "ColdTaiga_underground", "IcePlains_underground", "IcePlainsSpikes_underground", @@ -433,59 +422,22 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh --load information into the spawn dictionary + local key = #spawn_dictionary + 1 + spawn_dictionary[key] = {} + spawn_dictionary[key]["name"] = name + spawn_dictionary[key]["dimension"] = dimension + spawn_dictionary[key]["type_of_spawning"] = type_of_spawning + spawn_dictionary[key]["biomes"] = biomes + spawn_dictionary[key]["min_light"] = min_light + spawn_dictionary[key]["max_light"] = max_light + spawn_dictionary[key]["interval"] = interval + spawn_dictionary[key]["chance"] = chance + spawn_dictionary[key]["aoc"] = aoc + spawn_dictionary[key]["min_height"] = min_height + spawn_dictionary[key]["max_height"] = max_height + spawn_dictionary[key]["day_toggle"] = day_toggle + spawn_dictionary[key]["on_spawn"] = spawn_abm_action - --allow for new dimensions to be auto added - --this will take extra time, a whole few nanoseconds - --but will allow modularity - - --build dimensions modularly - if not spawn_dictionary[dimension] then - spawn_dictionary[dimension] = {} - end - - --build biome list modularly - for _,added_biome in pairs(biomes) do - if not spawn_dictionary[dimension][added_biome] then - spawn_dictionary[dimension][added_biome] = {} - end - - --build type of spawning per biome modularly - if not spawn_dictionary[dimension][added_biome][type_of_spawning] then - spawn_dictionary[dimension][added_biome][type_of_spawning] = {} - end - - --build light levels to spawn mob - for i = min_light,max_light do - if not spawn_dictionary[dimension][added_biome][type_of_spawning][i] then - spawn_dictionary[dimension][added_biome][type_of_spawning][i] = {} - end - - for y = min_height, max_height do - --print(y) - end - end - end - - print("--") - print(min_height, max_height) - - - --[[ - local key = #spawn_dictionary[dimension] + 1 - - spawn_dictionary[dimension][key] = {} - spawn_dictionary[dimension][key]["name"] = name - spawn_dictionary[dimension][key]["type"] = type_of_spawning - spawn_dictionary[dimension][key]["min_light"] = min_light - spawn_dictionary[dimension][key]["max_light"] = max_light - spawn_dictionary[dimension][key]["interval"] = interval - spawn_dictionary[dimension][key]["chance"] = chance - spawn_dictionary[dimension][key]["aoc"] = aoc - spawn_dictionary[dimension][key]["min_height"] = min_height - spawn_dictionary[dimension][key]["max_height"] = max_height - spawn_dictionary[dimension][key]["day_toggle"] = day_toggle - spawn_dictionary[dimension][key]["on_spawn"] = spawn_abm_action - ]]-- --[[ minetest.register_abm({ label = name .. " spawning", @@ -499,7 +451,6 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh ]]-- end - -- compatibility with older mob registration -- we're going to forget about this for now -j4i --[[ @@ -574,108 +525,119 @@ local function decypher_limits(posy) posy = math.floor(posy) return posy - 32, posy + 32 end ---[[ -minetest.register_on_mods_loaded(function() - for _,data in pairs(minetest.registered_biomes) do - print(data.name) + +--a simple helper function for mob_spawn +local function biome_check(biome_list, biome_goal) + for _,data in ipairs(biome_list) do + if data == biome_goal then + return true + end end - print(dump(spawn_dictionary)) -end) -]]-- + return false +end + --todo mob limiting --MAIN LOOP ---[[ + if mobs_spawn then local timer = 15 --0 minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 15--0 + timer = 0--15--0 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(5) do + local player_pos = player:get_pos() + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) if dimension == "void" or dimension == "default" then goto continue -- ignore void and unloaded area end - local min,max = decypher_limits(player_pos.y) local goal_pos = position_calculation(player_pos) - local gotten_biome = minetest.get_biome_data(goal_pos) + local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) + + --couldn't find node + if #spawning_position_list <= 0 then + goto continue + end + + local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] + + --I have no idea why this would happen, but better to be safe + if not spawning_position then + goto continue + end + + local gotten_node = get_node(spawning_position).name + + if not gotten_node or gotten_node == "air" then --skip air nodes + goto continue + end + + local gotten_biome = minetest.get_biome_data(spawning_position) if not gotten_biome then goto continue --skip if in unloaded area end - print(minetest.get_biome_name(gotten_biome.biome)) + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - local mob_def = spawn_dictionary[dimension][math.random(1,#spawn_dictionary[dimension])] + --grab random mob + local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] - if not mob_def then --to catch a crazy error if it ever happens - minetest.log("error", "WARNING!! Attempted to spawn a mob that doesn't exist! Please notify developers!\nThe game will continue to run though.") - goto continue - end + if not mob_def then + goto continue --skip if something ridiculous happens (nil mob def) + end - if mob_def.type == "ground" then + --skip if not correct dimension + if mob_def.dimension ~= dimension then + goto continue + end - local spawning_position_list = minetest.find_nodes_in_area_under_air(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid"}) + --add this so mobs don't spawn inside nodes + spawning_position.y = spawning_position.y + 1 - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then + goto continue + end - spawning_position.y = spawning_position.y + 1 + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(spawning_position) - local gotten_light = minetest.get_node_light(spawning_position) + --don't spawn if not in light limits + if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then + goto continue + end - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - elseif mob_def.type == "air" then - local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"air"}) + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] + if mob_def.type_of_spawning == "ground" and is_water then + goto continue + end - local gotten_light = minetest.get_node_light(spawning_position) + if mob_def.type_of_spawning == "ground" and is_lava then + goto continue + end - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - elseif mob_def.type == "water" then - local spawning_position_list = minetest.find_nodes_in_area(vector.new(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:water"}) - - if #spawning_position_list <= 0 then - goto continue - end - - local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] - - local gotten_light = minetest.get_node_light(spawning_position) - - if gotten_light and gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - minetest.add_entity(spawning_position, mob_def.name) - end - --elseif mob_def.type == "lava" then - --implement later - end - --local spawn minetest.find_nodes_in_area_under_air(vector.new(pos.x,pos.y-find_node_height,pos.z), vector.new(pos.x,pos.y+find_node_height,pos.z), {"group:solid"}) + --adjust the position for water and lava mobs + if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then + spawning_position.y = spawning_position.y - 1 + end + --everything is correct, spawn mob + minetest.add_entity(spawning_position, mob_def.name) ::continue:: --this is a safety catch end end end end) end -]]-- \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua index b979c7353..c92ccbba5 100644 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ b/mods/ENTITIES/mobs_mc/0_gameconfig.lua @@ -290,9 +290,9 @@ mobs_mc.spawn = { mobs_mc.spawn_height = { water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld - -- Overworld boundaries (inclusive) --had to make this reasonable otherwise mob spawning would go nuts using data + -- Overworld boundaries (inclusive) --I adjusted this to be more reasonable overworld_min = -64,-- -2999, - overworld_max = 256,-- 31000, + overworld_max = 31000, -- Nether boundaries (inclusive) nether_min = -29067,-- -3369, From 310dcf966016905d7a551063b71935fdcc0a46a9 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 10:00:04 -0400 Subject: [PATCH 114/164] Fix forgotten biome check --- mods/ENTITIES/mcl_mobs/spawning.lua | 7 ++++++- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 866591194..84cb9928a 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -546,7 +546,7 @@ if mobs_spawn then minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 0--15--0 + timer = 15--0 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(5) do @@ -602,6 +602,11 @@ if mobs_spawn then goto continue end + --skip if not in correct biome + if not biome_check(mob_def.biomes, gotten_biome) then + goto continue + end + --add this so mobs don't spawn inside nodes spawning_position.y = spawning_position.y + 1 diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 656570a83..48fcc8197 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -176,6 +176,7 @@ mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) + mobs:spawn_specific( "mobs_mc:mooshroom", "overworld", From 4fca50dead601c840d268f6108eeb8f066fe97e1 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 10:01:15 -0400 Subject: [PATCH 115/164] Fix spawn timer reset debug --- mods/ENTITIES/mcl_mobs/spawning.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 84cb9928a..72b014b27 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -546,7 +546,7 @@ if mobs_spawn then minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 15--0 + timer = 0--15 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(5) do From 26847bbb549aaf4f92c581f4c06ae7a753045509 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 12:07:20 -0400 Subject: [PATCH 116/164] Finish mob limiter --- mods/ENTITIES/mcl_mobs/api.lua | 5 -- mods/ENTITIES/mcl_mobs/spawning.lua | 74 ++++++++++++++--------------- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index daa209e9e..6c1a0567e 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -82,11 +82,6 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then end) end --- calculate aoc range for mob count -local aosrb = tonumber(minetest.settings:get("active_object_send_range_blocks")) -local abr = tonumber(minetest.settings:get("active_block_range")) -local aoc_range = max(aosrb, abr) * 16 - -- pathfinding settings local enable_pathfinding = true local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 72b014b27..08fd04188 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -6,6 +6,12 @@ local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air local new_vector = vector.new local math_random = math.random local get_biome_name = minetest.get_biome_name +local max = math.max +local get_objects_inside_radius = minetest.get_objects_inside_radius +local vector_distance = vector.distance + +-- range for mob count +local aoc_range = 32 --[[ THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs @@ -150,51 +156,29 @@ Overworld regular: local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false -- count how many mobs of one type are inside an area ---[[ -local count_mobs = function(pos, mobtype) +local count_mobs = function(pos,mobtype) + print(mobtype) local num = 0 - local objs = minetest.get_objects_inside_radius(pos, aoc_range) - + local objs = get_objects_inside_radius(pos, aoc_range) for n = 1, #objs do - local obj = objs[n]:get_luaentity() - if obj and obj.name and obj._cmi_is_mob then - - -- count passive mobs only - if mobtype == "!passive" then - if obj.spawn_class == "passive" then - num = num + 1 - end -- count hostile mobs only - elseif mobtype == "!hostile" then + if mobtype == "hostile" then if obj.spawn_class == "hostile" then num = num + 1 end - -- count ambient mobs only - elseif mobtype == "!ambient" then - if obj.spawn_class == "ambient" then - num = num + 1 - end - -- count water mobs only - elseif mobtype == "!water" then - if obj.spawn_class == "water" then - num = num + 1 - end - -- count mob type - elseif mobtype and obj.name == mobtype then - num = num + 1 - -- count total mobs - elseif not mobtype then + -- count passive mobs only + else num = num + 1 end end end - + return num end -]]-- + -- global functions @@ -229,6 +213,7 @@ what is aoc??? objects in area WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? ]]-- + --this is where all of the spawning information is kept local spawn_dictionary = {} @@ -258,6 +243,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) end + --[[ local spawn_action spawn_action = function(pos, node, active_object_count, active_object_count_wider, name) @@ -419,7 +405,15 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider) spawn_action(pos, node, active_object_count, active_object_count_wider, name) end + ]]-- + local entdef = minetest.registered_entities[name] + local spawn_class + if entdef.type == "monster" then + spawn_class = "hostile" + else + spawn_class = "passive" + end --load information into the spawn dictionary local key = #spawn_dictionary + 1 @@ -436,7 +430,8 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh spawn_dictionary[key]["min_height"] = min_height spawn_dictionary[key]["max_height"] = max_height spawn_dictionary[key]["day_toggle"] = day_toggle - spawn_dictionary[key]["on_spawn"] = spawn_abm_action + --spawn_dictionary[key]["on_spawn"] = spawn_abm_action + spawn_dictionary[key]["spawn_class"] = spawn_class --[[ minetest.register_abm({ @@ -540,15 +535,14 @@ end --todo mob limiting --MAIN LOOP - if mobs_spawn then - local timer = 15 --0 + local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= 15 then - timer = 0--15 + timer = 0 for _,player in ipairs(minetest.get_connected_players()) do - for i = 1,math.random(5) do + for i = 1,math.random(3,8) do local player_pos = player:get_pos() @@ -571,8 +565,8 @@ if mobs_spawn then local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] - --I have no idea why this would happen, but better to be safe - if not spawning_position then + --Prevent strange behavior/too close to player + if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then goto continue end @@ -633,6 +627,11 @@ if mobs_spawn then goto continue end + --finally do the heavy check (for now) of mobs in area + if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then + goto continue + end + --adjust the position for water and lava mobs if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then spawning_position.y = spawning_position.y - 1 @@ -640,6 +639,7 @@ if mobs_spawn then --everything is correct, spawn mob minetest.add_entity(spawning_position, mob_def.name) + ::continue:: --this is a safety catch end end From 9789cf5dcde09907ec1cafb623a682a81298f2c9 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 12:48:02 -0400 Subject: [PATCH 117/164] Adjust spawning to be closer and more frequent --- mods/ENTITIES/mcl_mobs/spawning.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 08fd04188..7a7ce10d5 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -486,7 +486,7 @@ end local axis --inner and outer part of square donut radius local inner = 1 -local outer = 70 +local outer = 50 local int = {-1,1} local position_calculation = function(pos) @@ -539,7 +539,7 @@ if mobs_spawn then local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime - if timer >= 15 then + if timer >= 8 then timer = 0 for _,player in ipairs(minetest.get_connected_players()) do for i = 1,math.random(3,8) do From 6279f5eb414012f175af39ae5deb734bf030e033 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Thu, 8 Apr 2021 14:19:42 -0400 Subject: [PATCH 118/164] test --- mods/ENTITIES/mcl_mobs/spawning.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 7a7ce10d5..206dfdd41 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -486,7 +486,7 @@ end local axis --inner and outer part of square donut radius local inner = 1 -local outer = 50 +local outer = 65 local int = {-1,1} local position_calculation = function(pos) From 6b31e8538559487012a25af294102fc451f4765e Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 9 Apr 2021 01:31:21 +0400 Subject: [PATCH 119/164] Revert (1/3) "Revert fixes to crash world border" This reverts commit 18f73ba31f3669b49a573fe6cc15050c81fe31db. --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index d17a3acd2..3a8e68f95 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -483,12 +483,14 @@ function mesecon.turnoff(pos, link) for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) - - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) - for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then - return false + + if not (mesecon.get_node_force(np) == nil) then + if mesecon.is_receptor_on(n.name) then + local receptorrules = mesecon.receptor_get_rules(n) + for _, rr in pairs(receptorrules) do + if rr.spread and vector.equals(mesecon.invertRule(rr), r) then + return false + end end end end From 26ce10d25c7392bcb3cdb0d8517db432814fc70e Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 9 Apr 2021 01:32:27 +0400 Subject: [PATCH 120/164] Revert (2/3) "Add erlehmann fix to redstone world border crash" This reverts commit b9d175e6a5d6654b19098c7943a4e14ca8e43eb1. --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 3a8e68f95..78d675e47 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -484,13 +484,16 @@ function mesecon.turnoff(pos, link) local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) - if not (mesecon.get_node_force(np) == nil) then - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) - for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then - return false - end + if not n then + mcl_explosions.explode(f.pos, 10) + return + end + + if mesecon.is_receptor_on(n.name) then + local receptorrules = mesecon.receptor_get_rules(n) + for _, rr in pairs(receptorrules) do + if rr.spread and vector.equals(mesecon.invertRule(rr), r) then + return false end end end From f0c2eb86a29b187a17554a7e8927a00906fece35 Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 9 Apr 2021 01:32:58 +0400 Subject: [PATCH 121/164] Revert (3/3) "Fix extreme mesecons/redstone crashing at world border" This reverts commit 0842a36aa6f4a45a10a3ec1182dedcec1d4aac61. --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 78d675e47..7986c2908 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -483,12 +483,6 @@ function mesecon.turnoff(pos, link) for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) - - if not n then - mcl_explosions.explode(f.pos, 10) - return - end - if mesecon.is_receptor_on(n.name) then local receptorrules = mesecon.receptor_get_rules(n) for _, rr in pairs(receptorrules) do From 7c8cf6f79f9f695ed570f4394615af63c3f071f0 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Thu, 8 Apr 2021 01:46:01 +0200 Subject: [PATCH 122/164] Do not crash server if world border is depowered --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 7986c2908..7ad5a2bdf 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -483,11 +483,13 @@ function mesecon.turnoff(pos, link) for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) local n = mesecon.get_node_force(np) - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) - for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then - return false + if not (mesecon.get_node_force(np) == nil) then + if mesecon.is_receptor_on(n.name) then + local receptorrules = mesecon.receptor_get_rules(n) + for _, rr in pairs(receptorrules) do + if rr.spread and vector.equals(mesecon.invertRule(rr), r) then + return false + end end end end From a733eb8e0cb0c4f241c7fd2e46b316e197097a02 Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 9 Apr 2021 02:08:03 +0400 Subject: [PATCH 123/164] [mesecons] Localise several things in internal.lua --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 149 +++++++++++----------- 1 file changed, 78 insertions(+), 71 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 7ad5a2bdf..ef12bcc48 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -47,28 +47,35 @@ -- mesecon.rotate_rules_down(rules) -- These functions return rules that have been rotated in the specific direction +local equals = vector.equals +local get_node_force = mesecon.get_node_force +local receptor_get_rules = mesecon.receptor_get_rules +local invertRule = mesecon.invertRule +local copy, insert = table.copy, table.insert +local registered_nodes = minetest.registered_nodes + -- General function mesecon.get_effector(nodename) - if minetest.registered_nodes[nodename] - and minetest.registered_nodes[nodename].mesecons - and minetest.registered_nodes[nodename].mesecons.effector then - return minetest.registered_nodes[nodename].mesecons.effector + if registered_nodes[nodename] + and registered_nodes[nodename].mesecons + and registered_nodes[nodename].mesecons.effector then + return registered_nodes[nodename].mesecons.effector end end function mesecon.get_receptor(nodename) - if minetest.registered_nodes[nodename] - and minetest.registered_nodes[nodename].mesecons - and minetest.registered_nodes[nodename].mesecons.receptor then - return minetest.registered_nodes[nodename].mesecons.receptor + if registered_nodes[nodename] + and registered_nodes[nodename].mesecons + and registered_nodes[nodename].mesecons.receptor then + return registered_nodes[nodename].mesecons.receptor end end function mesecon.get_conductor(nodename) - if minetest.registered_nodes[nodename] - and minetest.registered_nodes[nodename].mesecons - and minetest.registered_nodes[nodename].mesecons.conductor then - return minetest.registered_nodes[nodename].mesecons.conductor + if registered_nodes[nodename] + and registered_nodes[nodename].mesecons + and registered_nodes[nodename].mesecons.conductor then + return registered_nodes[nodename].mesecons.conductor end end @@ -103,13 +110,14 @@ end -- Receptors -- Nodes that can power mesecons -function mesecon.is_receptor_on(nodename) +local function is_receptor_on(nodename) local receptor = mesecon.get_receptor(nodename) if receptor and receptor.state == mesecon.state.on then return true end return false end +mesecon.is_receptor_on = is_receptor_on function mesecon.is_receptor_off(nodename) local receptor = mesecon.get_receptor(nodename) @@ -186,7 +194,7 @@ end -- Activation: mesecon.queue:add_function("activate", function (pos, rulename) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if not node then return end local effector = mesecon.get_effector(node.name) @@ -198,7 +206,7 @@ end) function mesecon.activate(pos, node, rulename, depth) if rulename == nil then - for _,rule in ipairs(mesecon.effector_get_rules(node)) do + for _,rule in pairs(mesecon.effector_get_rules(node)) do mesecon.activate(pos, node, rule, depth + 1) end return @@ -209,7 +217,7 @@ end -- Deactivation mesecon.queue:add_function("deactivate", function (pos, rulename) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if not node then return end local effector = mesecon.get_effector(node.name) @@ -221,7 +229,7 @@ end) function mesecon.deactivate(pos, node, rulename, depth) if rulename == nil then - for _,rule in ipairs(mesecon.effector_get_rules(node)) do + for _,rule in pairs(mesecon.effector_get_rules(node)) do mesecon.deactivate(pos, node, rule, depth + 1) end return @@ -232,7 +240,7 @@ end -- Change mesecon.queue:add_function("change", function (pos, rulename, changetype) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if not node then return end local effector = mesecon.get_effector(node.name) @@ -244,7 +252,7 @@ end) function mesecon.changesignal(pos, node, rulename, newstate, depth) if rulename == nil then - for _,rule in ipairs(mesecon.effector_get_rules(node)) do + for _,rule in pairs(mesecon.effector_get_rules(node)) do mesecon.changesignal(pos, node, rule, newstate, depth + 1) end return @@ -356,15 +364,15 @@ end -- some more general high-level stuff function mesecon.is_power_on(pos, rulename) - local node = mesecon.get_node_force(pos) - if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then + local node = get_node_force(pos) + if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then return true end return false end function mesecon.is_power_off(pos, rulename) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then return true end @@ -381,7 +389,7 @@ function mesecon.turnon(pos, link) local depth = 1 while frontiers[1] do local f = table.remove(frontiers, 1) - local node = mesecon.get_node_force(f.pos) + local node = get_node_force(f.pos) if not node then -- Area does not exist; do nothing @@ -389,10 +397,10 @@ function mesecon.turnon(pos, link) local rules = mesecon.conductor_get_rules(node) -- Call turnon on neighbors - for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + for _, r in pairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - table.insert(frontiers, {pos = np, link = l}) + for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do + insert(frontiers, {pos = np, link = l}) end end @@ -406,12 +414,12 @@ function mesecon.turnon(pos, link) if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then -- Call turnon on neighbors -- Warning: A LOT of nodes need to be looked at for this to work - for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do + for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - local nlink = table.copy(l) + for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do + local nlink = copy(l) nlink.spread = false - table.insert(frontiers, {pos = np, link = nlink}) + insert(frontiers, {pos = np, link = nlink}) end end end @@ -443,33 +451,33 @@ function mesecon.turnoff(pos, link) local depth = 1 while frontiers[1] do local f = table.remove(frontiers, 1) - local node = mesecon.get_node_force(f.pos) + local node = get_node_force(f.pos) if not node then -- No-op elseif mesecon.is_conductor_on(node, f.link) then local rules = mesecon.conductor_get_rules(node) - for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + for _, r in pairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) -- Check if an onstate receptor is connected. If that is the case, -- abort this turnoff process by returning false. `receptor_off` will -- discard all the changes that we made in the voxelmanip: - for _, l in ipairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do - if mesecon.is_receptor_on(mesecon.get_node_force(np).name) then + for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do + if is_receptor_on(get_node_force(np).name) then return false end end -- Call turnoff on neighbors - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - table.insert(frontiers, {pos = np, link = l}) + for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do + insert(frontiers, {pos = np, link = l}) end end mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link)) elseif mesecon.is_effector(node.name) then - table.insert(signals, { + insert(signals, { pos = f.pos, node = node, link = f.link, @@ -480,23 +488,22 @@ function mesecon.turnoff(pos, link) if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then -- Call turnoff on neighbors -- Warning: A LOT of nodes need to be looked at for this to work - for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do - local np = vector.add(f.pos, r) - local n = mesecon.get_node_force(np) - if not (mesecon.get_node_force(np) == nil) then - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) - for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then - return false - end + local fpos = f.pos + for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do + local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z} + local n = get_node_force(np) + if n and is_receptor_on(n.name) then + local receptorrules = receptor_get_rules(n) + for _, rr in pairs(receptorrules) do + if rr.spread and equals(invertRule(rr), r) then + return false end end end - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - local nlink = table.copy(l) + for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do + local nlink = copy(l) nlink.spread = false - table.insert(frontiers, {pos = np, link = nlink}) + insert(frontiers, {pos = np, link = nlink}) end end end @@ -504,7 +511,7 @@ function mesecon.turnoff(pos, link) depth = depth + 1 end - for _, sig in ipairs(signals) do + for _, sig in pairs(signals) do mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth) if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth) @@ -518,19 +525,19 @@ end -- outputnode (receptor or conductor) at position `output` and has an output in direction `rule` function mesecon.rules_link_rule_all(output, rule) local input = vector.add(output, rule) - local inputnode = mesecon.get_node_force(input) + local inputnode = get_node_force(input) local inputrules = mesecon.get_any_inputrules(inputnode) if not inputrules then return {} end local rules = {} - for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do + for _, inputrule in pairs(mesecon.flattenrules(inputrules)) do -- Check if input accepts from output - if vector.equals(vector.add(input, inputrule), output) then - local newrule = table.copy(inputrule) + if equals(vector.add(input, inputrule), output) then + local newrule = copy(inputrule) newrule.spread = rule.spread - table.insert(rules, newrule) + insert(rules, newrule) end end @@ -541,19 +548,19 @@ end -- inputnode (effector or conductor) at position `input` and has an input in direction `rule` function mesecon.rules_link_rule_all_inverted(input, rule) local output = vector.add(input, rule) - local outputnode = mesecon.get_node_force(output) + local outputnode = get_node_force(output) local outputrules = mesecon.get_any_outputrules(outputnode) if not outputrules then return {} end local rules = {} - for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do - if vector.equals(vector.add(output, outputrule), input) then - local newrule = table.copy(outputrule) - newrule = mesecon.invertRule(newrule) + for _, outputrule in pairs(mesecon.flattenrules(outputrules)) do + if equals(vector.add(output, outputrule), input) then + local newrule = copy(outputrule) + newrule = invertRule(newrule) newrule.spread = rule.spread - table.insert(rules, newrule) + insert(rules, newrule) end end return rules @@ -564,7 +571,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) if depth > 1 then return false, false end - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) local rules = mesecon.get_any_inputrules(node) if not rules then return false, false @@ -580,23 +587,23 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth) local spread = false - for _, rname in ipairs(rulenames) do + for _, rname in pairs(rulenames) do local np = vector.add(pos, rname) - local nn = mesecon.get_node_force(np) - if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) - or mesecon.is_receptor_on (nn.name)) then - if not vector.equals(home_pos, np) then + local nn = get_node_force(np) + if (mesecon.is_conductor_on (nn, invertRule(rname)) + or is_receptor_on (nn.name)) then + if not equals(home_pos, np) then local rulez = mesecon.get_any_outputrules(nn) local spread_tmp = false for r=1, #rulez do - if vector.equals(mesecon.invertRule(rname), rulez[r]) then + if equals(invertRule(rname), rulez[r]) then if rulez[r].spread then spread_tmp = true end end end if depth == 0 or spread_tmp then - table.insert(sourcepos, np) + insert(sourcepos, np) if spread_tmp then spread = true end @@ -614,7 +621,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) local spread = false if not rule then - for _, rule in ipairs(mesecon.flattenrules(rules)) do + for _, rule in pairs(mesecon.flattenrules(rules)) do local spread_temp local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth) From cbd2731e0609354da4e7cee687cc7ccbfbde7893 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 9 Apr 2021 13:22:45 +0200 Subject: [PATCH 124/164] Improve mcl_bossbars performance --- mods/HUD/mcl_bossbars/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 3a144aac4..3ab1a83c7 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -86,9 +86,10 @@ function mcl_bossbars.update_boss(luaentity, name, color) if not bardef.text or bardef.text == "" then bardef.text = name end - for _, obj in pairs(minetest.get_objects_inside_radius(object:get_pos(), 128)) do - if obj:is_player() then - mcl_bossbars.add_bar(obj, bardef) + local pos = object:get_pos() + for _, player in pairs(minetest.get_connected_players()) do + if vector.distance(pos, player:get_pos()) <= 80 then + mcl_bossbars.add_bar(player, bardef) end end end From c6ffccfef5f9401176014692f07840d283fdce3c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 9 Apr 2021 13:35:58 +0200 Subject: [PATCH 125/164] Add priority to bossbars; display bossbars of closest bosses first --- mods/HUD/mcl_bossbars/init.lua | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 3ab1a83c7..a95d533ce 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -36,12 +36,12 @@ end local last_id = 0 -function mcl_bossbars.add_bar(player, def) +function mcl_bossbars.add_bar(player, def, dynamic, priority) local name = player:get_player_name() local bars = mcl_bossbars.bars[name] - local bar = {text = def.text} + local bar = {text = def.text, priority = priority or 0} bar.color, bar.image = get_color_info(def.color, def.percentage) - if def.dynamic then + if dynamic then for _, other in pairs(bars) do if not other.id and other.color == bar.color and (other.original_text or other.text) == bar.text and other.image == bar.image then if not other.count then @@ -55,7 +55,7 @@ function mcl_bossbars.add_bar(player, def) end end table.insert(bars, bar) - if not def.dynamic then + if not dynamic then bar.raw_color = def.color bar.id = last_id + 1 last_id = bar.id @@ -69,10 +69,11 @@ function mcl_bossbars.remove_bar(id) mcl_bossbars.static[id] = nil end -function mcl_bossbars.update_bar(id, def) +function mcl_bossbars.update_bar(id, def, priority) local old = mcl_bossbars.static[id] old.color = get_color_info(def.color or old.raw_color, def.percentage or old.percentage) old.text = def.text or old.text + old.priority = priority or old.priority end function mcl_bossbars.update_boss(luaentity, name, color) @@ -81,15 +82,15 @@ function mcl_bossbars.update_boss(luaentity, name, color) text = luaentity.nametag, percentage = math.floor(luaentity.health / luaentity.hp_max * 100), color = color, - dynamic = true, } if not bardef.text or bardef.text == "" then bardef.text = name end local pos = object:get_pos() for _, player in pairs(minetest.get_connected_players()) do - if vector.distance(pos, player:get_pos()) <= 80 then - mcl_bossbars.add_bar(player, bardef) + local d = vector.distance(pos, player:get_pos()) + if d <= 80 then + mcl_bossbars.add_bar(player, bardef, true, d) end end end @@ -116,6 +117,7 @@ minetest.register_globalstep(function() local name = player:get_player_name() local bars = mcl_bossbars.bars[name] local huds = mcl_bossbars.huds[name] + table.sort(bars, function(a, b) return a.priority < b.priority end) local huds_new = {} local bars_new = {} local i = 0 From f5f6e232cc9e1f6e33810a8b04a8f652fb90091e Mon Sep 17 00:00:00 2001 From: AFCMS Date: Fri, 9 Apr 2021 16:46:41 +0200 Subject: [PATCH 126/164] Attemp to fix #1513 --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index ef12bcc48..6a90b98eb 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -52,8 +52,10 @@ local get_node_force = mesecon.get_node_force local receptor_get_rules = mesecon.receptor_get_rules local invertRule = mesecon.invertRule local copy, insert = table.copy, table.insert -local registered_nodes = minetest.registered_nodes - +local registered_nodes +minetest.register_on_mods_loaded(function() + registered_nodes = minetest.registered_nodes +end) -- General function mesecon.get_effector(nodename) if registered_nodes[nodename] From 3375e903ce87c4a5f07d8d84aea682c914e1db12 Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 9 Apr 2021 18:52:03 +0400 Subject: [PATCH 127/164] [mesecons] Fix attempt to call upvalue in internal.lua --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 6a90b98eb..a552fed70 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -49,7 +49,6 @@ local equals = vector.equals local get_node_force = mesecon.get_node_force -local receptor_get_rules = mesecon.receptor_get_rules local invertRule = mesecon.invertRule local copy, insert = table.copy, table.insert local registered_nodes @@ -137,7 +136,7 @@ function mesecon.is_receptor(nodename) return false end -function mesecon.receptor_get_rules(node) +local function receptor_get_rules(node) local receptor = mesecon.get_receptor(node.name) if receptor then local rules = receptor.rules @@ -150,6 +149,7 @@ function mesecon.receptor_get_rules(node) return mesecon.rules.default end +mesecon.receptor_get_rules = receptor_get_rules -- Effectors -- Nodes that can be powered by mesecons From d50fd06c82193e9e83efb2d1f3d77e629fa78696 Mon Sep 17 00:00:00 2001 From: kay27 Date: Fri, 9 Apr 2021 19:03:45 +0400 Subject: [PATCH 128/164] Revert "Attemp to fix #1513" in favour of next commit 3375e903ce This reverts commit f5f6e232cc9e1f6e33810a8b04a8f652fb90091e. --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index a552fed70..f4ed9df4e 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -51,10 +51,8 @@ local equals = vector.equals local get_node_force = mesecon.get_node_force local invertRule = mesecon.invertRule local copy, insert = table.copy, table.insert -local registered_nodes -minetest.register_on_mods_loaded(function() - registered_nodes = minetest.registered_nodes -end) +local registered_nodes = minetest.registered_nodes + -- General function mesecon.get_effector(nodename) if registered_nodes[nodename] From 849823af1f4d381f85fe8fed4faa96171c92284a Mon Sep 17 00:00:00 2001 From: epCode Date: Fri, 9 Apr 2021 14:33:14 -0700 Subject: [PATCH 129/164] Add player pushing ;) --- mods/PLAYER/mcl_playerplus/init.lua | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 52c87a514..a9f6bd5a1 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -22,11 +22,48 @@ local mcl_playerplus_internal = {} local def = {} local time = 0 +local player_collision = function(player) + + local pos = player:get_pos() + local vel = player:get_velocity() + local x = 0 + local z = 0 + local width = .75 + + for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do + + if object:is_player() + or (object:get_luaentity()._cmi_is_mob == true and object ~= player) then + + local pos2 = object:get_pos() + local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} + local force = (width + 0.5) - vector.distance( + {x = pos.x, y = 0, z = pos.z}, + {x = pos2.x, y = 0, z = pos2.z}) + + x = x + (vec.x * force) + z = z + (vec.z * force) + end + end + + return({x * 5,z * 5}) +end + -- converts yaw to degrees local function degrees(rad) return rad * 180.0 / math.pi end +local pi = math.pi +local atann = math.atan +local atan = function(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + local dir_to_pitch = function(dir) local dir2 = vector.normalize(dir) local xz = math.abs(dir.x) + math.abs(dir.z) @@ -88,6 +125,13 @@ minetest.register_globalstep(function(dtime) for _,player in pairs(get_connected_players()) do + c_x, c_y = unpack(player_collision(player)) + + if player:get_velocity().x + player:get_velocity().y < .5 and c_x + c_y > 0 then + --minetest.chat_send_player(player:get_player_name(), "pushed at " .. c_x + c_y .. " parsecs.") + player:add_velocity({x=c_x, y=0, z=c_y}) + end + --[[ _ _ _ __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ From 9e5fb7f533eb38123fa49b454f8e70e7b01dadbb Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 9 Apr 2021 22:04:42 +0000 Subject: [PATCH 130/164] Add #490 --- mods/ITEMS/mcl_core/nodes_trees.lua | 164 +++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 197846ebc..4c097bad6 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -1,4 +1,4 @@ --- Tree nodes: Wood, Wooden Planks, Sapling, Leaves +-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood local S = minetest.get_translator("mcl_core") local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil @@ -48,6 +48,166 @@ local register_tree_trunk = function(subname, description_trunk, description_bar }) end +-- Register stripped trunk +minetest.register_node("mcl_core:stripped_oak", { + description = "Stripped Oak Log", + _doc_items_longdesc = "Stripped Oak Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_acacia", { + description = "Stripped Acacia Log", + _doc_items_longdesc = "Stripped Acacia Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_dark_oak", { + description = "Stripped Dark Oak Log", + _doc_items_longdesc = "Stripped Dark Oak Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_birch", { + description = "Stripped Birch Log", + _doc_items_longdesc = "Stripped Birch Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_spruce", { + description = "Stripped Spruce Log", + _doc_items_longdesc = "Stripped Spruce Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_jungle", { + description = "Stripped Jungle Log", + _doc_items_longdesc = "Stripped Jungle Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + + +-- Register stripped bark +minetest.register_node("mcl_core:stripped_oak_bark", { + description = "Stripped Oak Bark", + _doc_items_longdesc = "Stripped Oak Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_acacia_bark", { + description = "Stripped Acacia Bark", + _doc_items_longdesc = "Stripped Acacia Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_acacia_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_dark_oak_bark", { + description = "Stripped Dark Oak Bark", + _doc_items_longdesc = "Stripped Dark Oak Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_dark_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_birch_bark", { + description = "Stripped Birch Bark", + _doc_items_longdesc = "Stripped Birch Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_birch_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_spruce_bark", { + description = "Stripped Spruce Bark", + _doc_items_longdesc = "Stripped Spruce Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_spruce_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_jungle_bark", { + description = "Stripped Jungle Bark", + _doc_items_longdesc = "Stripped Jungles Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_jungle_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + + local register_wooden_planks = function(subname, description, tiles) minetest.register_node("mcl_core:"..subname, { description = description, @@ -226,4 +386,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from -- Node aliases minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree") -minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") +minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") \ No newline at end of file From cbcaef19c6814aa9d8f7bdefc49f37ee9c7191fd Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 9 Apr 2021 22:07:44 +0000 Subject: [PATCH 131/164] Add stripped acacia textures --- .../textures/mcl_core_stripped_acacia_side.png | Bin 0 -> 361 bytes .../textures/mcl_core_stripped_acacia_top.png | Bin 0 -> 426 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png new file mode 100644 index 0000000000000000000000000000000000000000..2e2de8dbeb40446e193bc91c921dcd549cb8f5ed GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=De8Ak0{?)V>TT$X?><>&pI=g;PjhMmp=(bD+>SPZ!4!i_@(^)_lzdJhiIMG_2BP zWVrpy;p(&nvkpu&yerNT<0tmQnjyefbLN6bivxTmj@7w;Yn*In_d&gJ%SzABTV^z6&A;4L z^dzKHdG-+*zwJvyw<{R_T{c1XLh-+5{y8Sa*Ltd$pH8X%_q6qDlHQw%GwclJY;_5n z^k?=_y}ni5YfERoJDt~Z*mcvjTd%JDT{SO%VXHXLuZjMen~OICLx924)z4*}Q$iB} DGklU~ literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png new file mode 100644 index 0000000000000000000000000000000000000000..0746884de9e39cbf129e4291b660df94adc9676c GIT binary patch literal 426 zcmV;b0agBqP)61q=2N`9A;v0XIoR zK~y-)rBh97gFp~{4MHGccTre`7!Y#MQz3t&f2+T)mqL$?hk~F&5E68&)Lz;{JJa1& zN}-;1XPz_fLvQZyZa?skC$KMZB=~&37_KQT(Y5`o2LLNNWO)LmC6t!VFaj_2cmNed zC?G;H15&*yTMXmmNLcxrs-lJn1@>9OL#m<%0OZF5^5el7&K`(Rz+4TKmZ*x_(HTcy zJ;Kcx5M=@kmnr5at^qbh3FskGz-nzCh#!@!PA zX^DN7@W$d)GXtACy%X3b@mKb}Nok4m#o+Pbnf>tn3YLBz0@}>{`(li~oWImR0jNEf Ua`%pJIsgCw07*qoM6N<$g8! Date: Fri, 9 Apr 2021 22:08:39 +0000 Subject: [PATCH 132/164] Add stripped birch textures --- .../textures/mcl_core_stripped_birch_side.png | Bin 0 -> 531 bytes .../textures/mcl_core_stripped_birch_top.png | Bin 0 -> 439 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_side.png new file mode 100644 index 0000000000000000000000000000000000000000..a27739c1e6dcb48dbb821783a2d00a007b9f9c88 GIT binary patch literal 531 zcmV+u0_^>XP)67zmJc#F+p90ia1l zK~y-)b(6i0(?Ar3zeExKDb|Tbifvg!#LWua5UQ12ZMzS_JMbht4YX7ss$Cj_XdJW> zvJ+_(Pl|Y4K@nzlW`SE-cjlgR&za-N+c&R&0X#2L0HQEp(4+k}HRzFdpEdy0RY5B? z05gDGgt+ys+0k^8IF7lwy0n0C9Ftu{-rZ?;9K6P$N19FouwE@}KMDiZtA$6_bdsry z_~FYBqA;MY3hJt0o+O@>d6L+kA)cDyUMb7yUNq~wKzG~2g9Lz9YHtW22%Zpy0liY( zZtl6=+nTfNBrs3)`=w`^3_x|&D4`kLI2XYZw19MUQWttl<_h~&3-1Q!N;wEyQB=kzr z9S5?D$j<>lyW7+5_WuQQtLfx VuEYPSXp;Z{002ovPDHLkV1i8Z>W%;a literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png new file mode 100644 index 0000000000000000000000000000000000000000..e5290422d4f7f826064a1bff7baf1cea5a2b46c7 GIT binary patch literal 439 zcmV;o0Z9IdP)67!-tbnAQLQ0Yphe zK~y-)rIWvkgFq0*e-~0{BZ#1G6R;A}nJUlVGu@lqdt86rRj~`C5^Pol5p1-(D`eK) zM7ZLn+gZOq^UeD9_3{40Kk5kZ`TcO3Y2X9UPP22idjRD%UkRRp04nlmrRr2@m{0kHryVH;}4XpqG002ovPDHLkV1jcoxsLz< literal 0 HcmV?d00001 From 03e112ef9b1506701e91e15e0d7b5912a265b69b Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 9 Apr 2021 22:09:16 +0000 Subject: [PATCH 133/164] Add stripped dark oak textures --- .../textures/mcl_core_stripped_dark_oak_side.png | Bin 0 -> 382 bytes .../textures/mcl_core_stripped_dark_oak_top.png | Bin 0 -> 438 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png new file mode 100644 index 0000000000000000000000000000000000000000..9345a14dc22824b02974199546cd9a357df98c15 GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=De8Ak0{?)V>TT$X?><>&pI=g;Ur}+fsDTaRvrPZci7-5R22jlQ(7^cHn8-FK5Sd z)8~P~TM;JT_I-}m?HuCmoli*l1g9IxG;MKS__L==R|2b`q63UkTEUc^FZj&y%eO71NyIr4Z<=h!uSQ-{I%u#2s+plLlf%Wjp>hD|!X1N7(ZI+f^Pt0WJ-gM{OV-Jpre;-Cx4I{Mnb)uBin`s`&mMm>&*i-MjLsbOyqZwaHD%(KryrUA aW2j+WGV8#H%J0CCV(@hJb6Mw<&;$Sx!J6m* literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc45938f39a4c70c4f1b506a630a606676ebb15 GIT binary patch literal 438 zcmV;n0ZIOeP)6HXd)Lc;o;80Ygbd zK~zY`#Z|is!axu_Lm*(~sYTFAEb<3_fFIz;3koU3%8wiq8>*L7_hUa%Zm=gv9jy>nI7 zG))uwi4-75uwE~hi$xeIpJRnX*lOjy_dle76=BD0aP)lE_3JgPS+?Krb|Dc-09F)b z`FIS!&*$s)av6Z98i=SsBP+LffJmSSfT0ve%7hUZ*MKZSmYy9z8Gc_?pIeF;0t2C# zrBTJA6oLaNGLC$VQxs*{wqc5+Uvmj!d49Xy?_nyG;hvf!vDGHZK!o41 Date: Fri, 9 Apr 2021 22:10:10 +0000 Subject: [PATCH 134/164] Add stripped jungle textures --- .../textures/mcl_core_stripped_jungle_side.png | Bin 0 -> 415 bytes .../textures/mcl_core_stripped_jungle_top.png | Bin 0 -> 480 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_side.png new file mode 100644 index 0000000000000000000000000000000000000000..74f9f03d5e667b53454ffc28375b10408cf54135 GIT binary patch literal 415 zcmV;Q0bu@#P)6D3|;pIK0!~>>+~KyL~hV^ARrenyomw^iGcB@ z-BjvWY0|&(AdUX~nLoaJdwu!ZEaw314o3jCMUJtKx+-b=fqm2Q^!NaP%pJWa3kTt$ zMB5Jl%(R}Iuk<3uDox%j=NRi^EDHpj{P~w4uo>$})vWYlQq5S$?r@wa%VhQNO{=A*IS0ZHqj{N+vz8?6D-2_EWv~DM0c}Y{ zK~zY`#Z^110znWQMMRJhMBPMCbU`rQ8yFcHc?7THJv_li-e6)uSVh6a4}yarCcdax zsd~y-_!UJ*KYSn7_y4$VSE0uhmrp{%V zG3Bzg)`sU*eVi*Pz$EE(8VzI4XYcR#u;6mJULTJ+@Mts`MA7FPGm(G*12>!2R;$K1 zx8GkbTAAJMdVM@XAe@78OrXdF6flV47lqV512aKMfQj&0?JpM2ZMUJ40Or{VTEIO- zqM8NV5VOGf+%na=B2P04DkVS+Qa_*GdmrX0*Kid09l(uQQUm}I%6`grtJP+6I2bb= z_WSMjFYf>+vb1UH+&cjtHf1{i%Nbz*a}Oc$c$_40tnJ6~et{?oTP1DCQ~d42!o$n^ zatOH)W&r!sX_EAMc_F@ua?RH^RFXnMR)&eOf(*=r<+p&9;6xCD8 Date: Fri, 9 Apr 2021 22:10:47 +0000 Subject: [PATCH 135/164] Add stripped oak textures --- .../textures/mcl_core_stripped_oak_side.png | Bin 0 -> 551 bytes .../textures/mcl_core_stripped_oak_top.png | Bin 0 -> 523 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_side.png new file mode 100644 index 0000000000000000000000000000000000000000..3bdffd76e14a9a256975620422c6830b37462408 GIT binary patch literal 551 zcmV+?0@(eDP)6Br&{$HEsX^0kla( zK~zY`V@!DCf5(3R|Njg)fY~b58KP4W{8M4KGhSyS#Ldi9R76A=7^Wy}cex(Uz#!Dd zQ_t3hQ2(y#OXII92AqHe#>jc#xkqy)LIP&sojcE;fBcBsfK#XL+tE`ORGukr zQphntqLK++BaB9OIeHYq(gKVo7r-3=i)-{a&tB-cT5}g}1JE6Y%N!UuJ@t0w>nJP^ zz!lW6s6me+bc+cAbc-?40I6~Q`t`?;U%xUi+`s?&_4n_HxW=Xb|3QZL41#!~0GE$& zr46{n1OTjDfR`I+ro=y8r-0HO2I)e~I~z=94vwUe6qaV1KE8{%49d8RXp9g*FS%eK+|a6AKAM3cqQI&{-U~BIh)uLGb?E8|hQKbd zOW&W{Ffh2f>gh>HFfja|0F4p`>`?$O0bzhZ9f462;sU#OU%K?-1@2msP)HEW1%zrn pbO$OO6aB!o6%jRr5*@Ch8vr(5L|EFRL-_yz002ovPDHLkV1kGx<`@6~ literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png new file mode 100644 index 0000000000000000000000000000000000000000..b07c726135d63653bd14fac277ed3f4f66cfd957 GIT binary patch literal 523 zcmV+m0`&cfP)6B>{s$G=l&D0hmcd zK~y-)rIRsF+fWpRzgQ;1wGll-+YT{u~2S_lyjc=tPz%QczHp zgh-DJ&yooWRq254l?~arizPqb<8!`yU+p40f8`V91Jr%5^77=c$@BJw$ucMF#f%p@ z`}I9;@7I;@wtxS<2}otV7yuK6SXZ!L-veO2e&WaJHxd&tvl{>v^L8~~Uf(fZ(I&}}PZ>k5tNm8lCP8JWZpR}$Amp)Q$M-YOy8Pg|HM)M*SyD{iKb>cYB0 zdukWi`D@+x`2Mw_cHh$$Hd4Z@au+7coXIl(Fw)z5KJ0(FYM;H%{{im@)*MZ?;pYGV N002ovPDHLkV1mUX;dB51 literal 0 HcmV?d00001 From c73cd8b8109c847914181ed14824432d6c385067 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 9 Apr 2021 22:11:32 +0000 Subject: [PATCH 136/164] Add stripped spruce textures --- .../textures/mcl_core_stripped_spruce_side.png | Bin 0 -> 447 bytes .../textures/mcl_core_stripped_spruce_top.png | Bin 0 -> 556 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png new file mode 100644 index 0000000000000000000000000000000000000000..11ea15bebbad35c0a09c692a42104d22382c31b1 GIT binary patch literal 447 zcmV;w0YLtVP)6F$+yP3djHe0Zd6m zK~y-)eN!=ugD@Cn(DFHykQT21UpXyqtJH67Hpx32J5l;A~zOv8BD705oJRN6ie6y7&50XsDSzB@j)! zs-}Y!8dZMmGlv^fsB1!Ruy`}ybu%1E$J8m7fL^?p8@ zbb$?4GecRVh(o>^sx3nUDYO^m>*=r=DqFkpfHad2pWnac-d&KJ7b%{M`7kZsHLd@N p-J|ZkH{p1&^$y63M23!;RDYjnz-)+rfsX(H002ovPDHLkV1l;oxO4yj literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png new file mode 100644 index 0000000000000000000000000000000000000000..7699612b6bf2721104c69d9318710f7723554e40 GIT binary patch literal 556 zcmV+{0@MA8P)6F%~X7W)T1Y0l7&; zK~zY`#Z^6P!e9_SYeEu2tOnCMC~+6GgHVueb#Ulk@LzUtNH>>)LoK)~W@-JXABcu3 zb|{YtmmIozOY$b~-92~DbMKpKw_B}7<9MVinSz(Y(?0v#k~ii)&8^`Pxvp(nR`~tn zcD((5BzjnujJtQD(P%zjufzX8)s3-j#^a^C%0lf#07!{?z2R^&A#&?>*>b{tNR%U! z43CIhGRTSpbeA?+5nvq94F|vj@PyoIwNfdcKi_I8u5!-NaWWZQmx1*Ah*HjapDCi=URlsmr}xk zNO5BTc&jACf8{xSe|!l$2Y-lGq7MF=rfG^25g}J60-yp=!2?U0K_UQ>G<5=iIR;k} z6#%k-JA9>H!!>~7$rAyPIEI{4u3||Oe9bk`Y*s48Vp!No?3a!qDwM{Jb1qE}fQeHe zshkJo=6QpG?-Oa7s;VkcpU8Sb*YO{5$$m7v_+GvM0000 Date: Fri, 9 Apr 2021 22:13:50 +0000 Subject: [PATCH 137/164] Add stripped wood crafting --- mods/ITEMS/mcl_core/crafting.lua | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/mods/ITEMS/mcl_core/crafting.lua b/mods/ITEMS/mcl_core/crafting.lua index a0ad38a77..7a2b6a5c8 100644 --- a/mods/ITEMS/mcl_core/crafting.lua +++ b/mods/ITEMS/mcl_core/crafting.lua @@ -46,6 +46,56 @@ minetest.register_craft({ } }) +-- Stripped Bark +minetest.register_craft({ + output = "mcl_core:stripped_oak_bark 3", + recipe = { + { "mcl_core:stripped_oak", "mcl_core:stripped_oak" }, + { "mcl_core:stripped_oak", "mcl_core:stripped_oak" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_acacia_bark 3", + recipe = { + { "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" }, + { "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_dark_oak_bark 3", + recipe = { + { "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" }, + { "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_birch_bark 3", + recipe = { + { "mcl_core:stripped_birch", "mcl_core:stripped_birch" }, + { "mcl_core:stripped_birch", "mcl_core:stripped_birch" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_spruce_bark 3", + recipe = { + { "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" }, + { "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_jungle_bark 3", + recipe = { + { "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" }, + { "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" }, + } +}) + + minetest.register_craft({ type = 'shapeless', output = 'mcl_core:mossycobble', From 652f8d48ed1d4a8834aa410ef31ce893b1714b54 Mon Sep 17 00:00:00 2001 From: NO11 Date: Fri, 9 Apr 2021 22:16:52 +0000 Subject: [PATCH 138/164] Debark wood with an axe --- mods/ITEMS/mcl_tools/init.lua | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index b50782ec4..2d804b9bc 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -352,6 +352,56 @@ minetest.register_tool("mcl_tools:shovel_diamond", { }) -- Axes + +local make_stripped_trunk = function(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node = minetest.get_node(pos) + local node_name = node.name + if placer and not placer: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, placer, itemstack) or itemstack + end + end + 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 axey node) + local toolname = itemstack:get_name() + local wear = mcl_autogroup.get_wear(toolname, "axey") + itemstack:add_wear(wear) + end + if node_name == "mcl_core:tree" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak"}) + elseif node_name == "mcl_core:darktree" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak"}) + elseif node_name == "mcl_core:acaciatree" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia"}) + elseif node_name == "mcl_core:birchtree" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch"}) + elseif node_name == "mcl_core:sprucetree" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce"}) + elseif node_name == "mcl_core:jungletree" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle"}) + elseif node_name == "mcl_core:tree_bark" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak_bark"}) + elseif node_name == "mcl_core:darktree_bark" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak_bark"}) + elseif node_name == "mcl_core:acaciatree_bark" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia_bark"}) + elseif node_name == "mcl_core:birchtree_bark" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch_bark"}) + elseif node_name == "mcl_core:sprucetree_bark" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce_bark"}) + elseif node_name == "mcl_core:jungletree_bark" then + minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle_bark"}) + end + end + return itemstack +end + minetest.register_tool("mcl_tools:axe_wood", { description = S("Wooden Axe"), _doc_items_longdesc = axe_longdesc, @@ -365,6 +415,7 @@ minetest.register_tool("mcl_tools:axe_wood", { damage_groups = {fleshy=7}, punch_attack_uses = 30, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", _mcl_toollike_wield = true, @@ -384,6 +435,7 @@ minetest.register_tool("mcl_tools:axe_stone", { damage_groups = {fleshy=9}, punch_attack_uses = 66, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, @@ -404,6 +456,7 @@ minetest.register_tool("mcl_tools:axe_iron", { damage_groups = {fleshy=9}, punch_attack_uses = 126, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, @@ -423,6 +476,7 @@ minetest.register_tool("mcl_tools:axe_gold", { damage_groups = {fleshy=7}, punch_attack_uses = 17, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, @@ -442,6 +496,7 @@ minetest.register_tool("mcl_tools:axe_diamond", { damage_groups = {fleshy=9}, punch_attack_uses = 781, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, From cdd12a0c713653367238c02c3524b1876e046587 Mon Sep 17 00:00:00 2001 From: NO11 Date: Sat, 10 Apr 2021 11:19:51 +0000 Subject: [PATCH 139/164] Charcoal made from debarked wood --- mods/ITEMS/mcl_core/nodes_trees.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 4c097bad6..4af3eef34 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -56,7 +56,7 @@ minetest.register_node("mcl_core:stripped_oak", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 10, _mcl_hardness = 2, @@ -69,7 +69,7 @@ minetest.register_node("mcl_core:stripped_acacia", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 10, _mcl_hardness = 2, @@ -82,7 +82,7 @@ minetest.register_node("mcl_core:stripped_dark_oak", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 10, _mcl_hardness = 2, @@ -95,7 +95,7 @@ minetest.register_node("mcl_core:stripped_birch", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 10, _mcl_hardness = 2, @@ -108,7 +108,7 @@ minetest.register_node("mcl_core:stripped_spruce", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 10, _mcl_hardness = 2, @@ -121,7 +121,7 @@ minetest.register_node("mcl_core:stripped_jungle", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_blast_resistance = 10, _mcl_hardness = 2, From 08b7340ff5999abfc5508583c36d4ae2381acde9 Mon Sep 17 00:00:00 2001 From: epCode Date: Sat, 10 Apr 2021 10:20:38 -0700 Subject: [PATCH 140/164] Fix crash with player near unknown object --- mods/PLAYER/mcl_playerplus/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index a9f6bd5a1..82b681f6d 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -32,8 +32,8 @@ local player_collision = function(player) for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do - if object:is_player() - or (object:get_luaentity()._cmi_is_mob == true and object ~= player) then + if object and (object:is_player() + or (object:get_luaentity()._cmi_is_mob == true and object ~= player)) then local pos2 = object:get_pos() local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} From ea41c82834d1664ba29d41adddf532c4d5121250 Mon Sep 17 00:00:00 2001 From: kay27 Date: Sat, 10 Apr 2021 21:15:04 +0400 Subject: [PATCH 141/164] [mcl_mobs, mobs_mc] TEMP! Remove `goto` to run on RasbPI4, Oil_boi free to revert --- mods/ENTITIES/mcl_mobs/spawning.lua | 197 ++++++++++++---------------- mods/ENTITIES/mobs_mc/enderman.lua | 37 +++--- 2 files changed, 104 insertions(+), 130 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 206dfdd41..a0572f50b 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -1,14 +1,15 @@ --lua locals -local get_node = minetest.get_node -local get_item_group = minetest.get_item_group -local get_node_light = minetest.get_node_light +local get_node = minetest.get_node +local get_item_group = minetest.get_item_group +local get_node_light = minetest.get_node_light local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air -local new_vector = vector.new -local math_random = math.random -local get_biome_name = minetest.get_biome_name -local max = math.max +local get_biome_data = minetest.get_biome_data +local new_vector = vector.new +local math_random = math.random +local get_biome_name = minetest.get_biome_name +local max = math.max local get_objects_inside_radius = minetest.get_objects_inside_radius -local vector_distance = vector.distance +local vector_distance = vector.distance -- range for mob count local aoc_range = 32 @@ -536,113 +537,87 @@ end --todo mob limiting --MAIN LOOP if mobs_spawn then - local timer = 0 - minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer >= 8 then - timer = 0 - for _,player in ipairs(minetest.get_connected_players()) do - for i = 1,math.random(3,8) do + local timer = 0 + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 8 then + timer = 0 + for _,player in pairs(minetest.get_connected_players()) do + for i = 1,math_random(3,8) do - local player_pos = player:get_pos() + local player_pos = player:get_pos() - local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - if dimension == "void" or dimension == "default" then - goto continue -- ignore void and unloaded area - end - - local min,max = decypher_limits(player_pos.y) + if dimension ~= "void" and dimension ~= "default" then - local goal_pos = position_calculation(player_pos) - - local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) + local min,max = decypher_limits(player_pos.y) - --couldn't find node - if #spawning_position_list <= 0 then - goto continue + local goal_pos = position_calculation(player_pos) + + local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) + + if #spawning_position_list > 0 then --couldn't find node + local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] + + --Prevent strange behavior/too close to player + if spawning_position and vector_distance(player_pos, spawning_position) > 15 then + + local gotten_node = get_node(spawning_position).name + + if gotten_node and gotten_node ~= "air" then --skip air nodes + + local gotten_biome = get_biome_data(spawning_position) + + if gotten_biome then --skip if in unloaded area + + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + + --grab random mob + local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] + + if mob_def --skip if something ridiculous happens (nil mob def) + and mob_def.dimension == dimension --skip if not correct dimension + and biome_check(mob_def.biomes, gotten_biome) then --skip if not in correct biome + + --add this so mobs don't spawn inside nodes + spawning_position.y = spawning_position.y + 1 + + if spawning_position.y >= mob_def.min_height and spawning_position.y <= mob_def.max_height then + + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(spawning_position) + + --don't spawn if not in light limits + if gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then + + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 + + if mob_def.type_of_spawning ~= "ground" or not (is_water or is_lava) then + + --finally do the heavy check (for now) of mobs in area + if count_mobs(spawning_position, mob_def.spawn_class) < mob_def.aoc then + + --adjust the position for water and lava mobs + if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then + spawning_position.y = spawning_position.y - 1 + end + + --everything is correct, spawn mob + minetest.add_entity(spawning_position, mob_def.name) + end + end + end + end + end + end + end + end + end end - - local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] - - --Prevent strange behavior/too close to player - if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then - goto continue - end - - local gotten_node = get_node(spawning_position).name - - if not gotten_node or gotten_node == "air" then --skip air nodes - goto continue - end - - local gotten_biome = minetest.get_biome_data(spawning_position) - - if not gotten_biome then - goto continue --skip if in unloaded area - end - - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - - --grab random mob - local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] - - if not mob_def then - goto continue --skip if something ridiculous happens (nil mob def) - end - - --skip if not correct dimension - if mob_def.dimension ~= dimension then - goto continue - end - - --skip if not in correct biome - if not biome_check(mob_def.biomes, gotten_biome) then - goto continue - end - - --add this so mobs don't spawn inside nodes - spawning_position.y = spawning_position.y + 1 - - if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then - goto continue - end - - --only need to poll for node light if everything else worked - local gotten_light = get_node_light(spawning_position) - - --don't spawn if not in light limits - if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then - goto continue - end - - local is_water = get_item_group(gotten_node, "water") ~= 0 - local is_lava = get_item_group(gotten_node, "lava") ~= 0 - - if mob_def.type_of_spawning == "ground" and is_water then - goto continue - end - - if mob_def.type_of_spawning == "ground" and is_lava then - goto continue - end - - --finally do the heavy check (for now) of mobs in area - if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then - goto continue - end - - --adjust the position for water and lava mobs - if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then - spawning_position.y = spawning_position.y - 1 - end - - --everything is correct, spawn mob - minetest.add_entity(spawning_position, mob_def.name) - - ::continue:: --this is a safety catch - end - end - end - end) + end + end + end + end) end diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index ba04f8b59..5c00bc6e2 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -346,29 +346,28 @@ mobs:register_mob("mobs_mc:enderman", { --skip player if they have no data - log it if not player_eye_height then minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!") - goto continue - end + else - --calculate very quickly the exact location the player is looking - --within the distance between the two "heads" (player and enderman) - local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) - local look_pos_base = look_pos - local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) - local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) - look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) + --calculate very quickly the exact location the player is looking + --within the distance between the two "heads" (player and enderman) + local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) + local look_pos_base = look_pos + local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) + local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) + look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) - --if looking in general head position, turn hostile - if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then - self.provoked = "staring" - self.attack = minetest.get_player_by_name(obj:get_player_name()) - break - else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez - if self.provoked == "staring" then - self.provoked = "broke_contact" - end + --if looking in general head position, turn hostile + if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then + self.provoked = "staring" + self.attack = minetest.get_player_by_name(obj:get_player_name()) + break + else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez + if self.provoked == "staring" then + self.provoked = "broke_contact" + end + end end - ::continue:: -- this is a sweep over statement, this can be used to continue even when errors occurred end end end From 9ba1917209ae5510cd968b8772ce70232077e9fc Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 10 Apr 2021 20:58:34 +0200 Subject: [PATCH 142/164] Add end crystal beams --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 16 ++++++ mods/ITEMS/mcl_end/end_crystal.lua | 48 ++++++++++++++++++ .../mcl_end/textures/mcl_end_crystal_beam.png | Bin 0 -> 2065 bytes 3 files changed, 64 insertions(+) create mode 100644 mods/ITEMS/mcl_end/textures/mcl_end_crystal_beam.png diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index 92806d878..db29b63ae 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -61,6 +61,22 @@ mobs:register_mob("mobs_mc:enderdragon", { ignores_nametag = true, do_custom = function(self) mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple") + for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_end:crystal" then + if luaentity.beam then + if luaentity.beam == self.beam then + break + end + else + if self.beam then + self.beam:remove() + end + minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj) + break + end + end + end if self._portal_pos then -- migrate old format if type(self._portal_pos) == "string" then diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index 772776a1c..720d8ed8d 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -79,6 +79,54 @@ minetest.register_entity("mcl_end:crystal", { _hittable_by_projectile = true }) +minetest.register_entity("mcl_end:crystal_beam", { + initial_properties = { + physical = false, + visual = "cube", + visual_size = {x = 1, y = 1, z = 1}, + textures = { + "mcl_end_crystal_beam.png^[transformR90", + "mcl_end_crystal_beam.png^[transformR90", + "mcl_end_crystal_beam.png", + "mcl_end_crystal_beam.png", + "blank.png", + "blank.png", + }, + static_save = false, + }, + spin = 0, + init = function(self, dragon, crystal) + self.dragon, self.crystal = dragon, crystal + crystal:get_luaentity().beam = self.object + dragon:get_luaentity().beam = self.object + end, + on_deactivate = function(self) + if self.crystal and self.crystal:get_luaentity() then + self.crystal:get_luaentity().beam = nil + end + if self.dragon and self.dragon:get_luaentity() then + self.dragon:get_luaentity().beam = nil + end + end, + on_step = function(self, dtime) + if self.dragon and self.dragon:get_luaentity() and self.crystal and self.crystal:get_luaentity() then + self.spin = self.spin + dtime * math.pi * 2 / 4 + local dragon_pos, crystal_pos = self.dragon:get_pos(), self.crystal:get_pos() + + dragon_pos.y = dragon_pos.y + 4 + crystal_pos.y = crystal_pos.y + 2 + + self.object:set_pos(vector.divide(vector.add(dragon_pos, crystal_pos), 2)) + local rot = vector.dir_to_rotation(vector.direction(dragon_pos, crystal_pos)) + rot.z = self.spin + self.object:set_rotation(rot) + self.object:set_properties({visual_size = {x = 0.5, y = 0.5, z = vector.distance(dragon_pos, crystal_pos)}}) + else + self.object:remove() + end + end, +}) + minetest.register_craftitem("mcl_end:crystal", { inventory_image = "mcl_end_crystal_item.png", description = S("End Crystal"), diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_crystal_beam.png b/mods/ITEMS/mcl_end/textures/mcl_end_crystal_beam.png new file mode 100644 index 0000000000000000000000000000000000000000..1259a5d0ec80af0c59843b46c21fda8853fa9601 GIT binary patch literal 2065 zcmV+s2=4cZP)EK|00004XF*Lt006O% z3;baP00009a7bBm000id000id0mpBsWB>pMvq?ljRCr#cTL*F+ISkzY|5M2dmX#&T znmfV+7@-lyzN)K|ha?C#8qK(;ZQD-h|M&Oz|3Blhhld9$`}OM=Rqz$lhRC2cFliX- zK=(7(-FGr(4BX$}r(RrLU2&PIgD@~gzrMa;L-qy@p~E70a1@8sK-aSj_wDUX>Ygg# z_Hk0>>+5Tc1^xZ__=uS{4CCqc_SP7f3?blUK74$95U&@<_y0P8#RKVG#r^c{+qcv! zuGbPt;X%gE&dypMOx>s9jXijMeTBmr8^}Ui=7JwDFai}x8|9Glw=j$@&Q&=X3l(;- zw#9SgvLe{_{rmSa7s$ZkJ2Le2^n^VaQdlrCfK9Vdcj7U~SjfZRa`|@%k5b=Jgwpt~ zF7EE`JP!hM=|eRScA!pV-G{MF=R*mGqR`S;hkG&vQ^(8Pq29P>4f-h7+)&R*{0#vH zrR#_yl~GVroQP^@u(aUw^E30r0}C(US3{w8pDnP6ICNB zyS%*2w7`Jqf$Tyl<Cqp=>5bsjFN^1`~Kw;gkQ5gl#1H_3@GF7|}%=6OL4S~v^pP$oC z!~j?amKmv+x}6sl4q=T%l>s~H`}z4f(Lf7s*Lz!@RcPbCmUtBp#IU09NK|?JWPQ3; z4$ADvLTjb{TZl*t(rTEk-2ASsGA1hI=FE1v&w4?wqfHp;yeIaD29_mdNS$_q)}LF0RUuB3_Do|(<^s0m1S&A0vVhT6FWnx0plv~$|`;^mAAp>D$N<4>tp_FjJhyt zqp*W2olS%6^c%_*Up{mIiXL>r>9o-dTmF%4F73|I$WXVF`tL4oUgOVSq zyWLiZfj=ERz3~xCr>#XC;6)hDBo`_S;4x6e|4>FA=!@Ec8kw-8B~F*tW)emQI(AYA zyey;zMsg)chFm1beI0r-z~klur-$VdATUuK2~UzLo!az?-C-W2kwKT&27?_7pWf_& z|8C|+LK_Z#pP<|nuN;KaXZ=c4MrKdb;?;?T#H6@f{H-wkPl0MF$P}V z7}zeIGs%+(O$?y$O1p^xQ^x~4#vs#5W};D?AQDl^k~uqx_fup}B<;^IS=BOx@|=z1P&BVpYWh{#?y4>!D1 zbR?>b94C@LZwnwcufk;Pd?b=Z!RVd~uP#f^*2S=26M3$9B88rdWe(MyOz)-Gq)c4G z((E0h2g%e%4;cZF!2mjtMA0z&X*dM0dpfKmqa zWh|%<7+U(+S2r#VArB7W@;4KU5g0MB=XaIHp|eHzP7h4ERwKRKud=P2xvEp$Ls6j0 z!vnYw(kcoDZA7AuX(1whQN9F+GcbGDoD$6(fn@GwDztx(l2!>vrV%oP#EVL`qb3fG z7^9ev3sn5@}VPAtC!_|S@)Ry3 Date: Sat, 10 Apr 2021 14:47:26 -0700 Subject: [PATCH 143/164] add criticle and sprint hits. --- mods/PLAYER/mcl_playerplus/init.lua | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 82b681f6d..4dadeb9a0 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -119,6 +119,37 @@ end local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos + +minetest.register_on_punchplayer(function(player, hitter, damage) + if hitter:is_player() then + if hitter:get_player_control().aux1 then + player:add_velocity(hitter:get_velocity()) + end + if hitter:get_velocity().y < -6 then + player:set_hp(player:get_hp() - (damage * math.random(0.50 , 0.75))) + local pos = player:get_pos() + minetest.add_particlespawner({ + amount = 15, + time = 0.1, + minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, + maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, + minvel = {x=-0.1, y=-0.1, z=-0.1}, + maxvel = {x=0.1, y=0.1, z=0.1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 2, + minsize = 1.5, + maxsize = 1.5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + }) + end + end +end) + + minetest.register_globalstep(function(dtime) time = time + dtime From 3ff214ec2d8dc4c79c867af180aeba2b34dfb756 Mon Sep 17 00:00:00 2001 From: epCode Date: Sat, 10 Apr 2021 15:06:16 -0700 Subject: [PATCH 144/164] lessen the push strength for players --- mods/PLAYER/mcl_playerplus/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 4dadeb9a0..cbd93ada8 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -46,7 +46,7 @@ local player_collision = function(player) end end - return({x * 5,z * 5}) + return({x,z}) end -- converts yaw to degrees From b14ca5a84310adb4f3e0fcc615bf2ed97cea6708 Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 11 Apr 2021 02:10:27 +0400 Subject: [PATCH 145/164] Revert "[mcl_mobs, mobs_mc] TEMP! Remove `goto` to run on RasbPI4, Oil_boi free to revert" This reverts commit ea41c82834d1664ba29d41adddf532c4d5121250. --- mods/ENTITIES/mcl_mobs/spawning.lua | 197 ++++++++++++++++------------ mods/ENTITIES/mobs_mc/enderman.lua | 41 +++--- 2 files changed, 132 insertions(+), 106 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index a0572f50b..206dfdd41 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -1,15 +1,14 @@ --lua locals -local get_node = minetest.get_node -local get_item_group = minetest.get_item_group -local get_node_light = minetest.get_node_light +local get_node = minetest.get_node +local get_item_group = minetest.get_item_group +local get_node_light = minetest.get_node_light local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air -local get_biome_data = minetest.get_biome_data -local new_vector = vector.new -local math_random = math.random -local get_biome_name = minetest.get_biome_name -local max = math.max +local new_vector = vector.new +local math_random = math.random +local get_biome_name = minetest.get_biome_name +local max = math.max local get_objects_inside_radius = minetest.get_objects_inside_radius -local vector_distance = vector.distance +local vector_distance = vector.distance -- range for mob count local aoc_range = 32 @@ -537,87 +536,113 @@ end --todo mob limiting --MAIN LOOP if mobs_spawn then - local timer = 0 - minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer >= 8 then - timer = 0 - for _,player in pairs(minetest.get_connected_players()) do - for i = 1,math_random(3,8) do + local timer = 0 + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 8 then + timer = 0 + for _,player in ipairs(minetest.get_connected_players()) do + for i = 1,math.random(3,8) do - local player_pos = player:get_pos() + local player_pos = player:get_pos() - local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - if dimension ~= "void" and dimension ~= "default" then + if dimension == "void" or dimension == "default" then + goto continue -- ignore void and unloaded area + end + + local min,max = decypher_limits(player_pos.y) - local min,max = decypher_limits(player_pos.y) + local goal_pos = position_calculation(player_pos) + + local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) - local goal_pos = position_calculation(player_pos) - - local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) - - if #spawning_position_list > 0 then --couldn't find node - local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] - - --Prevent strange behavior/too close to player - if spawning_position and vector_distance(player_pos, spawning_position) > 15 then - - local gotten_node = get_node(spawning_position).name - - if gotten_node and gotten_node ~= "air" then --skip air nodes - - local gotten_biome = get_biome_data(spawning_position) - - if gotten_biome then --skip if in unloaded area - - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - - --grab random mob - local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] - - if mob_def --skip if something ridiculous happens (nil mob def) - and mob_def.dimension == dimension --skip if not correct dimension - and biome_check(mob_def.biomes, gotten_biome) then --skip if not in correct biome - - --add this so mobs don't spawn inside nodes - spawning_position.y = spawning_position.y + 1 - - if spawning_position.y >= mob_def.min_height and spawning_position.y <= mob_def.max_height then - - --only need to poll for node light if everything else worked - local gotten_light = get_node_light(spawning_position) - - --don't spawn if not in light limits - if gotten_light >= mob_def.min_light and gotten_light <= mob_def.max_light then - - local is_water = get_item_group(gotten_node, "water") ~= 0 - local is_lava = get_item_group(gotten_node, "lava") ~= 0 - - if mob_def.type_of_spawning ~= "ground" or not (is_water or is_lava) then - - --finally do the heavy check (for now) of mobs in area - if count_mobs(spawning_position, mob_def.spawn_class) < mob_def.aoc then - - --adjust the position for water and lava mobs - if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then - spawning_position.y = spawning_position.y - 1 - end - - --everything is correct, spawn mob - minetest.add_entity(spawning_position, mob_def.name) - end - end - end - end - end - end - end - end - end + --couldn't find node + if #spawning_position_list <= 0 then + goto continue end - end - end - end - end) + + local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] + + --Prevent strange behavior/too close to player + if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then + goto continue + end + + local gotten_node = get_node(spawning_position).name + + if not gotten_node or gotten_node == "air" then --skip air nodes + goto continue + end + + local gotten_biome = minetest.get_biome_data(spawning_position) + + if not gotten_biome then + goto continue --skip if in unloaded area + end + + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + + --grab random mob + local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] + + if not mob_def then + goto continue --skip if something ridiculous happens (nil mob def) + end + + --skip if not correct dimension + if mob_def.dimension ~= dimension then + goto continue + end + + --skip if not in correct biome + if not biome_check(mob_def.biomes, gotten_biome) then + goto continue + end + + --add this so mobs don't spawn inside nodes + spawning_position.y = spawning_position.y + 1 + + if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then + goto continue + end + + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(spawning_position) + + --don't spawn if not in light limits + if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then + goto continue + end + + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 + + if mob_def.type_of_spawning == "ground" and is_water then + goto continue + end + + if mob_def.type_of_spawning == "ground" and is_lava then + goto continue + end + + --finally do the heavy check (for now) of mobs in area + if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then + goto continue + end + + --adjust the position for water and lava mobs + if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then + spawning_position.y = spawning_position.y - 1 + end + + --everything is correct, spawn mob + minetest.add_entity(spawning_position, mob_def.name) + + ::continue:: --this is a safety catch + end + end + end + end) end diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 5c00bc6e2..ba04f8b59 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -346,28 +346,29 @@ mobs:register_mob("mobs_mc:enderman", { --skip player if they have no data - log it if not player_eye_height then minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!") - else - - --calculate very quickly the exact location the player is looking - --within the distance between the two "heads" (player and enderman) - local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) - local look_pos_base = look_pos - local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) - local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) - look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) - - --if looking in general head position, turn hostile - if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then - self.provoked = "staring" - self.attack = minetest.get_player_by_name(obj:get_player_name()) - break - else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez - if self.provoked == "staring" then - self.provoked = "broke_contact" - end - end + goto continue end + --calculate very quickly the exact location the player is looking + --within the distance between the two "heads" (player and enderman) + local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) + local look_pos_base = look_pos + local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) + local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) + look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) + + --if looking in general head position, turn hostile + if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then + self.provoked = "staring" + self.attack = minetest.get_player_by_name(obj:get_player_name()) + break + else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez + if self.provoked == "staring" then + self.provoked = "broke_contact" + end + end + + ::continue:: -- this is a sweep over statement, this can be used to continue even when errors occurred end end end From a76fe2b4875fa02e59edda08663a95432f1a6b4f Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 11 Apr 2021 01:54:40 +0400 Subject: [PATCH 146/164] [mcl_mobs] Replace `goto` to `repeat-break-until true` in spawning.lua --- mods/ENTITIES/mcl_mobs/spawning.lua | 164 ++++++++++++++-------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 206dfdd41..ff52128df 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -535,114 +535,114 @@ end --todo mob limiting --MAIN LOOP + if mobs_spawn then - local timer = 0 - minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer >= 8 then - timer = 0 - for _,player in ipairs(minetest.get_connected_players()) do - for i = 1,math.random(3,8) do + local timer = 0 + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 8 then + timer = 0 + for _,player in pairs(minetest.get_connected_players()) do + for i = 1,math_random(3,8) do + repeat -- after this line each "break" means "continue" + local player_pos = player:get_pos() - local player_pos = player:get_pos() + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - - if dimension == "void" or dimension == "default" then - goto continue -- ignore void and unloaded area - end + if dimension == "void" or dimension == "default" then + break -- ignore void and unloaded area + end - local min,max = decypher_limits(player_pos.y) + local min,max = decypher_limits(player_pos.y) - local goal_pos = position_calculation(player_pos) + local goal_pos = position_calculation(player_pos) - local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) + local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) - --couldn't find node - if #spawning_position_list <= 0 then - goto continue - end + --couldn't find node + if #spawning_position_list <= 0 then + break + end - local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] + local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] - --Prevent strange behavior/too close to player - if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then - goto continue - end + --Prevent strange behavior/too close to player + if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then + break + end - local gotten_node = get_node(spawning_position).name + local gotten_node = get_node(spawning_position).name - if not gotten_node or gotten_node == "air" then --skip air nodes - goto continue - end + if not gotten_node or gotten_node == "air" then --skip air nodes + break + end - local gotten_biome = minetest.get_biome_data(spawning_position) + local gotten_biome = minetest.get_biome_data(spawning_position) - if not gotten_biome then - goto continue --skip if in unloaded area - end + if not gotten_biome then + break --skip if in unloaded area + end - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - --grab random mob - local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] + --grab random mob + local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] - if not mob_def then - goto continue --skip if something ridiculous happens (nil mob def) - end + if not mob_def then + break --skip if something ridiculous happens (nil mob def) + end - --skip if not correct dimension - if mob_def.dimension ~= dimension then - goto continue - end + --skip if not correct dimension + if mob_def.dimension ~= dimension then + break + end - --skip if not in correct biome - if not biome_check(mob_def.biomes, gotten_biome) then - goto continue - end + --skip if not in correct biome + if not biome_check(mob_def.biomes, gotten_biome) then + break + end - --add this so mobs don't spawn inside nodes - spawning_position.y = spawning_position.y + 1 + --add this so mobs don't spawn inside nodes + spawning_position.y = spawning_position.y + 1 - if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then - goto continue - end + if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then + break + end - --only need to poll for node light if everything else worked - local gotten_light = get_node_light(spawning_position) + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(spawning_position) - --don't spawn if not in light limits - if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then - goto continue - end + --don't spawn if not in light limits + if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then + break + end - local is_water = get_item_group(gotten_node, "water") ~= 0 - local is_lava = get_item_group(gotten_node, "lava") ~= 0 + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 - if mob_def.type_of_spawning == "ground" and is_water then - goto continue - end + if mob_def.type_of_spawning == "ground" and is_water then + break + end - if mob_def.type_of_spawning == "ground" and is_lava then - goto continue - end + if mob_def.type_of_spawning == "ground" and is_lava then + break + end - --finally do the heavy check (for now) of mobs in area - if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then - goto continue - end + --finally do the heavy check (for now) of mobs in area + if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then + break + end - --adjust the position for water and lava mobs - if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then - spawning_position.y = spawning_position.y - 1 - end + --adjust the position for water and lava mobs + if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then + spawning_position.y = spawning_position.y - 1 + end - --everything is correct, spawn mob - minetest.add_entity(spawning_position, mob_def.name) - - ::continue:: --this is a safety catch - end - end - end - end) + --everything is correct, spawn mob + minetest.add_entity(spawning_position, mob_def.name) + until true --this is a safety catch + end + end + end + end) end From 40c733c91381ec83ca9a6ab8ebe110b93b1f0c85 Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 11 Apr 2021 01:59:13 +0400 Subject: [PATCH 147/164] [mobs_mc] Remove `goto` from enderman.lua --- mods/ENTITIES/mobs_mc/enderman.lua | 39 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index ba04f8b59..6c87b9305 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -346,29 +346,28 @@ mobs:register_mob("mobs_mc:enderman", { --skip player if they have no data - log it if not player_eye_height then minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!") - goto continue - end + else - --calculate very quickly the exact location the player is looking - --within the distance between the two "heads" (player and enderman) - local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) - local look_pos_base = look_pos - local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) - local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) - look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) + --calculate very quickly the exact location the player is looking + --within the distance between the two "heads" (player and enderman) + local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) + local look_pos_base = look_pos + local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) + local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) + look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) - --if looking in general head position, turn hostile - if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then - self.provoked = "staring" - self.attack = minetest.get_player_by_name(obj:get_player_name()) - break - else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez - if self.provoked == "staring" then - self.provoked = "broke_contact" - end - end + --if looking in general head position, turn hostile + if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then + self.provoked = "staring" + self.attack = minetest.get_player_by_name(obj:get_player_name()) + break + else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez + if self.provoked == "staring" then + self.provoked = "broke_contact" + end + end - ::continue:: -- this is a sweep over statement, this can be used to continue even when errors occurred + end end end end From ce49cd02ac5273a21a673329d28e4ceb32b5db34 Mon Sep 17 00:00:00 2001 From: epCode Date: Sat, 10 Apr 2021 15:41:50 -0700 Subject: [PATCH 148/164] make player collision box MUCH closer to MC --- mods/PLAYER/mcl_playerplus/init.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index cbd93ada8..de346256f 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -210,26 +210,26 @@ minetest.register_globalstep(function(dtime) if parent then local parent_yaw = degrees(parent:get_yaw()) - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) elseif controls.sneak then -- controls head pitch when sneaking player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0)) -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 0, g = 225 }}) -- sneaking body conrols player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then -- set head pitch and yaw when swimming player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) -- control body bone when swimming player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) else -- sets eye height, and nametag color accordingly - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) From 2313012f607e11283dcb1a2600eccc7b7a89a02c Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 11 Apr 2021 10:41:11 +0200 Subject: [PATCH 149/164] Fix #1528 --- mods/HUD/mcl_bossbars/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index a95d533ce..b5bec1334 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -60,7 +60,7 @@ function mcl_bossbars.add_bar(player, def, dynamic, priority) bar.id = last_id + 1 last_id = bar.id mcl_bossbars.static[bar.id] = bar - return id + return bar.id end end From af044e6a96fba49bd573eff01be751067403f0e3 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 11 Apr 2021 11:15:09 +0200 Subject: [PATCH 150/164] Bossbars: Add support for non-mob bosses --- mods/HUD/mcl_bossbars/init.lua | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index b5bec1334..209d9a2c1 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -76,16 +76,23 @@ function mcl_bossbars.update_bar(id, def, priority) old.priority = priority or old.priority end -function mcl_bossbars.update_boss(luaentity, name, color) - local object = luaentity.object +function mcl_bossbars.update_boss(object, name, color) + local props = object:get_luaentity() + if not props or not props._cmi_is_mob then + props = object:get_properties() + props.health = object:get_hp() + end + local bardef = { - text = luaentity.nametag, - percentage = math.floor(luaentity.health / luaentity.hp_max * 100), color = color, + text = props.nametag, + percentage = math.floor(props.health / props.hp_max * 100), } + if not bardef.text or bardef.text == "" then bardef.text = name end + local pos = object:get_pos() for _, player in pairs(minetest.get_connected_players()) do local d = vector.distance(pos, player:get_pos()) From 24f8f9166b0dbd6ce86e39dd7646fb2fb1f67877 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 11 Apr 2021 17:29:05 +0200 Subject: [PATCH 151/164] Fix #1528 --- mods/HUD/mcl_bossbars/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 209d9a2c1..08eb527bf 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -65,7 +65,7 @@ function mcl_bossbars.add_bar(player, def, dynamic, priority) end function mcl_bossbars.remove_bar(id) - mcl_bossbars.static[id].bar.static = false + mcl_bossbars.static[id].bar.id = nil mcl_bossbars.static[id] = nil end From c0a31f0e9c0f90e7fac688f4e345d21466306d0d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 11 Apr 2021 17:30:32 +0200 Subject: [PATCH 152/164] Fix #1535 --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 2 +- mods/ENTITIES/mobs_mc/wither.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index db29b63ae..a6f404275 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -60,7 +60,7 @@ mobs:register_mob("mobs_mc:enderdragon", { }, ignores_nametag = true, do_custom = function(self) - mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple") + mcl_bossbars.update_boss(self.object, "Ender Dragon", "light_purple") for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do local luaentity = obj:get_luaentity() if luaentity and luaentity.name == "mcl_end:crystal" then diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 8e7f7eb95..2d53cc547 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -73,7 +73,7 @@ mobs:register_mob("mobs_mc:wither", { self.object:set_properties({textures={self.base_texture}}) self.armor = {undead = 80, fleshy = 80} end - mcl_bossbars.update_boss(self, "Wither", "dark_purple") + mcl_bossbars.update_boss(self.object, "Wither", "dark_purple") end, on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) From 523a0c54d6ca9cc069d8ca767adf19596b4655f1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 14:54:14 +0200 Subject: [PATCH 153/164] Localize c_x and c_y in mcl_playerplus --- mods/PLAYER/mcl_playerplus/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index de346256f..8c8b784b2 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -156,7 +156,7 @@ minetest.register_globalstep(function(dtime) for _,player in pairs(get_connected_players()) do - c_x, c_y = unpack(player_collision(player)) + local c_x, c_y = unpack(player_collision(player)) if player:get_velocity().x + player:get_velocity().y < .5 and c_x + c_y > 0 then --minetest.chat_send_player(player:get_player_name(), "pushed at " .. c_x + c_y .. " parsecs.") From db5626fcb480a7ec3fcb1b2dd064cf8b14d2a260 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 15:05:01 +0200 Subject: [PATCH 154/164] Revert "Make hoe dig some blocks faster" This reverts commit c1e295de5fbe09c2fa6973f14b48dd73b2405eb3. --- mods/ITEMS/mcl_core/init.lua | 1 - mods/ITEMS/mcl_core/nodes_trees.lua | 14 +------------- mods/ITEMS/mcl_farming/hoes.lua | 15 --------------- mods/ITEMS/mcl_farming/wheat.lua | 2 +- mods/ITEMS/mcl_nether/init.lua | 2 +- mods/ITEMS/mcl_ocean/kelp.lua | 2 +- mods/ITEMS/mcl_sponges/init.lua | 4 ++-- 7 files changed, 6 insertions(+), 34 deletions(-) diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 897382e01..b1b2b9d35 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -14,7 +14,6 @@ mcl_autogroup.register_diggroup("shearsy_wool") mcl_autogroup.register_diggroup("shearsy_cobweb") mcl_autogroup.register_diggroup("swordy") mcl_autogroup.register_diggroup("swordy_cobweb") -mcl_autogroup.register_diggroup("hoey") -- Load files local modpath = minetest.get_modpath("mcl_core") diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 4af3eef34..fd6641552 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -268,19 +268,7 @@ local register_leaves = function(subname, description, longdesc, tiles, sapling, tiles = tiles, paramtype = "light", stack_max = 64, - groups = { - handy=1, - hoey=1, - shearsy=1, - swordy=1, - leafdecay=leafdecay_distance, - flammable=2, - leaves=1, - deco_block=1, - dig_by_piston=1, - fire_encouragement=30, - fire_flammability=60 - }, + groups = {handy=1,shearsy=1,swordy=1, leafdecay=leafdecay_distance, flammable=2, leaves=1, deco_block=1, dig_by_piston=1, fire_encouragement=30, fire_flammability=60}, drop = get_drops(0), _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index db470b999..e2e8342d7 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -78,9 +78,6 @@ minetest.register_tool("mcl_farming:hoe_wood", { }, _repair_material = "group:wood", _mcl_toollike_wield = true, - _mcl_diggroups = { - hoey = { speed = 2, level = 1, uses = 60 } - }, }) minetest.register_craft({ @@ -121,9 +118,6 @@ minetest.register_tool("mcl_farming:hoe_stone", { }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, - _mcl_diggroups = { - hoey = { speed = 4, level = 3, uses = 132 } - }, }) minetest.register_craft({ @@ -160,9 +154,6 @@ minetest.register_tool("mcl_farming:hoe_iron", { }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, - _mcl_diggroups = { - hoey = { speed = 6, level = 4, uses = 251 } - }, }) minetest.register_craft({ @@ -205,9 +196,6 @@ minetest.register_tool("mcl_farming:hoe_gold", { }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, - _mcl_diggroups = { - hoey = { speed = 12, level = 2, uses = 33 } - }, }) minetest.register_craft({ @@ -252,9 +240,6 @@ minetest.register_tool("mcl_farming:hoe_diamond", { }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, - _mcl_diggroups = { - hoey = { speed = 8, level = 5, uses = 1562 } - }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index e3ee79ead..9a8a9f65e 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -146,7 +146,7 @@ minetest.register_node("mcl_farming:hay_block", { paramtype2 = "facedir", is_ground_content = false, on_place = mcl_util.rotate_axis, - groups = {handy=1, hoey=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, + groups = {handy=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, sounds = mcl_sounds.node_sound_leaves_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 0.5, diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 467054767..f4b203acc 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -176,7 +176,7 @@ minetest.register_node("mcl_nether:nether_wart_block", { stack_max = 64, tiles = {"mcl_nether_nether_wart_block.png"}, is_ground_content = false, - groups = {handy=1, hoey=1, building_block=1}, + groups = {handy=1, building_block=1}, sounds = mcl_sounds.node_sound_leaves_defaults( { footstep={name="default_dirt_footstep", gain=0.7}, diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 9670943da..15d155fc8 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -779,7 +779,7 @@ minetest.register_node("mcl_ocean:dried_kelp_block", { description = S("Dried Kelp Block"), _doc_items_longdesc = S("A decorative block that serves as a great furnace fuel."), tiles = { "mcl_ocean_dried_kelp_top.png", "mcl_ocean_dried_kelp_bottom.png", "mcl_ocean_dried_kelp_side.png" }, - groups = { handy = 1, hoey = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, + groups = { handy = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, sounds = mcl_sounds.node_sound_leaves_defaults(), paramtype2 = "facedir", on_place = mcl_util.rotate_axis, diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index 75a99b0f1..aeacecd6f 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -48,7 +48,7 @@ minetest.register_node("mcl_sponges:sponge", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, hoey=1, building_block=1}, + groups = {handy=1, building_block=1}, on_place = function(itemstack, placer, pointed_thing) local pn = placer:get_player_name() if pointed_thing.type ~= "node" then @@ -136,7 +136,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, building_block=1}, on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, From ed7099fefc3f0091426cc2b61c9bb19ed8b96846 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 15:18:19 +0200 Subject: [PATCH 155/164] Fix crash with removed hoey diggroup --- mods/ITEMS/mcl_tools/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 2d804b9bc..ea695129d 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -51,7 +51,6 @@ minetest.register_tool(":", { handy = { speed = 1, level = 1, uses = 0 }, axey = { speed = 1, level = 1, uses = 0 }, shovely = { speed = 1, level = 1, uses = 0 }, - hoey = { speed = 1, level = 1, uses = 0 }, pickaxey = { speed = 1, level = 0, uses = 0 }, swordy = { speed = 1, level = 0, uses = 0 }, swordy_cobweb = { speed = 1, level = 0, uses = 0 }, From 615b15f1331d34c1b5c8e339cc025309b13eecca Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 15:25:31 +0200 Subject: [PATCH 156/164] Revert "Merge pull request 'Add #490' (#1515) from NO11/MineClone2:master into master" This reverts commit 7a8079bb64e02691352001927514bdeed40ce12b, reversing changes made to 849823af1f4d381f85fe8fed4faa96171c92284a. --- mods/ITEMS/mcl_core/crafting.lua | 50 ------ mods/ITEMS/mcl_core/nodes_trees.lua | 164 +----------------- .../mcl_core_stripped_acacia_side.png | Bin 361 -> 0 bytes .../textures/mcl_core_stripped_acacia_top.png | Bin 426 -> 0 bytes .../textures/mcl_core_stripped_birch_side.png | Bin 531 -> 0 bytes .../textures/mcl_core_stripped_birch_top.png | Bin 439 -> 0 bytes .../mcl_core_stripped_dark_oak_side.png | Bin 382 -> 0 bytes .../mcl_core_stripped_dark_oak_top.png | Bin 438 -> 0 bytes .../mcl_core_stripped_jungle_side.png | Bin 415 -> 0 bytes .../textures/mcl_core_stripped_jungle_top.png | Bin 480 -> 0 bytes .../textures/mcl_core_stripped_oak_side.png | Bin 551 -> 0 bytes .../textures/mcl_core_stripped_oak_top.png | Bin 523 -> 0 bytes .../mcl_core_stripped_spruce_side.png | Bin 447 -> 0 bytes .../textures/mcl_core_stripped_spruce_top.png | Bin 556 -> 0 bytes mods/ITEMS/mcl_tools/init.lua | 55 ------ 15 files changed, 2 insertions(+), 267 deletions(-) delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_side.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_side.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_top.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_side.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png delete mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png diff --git a/mods/ITEMS/mcl_core/crafting.lua b/mods/ITEMS/mcl_core/crafting.lua index 7a2b6a5c8..a0ad38a77 100644 --- a/mods/ITEMS/mcl_core/crafting.lua +++ b/mods/ITEMS/mcl_core/crafting.lua @@ -46,56 +46,6 @@ minetest.register_craft({ } }) --- Stripped Bark -minetest.register_craft({ - output = "mcl_core:stripped_oak_bark 3", - recipe = { - { "mcl_core:stripped_oak", "mcl_core:stripped_oak" }, - { "mcl_core:stripped_oak", "mcl_core:stripped_oak" }, - } -}) - -minetest.register_craft({ - output = "mcl_core:stripped_acacia_bark 3", - recipe = { - { "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" }, - { "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" }, - } -}) - -minetest.register_craft({ - output = "mcl_core:stripped_dark_oak_bark 3", - recipe = { - { "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" }, - { "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" }, - } -}) - -minetest.register_craft({ - output = "mcl_core:stripped_birch_bark 3", - recipe = { - { "mcl_core:stripped_birch", "mcl_core:stripped_birch" }, - { "mcl_core:stripped_birch", "mcl_core:stripped_birch" }, - } -}) - -minetest.register_craft({ - output = "mcl_core:stripped_spruce_bark 3", - recipe = { - { "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" }, - { "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" }, - } -}) - -minetest.register_craft({ - output = "mcl_core:stripped_jungle_bark 3", - recipe = { - { "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" }, - { "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" }, - } -}) - - minetest.register_craft({ type = 'shapeless', output = 'mcl_core:mossycobble', diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index fd6641552..3a8aef8d0 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -1,4 +1,4 @@ --- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood +-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves local S = minetest.get_translator("mcl_core") local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil @@ -48,166 +48,6 @@ local register_tree_trunk = function(subname, description_trunk, description_bar }) end --- Register stripped trunk -minetest.register_node("mcl_core:stripped_oak", { - description = "Stripped Oak Log", - _doc_items_longdesc = "Stripped Oak Log is a log that has been stripped of it's bark.", - tiles = {"mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_acacia", { - description = "Stripped Acacia Log", - _doc_items_longdesc = "Stripped Acacia Log is a log that has been stripped of it's bark.", - tiles = {"mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_dark_oak", { - description = "Stripped Dark Oak Log", - _doc_items_longdesc = "Stripped Dark Oak Log is a log that has been stripped of it's bark.", - tiles = {"mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_birch", { - description = "Stripped Birch Log", - _doc_items_longdesc = "Stripped Birch Log is a log that has been stripped of it's bark.", - tiles = {"mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_spruce", { - description = "Stripped Spruce Log", - _doc_items_longdesc = "Stripped Spruce Log is a log that has been stripped of it's bark.", - tiles = {"mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_jungle", { - description = "Stripped Jungle Log", - _doc_items_longdesc = "Stripped Jungle Log is a log that has been stripped of it's bark.", - tiles = {"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - - --- Register stripped bark -minetest.register_node("mcl_core:stripped_oak_bark", { - description = "Stripped Oak Bark", - _doc_items_longdesc = "Stripped Oak Bark is a bark that has been stripped.", - tiles = {"mcl_core_stripped_oak_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_acacia_bark", { - description = "Stripped Acacia Bark", - _doc_items_longdesc = "Stripped Acacia Bark is a bark that has been stripped.", - tiles = {"mcl_core_stripped_acacia_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_dark_oak_bark", { - description = "Stripped Dark Oak Bark", - _doc_items_longdesc = "Stripped Dark Oak Bark is a bark that has been stripped.", - tiles = {"mcl_core_stripped_dark_oak_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_birch_bark", { - description = "Stripped Birch Bark", - _doc_items_longdesc = "Stripped Birch Bark is a bark that has been stripped.", - tiles = {"mcl_core_stripped_birch_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_spruce_bark", { - description = "Stripped Spruce Bark", - _doc_items_longdesc = "Stripped Spruce Bark is a bark that has been stripped.", - tiles = {"mcl_core_stripped_spruce_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - -minetest.register_node("mcl_core:stripped_jungle_bark", { - description = "Stripped Jungle Bark", - _doc_items_longdesc = "Stripped Jungles Bark is a bark that has been stripped.", - tiles = {"mcl_core_stripped_jungle_side.png"}, - is_ground_content = false, - paramtype2 = "facedir", - on_place = mcl_util.rotate_axis, - groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 10, - _mcl_hardness = 2, -}) - - local register_wooden_planks = function(subname, description, tiles) minetest.register_node("mcl_core:"..subname, { description = description, @@ -374,4 +214,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from -- Node aliases minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree") -minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") \ No newline at end of file +minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png deleted file mode 100644 index 2e2de8dbeb40446e193bc91c921dcd549cb8f5ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=De8Ak0{?)V>TT$X?><>&pI=g;PjhMmp=(bD+>SPZ!4!i_@(^)_lzdJhiIMG_2BP zWVrpy;p(&nvkpu&yerNT<0tmQnjyefbLN6bivxTmj@7w;Yn*In_d&gJ%SzABTV^z6&A;4L z^dzKHdG-+*zwJvyw<{R_T{c1XLh-+5{y8Sa*Ltd$pH8X%_q6qDlHQw%GwclJY;_5n z^k?=_y}ni5YfERoJDt~Z*mcvjTd%JDT{SO%VXHXLuZjMen~OICLx924)z4*}Q$iB} DGklU~ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png deleted file mode 100644 index 0746884de9e39cbf129e4291b660df94adc9676c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 426 zcmV;b0agBqP)61q=2N`9A;v0XIoR zK~y-)rBh97gFp~{4MHGccTre`7!Y#MQz3t&f2+T)mqL$?hk~F&5E68&)Lz;{JJa1& zN}-;1XPz_fLvQZyZa?skC$KMZB=~&37_KQT(Y5`o2LLNNWO)LmC6t!VFaj_2cmNed zC?G;H15&*yTMXmmNLcxrs-lJn1@>9OL#m<%0OZF5^5el7&K`(Rz+4TKmZ*x_(HTcy zJ;Kcx5M=@kmnr5at^qbh3FskGz-nzCh#!@!PA zX^DN7@W$d)GXtACy%X3b@mKb}Nok4m#o+Pbnf>tn3YLBz0@}>{`(li~oWImR0jNEf Ua`%pJIsgCw07*qoM6N<$g8!XP)67zmJc#F+p90ia1l zK~y-)b(6i0(?Ar3zeExKDb|Tbifvg!#LWua5UQ12ZMzS_JMbht4YX7ss$Cj_XdJW> zvJ+_(Pl|Y4K@nzlW`SE-cjlgR&za-N+c&R&0X#2L0HQEp(4+k}HRzFdpEdy0RY5B? z05gDGgt+ys+0k^8IF7lwy0n0C9Ftu{-rZ?;9K6P$N19FouwE@}KMDiZtA$6_bdsry z_~FYBqA;MY3hJt0o+O@>d6L+kA)cDyUMb7yUNq~wKzG~2g9Lz9YHtW22%Zpy0liY( zZtl6=+nTfNBrs3)`=w`^3_x|&D4`kLI2XYZw19MUQWttl<_h~&3-1Q!N;wEyQB=kzr z9S5?D$j<>lyW7+5_WuQQtLfx VuEYPSXp;Z{002ovPDHLkV1i8Z>W%;a diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png deleted file mode 100644 index e5290422d4f7f826064a1bff7baf1cea5a2b46c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 439 zcmV;o0Z9IdP)67!-tbnAQLQ0Yphe zK~y-)rIWvkgFq0*e-~0{BZ#1G6R;A}nJUlVGu@lqdt86rRj~`C5^Pol5p1-(D`eK) zM7ZLn+gZOq^UeD9_3{40Kk5kZ`TcO3Y2X9UPP22idjRD%UkRRp04nlmrRr2@m{0kHryVH;}4XpqG002ovPDHLkV1jcoxsLz< diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png deleted file mode 100644 index 9345a14dc22824b02974199546cd9a357df98c15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=De8Ak0{?)V>TT$X?><>&pI=g;Ur}+fsDTaRvrPZci7-5R22jlQ(7^cHn8-FK5Sd z)8~P~TM;JT_I-}m?HuCmoli*l1g9IxG;MKS__L==R|2b`q63UkTEUc^FZj&y%eO71NyIr4Z<=h!uSQ-{I%u#2s+plLlf%Wjp>hD|!X1N7(ZI+f^Pt0WJ-gM{OV-Jpre;-Cx4I{Mnb)uBin`s`&mMm>&*i-MjLsbOyqZwaHD%(KryrUA aW2j+WGV8#H%J0CCV(@hJb6Mw<&;$Sx!J6m* diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png deleted file mode 100644 index fbc45938f39a4c70c4f1b506a630a606676ebb15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 438 zcmV;n0ZIOeP)6HXd)Lc;o;80Ygbd zK~zY`#Z|is!axu_Lm*(~sYTFAEb<3_fFIz;3koU3%8wiq8>*L7_hUa%Zm=gv9jy>nI7 zG))uwi4-75uwE~hi$xeIpJRnX*lOjy_dle76=BD0aP)lE_3JgPS+?Krb|Dc-09F)b z`FIS!&*$s)av6Z98i=SsBP+LffJmSSfT0ve%7hUZ*MKZSmYy9z8Gc_?pIeF;0t2C# zrBTJA6oLaNGLC$VQxs*{wqc5+Uvmj!d49Xy?_nyG;hvf!vDGHZK!o416D3|;pIK0!~>>+~KyL~hV^ARrenyomw^iGcB@ z-BjvWY0|&(AdUX~nLoaJdwu!ZEaw314o3jCMUJtKx+-b=fqm2Q^!NaP%pJWa3kTt$ zMB5Jl%(R}Iuk<3uDox%j=NRi^EDHpj{P~w4uo>$})vWYlQq5S$?r@wa%VhQNO{=A*IS0ZHqj{N+vz8?6D-2_EWv~DM0c}Y{ zK~zY`#Z^110znWQMMRJhMBPMCbU`rQ8yFcHc?7THJv_li-e6)uSVh6a4}yarCcdax zsd~y-_!UJ*KYSn7_y4$VSE0uhmrp{%V zG3Bzg)`sU*eVi*Pz$EE(8VzI4XYcR#u;6mJULTJ+@Mts`MA7FPGm(G*12>!2R;$K1 zx8GkbTAAJMdVM@XAe@78OrXdF6flV47lqV512aKMfQj&0?JpM2ZMUJ40Or{VTEIO- zqM8NV5VOGf+%na=B2P04DkVS+Qa_*GdmrX0*Kid09l(uQQUm}I%6`grtJP+6I2bb= z_WSMjFYf>+vb1UH+&cjtHf1{i%Nbz*a}Oc$c$_40tnJ6~et{?oTP1DCQ~d42!o$n^ zatOH)W&r!sX_EAMc_F@ua?RH^RFXnMR)&eOf(*=r<+p&9;6xCD86Br&{$HEsX^0kla( zK~zY`V@!DCf5(3R|Njg)fY~b58KP4W{8M4KGhSyS#Ldi9R76A=7^Wy}cex(Uz#!Dd zQ_t3hQ2(y#OXII92AqHe#>jc#xkqy)LIP&sojcE;fBcBsfK#XL+tE`ORGukr zQphntqLK++BaB9OIeHYq(gKVo7r-3=i)-{a&tB-cT5}g}1JE6Y%N!UuJ@t0w>nJP^ zz!lW6s6me+bc+cAbc-?40I6~Q`t`?;U%xUi+`s?&_4n_HxW=Xb|3QZL41#!~0GE$& zr46{n1OTjDfR`I+ro=y8r-0HO2I)e~I~z=94vwUe6qaV1KE8{%49d8RXp9g*FS%eK+|a6AKAM3cqQI&{-U~BIh)uLGb?E8|hQKbd zOW&W{Ffh2f>gh>HFfja|0F4p`>`?$O0bzhZ9f462;sU#OU%K?-1@2msP)HEW1%zrn pbO$OO6aB!o6%jRr5*@Ch8vr(5L|EFRL-_yz002ovPDHLkV1kGx<`@6~ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png deleted file mode 100644 index b07c726135d63653bd14fac277ed3f4f66cfd957..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 523 zcmV+m0`&cfP)6B>{s$G=l&D0hmcd zK~y-)rIRsF+fWpRzgQ;1wGll-+YT{u~2S_lyjc=tPz%QczHp zgh-DJ&yooWRq254l?~arizPqb<8!`yU+p40f8`V91Jr%5^77=c$@BJw$ucMF#f%p@ z`}I9;@7I;@wtxS<2}otV7yuK6SXZ!L-veO2e&WaJHxd&tvl{>v^L8~~Uf(fZ(I&}}PZ>k5tNm8lCP8JWZpR}$Amp)Q$M-YOy8Pg|HM)M*SyD{iKb>cYB0 zdukWi`D@+x`2Mw_cHh$$Hd4Z@au+7coXIl(Fw)z5KJ0(FYM;H%{{im@)*MZ?;pYGV N002ovPDHLkV1mUX;dB51 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png deleted file mode 100644 index 11ea15bebbad35c0a09c692a42104d22382c31b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 447 zcmV;w0YLtVP)6F$+yP3djHe0Zd6m zK~y-)eN!=ugD@Cn(DFHykQT21UpXyqtJH67Hpx32J5l;A~zOv8BD705oJRN6ie6y7&50XsDSzB@j)! zs-}Y!8dZMmGlv^fsB1!Ruy`}ybu%1E$J8m7fL^?p8@ zbb$?4GecRVh(o>^sx3nUDYO^m>*=r=DqFkpfHad2pWnac-d&KJ7b%{M`7kZsHLd@N p-J|ZkH{p1&^$y63M23!;RDYjnz-)+rfsX(H002ovPDHLkV1l;oxO4yj diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png deleted file mode 100644 index 7699612b6bf2721104c69d9318710f7723554e40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 556 zcmV+{0@MA8P)6F%~X7W)T1Y0l7&; zK~zY`#Z^6P!e9_SYeEu2tOnCMC~+6GgHVueb#Ulk@LzUtNH>>)LoK)~W@-JXABcu3 zb|{YtmmIozOY$b~-92~DbMKpKw_B}7<9MVinSz(Y(?0v#k~ii)&8^`Pxvp(nR`~tn zcD((5BzjnujJtQD(P%zjufzX8)s3-j#^a^C%0lf#07!{?z2R^&A#&?>*>b{tNR%U! z43CIhGRTSpbeA?+5nvq94F|vj@PyoIwNfdcKi_I8u5!-NaWWZQmx1*Ah*HjapDCi=URlsmr}xk zNO5BTc&jACf8{xSe|!l$2Y-lGq7MF=rfG^25g}J60-yp=!2?U0K_UQ>G<5=iIR;k} z6#%k-JA9>H!!>~7$rAyPIEI{4u3||Oe9bk`Y*s48Vp!No?3a!qDwM{Jb1qE}fQeHe zshkJo=6QpG?-Oa7s;VkcpU8Sb*YO{5$$m7v_+GvM0000 Date: Mon, 12 Apr 2021 15:45:00 +0200 Subject: [PATCH 157/164] Remove debug printin mcl_mobs --- mods/ENTITIES/mcl_mobs/spawning.lua | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index ff52128df..210c6b9c6 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -12,7 +12,7 @@ local vector_distance = vector.distance -- range for mob count local aoc_range = 32 ---[[ +--[[ THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs @@ -158,7 +158,6 @@ local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false -- count how many mobs of one type are inside an area local count_mobs = function(pos,mobtype) - print(mobtype) local num = 0 local objs = get_objects_inside_radius(pos, aoc_range) for n = 1, #objs do @@ -170,12 +169,12 @@ local count_mobs = function(pos,mobtype) num = num + 1 end -- count passive mobs only - else + else num = num + 1 end end end - + return num end @@ -194,7 +193,7 @@ end name: the mobs name -dimension: +dimension: "overworld" "nether" "end" @@ -531,7 +530,7 @@ local function biome_check(biome_list, biome_goal) return false end - + --todo mob limiting --MAIN LOOP @@ -552,11 +551,11 @@ if mobs_spawn then if dimension == "void" or dimension == "default" then break -- ignore void and unloaded area end - + local min,max = decypher_limits(player_pos.y) local goal_pos = position_calculation(player_pos) - + local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) --couldn't find node From c3868084af93d3ab345cbc02a504d5ee9e515230 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 15:19:36 +0200 Subject: [PATCH 158/164] Revert "Fix crash with removed hoey diggroup" This reverts commit ed7099fefc3f0091426cc2b61c9bb19ed8b96846. --- mods/ITEMS/mcl_tools/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 5e8686b4f..b50782ec4 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -51,6 +51,7 @@ minetest.register_tool(":", { handy = { speed = 1, level = 1, uses = 0 }, axey = { speed = 1, level = 1, uses = 0 }, shovely = { speed = 1, level = 1, uses = 0 }, + hoey = { speed = 1, level = 1, uses = 0 }, pickaxey = { speed = 1, level = 0, uses = 0 }, swordy = { speed = 1, level = 0, uses = 0 }, swordy_cobweb = { speed = 1, level = 0, uses = 0 }, From d3a325356347664ed8dac04af9707dd34553b40d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 15:09:48 +0200 Subject: [PATCH 159/164] Revert "Revert "Make hoe dig some blocks faster"" This reverts commit db5626fcb480a7ec3fcb1b2dd064cf8b14d2a260. --- mods/ITEMS/mcl_core/init.lua | 1 + mods/ITEMS/mcl_core/nodes_trees.lua | 14 +++++++++++++- mods/ITEMS/mcl_farming/hoes.lua | 15 +++++++++++++++ mods/ITEMS/mcl_farming/wheat.lua | 2 +- mods/ITEMS/mcl_nether/init.lua | 2 +- mods/ITEMS/mcl_ocean/kelp.lua | 2 +- mods/ITEMS/mcl_sponges/init.lua | 4 ++-- 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index b1b2b9d35..897382e01 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -14,6 +14,7 @@ mcl_autogroup.register_diggroup("shearsy_wool") mcl_autogroup.register_diggroup("shearsy_cobweb") mcl_autogroup.register_diggroup("swordy") mcl_autogroup.register_diggroup("swordy_cobweb") +mcl_autogroup.register_diggroup("hoey") -- Load files local modpath = minetest.get_modpath("mcl_core") diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 3a8aef8d0..197846ebc 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -108,7 +108,19 @@ local register_leaves = function(subname, description, longdesc, tiles, sapling, tiles = tiles, paramtype = "light", stack_max = 64, - groups = {handy=1,shearsy=1,swordy=1, leafdecay=leafdecay_distance, flammable=2, leaves=1, deco_block=1, dig_by_piston=1, fire_encouragement=30, fire_flammability=60}, + groups = { + handy=1, + hoey=1, + shearsy=1, + swordy=1, + leafdecay=leafdecay_distance, + flammable=2, + leaves=1, + deco_block=1, + dig_by_piston=1, + fire_encouragement=30, + fire_flammability=60 + }, drop = get_drops(0), _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index e2e8342d7..db470b999 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -78,6 +78,9 @@ minetest.register_tool("mcl_farming:hoe_wood", { }, _repair_material = "group:wood", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_craft({ @@ -118,6 +121,9 @@ minetest.register_tool("mcl_farming:hoe_stone", { }, _repair_material = "mcl_core:cobble", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_craft({ @@ -154,6 +160,9 @@ minetest.register_tool("mcl_farming:hoe_iron", { }, _repair_material = "mcl_core:iron_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_craft({ @@ -196,6 +205,9 @@ minetest.register_tool("mcl_farming:hoe_gold", { }, _repair_material = "mcl_core:gold_ingot", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_craft({ @@ -240,6 +252,9 @@ minetest.register_tool("mcl_farming:hoe_diamond", { }, _repair_material = "mcl_core:diamond", _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 8, level = 5, uses = 1562 } + }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index 9a8a9f65e..e3ee79ead 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -146,7 +146,7 @@ minetest.register_node("mcl_farming:hay_block", { paramtype2 = "facedir", is_ground_content = false, on_place = mcl_util.rotate_axis, - groups = {handy=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, + groups = {handy=1, hoey=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, sounds = mcl_sounds.node_sound_leaves_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 0.5, diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index f4b203acc..467054767 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -176,7 +176,7 @@ minetest.register_node("mcl_nether:nether_wart_block", { stack_max = 64, tiles = {"mcl_nether_nether_wart_block.png"}, is_ground_content = false, - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, sounds = mcl_sounds.node_sound_leaves_defaults( { footstep={name="default_dirt_footstep", gain=0.7}, diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 15d155fc8..9670943da 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -779,7 +779,7 @@ minetest.register_node("mcl_ocean:dried_kelp_block", { description = S("Dried Kelp Block"), _doc_items_longdesc = S("A decorative block that serves as a great furnace fuel."), tiles = { "mcl_ocean_dried_kelp_top.png", "mcl_ocean_dried_kelp_bottom.png", "mcl_ocean_dried_kelp_side.png" }, - groups = { handy = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, + groups = { handy = 1, hoey = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, sounds = mcl_sounds.node_sound_leaves_defaults(), paramtype2 = "facedir", on_place = mcl_util.rotate_axis, diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index aeacecd6f..75a99b0f1 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -48,7 +48,7 @@ minetest.register_node("mcl_sponges:sponge", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, on_place = function(itemstack, placer, pointed_thing) local pn = placer:get_player_name() if pointed_thing.type ~= "node" then @@ -136,7 +136,7 @@ minetest.register_node("mcl_sponges:sponge_wet", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, From 5fb791335557f938c1bd2e2249afdfa11a358ae5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 12 Apr 2021 15:28:28 +0200 Subject: [PATCH 160/164] Revert "Revert "Merge pull request 'Add #490' (#1515) from NO11/MineClone2:master into master"" This reverts commit 615b15f1331d34c1b5c8e339cc025309b13eecca. --- mods/ITEMS/mcl_core/crafting.lua | 50 ++++++ mods/ITEMS/mcl_core/nodes_trees.lua | 164 +++++++++++++++++- .../mcl_core_stripped_acacia_side.png | Bin 0 -> 361 bytes .../textures/mcl_core_stripped_acacia_top.png | Bin 0 -> 426 bytes .../textures/mcl_core_stripped_birch_side.png | Bin 0 -> 531 bytes .../textures/mcl_core_stripped_birch_top.png | Bin 0 -> 439 bytes .../mcl_core_stripped_dark_oak_side.png | Bin 0 -> 382 bytes .../mcl_core_stripped_dark_oak_top.png | Bin 0 -> 438 bytes .../mcl_core_stripped_jungle_side.png | Bin 0 -> 415 bytes .../textures/mcl_core_stripped_jungle_top.png | Bin 0 -> 480 bytes .../textures/mcl_core_stripped_oak_side.png | Bin 0 -> 551 bytes .../textures/mcl_core_stripped_oak_top.png | Bin 0 -> 523 bytes .../mcl_core_stripped_spruce_side.png | Bin 0 -> 447 bytes .../textures/mcl_core_stripped_spruce_top.png | Bin 0 -> 556 bytes mods/ITEMS/mcl_tools/init.lua | 55 ++++++ 15 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_jungle_top.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png create mode 100644 mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png diff --git a/mods/ITEMS/mcl_core/crafting.lua b/mods/ITEMS/mcl_core/crafting.lua index a0ad38a77..7a2b6a5c8 100644 --- a/mods/ITEMS/mcl_core/crafting.lua +++ b/mods/ITEMS/mcl_core/crafting.lua @@ -46,6 +46,56 @@ minetest.register_craft({ } }) +-- Stripped Bark +minetest.register_craft({ + output = "mcl_core:stripped_oak_bark 3", + recipe = { + { "mcl_core:stripped_oak", "mcl_core:stripped_oak" }, + { "mcl_core:stripped_oak", "mcl_core:stripped_oak" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_acacia_bark 3", + recipe = { + { "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" }, + { "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_dark_oak_bark 3", + recipe = { + { "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" }, + { "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_birch_bark 3", + recipe = { + { "mcl_core:stripped_birch", "mcl_core:stripped_birch" }, + { "mcl_core:stripped_birch", "mcl_core:stripped_birch" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_spruce_bark 3", + recipe = { + { "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" }, + { "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" }, + } +}) + +minetest.register_craft({ + output = "mcl_core:stripped_jungle_bark 3", + recipe = { + { "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" }, + { "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" }, + } +}) + + minetest.register_craft({ type = 'shapeless', output = 'mcl_core:mossycobble', diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 197846ebc..4af3eef34 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -1,4 +1,4 @@ --- Tree nodes: Wood, Wooden Planks, Sapling, Leaves +-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood local S = minetest.get_translator("mcl_core") local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil @@ -48,6 +48,166 @@ local register_tree_trunk = function(subname, description_trunk, description_bar }) end +-- Register stripped trunk +minetest.register_node("mcl_core:stripped_oak", { + description = "Stripped Oak Log", + _doc_items_longdesc = "Stripped Oak Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_acacia", { + description = "Stripped Acacia Log", + _doc_items_longdesc = "Stripped Acacia Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_dark_oak", { + description = "Stripped Dark Oak Log", + _doc_items_longdesc = "Stripped Dark Oak Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_birch", { + description = "Stripped Birch Log", + _doc_items_longdesc = "Stripped Birch Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_spruce", { + description = "Stripped Spruce Log", + _doc_items_longdesc = "Stripped Spruce Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_jungle", { + description = "Stripped Jungle Log", + _doc_items_longdesc = "Stripped Jungle Log is a log that has been stripped of it's bark.", + tiles = {"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + + +-- Register stripped bark +minetest.register_node("mcl_core:stripped_oak_bark", { + description = "Stripped Oak Bark", + _doc_items_longdesc = "Stripped Oak Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_acacia_bark", { + description = "Stripped Acacia Bark", + _doc_items_longdesc = "Stripped Acacia Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_acacia_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_dark_oak_bark", { + description = "Stripped Dark Oak Bark", + _doc_items_longdesc = "Stripped Dark Oak Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_dark_oak_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_birch_bark", { + description = "Stripped Birch Bark", + _doc_items_longdesc = "Stripped Birch Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_birch_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_spruce_bark", { + description = "Stripped Spruce Bark", + _doc_items_longdesc = "Stripped Spruce Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_spruce_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_core:stripped_jungle_bark", { + description = "Stripped Jungle Bark", + _doc_items_longdesc = "Stripped Jungles Bark is a bark that has been stripped.", + tiles = {"mcl_core_stripped_jungle_side.png"}, + is_ground_content = false, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 10, + _mcl_hardness = 2, +}) + + local register_wooden_planks = function(subname, description, tiles) minetest.register_node("mcl_core:"..subname, { description = description, @@ -226,4 +386,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from -- Node aliases minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree") -minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") +minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") \ No newline at end of file diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_side.png new file mode 100644 index 0000000000000000000000000000000000000000..2e2de8dbeb40446e193bc91c921dcd549cb8f5ed GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=De8Ak0{?)V>TT$X?><>&pI=g;PjhMmp=(bD+>SPZ!4!i_@(^)_lzdJhiIMG_2BP zWVrpy;p(&nvkpu&yerNT<0tmQnjyefbLN6bivxTmj@7w;Yn*In_d&gJ%SzABTV^z6&A;4L z^dzKHdG-+*zwJvyw<{R_T{c1XLh-+5{y8Sa*Ltd$pH8X%_q6qDlHQw%GwclJY;_5n z^k?=_y}ni5YfERoJDt~Z*mcvjTd%JDT{SO%VXHXLuZjMen~OICLx924)z4*}Q$iB} DGklU~ literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_acacia_top.png new file mode 100644 index 0000000000000000000000000000000000000000..0746884de9e39cbf129e4291b660df94adc9676c GIT binary patch literal 426 zcmV;b0agBqP)61q=2N`9A;v0XIoR zK~y-)rBh97gFp~{4MHGccTre`7!Y#MQz3t&f2+T)mqL$?hk~F&5E68&)Lz;{JJa1& zN}-;1XPz_fLvQZyZa?skC$KMZB=~&37_KQT(Y5`o2LLNNWO)LmC6t!VFaj_2cmNed zC?G;H15&*yTMXmmNLcxrs-lJn1@>9OL#m<%0OZF5^5el7&K`(Rz+4TKmZ*x_(HTcy zJ;Kcx5M=@kmnr5at^qbh3FskGz-nzCh#!@!PA zX^DN7@W$d)GXtACy%X3b@mKb}Nok4m#o+Pbnf>tn3YLBz0@}>{`(li~oWImR0jNEf Ua`%pJIsgCw07*qoM6N<$g8!XP)67zmJc#F+p90ia1l zK~y-)b(6i0(?Ar3zeExKDb|Tbifvg!#LWua5UQ12ZMzS_JMbht4YX7ss$Cj_XdJW> zvJ+_(Pl|Y4K@nzlW`SE-cjlgR&za-N+c&R&0X#2L0HQEp(4+k}HRzFdpEdy0RY5B? z05gDGgt+ys+0k^8IF7lwy0n0C9Ftu{-rZ?;9K6P$N19FouwE@}KMDiZtA$6_bdsry z_~FYBqA;MY3hJt0o+O@>d6L+kA)cDyUMb7yUNq~wKzG~2g9Lz9YHtW22%Zpy0liY( zZtl6=+nTfNBrs3)`=w`^3_x|&D4`kLI2XYZw19MUQWttl<_h~&3-1Q!N;wEyQB=kzr z9S5?D$j<>lyW7+5_WuQQtLfx VuEYPSXp;Z{002ovPDHLkV1i8Z>W%;a literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_birch_top.png new file mode 100644 index 0000000000000000000000000000000000000000..e5290422d4f7f826064a1bff7baf1cea5a2b46c7 GIT binary patch literal 439 zcmV;o0Z9IdP)67!-tbnAQLQ0Yphe zK~y-)rIWvkgFq0*e-~0{BZ#1G6R;A}nJUlVGu@lqdt86rRj~`C5^Pol5p1-(D`eK) zM7ZLn+gZOq^UeD9_3{40Kk5kZ`TcO3Y2X9UPP22idjRD%UkRRp04nlmrRr2@m{0kHryVH;}4XpqG002ovPDHLkV1jcoxsLz< literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_side.png new file mode 100644 index 0000000000000000000000000000000000000000..9345a14dc22824b02974199546cd9a357df98c15 GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=De8Ak0{?)V>TT$X?><>&pI=g;Ur}+fsDTaRvrPZci7-5R22jlQ(7^cHn8-FK5Sd z)8~P~TM;JT_I-}m?HuCmoli*l1g9IxG;MKS__L==R|2b`q63UkTEUc^FZj&y%eO71NyIr4Z<=h!uSQ-{I%u#2s+plLlf%Wjp>hD|!X1N7(ZI+f^Pt0WJ-gM{OV-Jpre;-Cx4I{Mnb)uBin`s`&mMm>&*i-MjLsbOyqZwaHD%(KryrUA aW2j+WGV8#H%J0CCV(@hJb6Mw<&;$Sx!J6m* literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_dark_oak_top.png new file mode 100644 index 0000000000000000000000000000000000000000..fbc45938f39a4c70c4f1b506a630a606676ebb15 GIT binary patch literal 438 zcmV;n0ZIOeP)6HXd)Lc;o;80Ygbd zK~zY`#Z|is!axu_Lm*(~sYTFAEb<3_fFIz;3koU3%8wiq8>*L7_hUa%Zm=gv9jy>nI7 zG))uwi4-75uwE~hi$xeIpJRnX*lOjy_dle76=BD0aP)lE_3JgPS+?Krb|Dc-09F)b z`FIS!&*$s)av6Z98i=SsBP+LffJmSSfT0ve%7hUZ*MKZSmYy9z8Gc_?pIeF;0t2C# zrBTJA6oLaNGLC$VQxs*{wqc5+Uvmj!d49Xy?_nyG;hvf!vDGHZK!o416D3|;pIK0!~>>+~KyL~hV^ARrenyomw^iGcB@ z-BjvWY0|&(AdUX~nLoaJdwu!ZEaw314o3jCMUJtKx+-b=fqm2Q^!NaP%pJWa3kTt$ zMB5Jl%(R}Iuk<3uDox%j=NRi^EDHpj{P~w4uo>$})vWYlQq5S$?r@wa%VhQNO{=A*IS0ZHqj{N+vz8?6D-2_EWv~DM0c}Y{ zK~zY`#Z^110znWQMMRJhMBPMCbU`rQ8yFcHc?7THJv_li-e6)uSVh6a4}yarCcdax zsd~y-_!UJ*KYSn7_y4$VSE0uhmrp{%V zG3Bzg)`sU*eVi*Pz$EE(8VzI4XYcR#u;6mJULTJ+@Mts`MA7FPGm(G*12>!2R;$K1 zx8GkbTAAJMdVM@XAe@78OrXdF6flV47lqV512aKMfQj&0?JpM2ZMUJ40Or{VTEIO- zqM8NV5VOGf+%na=B2P04DkVS+Qa_*GdmrX0*Kid09l(uQQUm}I%6`grtJP+6I2bb= z_WSMjFYf>+vb1UH+&cjtHf1{i%Nbz*a}Oc$c$_40tnJ6~et{?oTP1DCQ~d42!o$n^ zatOH)W&r!sX_EAMc_F@ua?RH^RFXnMR)&eOf(*=r<+p&9;6xCD86Br&{$HEsX^0kla( zK~zY`V@!DCf5(3R|Njg)fY~b58KP4W{8M4KGhSyS#Ldi9R76A=7^Wy}cex(Uz#!Dd zQ_t3hQ2(y#OXII92AqHe#>jc#xkqy)LIP&sojcE;fBcBsfK#XL+tE`ORGukr zQphntqLK++BaB9OIeHYq(gKVo7r-3=i)-{a&tB-cT5}g}1JE6Y%N!UuJ@t0w>nJP^ zz!lW6s6me+bc+cAbc-?40I6~Q`t`?;U%xUi+`s?&_4n_HxW=Xb|3QZL41#!~0GE$& zr46{n1OTjDfR`I+ro=y8r-0HO2I)e~I~z=94vwUe6qaV1KE8{%49d8RXp9g*FS%eK+|a6AKAM3cqQI&{-U~BIh)uLGb?E8|hQKbd zOW&W{Ffh2f>gh>HFfja|0F4p`>`?$O0bzhZ9f462;sU#OU%K?-1@2msP)HEW1%zrn pbO$OO6aB!o6%jRr5*@Ch8vr(5L|EFRL-_yz002ovPDHLkV1kGx<`@6~ literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_oak_top.png new file mode 100644 index 0000000000000000000000000000000000000000..b07c726135d63653bd14fac277ed3f4f66cfd957 GIT binary patch literal 523 zcmV+m0`&cfP)6B>{s$G=l&D0hmcd zK~y-)rIRsF+fWpRzgQ;1wGll-+YT{u~2S_lyjc=tPz%QczHp zgh-DJ&yooWRq254l?~arizPqb<8!`yU+p40f8`V91Jr%5^77=c$@BJw$ucMF#f%p@ z`}I9;@7I;@wtxS<2}otV7yuK6SXZ!L-veO2e&WaJHxd&tvl{>v^L8~~Uf(fZ(I&}}PZ>k5tNm8lCP8JWZpR}$Amp)Q$M-YOy8Pg|HM)M*SyD{iKb>cYB0 zdukWi`D@+x`2Mw_cHh$$Hd4Z@au+7coXIl(Fw)z5KJ0(FYM;H%{{im@)*MZ?;pYGV N002ovPDHLkV1mUX;dB51 literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_side.png new file mode 100644 index 0000000000000000000000000000000000000000..11ea15bebbad35c0a09c692a42104d22382c31b1 GIT binary patch literal 447 zcmV;w0YLtVP)6F$+yP3djHe0Zd6m zK~y-)eN!=ugD@Cn(DFHykQT21UpXyqtJH67Hpx32J5l;A~zOv8BD705oJRN6ie6y7&50XsDSzB@j)! zs-}Y!8dZMmGlv^fsB1!Ruy`}ybu%1E$J8m7fL^?p8@ zbb$?4GecRVh(o>^sx3nUDYO^m>*=r=DqFkpfHad2pWnac-d&KJ7b%{M`7kZsHLd@N p-J|ZkH{p1&^$y63M23!;RDYjnz-)+rfsX(H002ovPDHLkV1l;oxO4yj literal 0 HcmV?d00001 diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_stripped_spruce_top.png new file mode 100644 index 0000000000000000000000000000000000000000..7699612b6bf2721104c69d9318710f7723554e40 GIT binary patch literal 556 zcmV+{0@MA8P)6F%~X7W)T1Y0l7&; zK~zY`#Z^6P!e9_SYeEu2tOnCMC~+6GgHVueb#Ulk@LzUtNH>>)LoK)~W@-JXABcu3 zb|{YtmmIozOY$b~-92~DbMKpKw_B}7<9MVinSz(Y(?0v#k~ii)&8^`Pxvp(nR`~tn zcD((5BzjnujJtQD(P%zjufzX8)s3-j#^a^C%0lf#07!{?z2R^&A#&?>*>b{tNR%U! z43CIhGRTSpbeA?+5nvq94F|vj@PyoIwNfdcKi_I8u5!-NaWWZQmx1*Ah*HjapDCi=URlsmr}xk zNO5BTc&jACf8{xSe|!l$2Y-lGq7MF=rfG^25g}J60-yp=!2?U0K_UQ>G<5=iIR;k} z6#%k-JA9>H!!>~7$rAyPIEI{4u3||Oe9bk`Y*s48Vp!No?3a!qDwM{Jb1qE}fQeHe zshkJo=6QpG?-Oa7s;VkcpU8Sb*YO{5$$m7v_+GvM0000 Date: Mon, 12 Apr 2021 17:54:09 +0200 Subject: [PATCH 161/164] Fix crash in mcl_bossbars.remove_bar --- mods/HUD/mcl_bossbars/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 08eb527bf..8ed08a613 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -65,7 +65,7 @@ function mcl_bossbars.add_bar(player, def, dynamic, priority) end function mcl_bossbars.remove_bar(id) - mcl_bossbars.static[id].bar.id = nil + mcl_bossbars.static[id].id = nil mcl_bossbars.static[id] = nil end From 424685d3d3927b53f265dd3d424cf0fae572be32 Mon Sep 17 00:00:00 2001 From: epCode Date: Mon, 12 Apr 2021 14:56:33 -0700 Subject: [PATCH 162/164] Add elytra (sprint in air to use) --- mods/ITEMS/mcl_armor/armor.lua | 3 ++ mods/ITEMS/mcl_armor/init.lua | 17 ++++++- .../mcl_armor/models/mcl_armor_character.b3d | Bin 343384 -> 453135 bytes .../models/mcl_armor_character.blend | Bin 1174524 -> 1208156 bytes .../models/mcl_armor_character_female.b3d | Bin 343384 -> 453135 bytes .../models/mcl_armor_character_female.blend | Bin 1191204 -> 1212956 bytes .../mcl_armor/textures/mcl_armor_elytra.png | Bin 0 -> 746 bytes .../textures/mcl_armor_inv_elytra.png | Bin 0 -> 355 bytes mods/PLAYER/mcl_playerplus/init.lua | 43 +++++++++++++++++- 9 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 mods/ITEMS/mcl_armor/textures/mcl_armor_elytra.png create mode 100644 mods/ITEMS/mcl_armor/textures/mcl_armor_inv_elytra.png diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index 05a020016..a35841fe2 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -368,6 +368,7 @@ mcl_player.player_register_model("mcl_armor_character.b3d", { run_walk_mine = {x=461, y=480}, sit_mount = {x=484, y=484}, die = {x=498, y=498}, + fly = {x=502, y=581}, }, }) @@ -396,6 +397,8 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", { run_walk = {x=440, y=459}, run_walk_mine = {x=461, y=480}, sit_mount = {x=484, y=484}, + die = {x=498, y=498}, + fly = {x=502, y=581}, }, }) diff --git a/mods/ITEMS/mcl_armor/init.lua b/mods/ITEMS/mcl_armor/init.lua index c5502cf42..bce597b7f 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -8,6 +8,20 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/alias.lua") local longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive.") local usage = S("To equip it, put it on the corresponding armor slot in your inventory menu.") +minetest.register_tool("mcl_armor:elytra", { + description = S("Elytra"), + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usage, + inventory_image = "mcl_armor_inv_elytra.png", + groups = {armor_torso=1, mcl_armor_points=0, mcl_armor_uses=10, enchantability=0}, + sounds = { + _mcl_armor_equip = "mcl_armor_equip_leather", + _mcl_armor_unequip = "mcl_armor_unequip_leather", + }, + on_place = armor.on_armor_use, + on_secondary_use = armor.on_armor_use, +}) + minetest.register_tool("mcl_armor:helmet_leather", { description = S("Leather Cap"), _doc_items_longdesc = longdesc, @@ -322,7 +336,7 @@ local craft_ingreds = { gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" }, diamond = { "mcl_core:diamond" }, chain = { nil, "mcl_core:iron_nugget"} , -} +} for k, v in pairs(craft_ingreds) do -- material @@ -389,4 +403,3 @@ for k, v in pairs(craft_ingreds) do }) end end - diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index a658f753c3b423573cd735f196876364467c87c2..952850ba3812df912ed1b6a24802d72ecf4c7014 100644 GIT binary patch delta 98570 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 Oi{nvLF~h;#?*9Q#(49^I delta 29481 zcmeG^cU)A*^Cukk0tzaMiiJB{LV1UkW8bqN#)iEsDwY^EY6JyLZZ)waF$%V4i%}D6 zEZ`kQ1a2*fU9oHI#;DO)5{)s|-^|;0Eb{aFNj|^d_fO{Y8Q<=E^JaH;XJ_UOH_kg% z{oFI}60KTEZKA9m$tC8w=Z1MCFSV3k(br&j4bZDwkM4)tq+Tdr)8_WaJT`vWWI3-# zN%rZpxbTvOC*eQuwX<_wOv;%4H=TIT05GP1Kel9?S-CY~u6(?=XBggFmsXKcpQ-YI z%b#lZ@ZAO1=ds9DljWm>1;4$EE3!V-r^=Vk3A!)B`Z3S(W}7lQJ+C{cFMRfNgUnw(4f0+^h6w`Ab-5P!bzI zVX}O-gpl~>uPU)Aza`3NjDl{9)SvZ52Wu5>Qfyy#7lgHs_GiX{X61@qFzi*|n*|+9lzaG#f$uJdE$KH|K7T6EU#kd=i`8YO;KFo8VV`hBsT1lPI4E z5_E?f+6J&yeay+$<(#=?*clBPN;Um76Tz=_vRuYMRDU8k>}j9R%HRc_1jTS^4Qt&d-MD zxXf}NI1-6+r=eot);*KihDwv=+r0(DdQ*K^=G;X2=m0@?zxF_OyQ5j@_fSl*Ui~yy z?_HC!ZipE8<2A`F`bnJpyT9N!C^pT;PMJ(f`lFxo_jqXbK(?^0SvgZ?UcRAOQn@mm zh(x*L6ftnw1<9=0i#YjiBf&8JFCP{;IZ-}5QP9z^2eQ)b%u4U#g5SO2Y3#lFCdFRL zCT19MHJLrU949||Ts;3Ao9$`rslQ3txm--}annJd!Di)TZNad?{K{}566MIbV&Kzx z$!z}(kodLW*Y2ar?A+i)dEacE&ITsa%Xbh9Qp`#ZKfy5V+cY+&j!DT(6$6*AIiJye zaq{2$1;Ymq)0kg%ld`|HpqpVI#4a{BD<_%?eml!mVM(nL<+k6634UFEKC|^X5+^@B zDHxu=Uzv@HOq73IDG0w=IEZy?X;!+12!>OyrLiPGlk!7fG4SdB^OW;$&l6!LZ$?bT+$`Nx9ro(1n_! zS!8{)axh*n{E${<@{0snz9|O&Yu|iUa#oz|9wqpFKBOwE>Xs6e18PmLjaYFx=e7m&qp+|gWn;vp~Gc1EW{wqN7un59mmkeQ!%4TKHPQkF&BVYC~ zEkSNlUkn^I4Yov%lPew;6SSW4W&3v~$UEx@I`@PjtYKBN(k5N-v%T9RgN^z-KyiCd z4E*`g1#EoXIJxp7!En^-3|94z0HyTBtND98*?TBE=V?}U9~TT$$5n$9ksvn>7Xw#z zE?|)jK;l(`-@z``SoC)ZHaWeSAYAz85EfO@tjLE2!@rU<*xW|}O7TC$z)@uvGDF!o z+3$V9F!)La3;QiVsr;FsE15JD6xgh=TY_J!JJp!ytOVK81IM*-?Z5V70XydvCs&^& z7!Ej8joqG;AUisX37RGhWfRMq6>?oLWXCet_Im+JrDbAZ-}e@>q{p#xU8~^t%rBEg z-waTyHx_iuY-NUl2Ah?gF9pL>!>hxINRWd@i-9+^Sja{_i-h+J{7!4w>xPwE!jHju?2;4+~k!53zFNUyS+Z`12*1Y~4=*$~#j9UA9{c zD6mP%Xdou|#{fS#5eahR#bV&5=?mHHL$Pwhhk~DHxXq6(iAa#QBniSZKM!M9pP7_q z^#sGJpJ%d~7Xy@#`C{OY+!rx=Hi-Fx9FJx66An{(o@ar9ZtbSmEylI`F8#y?J8UHjXO{ZkC9|G=b#MhSi!jXT(=ya1*3bv`i0oo=>8 zHWqD*m0J!G46k+F!MqOyC_N?#!m+W#*{NG5CG`WraQ(3wZ2Yr$*>p|}octkd$qbNq zjNr#oYOqK{g1q*Gp!=fNaMtlxlM*t*CKyg^wS&z*7@$ObAqGB_y@)*=87o^u1;b7A zcCaRU0+c>}g6`GB;h?}KW$QG-uUUtha3bR6y7$Gv{kAM(`^U!0VY1E-OO~{A1j*OctXV0m|qxmu&en ztbKa~Xs}7yv_&xN-KrMzcf`xJs)-5St-qMv4hM;E3x?zC)?!b0#LKI^1zn2+BUt8H zlhSa5;CJx(4)!E7K>2XGYl5Kvb>kMZRkdT~PN{;Sv3(X>lNz8*_I42(3|ohdWHEX0 zRkKGhypdCjrL2gT{er~6juDI56mzWHAzSb({!J}5driE&qM@KW+-4-if5%OVIae@T z&^(J(wFf94H53E?W?#&LO2^7wW(bCdW@fSd-v=m(*%$LyP`)w}6xgJ!JumnrH1}uC zX2i?YBE-NSf47*G^aO#E+?mal^I1^MpH=-bUS28-!hvigGaNQ4rc;7p-^p1ld`o~b z<%Ag6@%v)N{+J~9>?mkJ;>*0Gn7d4ha(X$`wS2R zx4yoZEqOXgj*1Zs0~Y(U4IjnJOL_^q2Q5djIzO6}x_9y!8tSBFvFP;y%8Udt@W+8F zi@GpL?(>e|H^6Nt^IT;MP!^RHghS7a0u44P-*_bFd%Gn;wc$j>%ia^kz-9eaR{z>0 zxmPp6Fx{&*Yc?QWR>ufBnlXw+GLurvAo$(=Ba6*k9iYsw1LL|qi?iRTIlPj+RFfp5 zTaVKA9!a^ggz)16~8X3iz|$$M#LYUjT0a-qQOwY|yv^ z_$%OTz`J@M+xG$Q0saQ~K<{Jw55V669|Ato``CU0_$T0Fz`yi9wx0q14fquBx!%Y2 zD?r;z_~!-SYyAec-P{d^Vt@ufcR=i8yEvc+pb@Zy-p6)nz*2xE0n6xpY?lWt2Ur%c zg5Jk=ML;h=Pj}e=O8O1x7%Bt$0D1#f(fio02Ivb|6|lPA$97G?8i0O)we&u=>j2gU z^are~_pxmP3;?VLXx93$|JZ2=*Z{CTU?aVc?RNp+0c;EysQ0lQ0vHS!1Ssi!Y&QW6 z1+)M*)%)0P0oWX{8DLAjkL_?9{9^?S10;AuZ?}T00w@Ev2E;zLBLLe1wgGIX_p$vR zV0*wwzz%vJ+noVB0d@rJqW7`g4X`VqEeihWuHV3RFTkFFJpg;_eQfsw>wRnw1snnx4LD5iV|xVPaKISAk?w{b+70ZC27DiI6yOJXAKT*q#{!N4 z{7~;>Tj|`sQ(27n0Ddoq|Bi3fxl5b2$F3U}G>d3a8t-&y+qe6Qp7!kiD|?o}XE)~< z7p!%LxY6qN^UhX2whf@{2xtHi(D)&sAw<}$U(paEpix9XgNTr#U(p~Upm9V%!-(L} zuV@$%&`2VnfdsH=RuNlhAra78BA}&2$kwl5DK$W=iGT(Zf$3K?mMCmJ|UkCIVVg1hlFMXi*W+a3Y{ZML=VUa8kdb0YyN= zihxEI0SzpUuUS>Rffg14tt|ptS_HJH2xw^$(CQ+f#YI5Nihvdu0j)0rT3!USwg_l> z5zq=FpasV9HLHtPw7>{xjSntKE^^$2Lv5zy2lpxH;LrCpz{faIC0o?%tx&nm8`W0OP0=fkRbO{J(`Vr72AfS6dK-YkPE&u^t0|L4U0Gs9` zu!X(=0eu7l`U?c~6$t1a5YSa1pqoHImw_PbS9BQ&=q?b@bs)6Sujo1u(2Z#Nk3Iwe zeFXyg5Crrm2V^$)LK>j2 zK|mjbfc^*peGvls90c@52MJ}hv=HFn}!Y6eLxzP-=BN(n|bzL{howm0WEEn zV>jI1B^eA$Qi}oYYoNt<`W{Ij^*VLRZMbx${YljHkexs)f8y?7OFKKDS%WBR>Y=~Ga)Dj$#gf|% zo*51~+jl#1dk%DnZq>?@*m^yjW$ziSHHUs`bpq|{nS(6`_Rzs*9S%lXmq;hO_>#Q| z9h{5S-rKqQ!agel+R$sV1%CPBptBC!G-8ws@$t+?q~g(*&Oq-o*$r!7x9$SswG|ow z@#B2P$Q-fhtPW(+N50NaN^Z%vG}vL?4Ya*h`UCA5hyUfn+JsRs#HBwCAT^E{oM~0R zw0}sWtb2fVY9-`rOL2G>AjVmraPLL7Jul-7Pj7DRJ@HY?y+G_Y`6>`^mZt8X0~^67 zixW;hPDr)aCTH}sbJmmh-^uv_Xd{=yO3 z{0Ov*>mMw!-H^A}LZ{eMai(s-6!EJI-o$rGXJ?C(C#~$^PucrauVo&Ud~s|fE4*9# zwa40KB1w;r09xC77Emcox|c9(#Qi~)N%Q5Mo!$y-`BAso)?+~2aL1n^ z26`IRFBm0rO}OElAW~;^Qzz?U$yt1Kk2McyZ)X0v-9UfVXkB#p&gso$aJ}uoT7fCxO!8BuZ@TNd{dm?d(6OVa~mkDb^D}{BKqDBr-0<*R>M% zM?Fa(XzGH%3Zcjth1Y;q3l-6V&spF^B1uG)yN%8|ySdpMhpa|>gams!sP?ZTcW2mIhX%|+|l z=82mslg%l^Iyy~5OXhsr>8|xBAkNBM0F002&lri3dAoroa$x{*8p}rH3_R{0egSAr zaXoajd;Y#3&^bKxCDt;d5q*?p2+cvyty{H|usxDP1e9$uDPP#w!vf;)z$qge3 zj~Y7-6+g5Gj4Hi70)7d7w0A2Q1$O7i9EWQS@p{kCNS<%(=aeUmws!Qrlidzzr+l*3 z0<*A$$BeKb%`+V{YM{6Ch?At{0j_mu=<9=`uZ>cUNrA`Eg%b*n2>`b>L{2Fts49OXjx; z*8ylN-x`3zh2A(~@Jqv1RHvJP3{-^O|S`8sQ)uQ8`15O1is`VHw^%$J_L9-dWU zm~-WvC)Q0XI_Go(+DON?g3@WOWyfxLoblIEi!`*2LNU#e=YubsJ|70NN#2 zDoC$izqW+wTk0~-J#JSa6B9c+izhj)&qtQZ8K?%{b+2yAEBiEj?u3EP1K&KiUY}~o z83ZgwcVB4%Mb#n(91d9^uJ5}qyyxT5&UwzoR`%Pm?7=`AS!Egym+!rh?rlmN4Yc+9 zwni~r#}~!mC#RxgUwFjC51iYqAvwQ&UpH(B5Wl*%1SY}iyTTTi&5j6gCkG$*bGB=< zBInx^qr-**Z9$pwgkfZX^xt2tK^jFyI?LbQmXqCOV%RXCUG?B#2+&x#4Y3L0Q6`DR zbZz3C{(4Z(@U@M?Vu1MHD&cUTExbvtm0R0EBFRmgIIleGVqG@yv+NNCCtM4531{ru z)sUPjWVq7Nd1v$~YxzFjIqJK2;d~U{q*1`4@FpP_#PmMx$O6W z_TO&OXrL{;NwAhYTLKgfNEICGi7}BoBNOot?>z-pTDLlWI>YISvPt2&I{YRWFG)d zhIU;YN%42!d!-@jh_;@%GwYfRBE##v${jL)_|APFby9<0xclV$#&KUxCL?2}=Uyty zvYJ+EkgX1S;qK?TDBeb9&6}QczWH}M_V>=+sebXoJy?^55{z2&8_Mj^$m$AI=~U`a`~U9`wE-wf|QwMk@_N2t>{IK}#F zwddJ+Ks#>D8Vh~prM7+P?qw?+upS43I$dix7zC`YU>;Wqv2eh80%&(sx*#zKSflko z1}BQER5)Ng3AFd$-7e8r?Ja1zkPaNon70P3r+_&1WpRl?z*<D+T}Pwj8A9k-wVhT_p)$+`V$auN68^TMafYTm$54xpk4sl2ilUh&Hrd|Nnap9 z)#B5OK+CtP(?9RkB_M7UdRC&v{xLvRSHFfO#pOig5h)Ky*FZpe1sIW#<&ymRXuf75 z9ZFs}AiWB-l`nO7&{sn&O#k*qX>hyB_HIq4&8X|F5Wg=w^7$U?HJ~*t-2V=^gv|zj zL*xdR*mx~`l&%Bui<s{ZZeQez2rj<(!o}kY5 zGB$rBabDn$y38%(VMa0Lp7F_6H&$BR@>y}Fx|J=SrT?jyl8xH$Z7AU-eBgZaJ}=>; zgqQG9!b|ul;U#>O@De^scnKdRyo8SuUcyHSFX5wvm+*ms*ZJ}iJ}}Oi`VC&fM+qX#7p=n;U#>O@De^scnKdRyo8SuUcyHSFX5wvm+(=-OZX_^C47|d5O@De^s zcnKdRyo8SuUcyI-UcyHS7E9v<_%Dqp;U#>O@De^scnKdRyo8SuUcyHSFX5wvm+(=- zOZX_^C47|d5HK*KA0@nmj}pCvj}ok=#tHBeK1z5AAEdJM`@Dn??62PEC46AF z^}az%2ZQ0!ue^kh5?;bb2`}NJgqQG9!b|ul(M$L!DXG86GwYO;*89AKj}l(O2M%1n z&rA3y;U#>O@De^scnKdR6?HmZ!bb@&;iH6?@KM4`_$bj!_$c8ee3bAKK1z5AA0@nm zj}l(OM+qFU5?;bb2`}M;%&h*Lm+(=-OZX_^C47|d5j}l(OM+qO@De^s zhUo9}5 z5?;awE2Wi-XOuA;KdDv9c){C}7Pe4cqONRetm4@uHeH%JeXEvOUm~q>sMF$%em>1t zIi#jYHozFir3fk9MbYEhooi9V>U_-^_66-UgCJ~G^zII+f_?D zqg29R#}Sg$qh@0jpVRiO(xyLlNSG4`Zju8YeWP}6ZLCruYWiv^tCdr7YL5(R&}3r` zpK)85RHN!{2nIE55g#4?@pIG0z=GF!`!s7zC8afx$=dLTn4-f z_}CbV=zQs)7Z?_*4O9o^gYs7?;Mc! zX^#pnjHhd1_Un(-+Jj-~QSVVJ*OXGlw1q)V7&hR=3w29vav z^cnV5u4FlqDq&6;AK_bx>Z@kPD%Q(YQZ*SdgKRJ)IZ%8RWV{Blp`3^)<0Fs}SMVt%*)BG*%QM_6+5|n$$&v&Ip?w2G?*#giEHN2a#x)*Le zE)6DU#j;pk%Yu1WgCSaDGzXRiwZ?@m?Li5CgO$ZREHK8Eg=3>ByC3X0W?TU@7R%Mk zJz<(SAijYKR@aiu(A3uR#_MqA{QxrcPla zw8fdqm$Y%8AEhH_H%pi)z53n&eYG!JVANTqc1rdc*%Bs3ZwzXzX-k57|5IbFP)vVD z)ir6SZgqh}a#2?xJS0~x?UP!kZjmtkxx7xIBTap`zp-vf%y7aAIn;NeK*gQv25m<% zmHDu4O^x9c&ARv;3H?Db_5M!6%%x+muQvQ>_2?Hy|FUo=@1yaWW>3>J+iT6i!%~&U zc~Td6R4X(J2CLcGSY55r-&nE~<{`CJQ{Rn(9dr$eDaX&=Kj27Lvm#*mUBh8^acWFM zeK<|p?r`hj%m8h2ssA7?W)_9C({-?_+8(Ze*YS|JOs(snyi|8c59+2%n5{##MN75@Xwe)OHdnPj-YjL!S}$R? zj$UkKLDM!{z1#rwc*gT|DX{Yn36pamzQ%^CsN!A=LHvGTVKEga7OEs>+aTZOP-{y@ zKd*am@~rpl66Vza(j4mCmY_#DV7>yr+9HjF+izJPOrhaun)&(<0+x@?mG-CamN13( z=K7SwOqszjTa#m^`pICJtizBa{gP;xFfRtj&yuFDG#jf|sN`@;IH6jQ5Tl)PpJTT-OYV1fN|>EOhk|SSnOZXh7U%l) z1JZ_o;}RyL(5R-XTN{A3x;!4Hp#H7L!xWUku+)J*X`JQ^^1U8roLpXSHY^fqVPU0r zc|A-xq1i#Lo%yEM!~7C}Wjj17FJq!z2$b4~{ie*ZKeC z{Vr>?vSs_5-Vf6|02Enp@8{+6ewfX{1qHqDZmjM(;`(~cb!dqjko`^V!3+(`hI~|Q z9ZO*B^}XB9jN9?9jLemu>Z31=%?tj{F>Vz`#{OT;mm*%SmnW&KzXc1DoY_9r>VGo@ ze{%BlUYesFJc?JZtpdF}F(hGI{}UBcF+9FnEzl9Eu09CH!7nT{rNNXMfm&!RKatv~ ztDhLFmz?+Qkif_Dl; z^7UD?_E0dq70iR-+Y;_Uf;uD>mJS$iTj$sq#DigK$46uNS_Eb<2?ohhcra|Rv{P5# zg|*0lbwHtcAS`S9K-Jn#jaga{JWAzp?^6l4XsR{^FIc^xlQ*ZN@Yr{iB~tBr2$%tN zKqkzLhq*8Yyz#y^yw5sEgVfi?&_Gw1+Xfy@=FD(&a0)!kl`RqKYNxhKLs86B9^w|< zB^*cFB_853eP-6zuz?xy1~TL!E(Kvos2=t5Ab_ju`N#()qTV>|~ZpqL{_1Ys)L6}o;NW}GE9?KeN8#Orx;x5lT zqp{qd@Qequ+Jx=^c?s`IAt4b%gLxopu(VYt`~>5E5w|v_O|@Twco17~+e^B(J)`4~ z#v5K9w?k$GN2o6^7;98YTNi#|nVE;Q1`BG+IQ4hXW}l-2wgoR(dngD)+LEQqSt7MZ z+R?bxzf4HU*%84Q(nfFl)Xt}?fRa~-<6*|ImabPcwVMXo3q4J9QG-EJ?c1-vCk^f! zQa%;K+Di5knzBt)i(NGO>NDa2u0hkO1hwl0SnQ{%&){rejBD^7v%Q^K>@W!ZbB%|= z8(+9@$N1LpB+QPw0cyh)n$M>*JTiJ@X~Ip=)YI#o=SoP8ZXO{R=uRr*8PcxcV(>`U z--7$hhpxnj##pz0<}~fhCu)W(e|U^{4Y9TY!{;vt#=Z5+@a6dYAC?2--nT9XkARsS z=QLeg4t-7-|2{1{yTF{hTuXv6uspbmD%3~Yp5%X+55~d&OIa`;e(NN8 zWNgqT`Jwvz9?+t{;IzTO+jwNmjf(CLc7Po?adS#4M#eGzerbHUi>-yX=Dz$e_0?Io z5FQ;fZB^sBDa!8DHMn=o%54}7U(H*i3kRo~?==sIlQeDpRGoGP?0(R+#bbkb@Vi74 zdN$v>zV~mXf`X@DtQ%F_Y-tTk8?RXv&qIS(Z2REClwcm~Zg8lp9PpI|XF5oNV~1hx zTjl2guYuxG8P81@o?i3`deo~~8{OUpfrEiVpNf(1oAP_PY>?>jA2)d-7B~! zIk;o+O1`=-_2aVjQh9`HkieaT-}ZWBObbNw%cENqYr+n=4W2CJ#LcHEJhF|lN2o(q zgO|tKFle9}{Q$gtL30KcmU}TC+c$A1ShHoYA!dx*c4{*?A z=DRRGW_94wj?|RR2MmYi!g$OoYr=fYAECCP8{;wSTiqCsS-BgVq@o)GJ>_nU$E@Hr zV60D63{mo38IM`zP@D#LW#zdm;}I)$sN)}k#=ATj4_4p02s~KL)7`tSy;L~Yfjl%Vr~qCr1<>PDP_W>A#_FYx z-JF7<*0!J3X^)JJGUy}YLjFg?sD0`nqet6~`*yfM5)w!tKnKDeNCF9KfGizAXjCL@g0hA+$d<4M5EB%gRzQdm z3Kaxg#*90nHmGbaW9y6xGr}+`Bk1VFU0iX&{LeXc&g})9cfOhV-Z%cRZq+@{b55Pw z>(;&f^IwL&^S9xflROC%N9_B#(m{U){2%|Vu^f&uGiEJRMJt?n)$=X4Z^wUY>TXd?h(EC&wzsJ0UHO-hk@;J?k(ZzUjwE8( zuV3z=J)7$ck7=4E0|(}v3cs0OQ1GV9VaA<(OL@29Ibr*!dnJlnx1uS0xaW@gs!z#rRNdpw%}SDBEQSRNA-Gt)4PJ)7<~ zJS|(c+=N`peTy8kLZ~18o>EU|@s|Sa{8vHCq;inHCopw+I~gw|~oqwr%f>;v*Y6b?SUS+JOI% zH@t>{k8X~_Ol#SyRW;P#Uw8aJ^F!OVcSZ4$4c)qRdsu8JD2%LK?K^ac#!O4^+V#<4IB5q{{=Bm0qXjMM2X>D{N#oBwSava@rZ6&s=}KGeO#;Wi{T zZMq85-u?G&NZS$42iH^<&^TWb8<0D^K1h!vxa8#Ib^nnKX=!&07l&j+-+uj$K|QBB ziD9@6Ug*@IFPkU0=FOYm{GZs6mX@|txPHwBtec=W!Vc^=1qU72#{a~IwrT&YEVLh} zeO{z%78_DhQmX$G8``vOd(l3sd-onsWB+8g&kK70jQhj}=(M+z4bZ3lJAG7Yn>Jg7 zi$mQ+Pf>SnNhR8U`@Yn-7*T7E?ZWQ|3Fjy z@`{T3wb$QZ|EsK8`)y)k(?+O$(2yZFEi5Yo%`0juuga*obzCE}PoKVH_wFi)HEPy* z*9}f-*|NowWy{VlUB0{?!g>s=!q||xbC)jNkZt&-m)?qOioRYGCea z_UhGp1h6I;HU2?Wl`vGhK(bC)ks0i=ZA8{Sefy3<)+>sO6|&A>u#gz9tE{R=56QpP zYp$zbv2s=Yii(x>pe-VO8F(}^E9(;E3Hw*`SiyP7oxk6VS+fp>+py-k$_N{V4jr}} zabw1g-MMfP+fY$~zG}0!zI@5jFJVHE5XS6)iAWQeWDKv_Rq!)pbzT1GF=K8=6hT{I8M>pgX6;p7(&o;a_f)tF=(-cHnK%Er zRo7noc}~xs1$#H&l}U4Z7CZ`WBUyA4aCDCQjTlZ~nsiMc~#I zkex+SlWR7NPw6>0h(?uJ3Es4_e!=TSkT#GbI^Y zv2rCV(+XFwSyLAi)4(}#^5kbQQ>d(B<*J%RCCN2aQ_Y$UkPE72B?k%T}xiQ@ReT=Fc!sY%zOI>H7;8X{BI!O^?Z- zw8Uh^39&P0&wj8=m-K$%t+#8c#x-wLg>B^oj0PUk1tr%HD=8QqQAw%llSeU=>*`@> zF9c6D!OY=5DBYSKQ(K1VinW0F&1&pGzU~(O6t5|a#s7MW|xT+1b+vXNjiGwg*Z&b5u-anv#ZtP{(JZ`#RLj>{I zaaZ09)whul!+jubcLDLNIdh(hjg7UyG4DVjZ0KcIGbVeg16((M}YE=aB@`{zmEz2@Bad|y-1wh>O0^&(irreIidmo>Z zqMfYk&2qcmP^TDHj+JY#{}!gx&4hVPC7PTS&1_yVa%9!s$LDI+3u*}3OQ$?+1z+^JC~_{=5XQ}GiN;%PD~ARYX6H6U-uo%BZurgJbbLt3p$-K;jCaz1S|AE z?;tD6pt%*RR)M+s7qCM5M=(Rq1wR}n2gA~!TR1UvPW9J^m0T4#d=U`hz=A^>c3y=g zm*_r(8eLNhI;an!59mXr=v-`2iF=n_JNRz5s^B?LE53XY`mf zdGdqdY&g;g8;01&Rjyr2`PM}Q=1Jeloz1M-v-fh-eH@&5dyiqmd{yF1G!aMAa8j%b zn1&`oe^Jw;WJENn3C(s(&C!X0n)Od?&b%_54F}C|Hk<=suY)pF?`MpPVvDz6F7P1? z1zn(Mw29&6jV59dgp*=<;{*bW4F<289<# zhBM+dmd%o-OQG#wSJQTC1Y@JMc=uzNK4sVFqTZ4*kBVB;$>0`FiCqZPuX^mD+Ll}u zGH`r~1x9}fv%lV48E?rpw>Z0G@MMy^h+@y_su2*)K5 zVL?H`7;ZA#GKTqlRhU_{3<+_px)>p(*Nj{PgtNj4V{Jlc*^`WnoSd91!`Z+^z;>g} zh~_N@*FgoXDO{0NQ#>OV+es{H1(Say({$&vB?C)0oD8dnCJPbjZWPE?X4QC0fULx{ zpxyjD4)4e8tRzLHy5hGUC zJU;hr=pOFqaQTQ4H-`gZFpB_Q3p0jy$MytZ4|CM$F@7-iG-P#K2bf~dLLfFu)QBTN zxJE3-`ssZE*u}bX{DjT0U1$IpX93$gWMpI%hJ&$%hl62~Tl2*v1b47t!nxHQ6XWE$ z$(9bV)N29Y^VmHi33lq?V7RV%cS1(Z6)W1*c&El%lO|8Ovw>x~WZE>L1J2IM7B8+t zCnE!N?-ya{W6fW%;1F~XU({qzPO|1+Gw%u5>U2XUJ_QeKZ#!%DoI}E(iz~wCHBA=v z!TI--u$?jzS!h-c)el1?YYKC5B3tL()d5xsx7%c35_Qv5pRv~5hy@CSIUeXdYjM^K zGlMIH)F#u@>pMEYykQ=a(LW%gUOI~G-K%p_rc9f*UFPga2!rfyv`SV56RR*VXe(*_gbAC44MW%#NQ3<0Qf7Nc*t=^1MCXMF`kQE%*Vi1Kly=+X z1QXVR>-JVHYivLb-O&*Xs~idohf*x^=;FqzF38I+A92%OT7UWn?ef6n^B|$Xcp9L? z3^UJ#h=@Ma{4(PPH07aiNvT&8IZ9z0|%qOc1`lMv6fCP7*wC7zGqV8<{mj~* zpox51bM&DnVcuU%9$m0-;a4H>4fW7cX_OQ&5&{8ek2Rs^|BAtvqvnna7A^V)YrWQd z19iqYZX*~6NCu;J6UzMSaLo;2Mg1LtYt}y0vF6n5E+kc1^=-I{1|W3~q-rW3>I^a& zw@o%p=p()hXKDabq#seHa0|@vce*u~X@UjchjDFh47;8Vko_4aC{uT~u35OFNzL(@ z874U9To~cD#?U}bm?E7I2{uDg6#OxQF(DzLF?0cX%A-2eEWE2RFm^G){Xa!8!epvh zxZriWn*d`66TJ0v1S9NNw-&*XJGwAqXXAVX9qa*j442Y$?Tud|xL`oa5~;#FGMKA< z6j!Ito%@DMX|C26ng&lGyeNpSo_c>qjV&0RS=fml87`>(42;q4>)Eqs2`oo(&Qmk; z{?wXjJKBL)TA<($;rVR>bMd))W=-1(q+YYOh$`k6H`hFz2ZaI?T-?yY4sYj6sg1FQ zVjRMnLoX$JaHd7^s1SM_12(c?kXirxo2z%lHg4Xcg+CW|siFI=+4S0=7PyHT^{)_~ zjP2RH-DnKkA{GCGEG$s|x@Yq)qd|}C>_ZR%&Y{hs_(aBpReDuT)hk{4oPxc`w+adh zkAoFQp}9?Ldv1roF9BeB6qc>O?bxx?t~A(>hP~MBxEH!-^L<7pMDE0YFb&<9 zlG1W5)Wg-yl9HCea=r{Vp&K=7G#iG+>4xEi$8fnhTQ(S$iBAc)Y%@H`R_8sf9hDA; zmGsJR4E?)Xv~@i7iqYFNmo{(fP=?#sWUQ&qX?@A*#1$TtkU#(N2U`;2S3(y(dIZL? zk2fc|?!RsBP-opnv$*sruj-`d--e{b7~`^WzPo~?KX``@CGNj7GQHx(XGS4gbQoN5 zC8djX`-c56+!5FlV|?Rk#0GY9I#l_3BRRFI?b9UdzqBd>Lq1Sv8X1@6rC~vG` zGQ+Vi8nsZ%A}I@RA`yb>44}bnBwggr&DPp9UM<}1YLzN! zA|vHQSamGUXzivXbvDju<|b*?Fy3gL736|!%HEj3Spmn;pLk1WZB)F`EK5WLlJXQd z5KED%#5?Sbt4%06Eg=a10-Xb45`@ksZeX6>Nk(9|2g4pN%h1@Aj z;%@Ddax{x21Tmp_Ahm4KB~H}{op%-yh}3^kCVtl*E}vi~nb<L>PS`6UpNRO2y7+Dz`sp;1 zHSx^r?0XEgXRHr&_JSC)&sVU|`!&Suk!qFG(irIW)j_YQ%3H$dbzOB%Myjtf^p0Si zgeia8L~#m{47}0GNHtMRm3ZJZ%T5>w)u=Yc8%Hu?h=Xp_{E@Jvs|iLLaI3NFyfG> zg7Yy{SEn28-6XDSbVsbwXZk~pMkv*2yS@l(bbS#@DIcO%qwOFVO=VEeuPy_ zi$J+Fa}$~hMwxqKl2mq$;WiPbJ@$b1f)7LOF}eyl!S^OQA*U-i;d<;u(y_OP+96?( zeL$gZ&ZlRFHD{7jXS1Lz(lPUU28L(e?oEVFGB3S}{|Kr#GC=(es6O~EcYqQe)onM3 zp;lkqG)z6otDH8VzKgA%WFtB=p^a7_d>+*w%LMi7P`$-!C9K_~=WP_yR5gwY9$NW4 zssOKMK?NXb?SqF8LXD>$LqpJt0_ib?RjiO^W-+JK0L?9hu2!WP_qZudL6IlBq$O7O zPKXmfT8A(rySqb1Zp4g~ivK$5-Z__xkwV=E`mfPd*;k5$cl0nic4W}+WZKPOu_Uj=#$P&RT<7aFMrQhR;7a3WGZ0M!0Q_r!nG-9Rme={%{R zkgM+;uD-Ld#>^cE(^HbxoxxVLg4&^mL{vs$6*Ht}`I%CxM{qV$V^7@2$HPffub@`WKh=ZcXq^nR}A!BvD;yP$i&7*;tu5?`~GM2i@I6chl((TQM zp&n-Fig<7C2;)6fZ9Oo*u5GBpkOyYE)WU;7824$EF~ryq3)cJLUph7}Dt32qBbe+_ zPaIpDLYo5C^&f$&p)RhA4HnWI$-m)+HjY5aCB}LKS3>4iWth%2R^Yp#MnPPh|F_!M z^as$`qOrzAcO6!*04y+i8|wHtV`sJ3a!=@b6088)RCV{2M!ef!`2?uJy&d)9mBu-@ zH4x_h>d1KGu4LL!!a~Q5B`m=mSe2HV`8+a+ONhY3$Yjn1C z^%r!%wz3;(cCkhY{9UPxXTq4KFB4}OlT2I;Vr9uQ=u+*OZDh<6iU44d#(KP?uAQ%Q z_>2z46!BxUDgHM%kV(;|_%hIxqB&rSz64Vyx_vnt!InKY#egk%iMC|UWQu>q6l`5m zl+VF6d1bpU5C2TvA+>JhEh>TRp-y%f~yxF%Q)O$l2ERs+0N zXReFMG_mQccFVEK;*gF4{fvfV!J`ycM^+ef+`3~Z>eOJOy8xY4qzO zjr&QSr9wb|b*J>4!ODb=I;>~HB6F*Di;WIy(kjDplbo8n3Vne6gt}vu(IHt_(a|O# zsOwP2Rv9ha)c>gJIpEY1^3D-#Zg`1h*rg;J#HH`Ta>V{i`ZVixu7r zb$THzIf(&#A6?t9Pjr_OjxIF@-PI6_lLlNhVx!Tou?(8OUO88YBw4~`dIsP zH|~E(hnydWq)*`c64vg;;%s*-Oa+59xYKBTG|RBm=`6!k+e_f8>{i2!t9ww7UKA>< zt(R0htCe6$_&}2=+0E4~$oIvF6OO+)>gy#2@-!r^-E3s`W=TPAdrUJ6;|a%!NF+{V zRLLelvZNqOpU_CreF5@OM8d2&qmPIR^c?#}lwSaS?hJNP2o+I*rnCJ*c>(l!8!Dm# zm68(53!p)Px=Bm6B`Wmf`_h*`>lC#wS1F8 zy>g6fT-r?W+CA-x=TVWCEf(RV{u_VjmVDbH48k{WWet9i9IGw{q-qo>g!{TDq2 zlMrh*&VnSqN!-wJn^9s?^*!sD{vTq=Jp9~x2m+eq30m> z>dCM=;cdepZ5x(91`A}mI&!yBlT4bxPhM$`mjXFbm8e&D8jX|Epo@arBe>tRI!c$N zVs{zCRa!xV25#%#ziZ5hz@xj2=1#Zu%C|7br(U9LbAvRMP->K^)3+GzG#Jx~BAhZ^ ztFTa&&hx|f8pX-M`+ybXC>=wTQ;GK(!_?uShH1tmeDtK+wbDqjYU?Wt-$}T(zuL9S zXrsV{rs=;xQm@3H`-?;2dOxN~{EttK9q4dW^-+fx8Yx|(?}FqZOhf6!O;}*7X6{*Tbv8$_I?3Mjm#C?e9!>j`+Q``t(G@!RqxXPF!)Zhva64o0OmvlhF?` zYW@>O$AsG;<7Wq7xBrjt{j~4Iw~sxoyiXe`l^fn$z5o0t**LN~ZhmhyxT>nK>iCAI zF+S?c?0$~J8~S1z#$UWNdHEnoQdVpK^j2<)C3Zd93XHEgKj_8Y_EtOujqvFJbcM9hEY zi9;87;$;{TPNHKDMLJ=MT_<3_x(&9m#UUqfrfnzmW+$L?v=i=o&M1xxJ`|PzC1yg! zW?c&gP)VkL_V+Pd3#!u3L-R?fNO%TI5z-%p>j9XCamTAYv#)5<1D1IAJfn^tfJf?x zL}`$)%RQU{L7%$rJao_b@kOfa8RPfKp?LZ$PxLsp=FUUIe)@~L>{;khp0{)R_}-Y< zs3Paw*||0KGT%Zk=-ieLPq;)Ko#Jd9=YJ$B%Qb4+=g>dIUt+|U{%f73gL{Lj!qRr_ zpA6o+^HIzS{$WRpT_#@7ZP&hcB%jxt)Ts|NY9D7e6o*mAo6`OpaBMf-;9s>n(CsIU z&7pGToY^_GIH%|VozrbYC8xf}IHz@>iz2Rp|FHTi+}Q2`x9RHiH3~753#5}EN<`4#a!)r;ivsY@0$DSrP!Z*ap0@> z8qYdTKL^%V6-MLl1|ILbX0B9%Xg3GwtGJg+k z|A<`?%JQ6Ho?%beo{7~@F)j3%YB$sLs7FpiFSzMt=3F03QUOi1Idz0uAo%IbLG_=&_OB0%?w_i8<$N8V+ z{L_>H>cIbEKX6!TJav1`y>=X0!(r|Riqz%LLUj+#q_T%uZLyax4`rG&X=mEvOrtaG zOgB^u{scpv?`h62-GuxuO28iATHOQegC3xNL=Vs(dVu{{%FtpVtSX!q>H+$XitGWN zefh#3z{W!lu)jF62Z-RqJc~c12S^SjK@V{FcHIN$I`Ep*0p(pD(E;ep+s=q(XP}eF z8SYEwuUuTBir;IPhg%dh8d&?HYQds}7jLXAJbd80euYWBo_or*JYRdIvc+|Uj&;j& zcW(XR0M&g*@m?DGn(L|cb6bDNcclHepX5LwOa1APqjc0jNAm0W=)J*zT2**>*Q@=v zetvlY;$M1lc)|1U^gWpK%5oYl{`yWr{+;iwE?kx03wHtOPXk@%ISBLiVyw+Jh7`xdm`nE-{yZ8yQ(m+&1JvpiRK|sl)e7gp>*&>e(Y)P zA}88ie%_h}=}X*5u8Y&WKuD1uOkENk)T?C@eQcxb|($DI{uIVnPd5IXoeU{7MQ$MlhBrpio`mln3?|mDDU?L_k$RYiSN)3a4YA|6GH6p65 z)HEOd$e5HYRedfXv3lt$pZc*e51yqa&UDUEUw&*@sgw+DT*R~@=pU(tB!6PeP@9Lu zB;XTWE7Zs?Q>Q;M8k)45NsYDrr^eOBt=I=_ZjFzMsddV#WP{tk4LVZp2-*kwer}9$ znY5ot;OEZ*coTIXZ7%}0wuFOEe2rk*(IoKn?~SX~ebb$=1sCHk-c@m-a%;Qb)viFJ zw7}9IjBzfLb~%Z`c^=ePqk8Y|i@^Om!{KcM&FTT}w&)b+*)e7xb&u0|wd#E*TF^Xe z->v%Wl7GDpx80({lpAyiM_uVTi8T$6DuA2XsXRo=sFohnHplJYj(0>uPXS)aH( zV>v}6d>j{~R3S&q0T^fv`~3ou6I}2e%}g3psvGQ+BoR4zl9i(hRr0av@o}yX09`4YlL88bBuI?{vAL7+{v`>;mq?8ZJ5mcQT10s?nBI$2x z7J{k;F<_u1iAddzx^4(m3~cAxg)P^1pvVbM>KO5+I@T1v6(zwm1yt>A25}GirR3C0UZ>O%{Iv+zMn>x$ZSm=^Eg2k6;id zOyF1_bGu;@6TIM&WD@YT1Sce-I<=?Vd`%5#<}Ap!qH^P#&S(8NU2h`PP?HPI zMfqZvc->#Za|E`N>LcV|26(9uRLW{ZOJ|}sC?jbiLpEUPA)jjZwt3eB zhub<0x3-On5LwWa8`QLR&W}t-W4%?wi>I{yZa1X`*0gs%=Q1&mYR?tsUjxm%IH#NW z;x2Jt5T{n4P}~~PJwZCPRS0!g@>B-6@1!nfKZlkB4mTo$8$w;ooFbVD8gM5tITMOG zm99Zr?)hCBO)P=b?&K6s6B%L#3}JQF%lbRhR7JM)oLj3U&mb(YF$e1n+NQF4Ip5SL zHNjmI73^zd=SzMi|1`A(Zt;t>bMb?8jJn;w)*JHw7FTl#8|WPPVj&umWBu8;kiy^ z2E+wMc%jHVoFo*!W?Dp3WwkUtfp&wORfdPtMb1JafZC6EYB8!T8=mt|8{+)I)CS^< zdWh0hr??4hp96Pxa#Q@_3q5Yp}$9r{(-gWVpL7U%TvyTME&Q`X$o zI1GiBH57-e%Kem8S`De!%Nj`%k!@^=raHCT)jCy@L}VY2oCH;=qhVSuNg}e1=Nkl7 zkKp1+l0?K}+X<>R0?Rl_vPCdEV7@?QoOHzGL@a$QmJ{4LjuW3ckJOSRB0+IDi`vwV z!*nUD7LgNNZM`la;!_K7Ng_!iQo&9ps9xAel8E@P)fpowEo|~7NkpV(2sC71R^+M$ zYmk0TnkdwWvCh_6QlDf7vn?u{xg6Kdr#U632%>g{Hc^Q#F@`*6tV+lc|ujJBV zCMiv=gC=h*Aqd|Zb^|jBLhGP8yNC#+l&7V(vhZ@$^S!8vtADvxB1}?Q$OU>~AR?k9 z$T<*Y0@3w}=F?H$%4IWzN!qtAV46>}gy=ZARGTHbq@1<4XkEY(f(UZoAi4yhb&ypo zA&3fQ5M5%G){%o{7_H+vwu+fjq{G1WtXC2&Av*SzXoTpJdaSLY*Vb7=5a*aX$V{R` zSKn$}twiNx8%v5VX&btpQ0&D+5GNJ|lXg#F?nD^uOk$%E9uX?*L04*^{bU^BQ7=v3VJnYbQc%UsoL%!c zOOnOlMjm-M>ykC;gQXv!titO}X0xr+U`g^ePw_akJlfn~DjGopKBq_q=uTkAPp!?Wkig`5 zI1fduE;bL#mz+w@X=;EqKs>->iZmxFFsjvR$3mEuWwEgmcGmG=28252oFcaS($TO> z7GciuGCb$qbli`SfV&)X&PjqMUd%bM99WFmBUO}V6b>v~iiv2CI(EeTgIj;f<%8wU z7u-DcDKwjPlB`RiN*^N)R=4U8;72k%f8%<{p|1y9*&9{pl^Q3Bl~xWKvatg5h?ik` z4EEGVy2RnC>bB1s~W!czo-s{9*Z-X%#Q;%63u!uM!^MUq6s_k;EtK~>@^-%n>JvNasKNl*7kTAc@AmedLvVkgYh7Rop!C9Azh6DtuBNGTV#P)RXrZ_-8@O9&#!abc2D z)y}2)NED*(8f}*7k`mN9_TU~OONb8t0*w$|VwEl(%7};vAz@*C=-ZXBuSYpVI$ZV!ep^Gb!~vW zU*N6MMLO%Ei~Ne66V^sOIc5pbQ8$MXtV{X{UA3u1SV9o{*hh18oR=JSi!UyKEWAgSSLYD!IdqsD{9x``Dt%W@k0< z7H4zM-}xXWhrYggBntM2kcT=>lEKQ#rD5n69P02ANaYrxAWkgm$Yrq2aK{Gc(bzRS zX~j?(F^zVrwEm{sr0A%p%naqb)p^Dwl{Bg&tty{xc2K38oUg=Q$ME;@IG_zr;^bs{ zKnV5oG@qC}gr`kdNfBBcm(f^?PU=)-w*^Jm zOl<}lPnj+Ri$niF9rxv<7ilWWDN;=O4(xxYsZ+N&^8)9Wn8RSNm*i>EkMe<%W#(OQ z!X8<}C(mQlbK9M%(YE_;<{1R%A)*Ta7g5E9kUA_?v<9~APan~r?UArhn{5pxg}80c zDPnfei)J0zffWxgflhAu2Qe5Sfi*jEj>SnL;v1qxh(*t_a8EsObhpzmJbY7x$q3*l zUY>5>i(8-CINaGoMBvyue9nP6P~|t7gYiU~88~dZKTpSFDe(SAg1Yj4cVQlTM@ri7 z*WQv6mu_6VB+XrS>v2b6N_qubFX1p9w?;sy+i8%KBoFYC5m@-tQFIqxhPlgknT``A zu03O5u*o)CF@O`bdoOm{ul}eJ~)nvXb?@i{h4FIP=Wy@WLzBt%=H8Zkp=a_ndK*7TEZnvzO)O$#@}r znvJWAR1fiubPQBo)cKF0nw3#|^o&N>q@{%MXwY<(C zsLB}vERrN5Cs~A`YC%10TT7CNRPcIBpfbVl74xxu`Xmh!Mb5_YjEeZwsd}epET@Qs z#nU4}3Ug%x{9tM5l#Iv;PD-Kz`L>L3;fFinN*|IDVIk`kbAm2$cO4JONb$)Gt1fEY zA|*xHRWu!C2|?`RxG;%hbV<;3GzyV2PZy`?lCspUIg5)BmJl7atMs=#MVAzcE+^Uw zX9*keXZ-+T2QcrAX0ecTgpsg6(JS*iX{Yb@{nFWi!P}Fy7ADqHcJR1_keD?qDv6E zp;Y7QizNh+!i`;YNfit$L6#7NbPu9S5V|~YLE$D5J#`m;u|!vB`tGU4{fmr+zMFJ^ zBNbe#UxcHeP`Emlx|^vo)0LEiFWFla>!|<*YhBq|&q+D-P1D_Na0Yg)IF*gd&4BOs z0G)3?d;wV<8}4qMEK<@*Thme6?RK4Nrs=KG59zO`uuL~KOn@8559Ul zX%WD1qt=52phE~rJ?cbr)bFOkv(Pg!uKgXD-OKC}e#oOMhDhBjuCz{T^M7P(tDTJ6 zU{LF)mlGshGQ#aK_uLP#wIke{)VUHfMWtWi?vupS*lFO2J?#%1otv?#*Q|V$J+AJPi)Jr zw6bu^lbFX|SJZK~TdN6;UH7SueVxhG-nM#0gZIFZw(Li219GS%Kft@Cb7Niis!2^< z`5wM!%YMwV#80v-_nDlpnl?!OKw=umPhP zfJCHWYjf9jB_9mP)c#^28#IPNNT$t7XaQ!mvdv-v8!(muNTdO2DFA3~16aTYjAH;2 zX+U;Mu*=gH>J;CzWv^sezcawT)&08*mi^kVpf{QUQ==16aTYT+IL^(txTq0BC0eSilBMWB?Lrz~;69Xm0~p zzy?fW01|1yt~3C2umLP!112*7i8SExb^wUC0W4qxrZ51BG~jT1@F>1>SM5#K^@n9_ z%v8o8m&P3J0GK~^gHqsowrm2ACdi>>Pj>{_cQQbh@7c16EQ=gk_RCHnJ7K&#-^2H8 z*`_Ru93;E73y40~6=?aEE!vDlkpe{n>h}KdMp0Q)S62_;vt^T57CE#DXR9*`nH;N`=#r zWo%4a#)z_sFhb%`)>6&Ra=p-pM;;u-&cT3XvA7NQGF()zxCcfH6;tiJRZZ&aN>No; zyZiJRqQ@wkgh4h*5tE25tB9oeZO&U0Ti4gu_kiK^Mo>&=`gPBJx{4??Nz1?}M^OIlHFFjms z)V|5?tUkk|co=8%q%e=zb%Jtn5r;$fW4 z)0%n2u(yzBO}6U+^-W_}?><&^L9x7z_b^`UIfeL*Ie<6g5dWJf{VZ?eQyDLIoJRbP zo|q5*%bdx^Fq6&fV-#xC%vOIe<>vxdmilXdSAvHHY`|~^Adv>73;;l^ z7XbOI+>P5&j#oEQ~8Pjzyda)m;p$n0sbNY%pVF4#uD|gfDIVM03_0YZG!-S z-#@AL#;ag1C}9~JGnz5Tr7^XGQAtNvraIXl04!hw#xMYhG+^Hl09@M%0C}sVJXp#` zjb#+FX;knMKyBy@C@OXqumQN%f%S)lL>h2%C;;I5KF~6Txe`qjQ1tWzp<1MF7>K0I zbc262*x}s+l!EK>DYy zHXIL&eGvM1!^FDv4DA`Befuz-*YdKq_ut4{{k-OvHGRbP4;UxgD5OHIEOj?lyNX?= zdU%AZdBzP9OMHL1UR&GYEFJgF!L{|C;qIi^fc|YGKd$uk3g6E{vLM&O`B%USU$a|- zd2x%OUg4*Is#mUc80r;%-E9M5+ZEQ_@FN?fj-D4Gw>m%4bzHb!<0&SFnydCRUIl+{ zbJbSmX|8^%Y(Bg`fZ4()O@BzXu7X$Lv66A<$M4^&Gb_yTkmzVcK5`Em?K`Qz2#dbQ z@6VAKNDSg?1z&`7;J?lM`COFChLKs~MIeXwaT5_=f|Q@Z>dbNZv>ZlVPPo6Sc_meT z_;?tIQv$_N0OLXY^ctGTar(|1#Bnx&_d{`vg~y#yas2(P@cSmmE42bQP(}*GM8xA* zA-!=QW)N+ahsW{d|L{0Ix(SctYx-evel*8imDl)|5!2tAv6hS; zIDT9e<5J1AKf>ea;_$du7?RftLvh^;hT_1884V>gh#-u2=(rf@rg*3pHv;MKGS=VY z4z(ha<)sK?999&+<){qLv6}=!3St}$qX0S{G6>`0@@P^hLvE! zzTP`OHQv<)U&e4)TlEh=p=0sSTB03mhjVq@w-7>_TEyjc*1OsJaLmK8&XdGKGSmgH zLE#%Gz);6OD^;ZD3>Jnw)P13cC*PO$@RY7(s7oaVuvQrT^Vuxaq%OJIrGJNO)DriL z9=;`_WGO(k5wLN7gQ}Y38co031@dr0m9m1vXd8y&hlLyo)+G){+4Jaxp?9AieDev1 zdSkNd+0gHO)uN?9T=$i2aorBKxL?C!sMqAQ=tH9LHdeCQG0o*M^}|hkyev}`es~x0 zEDKGiM{(ayb7e(MM6BlUG!z8v@UV{Sr=<9u!zBDF4M_O8ko3k%NDlvdEVf4Si=AkBhXnkBBX7K9M!ca5U zAtPW*zqgr#xAOEP&%;DQ?0bpxNhY8D9c<2YpXGYag)7!ykwm{>s2^YWkDS&& zdf8?z%z5acKkkK_BtdJx)3agi$Hbz@dRZ%?oTyWCpq_~i&ji+Sl@5dLZlv@;NUHD>@r?IdgQAS&@XbQa|y zIrx61J-T9BIGKr${qbQFZJ(J0PJG;*>KX^m&w1Q^S%cAwmX<7?kt8K#{)7v&w|3;@Z_)Go_Zs#D@49J=M`Mbe0oUpi+ z07n%n)!#~7&DH!eSF(w5g$EYYePyo9%4y>r2k-w=T>g$fuPH>1{y(iLTsdyjz>>iZ z`mk2o!;SVdJy}`U?(6sic>k~IuEHhPcRn)umPXJER29wvd;wrg#{=*cQb$z{a6LD6 z)4=9{!T3GEI|aA~XnfW8O&SjxVpVu&CpIgB+m(eYygd&tobg)zU8mO^0wWIPO?$lX z-kOnlXNNluf)NLwxx>5XL{We5;veJl!HE3pyY(&nV~4Xx)Qb%Vff0k+y}s{2%&ESG zr*CZC`HHn{_v-Y` zpu+y2bRs9c-rQ3->9Nlb2S0L<6PE0Lr10SxuNQ2)whM9;20sjuXvtYnu!v+<;cFW*m%gQ;AhFf)B4kf>1X&8hv(tcNF{U? zi+PzipO2jICuamF2PJBe2kU>bf>S2(sT2pi+&{^B2&a#kNRo(HY=WkuVOY9YF>PVF(Dn z<{SnjIelB*Y zS4aJ5?l$@5TV@igf@qye#3L6`h;tklUE(Z_pySoi2tE=ey2u*HM;L-7?0j&85?xY; zx+-HnOq9@PG|n+t+*7Je$KR%v25C=dv0;K{`4dQlMQ~rYDmI!0?-@ z&fe$j2L}O?t%sL9HyljG=8gli&Oe?lZIAhdJM@RgF&uxfjjyj)gX=2?s~2u?byXWS zInnwf(@nHK8@{Xx)^~7gqmT540)R9yTmRvGZT2KKduoK)Nt|rYiYDW2niWmRf`@hw zS3BXc!CCJCv6?o~Q3!0cK~tC;$@CLHI5BXo`q}Fmk@-}&rz5Z|Yh%$K;Ic?Do*aoE zF>=V%;;~bU7B47Sx@@s3TH%~p?S-G;g+s=PZg>#a1sta!dlaf8Sw;)BYofbTQkFXq zp^0)zlR4B$levG&JsOHEk{iB7H!#_9HjB(X)?xiAm!>zlnj42y^^dOfJZ>n`a4e2X zgOUbAZ4L9wotbXZ*l^tWP--8k#3g1&&r-e6@^ct`Lst&}F>WsKks3~tMxbxmhuak# zZXc=YuE1xX>z$|F`ZgUkMIi24rl|9GIM*Bb%9!Z_58jDVsE$D2Mo|MlJ%1|H=laYz8kuNhsf0f}O&m%bE%AS8zXz#c5r(SxIEw%(tXj{ZaR018#uiLWK-J9FFoQLTX8%ccRD?H52RROVUsR8;a3{s*0M7t42mW@u)ZMAh z=BjRmJ5Swbzzbd83iy2cxlfFgIIDz5EDXaY02GxyjdcmEZfKrAeMs8K|vo~m)( zyrF3N&@<*aY}ND!*EoF`jDDTc+)Bc= zzTAVgJY43)sAryVw>I$>E&E+lRy0#Rl?kQZq`0oWf z`s^?0kh#BLw4a$>XoZy{&$^K!O)cS!mVpO&z=AN(I;NKx#vM|>cjaP&-|YD z2u2OAd464U=b*R7r#=50SYqG(K=q*G4?3RTs@e<+s3Y&f8)0QWXRg|{%@zBvXbrrv z&2_)wYUf(0R@~_tZDLyrU)u&?ZTpt#_S5fI(~5S`E?ChjT+s%3q8*&APs02870+CL zxx#;qo-q68@QSweML#|yG_pQCN3(NU;D)_Z&bmaXjz0!MU}exJQ8`IOEPl5`^U)WG zBuPYk{MrYx=`RpTl89KGIfAMY_qgEmLYyQbxf~a$T`OWvQSFfht;h*Z{6>8008qOr zNiSVRI>a`KI$vbN>4bP&mOcB}`ywya=1RXNibFY8fKRLio4sJQ3%gzWP zP=|>Udg&_kw(TTDZw7P2vnSwlBUi3MD+WcC34R|k?YD5Yays|!90pJ6uGM!2I|)1i zkSs~k`}*I-Tkxfsht#wOTt9d)3OSbBghUS@lm6OFb*&4&HbabbkN^<@_}UD-SBPpa z_|QyxzQwtb+)?)eq|)6;e-hyrxKFuO@adKoD)SLnC(m-du&^Y2U)$=dL)++6Gn^vU z2mg+?9e4ze5_#}4EMxu;b=*QoV9jG-zK4?pO}vq=Qc6}=wXCOId7j7lWm^e9W{c0FIh0*a5rc!D zu%YrPJ&cFv`7>rfTwu#S%rhqmh3^Y3LR5hf&!7k=iHL>zfz^-DfcrVjxHbu2u|?s) zfdiO`cH=9yz1-G!J6nOmL#{Dh-M%h+zV8Lh5lzl0+o^S}j6k^kuwpk|ZJ%SVW*QGB{vd!nvZ1OCl$@l-fA@Aw%L* zJ3fISPm)B$$07n1>Ol?KL=1T%C%Don1BsgWRNSXPElDD>jYR|+qP_wa)}a>&MNV*j z=Ve4qd}<9+OOlAB_^u!kfeLk+GjgC7Il=8K(e;M-)MrR7Ng@JYF{LGuKtt5?BCHlU z!ATV*J~jC>m;+FfN}OOOUCyK-GWg*>_>(Ds)N2_&;7hvpx(wx{Zc+u%pY4u%`7f8_ z!X#Bw7d;JXQHX6E7hO{6s3zz=-zda6j*BkQq3b|3j?Pht^qD#zqDyL-M!@Ktl*tm3 z^9dXmT~g(BK4?4_5rM#uZEd{LQ||LL>JJk}A^dZ+RiaB;KI_0auZW0Q`xqk11frEtJz)t!)Nx#xq?^#A2-TA)L<)~(qDv53 z2h|gn5FI{_i!QNB_cywpL_uW06lEj|gI%ben26BxQQ;R$G%vmGDg&-e*?hAiC!|uF zBC0Ov(IX^%9Pk^MkIvxvD2KtX^wh!k9fUj|)@=U@mBm#wn5ky2D>TBq2K3fI@-E=h0?l3jcOXSst4w=K7{< zbEQb6D~KpXDe^5F;l18x;Uq33SRDF)(nk8uqmlIdic`c$x)bPQnDB{45+cWZ?Z@fn$5{nKTalPOuLogALG5axABaojw!p1jaQ6J3V*_!g9-s(QzWNceo1F zi8%9Z58o46Qh=r+2gwHDQ`PXP8&XVpM?~Pp1S~AJ?h`7k0KCAk)|tn7mAuou8ZBp^ z$fQU*Tk1ODzMk~NB}3jlx=bt%{SDdt1T=~A&M9KFuQ40DKHzN*#(FRw?tnOEK%9aP zeWwIAwlLQj9!?jYV7!(iz5smf87u0wtm!(3YK|Uw#Cs9_ zb){O^&1|kVbb5?QlvhY?QH61HBNzrB~;sU3-!sl2TT64AT zFV&GcSKHL|AK_QmzytD!6Ht7-LFx2cY3gVOe0qf~II9~n{Dz&SVlz$HCuTYd138&y zZ^L{TehFSL+;(P}R~dKU!mX6$Qs!y(J`PhBa(n|fs+)P?#%E*%C$s7x@`Rm{p*Ywt z_s_8&!s#Wt5wl*CxEgV+^))tXzQ-R<9^Tc=bEu_GeWkP~v7`t<`c zU#05_28Y39-Jkhd+Wna%Nq^>VfwwMpLMD}Nfl?7A7Bm7`=>vtX|IS&MnLIhgFzitn zMdd8a(PZo6fiKC)41D6HGldhP_Lv7SO#f{g487}%5`!5xe3WFcdZ3^A@1J^^#Ri@Q z_l68i;$-^}%51csPQBo1-=vZmOXn`1HFfEtMf0c5Tvj%J?u?S9cn+n#`gy-OB;ids zgpv*U$OKa{RHIHBd0E!3sFN;83VE}Y%wbzlxqY-aq4D&^%a)W*T{3I_tQjhCztPD( z2ouz?BG*9p-P^=8R<@m$ZC7iHogGwmk*j6qy-^xjgROA^YozSa_Z%U632xG;PAxDq z8j!BEG3wm~W>&Q~A@SsSoi)rB{@bU|*PPBW%s8u*>E>ew@Wgk=FPlaljbRDffVn6s zeobgDSzWqx?!q}srk2cHUb1k;EH!E-JX$UaMe>bYWz2;W#8dj4nOWA?QA&_B+^^TL zS*SeZSI%Xd$?gnetV)~g?p^I|Vx(ze?>r>_E{d3mZ0qMSG3CN`pA^{A#f#=)rRd}y zBbSASrTMo_bZ2G$5Jk^)Ha)r#@?oLcklk_GNwZ7l&tEiqc6CmN21E5FK2^_metBN~ z{&wf3$yR+7I~59@c0xTNKK8??+npKa;AM-KsG^tMP_f)Cq^PmIVNv5>6NkC=33$?6 zzs1=u>w<$%T%GI;EaVJewX+pAieEBg+5EDlQ)jMRxO7q3A~NDQCB7SCIv_M}oz;+)2ux!sIdm2jCWE!lcGiWo;9eYEYn{$@dbkOwyz z?0h%{g?#vU5R^eq<{jxg2Sj!LxB=M)*Y^qpTl)TVFK zS`C30J=Au_L~XckeaFPbJHAf4w33(c(I?u9IUQ%Hc%n_>|K$^Hj>`Z4-Y|MEl|9m`X$cAd_J1 z;^prmC)!*vH;8qnc-r$m2#5YQx?k{h!A6byAbmMS`UPK_mJn_Vr|tOlV`TrGBW+vT z!ihFkEv8uQwJBmWnNrpC*G>7iPPE}!x(wDNnu8tKO%cw36K$uD{PPoSozxEvU2&>a zg}c!OXWPE!feJ%CU-p)mF)obRN86g7{XrjXYXXN9@tj$cnChGXFbGDTZ5R8*UVkTT zFL~^Ob8YH$Z})KziwJ~j0MsXF1%-iT~oUHg5|WouxK~ zA8W%~p<`_$zj1a|d6${%Dia>scJQ__-yi&V==TR(znoL}RbR94gX}8{zvy&j;XSLi z?2Rdp_wK!A-N8?8Sa)#eEd@QFE_tw5VAL7!{D=SHow=)RVcO_@1slh@dM{t}M$Y?< zXCL^m|I7Iw-E*Sg!S9Fdo%+}HM_%jyRne>OCm+fFdFSDIE`O18%O^+1zMNPz&D`aM z*V@#I0q(fK<(HeWPCCXm@d|UaiOnbM)4&Qo4ZJ$AVWe4Nn%myT2Nq+@O~#$LmKMdK_~iac+0i07`WUbz ziHNmGTcD}*TUwkXBDowVD8Ho@C324A!X_mfy#pn3LY-cwwTp@nE^-G-Xd*&C=oWg)Bp9NF^n-35E$mg|O_5uo!W&Tyfr4r> zZHXq~{4DI9K{%=9Fx2K=X0m7cE&4H(gk5>Mm5HN0trMz- zAZ{VWe{);(8=ggB7}|9-DH^sdnzQAZ@NH2thkg#AH|7Bh(|@=PdXK#=>Vj=i6LxR$ z9=@$6TQ_lP_jI$ZelyTRGrR`)BH+LNg5bAobP0HzwiM!gNA$y43f1nB?sZ8lWN&PI zhdHDTK6qWwueMb?eOcCPp@|^9E{H;q8yoaJYeF);8v?&Z6QdS(cU`ZNu7Pi4Z!U%} zozf0xOw>Dl47I7wF%{WCTXfs6fd`%))S20^e@NSK--KSbAZr+6Q~babNF8R)t=X>Y zuRe+3Rtj+Zk zbD@qfu19+U*Vu)?Rkpc7TD3Pe%Sw-8Vx-OVGc%zE&GgPf@RX^_%goENtnN{87PsN& z8IH6X{^=rfo%7Ql^){Hjr*z>qI3sPQUziCsXr_c}=Q;y+nrA|heK`yF)80QB`O+w3 zY>s;7KyKSD>)=x!$7TTse_#+cct=OR5y~)|W*T=c|Bt;l4~(kF+K1DjJGmV}i3A9c zu&ZHHqo7fiBrMVhD7Z!i1O<%>3a(MnfTFfDC`KJBE~7BG#ND_B7k0&Vm(dyHs3SPe zOk74`#!*Hc{hsHXs_xr`Gw-~=_xs-8KOcHh=Tx2Z)TvW->(;G%`(DB;48C`?1n*|u zaXMqN+tJzPRy}RbBZbokVbvVpL0S^|jC;TnI|o-Cl5H*rmh9RQNDc6Pq$QEJbkn%z zz+CM0ozyRFmBJye#~xnUcM-oxI89&w!O2j!>AFvDx4T(%GCsAQu(Ph4g;Ps(7ItfS zH~YHtLiWldd#|p4$z}HTx=j=N+L+muF|LF_#Tm$fXQr-Kq4f+o@-|X*C|6lt( z>3{F%q2{zu%6x3s$4tO}TCgPF!iXQS8*5buof&b!%z4 z9N^dCI(6hi_!-odhx+?R?v0rF-EzB?EV4giv1uxTSs3=IAUzwqEH@h`+o6abjawBd z6CUcWED^Kj76w(~-(&cU+b?quZ~37fU&1P}D$XRxR}+CsZ?Y8|d_|5wOl??|TWT&J zoBLjg)pK^@A*z-t({{ZLeo7KGH?PY5DyD6adpNW;__SPU-kEE2s_v_7DDQ9f|9x&A zeq3>#>2p=|Xwq-F0?UpX@TvAJ=kt}+|TB?=q1{tgrBlo6&WFXs1t+TEt<7a9}>7! zSiH&klan(I^5#u^>B*x%Mg#NJUHBc?mj_2X<-ebET?AzMJRa@m!pc0nwgvy?W$=~sfad?r~S+R;=KK|tdy$ImT-HNP5dYLqbtCguwL|<(` z+hQ@z7(^+y;JT=Nq=dR?W!m;MYe7t1F)e*6x~;@!r`1lkYEqS62DCuUW~bF^ts2c0 z?ZMShv)O62GpriTRqeT_p=PtwYBnMP%~kEyXQFu8BTy$6IGjfZpfMT`dYl9MxLfHXLrgi80lsW zH;W{=dCqXz*~M+)xDBQ{yB8{F0fSFHc5TnMJ;deN5Rj(a9e5 z#cZ#x!)=!9rJys5@brHl)AM(^Ka0Hy%uh`DE78to_ZOlcmarIJIrUT*l?9o1W%@0z zZCAwEbU)4%d3vwtip|k|BX5}I&C#z)tbqea(iH|#>cy8LS4DoNuasGsik7!O3qziz zOha2CBI1LQ-*pZ`ukBgEu9T+n0pnq|CJp-1F*)mJJ+D0f-iWdFXN;|!oF1_1Z%4>$ z5p(v|+@6uwID2(Acia}qGc()aq4)>4=C+T$9_b%>opW9fo&`Gg#QQ6@Zq1EGu9f(7 zc-?{!4r=zSf?;-TBpziC=m#wC`H2r$GLIjy92!LBo=M?v@Pbi$8gZw2*WvC8Ot;YR z{mQN#+-p8M#P-d_IOa{!GJ8|hrit#hpZXxRJ#VvIPXr|_N`KSR;G335%KJG??=QH$ z@_Fv>N<}B!{iPO`Sn`ESeh>5Ke8C2-ww9)>f~zFiOAWL#eCqPv$djhRO&&N^)Uio<7b#67jjd9bI=4?li748@CzfVCIw zpM?$ePX_LRz^vXYRA%vTIKr4JStL+qH|u>7x9mjAIPcf`v3_8)cWMHh~`^OlG2E&SlNb#+}&9`nui12!$ijlt_4Sy9>J z=oy=~%|2kvvr%*Ip|L$%-u^JUJyKfTd}`%u&wR4>Z?guE$p7@-5x;o*IJl_)hM8^K zqQ^uzu0nSU?T18@#@;C$W*+`?^u)+*yj@s!q3-nub(+@NwDD4vQRtulF*G z+M*+iteLxOR707?ow@$YGmBQX3rZyu!^9~it&!BJKP7fqPGz-KQM{2+d@$5yIh8i6 zBBo}6yeY$GIhEpz)Oj&ALq5X~l5LLDNLX3G%#Kf@JxX1cQ>n8m0%it$3Kf^-R9dZy zn3`FiMt7;lg;gxgEzpQEz34cNJ2$8(haqJP=CtS9biZhO^jdWryU# zR!krD?vrOxcCkju)#U=Kt-;-=qQO?f)lp+*SC?SJtF#54{`O3gR(6#+w=^KA1iv=) zOjcXjLAkc8iQMAyEZVH>kX%=)MKf<$c^1X))1@}QENf87EiUiVrFB+zb-8Fs4D?q5 zo<*ybU0tq@R_PIW=HIiZum@ebF6)(A$h{=1;d-Rj%C4@YwFubPdMDJga0j-lOZ-P4 zss-;pMQNdThSKnMpj#!rP0~#a=_S!+I#IY0>*ABu7pO;i)5tH{*0;x}-sjpygiHJB zsU^8L&mVFV$mY0{PpUskTBd#(#gD|u0@D?V5!*tOmckwUX`A54Z<@sJrN1(hm4%*# zOjzGtTT+*5TU;Am8(gfi2Qk_*qNLtF|7g=hnR*rsL~2jzHp@9HMJ?D=U4>85i<)eq zQmdu33%^57tnA-9TECp12~Nsruk+uHu&hylaveVtzJs4r>~@1qQ-jpc)B$NfU6%7R zIfO;H8kE;&6h}%WBNX+-einmREzSSrFV1Y1!wAY%MNC`H_>n3$%c+P5Yzs|W`b1&~ zfH)=l2UO<%LFbk)a%0y-qI5s|`}AY+?hH9c$@0twN*WGO8MjDX2g=|y)%(Uqlj0|Q zET@tjt}24og0(wTY?f0I7g4dGwcrUVL`=Mv^%s?O{e_o-7n}YSu`SUA*Ht)4_mitD z{TUzgS_T|~7nMXA0{I1>d3a*(NMy9omDen^ z@S-OV8M!Q{lC&xcB@Y?7ET^*Cs)(t6aolA&l{Tv)rsfQOl-y-GmEz0P7cn&}sp7Jn zN|RL)Q}eET+T3P2mB0p0Oikf9ptvlj;$kdlW&%`VlBH`1(Kd^bJH&N@J2y01Y&Rpj zXsXBZoPpJF7AY$`Bxye4uMLn@hi9?V%C0UKNNrC8*ASjXO}*_yoA2VP7P264D$cFd z*2Goj+|r21g1~Axi#97eB-eDckOhHfQM|}@r_FbLsTQ&zuo|w8gq2-gZZOwy?AT{s zJd-*rrz^9=Oyeuhym%H(R(6%SO0?VMnHSHZ)yl3e*CW<~&%AgRwf3NObx8xz>lN%F zT|-z6*K~K7ySiK-s)ei}Xkph7)>s@!!|Kx|bvjL?&u15@>_)8fJ*zVSp$GQ@`_=HM znU4>Inb!8Xg(YLJ(=7>?R@%9EG-pFuP1qbaiKePpf=5aoFb^Ic+utlaKbk6)Ow{9) zk~D`L(3lUCyk$$B8DCY2|Y9++aTf%*Caz(JAm~c-VD7ylHLaS zu^w-RuGEJ?_Qvi7zfH=2?fEcBSM%l(u@UC0Q}`|Lf_ClA{zt|JTc^&pPK`k7TJ>7wyp@SYTC| z%5T+*{?V3x+D3eo66pYZe=-@TG5_srHr$lk$^P`L`zP5p)`7G`=h<55sJ06qsoVuC zQ4(q2FrxR6pwxr2=4rU|EgY*+IDEp=hg*I+pOEl>Y-ml>P#0JzR-sV%uB8u!Z9Zc8 zKO?lZX{-w^7VA(feDZP^tlno3>mKhHMb+U!)#1B>2w5vbJfgODq=aP%L~| zGd$Y$JJlVA1pfH4mT9C*EfQ-`Bz$ty_sY}^jqQV9^bHC8A#Tmna0@LQt5G<7kW-JJ zcR2KM2)tuH7~F37kib8pt!WzSG7H5j6bj$zOqQmPB6~F92ZeG}@lPiS-uK>NXo1qe zms?;~sKEH1=Ppf_Z(++5V!7TiW$n{=^%jryC?3A_>ErS9*XY=ohh=TkSc{hG6wf*o z3m*YpQuq;G9M6XH+b)ut@(XhjL%%z$c^Yo9g=01P+I)QWe4(j5F;>iZHHZumuQp%! zjeAT`CN681hPlGR5ME*MG4zF{ar|(Y-tblVE@d~!Khx)++~S6+u0w*)ys6uwrO~gn z=&V)I@!9l+9d_6@6U|PU3tr;{@J|oV+NbfBSUlEazZK9Qc<=6l7ujE0?+4M^r}3_` zc&tb9@cH$H9X9NOXQq}$;GaMKtbH2qYKzBu1P`BRU)bTkUE#`u-2mqg8Ec+~yT-z? z8p4?l4ZA}9?&@gAhN_YwL6J8At#ukLY0+4VHWnXxU)bT|T_Fqc$>v?>7i*u!yVl~d z9&K!wtO3|py5KSIhNiVjqx{UG5M90M*cC8!C&h|+e^37P6D0pb64o+}^mB{E8f^QD zfs~wvBckS=2tGyOKh0?^(g;f}0+AJA|878NoDPInZ^ALPmpI~&Qfromxz556USX=b z1Ey()gW3Bh2d6bl!(4A+2(K_xdH`ni$ri@+`*!z2d?|g`VQDSXNXsk|Yfz+_B|u8e zbPn-D>AMa`YnF!TZP&hpSD5*wfN7oOUsW0|jPx z55}6MVftDa!Yj-Ty#TZGR0qSarVj}UJs4}2hUsTv2(K_JdIKhyV`0qAC${U-P}ODE za5M-Vmd zpBWu%s-B5PvzMQhyPkh7MjCT(i^;kKGk@H;pQ^WLY4mD~ z&RRq0{HZ|pjL<34Qvm(WvH)qo(H4*ug#h_`0l7?m3qI1_x6Eaoxy<*kxUGE}kNX4M z)L=b|$6pO}h<>MQOSae!&ff5^^DZykpuIl(L}W$a4+lDY{_QRZeSol6_|bnp|L(RW z+*j=b*`APV|3?pRm*DRoqWmb-kGq@dJ0eHprx0f5MBG;vJ$UZyWLpEW;PJcn>*9ph z-3~ln-ziTm%%}6CGeVErbCXE#0v*~Zchty)-Fus7CYd4P$oa4gnY+%2^)?I7!e&)LZDhT;I$YnBjHf#%|4$yC599sRv-94=^?a~8{BXUR{0|2V0h5#qv{S%KFyw0jxVF*ROQO+^X#Y3UB-X^+wA|NPqQC~{h{n{ zv%81s-OQSvX?dFvhpU@`-Cd5XI}s??dl)Y*z)UN<{k`qYY@4RW>r9)RlAdW@mYZpl z6Iit1+}L|MdEzP4_}(7lvP4Yr)+Hdcb`(~-LbV#Wq6iIwBD=&&&xy$Q3#^LP6m@p09dk|5! zzUN*XyWNys6&;LAg&{#s=GT@hFsfVyu0n|!;n;-GSFR5~DAu>3s<#>Z2rjtLc--_j z%vQ`aRI!LsaofChen0T&C9$Qv<#8zc<7~5jEgl7JyEIlB z<#4cH*4U0OYnaHqNGDlGM9hY(qupB`xhMCfvaX+f`r*cRY9@{TX1`aeZ8iM4j9K|u z9K#}cw)2*IV$bTp{gcggt|9%uEth-D@?uzI}VU=0Am)fEVAfH=y{2fdt(7UWrIbQ8(}kI!FE1Bao=OH!BOGfeJnPye(npGRE`*N}9jH~)F^+P`#rY}A~2XRhP0I-%v1Vb4uDr}7tXJ}DnOJ9l&6^?&;4%k?|ITe|^I zmR6n(`xI<)b54;bQ;GEj?AOAE_NN2)bYLx4`$Y}kKeO(Qo_B1BK7SF0EuKvMvgqx~ z7rMVPvg+!pQE+0^k^LTC`^RbDjGBG%nU!#&a{F`ZhJCgFJ(YiW_sO+zV(kU@UAz8* z<$G`FK6gzuoT%P=bWvrOy1%Vy-hSt>C1Vo@esR-LBhMSYXw;u353W4xz~G7fpZugM zy7Gn5!+v|~#%1_I+k`cLSU>)^n>J1@yLI$h`w{esf4#hNueB>izH<8^BkA2+1m)?|W5e)Uu*xluPnVz^xNxuaN8fwp`g6X%MS}3h+uy1Dw(7%?6Yn`> z4KUWs{71>CWk=t#Zo!W~i~`1}i|?K_Y(Kn;XW+W&#Hbwd)z9%U_NUfAIJ>bL7?Eo3 zROm<02mSf3sg=!lc3gKw`?E&&ns)!l)B_J9Q2KAw*)JSAbkN@G_nSX$=$bL#nlHCS z4~z0hm8WI>&!4w%8Qd?5N#)gNWAWe$UDe;uS3&P*+CLYY7WrjEd5_ql_7~|RE`!Vy z&&8&6NZos#yniQnrV{zs748~ui(sUQSiUB<%uJfoE@-GIif#Y<KP!o1LSJ@PiNj zM&ZQLU@gpW1O$uh?-!o4Z>MK!7OaguS7bF70u}$Orm0>Rd$vPrnjU<~8Fny_Ge@kC zZSL&yFSRCGK43%ap>|i|mp%=fVvolHselhWMa6n*DpnLFp7~^B>~5#`Rg`|2$XD^A zDE%-ipN~CWnwY8e2B&D6IyIE?uJSO`^Y8J%Jp4jzZD*(KoDn0lc(Zk;{KeR$=sDfd z*u^i#?ow_*D%LNidRsQaEmmjFNWraR;C|stv5B!@wl!I0+4#$_5l2k<%ds`mfE_R6 z8Fg*ww!Q@=B`(G`qG`9K*?nG(b&9**ERoi~AuB~AxqOP~39Pv)8VBXXlHM|~K3493hhv-;*wOGA!` z2y3dp$r~Geo?tsZ0@z9g`*82PyyzLkD*sE~`23cRpT+v)$wTJ+VoL}Gj-|vgfq9)U zeZD|rw?Bv(F{q6kY?igg@?vMg&NlRzFWJx(bF`t`e-j%QU6W~OK;C2;+Dg!=|A23+ zLJdvMwa#tKd-Aiq`yw&PFy&q0TnH>7VB*|I#9188TNb%1gp)Yi;;heW>DE5)0mOe|*0d1GTq2ZxAd&^{+x^B#H2%%;b7E0jf^VbEgR-@td$rBBVm`FRhU-Csu})}D?R z!p>L`Z{PB8Vcuc+I5|K|>sa(ncJotGN2d8-v!ZR?;r2c1HUk>n0ef~0yuP?Ey-qPl z5v%&c>tJmtqU5!sr+kUF748kUZ<^cQx~*gJZ)v|<#_p5HvB(@nl(85BObB4c#}kQK zT@D|cGNH{&{5=i%lc5-OAVVQqX64`Wjx?=@=CzL{T|EeQ#_!pzVZjL0aG%ytKOo3& z2YefZ_*e!Z_{O=sd}`h}F}FugDg$*kp;nFu)cv7=?zC9z@>(j6%zF?4WsWxg&HHgE zt_#JJyvDPRU|Ws?*aMlC$CBR?4M*V-`7Pg^n1=`3Cg=i$*EC7YtD->gX<^)i;3BMJ zqtrK%8F{yjOMDM3&hbBJn)*@GWaLfBPqfoCh-sS2(=-{_@&cr0+l;(UF@Z80ZpI-p z4frh!CgdZ?WX+BXB7>u>!4%fRsY?f9-dWthVzOr2<#~gntk^8LH1DKX(`lGLTkupX z%E_AMMJT63X63UmKbh!iPSz~G0>$*xOuZV#r_;Lm>O5GJ)ynC;%t945Z#5M6;T@%k6eh$~Ju)R3KTy;*~(UAwWD`gIB z4`BA>w4ms4GzA^u`Y>RT&Z%x}z@TG0%c63nY?q zLX<&3ceI;kWvt0+KhR6F<62ms#p0Ehu^-54-E?02foEk4t|w@Y0k+BXNy7SkcGIlY zc_Sn3*h^A1TdKxGIe^qNvRbtSK#XgN4P#VI)<`EVWhZX zi_GF?c;h;dr?X5CQs3-Y&V#TQRCy5g(KOXp(`0{56MNh8GFv{tmJhP!Ly+2okWkut zGE}wqWT;9ISc5&vhD#LWC?l&;V9mB%`%lWH|Kup7M;hWenJAIf-lwBx+oE*u&xx?j zneJx;v|Nr-9EL2H!&D{#Hca8gd+h}AUTSB1b$Fc3+I4u4)!HQtTb|CF&Q75(QQQl~T-krE76z^=0Msm4m? zQ<)H1ug=DDr0HxdN16--x?>hEamR`lOR%IP=%vn=GZ|@}FUjhGNaty-kyhgi8EL7S zP10UI#Tv7h$?K8GrfM(GW4U@xR>z=3KwPV1KPoy|vm-AU(vIEO{5%fCN5ThU6)@R_ zg%Pfab~p3ii0!G|ii;!BmRC3DmF35h)Y21Us52Af^@Mvr!MD8u@JB=7iP0AP*}RtX z-^p7UDVm%;N<={?Yln-;Lttf$P~8;1heJIW3n&ba)HqF(<26l8&@`B6%O~0LBW(E; zTYeN$J=6sXuk%0`N)PMNkeN$agFTcb%-V+%W*I-M*_P{UDu;SzHl;_}ix){Z=&?#( zdy$^%30bPwnI=;`8=&S=Y!7uQm+ILtQ}{#v^mZHr>bwjv8A5EX4iOoDIz*&cMz2Ic z&J)r!wU(yIWc`F4BZrt9KhHZZ(yVp%IZhmN2t+5=M9vX^(Z!EcCORA;{~XN)ZPaX~WDHx%nrWNegoA#S53lvBdF& zYG{`aDB<-gBLtPmK>a!m)pK`1eT+{`nW}^G_m2f95M{&eL=m2A-i$*SjTw;l(;!E5 z%RdpntLCE>awQc#ktjR5@V-%0o_?Qa4+yV_mFutc$hOErF1w>wz3zS~poe zt^Fz7oB8J5VfjZ#o(c`sLDhbefZLOmi4kJXcBQ zuz|XsJ%DxVIhw52&33Etshs6>jwGv7sDwi4h*u|wTn)`u2!F;@|Q(gLdWP3 zVA_3?suT0EZ<1n;&KjX!Oh_-v-o(#{Gj%#}R%ZrAUUEN}*=>_0GxB*&&K!=1uBKx* zT;V!2%pPt?*zKX4iMY5Hh)-t_V~KLQhLbSPlST9Mah~khkabZb3YrgW7>C*Y40a(7KaLOb+QoE8k6yWCQFFOuk>N!@_1G75?P5Wf z%IUr?!^B#LcIJYIt!VREb5!gEK<1yL8cBhm!U7_a+?+I}&x8iqXdt(2xr!%(!t6dwvB*vur)GLFAg_}K4Y(riWJcVOpB$GQ3j>}B4%0M9 zXquX!X>y`1pKQyIwB=K5`B6yqOh6=^2=wwnCUKdiB^<0kds5b&+7+2)C+k(~8v3ol zB&*9#x}%f$@hsM1LROD-da1FN6^R`OnH3AY*K!wYjuQ#C^aWd`Glle(&J>xG02`|_ zg*c}(g*YdpP+}k#Rv+M5ST_pE>r~Oiu3WG(f0?;!8s4iTYl6fvz~tfhWM0b;P5Dn@ z^N~4vfWJ8o+jxmk2MVtXmd6OT@A@&cZWJFq>d9HO?#|?CZc;7s5%LL>xr!!@QO^d*@#kDcUppAP@z5ifs-K7M;lw zf-9>b>T@-OnQS_niJ5GMrpcL_CQi{bm~G4F*z(hD`5CtSETncOBb1I{UE;|2m&;?B zOjv_nFv^9K4l%iKk}<@J)mk>-bo^&780nAMw$WbGsj=*k$?&C@dKPW90}$OzRu3LJ zuM^cy+JvDHidXEj==DUblm6Y?R7e_;fO#|DAK# z*-+*jHeb`=TuoEwX_~yimS1GcFSg~E*z$!)bq*tvcGCN7s>YeDo=#YSUB@@a@`g>_EMQ+`f}n--4i$)6-TyO7g-o=!MAk_umvA5$4-Xaf}fK)kOT5M zK_m&bxD;TU6ilun7hAA@{Q zsSMaX1S_lr*yd2!uCZ8S^6^807W|@+H|m&~j@)59YTTv6Y3aZ{O1SF7gJovniTGA= z=5AdQ#{cFP)~HDV?%SlOB~>hcDnDF9LTbpI2%cdz3yy`?sZa=#KeKLc$ZIK>9^8*m zGDky61p13mX54+AI4frY=cN!%VkvQOB52NQ8CV-UgTcof8GH_gM@ReI}3pg)l zq8Pg#M*pVGug_zf18Qkl<*w!Fp}3L{o&H)`OXMQd@`~0X_d%DXYiSu;7x0A297U9y zY$3#ihxic@%dY_9tC{xaB^%O^KY5dF-z9Whv^2J^2Ekdy4^#GZ8>uwTny#}YRI zn+GOi%Ft*Oo;T^^wm6Ow(_qUq)ed~rs0KSfgxjWPj!5o6wx#?og zgSf}PpTUbphMFmZ^MiU6cnN1E=5&+Rj%42Nc-HSe?ErclxOdYz4NWz&_RL^j*2?pJc-V zj~q~t+9oG6XCPrixvRiM#sLMdtNxhkoSZ5=)ahQ^-AkW8nRHt)E%HV~`7rb5jNDku zA8re-#T4-ij=TlG43@>;1YYfOzSa;uGssl&UCj>JS(x z!WT)+hWmq(D058Y?%=ErO}0={Q@+9#PF)e)6iW$Q`8~l&v9e1LA$#^AYqs1Q430Kh zkA|DCeia-O-vYN1jk~xtDVDg^`gK!G%V)L4=eDONV<;AjZ;bSaDJza8Z_!do&Ek(E zB~j)WICgVX;NaJ^sJNxeF6Y*uSa3V5i!>opzlKX?x9;N7x=CZPyO~veD-lqR$Ob-pb`3zgT#qCqHf@W7Z`&5ItTN?vS@!> z)N%6!De4hR3~q+jw#S2?n@67rqUPf#f~t5sM1X|fK6Z-LrpA=u()fwsy-2L-1-`_h z`KjOmv*Jl;cU&Fxrd?oeUK}rqrJk2}T(ktA4d-q7H$nWzpYYrdY6|_9XB7)_7Cn(V z;un=){w7*I?aH^S4u9_cst>;IYF=C&^f4vXxlhQ1Hrq9n21ImkWOvW^yJxm}c;n5` z>3}%>`@pbfR>_ol6#$Z^BP!d#o2mJ`jcKUr6L+D?H4TU0rOtS|HPInpxS-e<#{D^= zpVTv$zfpF3iM669B5NaD1(jr^<>hCBjqO@K-x93oRzGmoRqIczd}rOA@6N6+-n_^2 z{bu21v|s(cva$B6^*P;>>!y#IbAP|pk(@8Sd9U)tPA9IPpMT4`wnKId|KN^D4x+N2 zdA)DGe$=$49mB7I-u}I>t|HzZV<%VNb^IRBUpyW!c6S)%zWN+p!1kiw~~!zIr_}*X?-rlOOE8t1!B0976rt3%Db-X$Qr`IuWCYb1oMU;Tca zYw@ZL+G4h(ADr0^XQq!*XBe$w`$xs0}dWGmE&LZ&?M%4@yy#9#FLC=RdIlj}UW335G0jx$Jl3N@bG=*hvY zOXS?@>?<0x<)q1$Yi`SyiyN2JX91)ob=>IPj2$$)t;R4 zehH}m$~=V%PfmDpttZ!ca?+Cdp4{fi!Pj1kJh{x1D?B+NGUD$X zsPPnPJ-N=4lb+n@$xWWT+LKcvha7126e_;SZefilr#!jMlXrSD-iDPu1|Vmh|7$#j zI!{h|a-%0Vd2*e%U}^Q_#a)l=+zN^m$sPPnP zJvr&gjh@`($*Vm%<;kt}UPhZI@ATy0`)r4cJ-N)2D?B;j$@Mi}My)5;d2-T|8$G$n zlUI9kDqF74Y0b{aY4hZro?Ps$>B>C0!jlu8T$3f^@T<+rz{$sxlb+n@$xWWT+LKeB z+!~fS{}=y|-KS-qT;a(HPpe-vD&+K^W>eLTs%5kzs!>> zJUQWHTYpZC%h39BYCXBmlarp@=*dl78%&2C|_CzpA0g(uf|a;+!Vi5zku z=_xdNa+4>o_T-c&w|a7$C+~!ub^Z^=c`f$jGEc7X&v{13QtaWa*Zd~dUBm7H+phYwp^dHIy)mL<;ks{ywj6|gx5k(F7xDy zEE$JiA}a&Cm7ZMd$w^Oc^yDT_UhT=Lu*~_tHJkyt&69U}axlSbu_u>#a)l=+LNe>m zsR?CJuJz(ANg$-%_z7FT$3!jo$}xz>~Gteigo zCq0EmPj2$$)t;R4c>XU_k@r0fd60hpqq zDeM$4iSmlxOzi@Wm)@Gkt9aAAXS_#D?ogO5#VD4{LUN+Gpc9JahJ+DT?nNjow;@ae z(Rn{Xk>u8cDKB!Fg+;KJ`wgbK2ARCmU>2~Lw+PIZuHblcKq2MEg4r^|6;EZcDDI$% zC{FDRjytQSJk2!_n)eKhaJ(=xThfi)(wROy$6{gS=71?@Id2P?9mL@c0JGyb$4RJo z6Toa?9=HF^mOa67pWlW;*r@}N$<2Jz(8qDoXxZV{ws0%nG%%*ho#43U>5kix=E~U? z)nl8vZEu>Vf#ZI+*^=f2Px2NJS-2ge9k-w=UfNFjx58yLAL_VVN*l`Ub9alcw zaSN&)$RWs*m^VyzTseUyPihqowc0$XOf6WM>ZMDi3N0PsN}E{+H=Io&T@kLFE(^C{ zv~@+QkgR4ppj=u_S|)irSecfxjlxMAm1DJ9%4)f5Y@{;b3P-s-sZH{vHsx5Ga8jFa zQk#~tHZ5f{gp=lK9>d2iT_fQWPMRy61X4>`hnCV8;lu;sq+a2qUM*$4TFQEblX^9e z?NvRtms_w#x>7jtML6+AIPpdE=z(w&4dKKW<>;w!;)~|d7vUu0!ig_hN)Nb2svZa@ z9tbBM2qzwBDeKTu`XZe8BAoc5Tv|^eBzfYMmeMQX#4F*XHg2zK?+Yi#gy!)`5Uzpo z(^7gbv#G>SI2k#@iC4mjSIW^V;l!(qo=mmki_XLx&ob%C!6TeRO*rvDOX&f(6E%Lq zN&JM976~Wu(^7h%rHr3&;-7NqQt?mnBx+j9s0k;Y3MXD^9^;~V^om=2>XmTfm2l#f zaN?DgvR*BvSHemBgcJXiOY4b$k|+LYDg6^p{1Z<6(>(g89FIIXF^E^fiC4mjS6a&2 zw3J>6Cte9BUMZK>6R#vsywXy7C7gJr96jI;n;!eZi3h@o2U<#GEu{y-i3h@o2g;@O z!~@M^y~0Vo$}t97%0A)_nf8%z5)I+R7vaPg&7%jx$(R&QYSTQ{rg@xmgp=579_v*- zddi(PBc;O0cvg;a;jWa%ML6+AIPpbGiK3C%!0`))QYOPkhl*`XZe8BAoc5dGtl~=nFS} zwBLl2eiKf-(md9tdGty+@k%)HO1ZS2cqMt_m6p;g;lwN9#4F9CSE@&^xKX2C2`63& zCtfK>UxX81gp<)EoOmFdc%Y^9KubBUgcA=mj~=KVJ>W)(dLW#5Ae?w0oQxqYWy`gc zUI`~&2`3R!F0Cj2NuKzprSwlYiI8yOpXSj&)uVsh=1~8H6aR!;zy+vqve*<(SL4DK z_IAZPN*yPQO(~Vdrf>@~rQMv~mVF#ImFsueYSBd`w;*&8DV(h7%Q9?5hD``t&NZlT zSkzjs`6S25LbuTs_lPyAO^qv;^}FOvosrI?N3u0ycBCP=(aA$>Cai0xoZPxy#o&^Bs%slGk1A|EqF$@&B*N z-DbeQDzA6D1OH0F?H2s2^1xoa|Euz{e_vjo<8~JuKzlC&2@k+8ce@Y&%D(pB+9ULC zd*WXKB>yb{?o$32Xi_257E!(~>7=*8o7vZt@DR)Mq`T((Mo*AE8YM(#m zm{{K#`c|$+q~45}LubV=*>flcPnGPK^p%&VS4Yg|S@DBP$0Kio%^wK;K@#1*In$6= ziidLJohHu)i)UQ%udh6-dzMw7hx7!?pM6HB0Q>;#?@je=RGXX|Z(le9vb@m~YVU&oooP4=YHeUYF@~BE?`WS!zX!-d_7np5xztiG{!=g}*S%cXqm}8Z0Me0Czfd8w_ z-ydnY*>)P5$R_>CW-mv|uWqrqf5+diO&>Hdb~9LGn$JLMmw>$nL=FDlfj=-H|1$o* zV)^w*H(CA!q$gT_CsOu2^=IPmEVAJF64iB|!QY4?%^zZrjB_a2+G2ga~1 zxC`mMCUQ37vkmM=W&uWI;WJ>LwHh}fy~%W#6Yn+oFJQm0*{w*OXG!osxA`0_yIT)9 z=J;Vddhi_ny6}7g{!>$pp=qYgi5Hulr^MTra&#O8qVj6|b@i_RzshXDkS^U0miNSz9Y(rIP~4~*-{}oaWMdmNWUycCs zJcRn%O7BO`12&)Y$B~wwh4d85zloH;JE1KH>GOw?Bk{!Jz;9jh_@eb4CLcMG~v+Q$C_+K&L5bK{Q3BMp4kBN z(%*yqkh#eI9DiN+jRIe3W??dpEe3l9UIvS)o>SSuAZl~D(awT@gd7LH2K-v8K&K6V zKeK!hbou!b=Kp}dKbk(6J50@KnCdw#?qL>FZk&U`%dhUbwmuDA9ze7^2!9VYTQFd% z@hOUQ_17Z%XVicSXUW|_7q#XP- z&4W(9h1?%G2b!sv0876G`yDl)avJ`gZutpF4>#qAZhe1Pxeho5*{52S%aC4f`R|eb zXnD@5zp(sFq)vY__#fGV153f!A?0Bs3YZQEAmCi(ZmWlA_ zUk`SJ&F1msR5%x&Wwu~8DQpJI@x>P2fWHl97F%@)SdMCDb86 zpTb{`Wb&LK@3wp^(swP-5r2;57a?72`LRgHS$-H&i~zG~PQ0*s0fcjH!E;DC>{!8e z{QaBdS0G(!`F|qiu%k{Af3Gzwxt#bV*gH%)hQfddg2qurjivZ|9a-?4$#||Ne+&NJ zYML=O4X6TJ4PtgV{&Mt?e*%9wddN57?|o)5XVM43KEzyPmjP{nMdas;2AQdK@lK~5 z0`^dwJpyTk<@bb9rR4`Br3qn%AT782D5TYvAB%LH5-P_V($XWpMn&NLQdFy zb0$NWVhd<+y5)~S+Q(LQH28CE{+UQI@uY2!u=%WLKbucHI!Mi_NRP7o0OSx$^KqE7 z5(@O*DRC*f53`ZK7ydfFH~8btmiZX`Cqjj*S*mam%+;(@=W3QbgHU7nlaUT&HuC9P zf6LDVKg;USFX~Z;0UBa;1|c16`Ps-vj5Kic>ojYyFL)O?I#z4*&p_&Q7&w>D<+ErYAkx<54`KcDtkT&?-7q)@JiVnc^XFR~_ORpGDh?6qu(h-y&z^BS zqvJ3cHP`cfz@JC`dKggPxT7(<*zt^l8wL!UGiDEqG4$EPWi$of4}TdA^5=(i7&WKU z8>MdSGE()ffC58IV-6L^v$d{|IaV1~>h#242Xqng-1uOAFRDO?gQ#sF4Z#dHSWWjUZ<(x~t1OBp%JoR@YYjs>cF`O;!XhWUx z;JYhdFG4q4z%+qEDlxT6a&g_m>Ku;zk`V7~sq1uD?r;u*en+d%^k9q6bXX){3D!&z zbLJvMV_2v#-x?i&yge*`Ao!tHCx$$h(VqE^9|_*+lV=%qXh$3JRp43X_}$5J;PN!a z(-aE|@prW4nK#Dr)kxi`jw$u1&vK{V2|2`KKKZZ?W#(TB{YyX`$_tTR?gsAV5bC7> zR}M%o4)JxCXL_0CnW|1dfH=^;g275y8S$JgbzQ|QSDb!1S5oN;5ItIg^lIVzN_vgu znZG#1FS0z-t1Qn{b^3{|V)o4;#+6owytAb)b#N%d3or`QPkxX6Cfw0qk6*huJ~!Y` z*KvS%H#>&3>t#x=h>tGOU#@fKXe(wWr!fh3O}Q<(w>Zp)BWm-*`e_`_&f&0x!xfGSbzFqPtqiw*I$G>n zN!~?b6(Z{L$-De35YhUu;FPYtCKHuzp>UCRQK63GIoPVOW_52=7$bvCSIkKaV2&;K z52Bm~IH-|dpK~pkcF3d>3xCEx_8;?q4!I1(Lxksrr6Bw-`jmNC^1Q-4{-Zs4>d~I~ z#HJ$yKzo9SN8C<4c%A~o8R>DPoWZ(+I9ol5lxMMG5YLR9On8>#A;~ixCkmeFI0sOV zGV{BEc*f-X!Ksu^a0{JS9YT(Sbh6V2Tqr(4gAJ3$0=-~^xo6$!u!=l~s|Lq#A0 z5_lx&0T53tbeN8_rEKy2NXLMl0F4Gc3Sy)ganAcKTphFJ?7u3c4}%yohKAlVB0QJV z37)TSfXwsx^&pp+KqI)k`ASO#KOvP;>ukAbQ|-9e*3kMJbJiXQ^8 zCG?n{v(M-V9ik!)Xh>(+61IpfYX)&paWu0L9E=>49IPBMcNHgN>3P!Mq z{m%$+3^0TYB^{wdbc~>bkS+#suu-3bYY~W1;u(>HvlEDVl$n18QV!P3L5#$WAV!W6 zWF&7!%E;9-L^LD-fjHVZnmMXjAuFaL4QR-&U=$i4Gvo|C`}9$yj10>dDTbOMe;ha&bp#;&^wGP`iw2&VZ+1cN)SC~3)m92lzmDA8nW-%61IpfV_&l?FqmXeJ&BZk z{s>ZbT{CDLs1JzO%)}@Hu`$Iw{`=d4UPyVt&3@+vcu&Ywqyh6wA&&+11sw(|0a1_o zl>32r!A)S=(VpehqdoEI03D%2JwRjGp9E$G9U%aL2*`?9Ar;4imV>y!G)NPmMi3X8 zzd$+xbPI@!P7Yu$I&X!1IH)&>cC;rB2O{;EUr&YGKrA2-0dGf2AOcd62CR@36Nvh> zV+E|}mq=+xhp0!H`E-Oh#G3|Ux9|exQt-SMnalp~1!kUAU`m;jLvIlK{dmv_(1jo# zY8Qac1QCEh1iTn2^=U_Y082Ubs6X4Lv?mUuOx#0w{P%`H1$xMeSU?3T5||ax^Qqv6 zfsO%jp!PxDNk~rx(e_x-L7<~R2ZE^2e3tJG>H~e+(f(Y}`JhwS|L1{D1QCFWG$3#v z7%-pZCxZyg3aCe!`KN#gL}ytcE2bW0=CdMJNXHos9$9^Xdj?WQseUs4u#zJ|tdt|Q zA7~c%vp^F;wIKE@^I1;4;UL=4o_eG(()U!e! z)AY!BMw$7nkU#_^Fg+fCbSP3rX*7rfk-BUpj~u3ynO_MS2z{O(27x#*Y47wP*GmCs zxxpx4xM)aVR)bnSp&)S@DJ!H7afru!o(G6C zr5=B1NROyE5JUhvzzSFq6=^_20&}t&2adWzGKV;H79(vU_rObSe3jz_4z!xATAc2|Ba_SL>fMp=+u_9JThghM*rTzXW zdk1tNkN>y9902Nof^wweK|?{$fer?}3_1w(J!lxH!qUA+hlB109SZs@=nxRc#R$+t zpi0nc&?wN~K_fwQt_rjmGzRtOTn1(|=nYUcs68ARi}WlIow*Qn80bmRIM8>X1ZWv( zB4{b-aL{|82_T;NCV`fNjs)EaIs)_u&}2|A&=k;%prcX0+~_(AX&q=Ps1kGxs2OxT z=vmNlpxK~fK@49F=$D|AK(~NS1RV`J0n`UH4YUe$GU!3j3=qqvgE)!J1bqamKNWv| z4>|>8K(j!sgq8gobUNsFpwmECfaZW0om$XeK#bBSpff>tfzAN2(z&1=pmRX~0G$oG z4>S)%tofiP*#GB&c@%Um=m*dO&@j;XpgTYpfto<3qd!57~$JNmxDe8vAcVN7J+86^hz)cBU|?jXffzp&=L^)?-~%peKqJ-&{d!> zKuHi=M<>|YpMhQj(V2D;9T#+V8HiZdgEoP#0|h9*0qHb)M=u$^8$km>4WR9yn?aL7 z?3Tkp98eu$_zR@lK#ic0pxZzkm~^fH<+mW+0%EI2gYE=Xff&sg$~kUYK`TJ@m*CGT z5L@#r&kbVhj2JHpH0Fmx#LAnU^6zDggCqcUdU^P>gm*v-K)(eY2x1iag4mB|gWdy82mKDTALw1sPSE?HTF{3eM(_8aL7)#nUxDhk z;t#|B2N1*a5s1h9Hqbtxk3kKfKZDr%KY=EI{sX z#8!U`>JIt`=orxVpsgVGH@o)-P%i5EC(|Ezos5+1YcFBay5cmx~(Ig0c)q|9UZ zIj|TF9!g`7@>piS(s>R%9)bjqBOQg5=M#<>9uY&3a^TKK$`jrpte?m914ug|<$&4~ z=|xC+h?F5MLb?HISEO$t?Shncosk}dv>53%NP8f?3Tbzwha&BUlund@E{EI;DaS)k zq}L%WMOx3+^#;9yjDASj-+htZjI0?OuMmh`WUPvb)U5NBKP#tIu z=rYh+(8ZuRZ5bx?~_(KC$$chO>0~)ddR`dplhIEK} zl$lRQ2t+_`!E!>97tf+m+mM%QX5A9$XO_MguXgXe9mpF62RBrel?Dgk6|_*K;m&-F zV*6Iy(Ez!><&ziVKabYuf~V(Eq~wz!erbrmA;jMt;u}N!?IC_eh`%euH--2IIW}Cy zkA@1K2=VMgr}JEhUmxNbC8xtKay+B!_%}oR+i4!rX-x|_bVB^r5dU$AZwv9ChxqLw z{;LqbGsJ%%;u-EJ>X)!bDOf%T@$Ex=#}Ho>;)_FkNr>+q;`@jAvJhWCI3(;J;)jO# ziV!~{#8-v*u^~PY;wOdpDIxwC_BL;TzjKR?8uAL8pQkLc$t z4DpL{5r2lA1xrE&$q>IZ&FALakmfOahWN%1e|v~u5#sMk^SN?FHbD;R?IDW##R)p{ zze$`$|5q#Y>eDwec$xo;4x#`5?^TYvdHnz1bYSxTr1I*cbYYX6@QJ+HAz>Ee=I&<} z{yIL*3_YP;QA1S_+xj(M(!Succv1URcw;=;8!$C}mhM&(y^9>)%3fq9zZLHl(~<>m z#Rqjru?WhNn)}|0Um4lM40${LVN7$j{65~lvjt4vV|AZqYVP=BWSm*{oA}5`zIp98 z@eez@^6_XZo1182wL4;wP8N)8%jdt1&x{O_GSusIgZmZRVZdDesTX3nw3UWV(HW*5 zP(ug!6NZC-M?=d-1um7>nVf2iFEwh0BiP zWkk-cx7<>B*0B7l!|GmIKWMM+RimFgw{rAve>Ezn=$}tdsa!GY+!xPYS8?3Iql)L8 zKJvbuL)Lcr;L>$Dz0DEt$Ggm>9cR~ zO?3`_XqL>qXYD>Yt(D|od-c_kSmjhPee2c1m2bWJ;HZZ3?&gT9{9<$Y8?gd2xHaA< z$~GJ69~*8(b%&rFF52qC!#WNh{lsq~>%*;n>GSydNx9nUeuK}g9Juh-wO@Vt*OBL6 zv}*00!_QuKFj~E6+i4^BJouQkPvl*aZZ+-L>L>pBrz+aPW({pwJ8fYn_LON4+e%_k z=D%>Ow-*0-)S*Ao>UYuVcXw&^tA9ePulxkRGvD#2czw5b+bN*?%gewv`9OskvLnW&4;L78eZBFIzO^fE3z63 z?Q9t&rG~2up6!r)Ru8mb9mfhjf;i6n{x9(ti)=Qpxaf0Y4T}+r9%kl^xmEl#7T=FD zuWpDHw7U{-(dn}zKHkh6Q7|tmwa%)F4lflWIO0I04#-lc9CK#=O#s6mf^}$@Q-#VR zIl(;^@vEqKwPjLXg9>+!1a&zb3pKL^8aa^EiwYt>(U+d)#qZ+RxK>V#1)nqY)hpqNa1;IsPppvxNxq~Y;*m!F z_J782RCj)ePmGm`>C_1hr2Mdg{w3DPfh1nBQ6V@zDKeM+r~}~_g$0we_DG(Ckce0l z2NArc5aN$QOpg@kSlSUOm>8=SKLE1IvOwuq>dYKW>UD(?kF+@>+M(w;B)7B!Oj2NW zOn1J#6h(8akpoG-sUQNbASE#if=-?oYZ8!IdpHn@i8XQ{iC-&-c%&fT=UI@3e1N0` zM8=755*2IYK!UezR0yt7`5>@SSr7+Eo0v*el+~zMGY6CUjlzge3bUrb!c5%_9rTy< zKoL%YVr?8o@*Twxm+U}kZ`)Je0j`vZsSFh1Bq-L%fh68l5OGLB7Vd6A7Bo3WWTXg2 zyd!$Y+Bl5hJ;e}*6k}RPi?O349H|vk9Vx7#G#3G+Nlay+2q!VIMh+ygRYAlf1^K=+Kse76!hSp|bjtewMgX9RImaWIk!%=M)OIvYoNb0}n>lr8L4FgVJSiK*^YP!uJo z8qe)zoq$~;xaay!$&9J8FvSPNcmguzFUNW`RCP4R^nnrksbN!WoVotlf=8k}k(tO> z@uH}l$GMgcSI{ed0B)xQ9r>{~j*rf6 zQBCjph?x}er3lY<2-@WpRP9#Wa}hrxwlIkA*|jRxzObrg@t)D=BONAJ>oXGaJu|cN zz=Ha2ziVf!wMi?|+7(kQU}K>!Sx{dH*506KP&huDqc-ZVNEU${KT5P z=ilOavEWOd0Jc4e1&nZ9lSieIGIg=}THoNW;wwrMduf|f6E#gv4yA15Fmw6!h=Eme z?g#tOZHYnA*H}_=qLkJ5iZM7tNWHRJ5H8YyQxFY8?N61dEcJ8Qvg=|yp~hTV3MZ!= zYv%k&4pbQR2Qb--ZM-BzOyz{5?1r0h!m(BkB{5i0#3?%CueOtdA`1rL?pux)StAD$ z?5iN+l14bZ+McA1koAIK=xWXyIgr$THY^0!)m&(`jfJI{%ED4OiHWsw7|C+Q5Qh{a zd%2xFiyxYn)(9sn7i;7|5(g@XIHaw~UTimssWeBp0e2uI*2sYb!xTh3QjqM$c1ld8 zIl^g7td&Da9i%AYlA>g`C_{a8R6nD$NH5zD~FOuD2n)|D9?4X%c02WxCRhY=_uhO zI@ZQv1c%$`&?ChNudJ~c7E_((gyo91)R{RLH_3}j3X{FCwyX4H22I%otFg4^8N#ew zjioicQSC@^hefR`Wo2)ft=`+P! z`h2A82)FcE{aAYGBYTr#D0`Eubm5a^s(X{d$=>8$T2^~^dfiiIv)sBzi?BDjBq~a> z?hz$j_s|X9ntb%fXkhA2hz;3g>GQE&^0aB1uuGqmL|C>Xtwwt3^Cv;&c4Xp6bQ6w- z)KTm%w;j2;v&(lQD45Ff|7z_c`;l7hm(dX=vqoLKyeq{0(bt|}3)6~LHsw*MvM{e%y^jt_1 z$3ag+lD!crOQCZ(mFqsF1Vr{B(jJQR2{MAvDz{vbA9QGnH4O%OQl9;Y2 zg05jtFOM1wCJ!;?)EsLQ7ES73VvQU~aI%dI!S(#>mPcm8B!HaK9hcJrQY);+#acO( z)J#PYmlVZYAc?Ikkc5-TIcnwST3MnbJ(jws` zEY`?@B+pO~@kv3_E2QSTc#g2H;2c3tqhgI5Na8F75s&Ox39XPOMLQ0FshoF(lb~1| zhY`$E3~@*?((9wbJ+OaNCZ@8=5)S*3SWs9ihmty5QN$xf$zCBP#8wVO;jkasuhdyN zl;nIH6rw9idWBT}AcEpRu*?!x)}GeLfh5jV5CK<^>=jZ{Or?8-lc-oD2NImGAmWjN zq!&mHUAU_$raYDda+sAe8Jk}P2tijq&{<8!(`DWxUxWUMh+x-k%9=g zZJ67QoZ1~ewTZ3nMP??^s(<2Mij>^<1dl9>;!qP8+i=lEMNKc68lHq}g&ae2nJgT4 z4@<0#!*Hhp!B&i)TrZUgg3P1J>V6_mBt~wc5m)Wg3ntma4CW7XP6#LKES`7%#fnL` zA$k7NZAdwPyKTr7!;+W75QYBnBdUQWuGhfV_(!RC-Z4*3Q{q#%hVj+ zKs1Bb6$G&|aZ=l78Z)TcaDp@8}L4$0NCxqpT@{>v2}|Mf4flEquWwg5m%&F#BPb3UJ<& z%l4NGrtco*05DVEEm#(LzoC4Psk$uk|CDzv;8hjZ`Xo7#o$T`p1PSIr5LBK*3@R<4 zffFFgLqL&;P(eh&`a)?7f)MI!Td6=%r|q>ZPYobS06B<{VrwgUuL}Lts#hwAtqAhU zt(1VmU2Dx+Gy9wz5xMuaw=|!htiAWlKmV*fkN?b`y;mf0#{0STSz+fxz0cLTXZh(Q zT&`Aghh*aRBXwKP%(m{%wIG0@(jUG!S^fG?xi^QMJL~mIHvUU@t@(QXo-3AL0p6xO zYV3zVav+mzqrc<2>O)v9!gHk8gNc`SRmi>uHC zKgp$9KBg?Hz2jb9ET<%ibCb?OS=G-liJX!owYTUblvU;AAPS$7Bon6TB$QQ6#Uye{ zlGNVGD411!N+^6vl8|eGK4n!`<+@h{$=P+eF03|VV)bgSdwI4u6FP%x?YeU^KBVR5 z&=0wH;J=9ju6uPxwu81B8g>g$cW&ed2>dTN4*n8947(q}t~NgTB|p8WN=gK6ZkPU@ z;?(2#J}>IF=`2Yki^hYboYgtVSq@{C?NPUFTLwA8g*bb43X^lej57j>_Az&DMq9pQ zl47~o_Jzk1Y$+K{A!(2()m6IrALGrUNU^P0QCSdg;(>@2r3FGvZtU*P`L zZObf8LC6*gl0WAQ=o5*CK8QsXp@O7pH(^0rD)Azvd!V12pB<#L3kSI4a&tCas&`Bd z(>o@6Ug?g?*fy`Muz1^Uc#7dG$CIwp7e_ywHp3p8Sm%Lwie|!XyW#uNu@P?QEJ^=u z7`L(gJ9p`>C%h@MD*L`$9Q}|+4Y|-?-8{l=kzH{251=7EFaquh=QKz&G?J8{k$R7C zi(=chr$Bv)P*nugvKpW`t3Y{tEaZGphf<+_Tn$jQ1a--G8bdiVd1w)KpngYE zNEKfNNbeHTx2^&t&MBmvzhskJg`AJnU!hU??n#AO2~auR?*UiA=?pb?q}xnwyUGo> zWekJ)iN+L`K1}CW3TCg7fVs(F9ze_?-vvy@Fqk_TQ}|Mi={^*tV!jTT*@qBQ{cIFe znX?+GPZ^4f@X@O}eVD(>oz&>7fnK|N8&{bz4CXGz8I#NMVb-T&-ZcuU>>;MEGG{eVpD~os?1!BQy_Y}xJ*&a!0ll;VQArk?w^_~HHTn6llXR_E7Q->a2b|7BIUTOj~QlFf{qt z(6yM4rD7Ie3!P;GVyaI^LiQ zc8l9+6ho3xy~e0>)1gk92qfVb3bgMBCPM$^>;mT;VUj}DlAMqZF5^akt0Fk+E}UK9 zJU;ds!+n%;Gr)!LM(cHMeoCvM?veuQe8DV*tz|hkxkH~zu(QVdVQp_=7{iv2g|+X7 z|1upcb(bj*m|-;q&iRsA3R}Z6I0cs)=3Vc$$*INcDf1@hGqm{FOTrm@hg+P5Fs*L@ z80SX?gyO7*6d!v+&OqhoCqrEf?&_|_w!?|S z+(bK3q~e~*6b0Ynwo8XQ>lU0S46bb)j3a!VHX7G!jN3CEZr-hMdk@*x!r2AR6F4qL zdlK7PG#TyN{Db2`X}-4RDUeQEuDL*)n#Zn7#neAI45sbyjA3ZO*qy(Flzn;YF$=^uo2)%O}BIp;7bA!kVCe~?Vd*FSce zJ8FN4Gmc@%$6jOH{poP2e-zA?)@S=i3a-Cm3`?1^ydw)5fVZ_H?W1J0$Q-?U+4UWB^DL76?<|BB- z2U~I$!t}lqCqsnM_m5K>7JTd_<;K;8;5(Ro3ufO$+26y(td#6dCoWuItTR5w>|>`v z_Cu8Y0Wi;!^rm>u?={X}kNFQ^{&o)``H%oU$2EpPf`6YMUw9oi0p6=v;zBH@&!iH$J3z39>sL4rNdsHMEIapoaW9D;q!O zBUud-h7v{&LCu;24dY&f8afl8Hl>B~IIBQ8tA0S^iWH%ta2Yte>VCx9j#$pEX=!m@ z!SeW6%FtNUULQcHNi_gfl@>~}3Y1gFw1l2@){hV>W0u>dNx>Yt_iECE87-}^IHw?a zd@LpSd^KBq)ubvNlH?R5XEk#YZp2Bu>LGDelPT$-B&$Gq3?)T)1Vx@YA0MUE{SZ9$ z?kfEhC%G+1R)KQXFe`zyP~8!#_uUA!A{~@u6)2CPqzE6Y9tgDsq1NLD#6~StvI>;5 zmRSj;WpxokjlBn;Ha(dRO0o)+$52v)kClh7ThIHE+x9fwsFGWPWE3Fh8RjH_#EE*% z0|?am!LI<4i~{5_kQCr!^dJJ&Ay8Ks5@tf1_qR>SC_v6SW+comHEQm?tfc8a1fxK% z+A_m!=2U6q)FFbQ1lr?cDblgfKS&Eb*UfK|7Fm!4*-0>IAy3HY#{7-xkjKvZDr7+t zWRH=hL?7pu(;*)~mT2-R*~Iw;91P|gd?O4tpM z;U_o`-F^TD=_V7>wkggjNFEaRdC3ywQ>8)u=89rBC zZkmFZ7D}=Tl*dp~godJ~aD{0Ko6d7_&@F1aWyxF*A*z=aRZs-gV^k?kb0uG< zfO<6mx+yKFfC#8l$y9~1*<+DCVRhZCZrgv^o!(NdLs=b;PR6qpO zk!>JC*;1`dLDgPugo+!!2t_S~c{$V=r|QXMcG{6iIHhh@cB~oT?9|&y@LQ$*69;}D zX_Ju{HQ((KQ@7T-E!0zs-7*!uA$+>}e6f3;wt6iw)>gMg*6v3d)UA)W#g86zV};Fk zHN^4TMK}!yY7QG)-Tb9$rQnCw%yn+_qJ9Gdl?z^)sZ&*C8hb-|uu`p3Zs)>*+3=v8 zVJey!dqa6nrP_Rc2omI)T!D&^u{V@QD%FCYxSfic#-k=%pd!!MUsUH+s#4`PSC{u$ z6ApkKsBzgQe>Ec{1}McW(7n@O4i6@{2v38xCM^mO>JG4ux?z9+ zy0%QpKyNnP5)WONM?TX3YKLqj*? z3$f7`Xj@-Yf2-RIddSVJ6q|feQyJ>Sj?hEo@ie65L|=$azF?FSRZ4odtn~+Pgw<_g z`*3IzC*=yR0Q_?#K4bXu^>~b~=vi~@Sv}5Uvv~M{)z4E(7{J9QSF9SruK3#xE~jWx zxw~-7LQG9RFXmoJDRMDiPmK{WHaViAS{emi2AN~EbgE*^3DUk)>jvJy>uVN=ZaCRy zQIdH#)gOHk-0`gO#l|+*`+RZXq^TQpJu)lBCSSxRurIvd{RV?$Kt=GUmi{AOY@Eox zD7<|tMy-Gpp-QpI7Yj7Ti8czoNtwJ+9f5&@_aCD-$`g~OhNgvRp!l#Rgabw1oOf1J zsW4lMjRVELd*KG)7$GOo0b)aAP;cH7>P*9foWzM-Y^wX_X?h};lUQ}J^{-4ykZVq2 z&20jl<|skboWxdO6Tmb#cWQ_ya@tF+@)p1ZK(*%G(Yn^-?}J)9I4TUk{ujSF%G>n}ET21`Nn*gQVd}$GSw>q_mT9kHY>YeCV`OYZqR%9h&&xI!Zb4t6?gVCHIZ90aI zUZS2`5enx~EqQPJsZmS)>n>e2dAt58R89S=fxVkr-~{NwDOR&Gao{(h2eruihCf7p zeV-L@VpD(I_%iqF<4ZXBF=2kVv0a1nD(~?T11asC{pR zvbCh+Hy)_QTGCzdcBrS-F|Z6*P^5o@(NG0Hk#GrA|G{rCE9!8`Z{YT`ja(BOYmTX)sxDL{Pyr?K5YUUv$FK48heD6z2T&)47Vjv`P%pFqORCjWwhnC9Df1R+~NN)P@zh(vBqc%)YsOxb&y_W zpz4wksnGAZ;2kcfrMi&OE`l11AU0g3HlFfDtGOKnldEHHMy||TO_?yi{5}l z$FJw?Yoo38?9;m-+(ip6e&^B_^n7w-CRYgmpX@ zwbIq@|LOvme?mFV(t$r2wpw{ug{{`N80Jrg?N*Z62U4;m)Kqolv`09p1Vq{(i+kUJa^t5w&IzZjX4S{ z1U5yLN%2m{OUTx1{R=jPgN2s&03YuGhPN6rJsd2u#0U9^5B3uu>?1zJM|_AOuC^hR zvGEr+!hFe;<-IYXZgpXFWpH{Vx)<_?%k%rczGm==1GOX&yX&e37 zp=4D2p7N=DV@4ahew?<|=1t)aiGJ6Ff0U^z{v#BMt)6omC2pu&6ps!Wcd@E@DcqrW zQT&`P6%4XC-r<4{I!)Q)c;{aEcy~J%E{?;eCUlY-YuE1pTfMX^8}^}W3b$-kv?N}% zCCbT`#K#8C(@1qo;=zKrF0F7$Tv$K|Vq-Uyfvsl!-0fJ}Wbjf;sAj1pRJRlfG0alS zDDb$k>&Jm@7@bl4xFr;L!V)Tb0txA=Jz+QmYOLK*2R89()#QyQET2HFR&sAG$wowEk*`M$cQU8H&Ncl)NpIR0k1ePaB?@EwlY*3&o8?{5ByZ=i2}<0rn6 zX{Q;P>c{Q0Bh#vRNh8yzW@Os^h_>nZaLKMu?Z{NK%ZyC*J9e3oNmcyBKQz_sHbc|y z=AZcn%;q43d-c)JAO;z9B$iv zjEyn^&y$R31v28=vUQBqH~yy!hA~p#_|~oO06lp24vM6op@KR>D58!aTBIZ7EPUq9 zq(B|vBaS-45+C3rKEM#yI>Is^Urdv~~L$&&aFA7d?Avm`!YRC5gj^5N>9nMOVc1(XkB zqkQP2wqFqG)C$ytAp`2ckOB1oWHd_4rG`NO)PrF&?s3B=ujH}EEgcXKh7O1apd;cz z7@&9%8^r^$>0JDTB?HpIkOApnJX34RN9ka=?5H(dnwBiHR6sWvDxe#zXO@}rA@;Yi zQ8$QZmRm9)8w?qc4c0Tu4Fd>gZ)}hah7EXTg{1?k!O#KKz@F*cQhX5r)gX2Qs0Qtq zLVGd*l0g!nWay(74i0r}6?tr>WecJ~*rI4)*R?N1(I5^((I7U62BQ1uhH%s3RX(zH zhAip@Cad*=a0moe`}lw@d{+DTtnu+#JfnxRvX>FzauG2IV1l4;IGB##f8?7gzpa)EuOej?`R10ivRw};k4lx zg~71gFMHAQLMbjU{Pqv`@@!sVY}5sKo;I7PnrA_j{rNv*oUBj0<16DCEFND!a{dc? z((eG$;DTw7yr@M+Ut@p#incXa45suVVT0O0Y}5v5>oo>Bi`qbJ)CQD7iy8#7ga7E{}h7W50{YscPeM zNyLWxh-q8EuJjQb;UiX^M6BA72?RzO`{P%%Em&6@G8o29JcjCkJcjC^<*4|^-@dH( zbp%F(T}d{qGpK9!fvB#yChR1({UY2aQ=Pd#)URmb*}viK7>nX!qhdf?7u)2GMe$ut zui$pE*w_uA8Sp%(8oW4OIR0*GF#(Vbedql2JZvMl@K7*5>qXsqBCzf-;NTS9dO$dc z-2lP?ZNgHUH-c{`99_e=V5ubr+Tq%xYe;`~C|PQ#1VB9q#RgChK3Z=qwX{G#7+SFU z;G+csLZ}2lK#1J{0>aYT|B{~;hzRSiCp0ZwqbYg9PzivJFtk8N_-GBTwX{G=7+SCj z;iCnM5JDvYVnXZ&5EGVG?6-bepeGD1&=b~M%MFzPC<;Rh6orr08_O*%&=iIiEJgTe zfv6BF0T2~pH-MHr#Pl!g9wo3E>+E)EOH!25~1O&>p7st@bfmZT#7;H1gPL!y^z_W9<5I z+NKq~k~Ka~Yki#7CUJVk@CXFf8M}U*wl&ha_?wT-Tcd~FgyDoLBM{j37^;jSG$=uh zK8bciown72fsqc0qfdl8IKfeKLeDGGA!Gi$?c2C^(aBCDphIL}K^=x&>O9 zWwpo0O556bdwi_+`dIBvVzt*W3DoQ}cKr@*GpqfENub8sC_!WlZm&LHeKHb+-Wh_Y z;CecThpuAdL)U5Qz@zZS7C#05dJzI(^hlk-=#e_v`jNUH?D&sf^&@rqu$NuC;LptY z)-Il3i)$CE!z1VDwTlOr-}1PuU0nCK`<~Ygw^!Vq@HW{fQ8Gr4dBIAQtt)=R1AawZ zY?LTy>#>3)%JtnYVz55(GY9>U>V%6IdEIW*>k{y@Js!`$b*i3<0`L%oZImcrs}Hxr zJV**f$e=sCiMl3B-BSHn2G{nXw4IeFdBqCH$kBHp>dc;Qy^oUTwr46z1sff^m5qX*6 zf^x+00y$!NksJ{&xV#}YE^qjF4PI`zpdc~4K#=%&fglksxX2+kJ{u8U9ZFUhDkw(` zEs!IY7ReEzf^tM`lp}@~Jt8TROSs-4Hp&r7Mzh>X!x!aJp z#GH2Wq8t&vC`ZIbIYQhCsm`##6%Wfu+j@puZCIcfv5d5>)2uNpaK*zi(zc8T&lnac zMl2(3YovAY7QgGluVy6-BNQXU7mYrL#E8%gfEdA(B1TF_-B_+4mt68nxFZAwIT)@g zGBX6I4;eO4eb^ZS)rTF;b{ZSi2h9-Vshz&D>{BzAq581X1F8=hzXJH=gr^5oA7HCD zL2sh?FheYe56kH@-w;dU!;;$LBc*NatUW$bdwrz#CXw1}h@kkeq{wDc`wbD)9zqJW zhm5c7RqsEXjP{`AkAMH(d3pv0?IAX5542@J+Se-&+Po;)amSa~s66~oU#mM>2Ss-D zba2}YevLNqEjRpjF!7y_+!-0`J_%Q4W%Zl=se1Djw|Q{G9eZdqX2sTMNn)^y+?nys zmx2DjZG5|_0XBrKr!6M)8p7o{w0#IapZl-qhn*>Y!0-M3EBZly&6wJQ2k}20{7`XX z%SG5P2A76rWIVCTjc~u{9crEh{X)HYdALi)UNvW3X!I$vvF@@@143 zJE=DuzVb^a@SPI#>cR={G_`1rzk0%G<0{kdG<{Y+eG<&d%E(Y#W@R>`$Y?p8Kyc|# zd*|H{>7hS>!e8yipY8o|%fT?!<^9N(#PeMu6({k+gM8z}Xa@K?3E8L_dZ?F{x!-iX zLI6-Th>fbj2X=mbA8^E?hx9Kycp0lEzxqtnmPf%6&#$?r3~m2kW*Wcf@044=O!u`6 zy%nQiPoyF!8~u`m^|f*e z-i)B{PuqI)2h*uNBqm)E8Q1iiSC*9H*wgOTj)%&Mjg>|F8!AW1j&&6q>*|O4+Nz$J zgC)HExorPx@@f4~b7qzma&^lGdZDc7~ckISEW zwWJT@`)Y}wx#8|jiaBnDlR z;{u$bwXII6Ek`UkC2Ly}w3Vgrt#M2RJ-xtZ=*BfYneCib9A)}G2?rDD-&<GfA^3nP0w1P=iS-1RZVmF!oZzH9u3?obK?2d_R-DJ<|AUcq? zV@?giyn~lk{yaKA%mH%XQi1}@M2w*u4d?F)mFa{D}sJvak9;3|gSqd|w&rY^yb;I-~S3}BL28I0}7%%%t?YD;cxNRVQYjE%%bBr2TPY`BCGN%SR( zEkc*3yLgErjNqld>Y=>YX*ruA__%{nLlTe(P$_JPx$Xur3P|FmF0pCgEvh(VEmMP= z#hL{%t_NP4&MuKFIjU9jSZ)xbb#P7xV_zU>nflY|u}I#SEGU$NaA401CB8g8wm36u z_}d57n+Kzv3s)>p|53{o%lVUm(S+N)aQNGY<9`j>PX>y;qQepTJhj?Tb1*`fSqgHKa54m>>|X95<4 z!8H=IzJ&u8Mb}UnJz^JTdl)H$PgAH2Jl$FC>IvmL82f^+ZK68>*UpU`!(p1ZV?+z& z-X%kIJsiyrV$cW7-&P%ZIGnFu?-p~jt1wgrQi4PkU!+YG3StZjPBY|a+B9zVCX6n@ ziAoQpP1K~@T<8rBMtPVS2w>}gK|C;g_~H1=_wtvuV5kxshbpwy7w~eDf~- z{vLEmv9U{DskXcdpHli&0zTPJ6~#CV>ZJrkN$q>n)Z53ZeGi9=zdin1bPO_}I1?!h zHokE1LbwE9Jvkf~8yTQY3~00r^gWoMR5(DfjSSFMvlH;GVDe$Q@@d*42T(wYl;SVW zFV|cDpm?#dc(iTts}{XT8$)q?6dQ|2TNh8aCtdNr>Tkl>6)ELEll6VQu@uS|8_P%A zmjC^GviJ>|BXO~@e6)4>bm!BRZ>vv1E>en@dyd{0JL&$@oH^Wg|HX#l)tj%v)L`#E z29NOH{iqu*#vXf`ZhjcJBBgk5z@8p*^To#E(YCdJ|D3ycd*+e2*jRhCeK-I3#Z%mj zl;V5mm+RXKwHF(UN81+PZ}E$!c(Ji~w0$@K_{CGWjg;d1bf2uBbwcrCWASL);&;u- z3LTm=caDwz~Qfb71UUI3qbIWH6>+Bnj(I z0jSlF`!&wtVAw}2gONom1(Q+_09Tp;4 zIS?tuvQ)jQ&|93ul)}dXCBY#*3|FXLuL52vIVe^c79xd7fI|#Nr$%1_IWSI@j}`@+ zf@6w!hyQZmI*KKx_N2){F^RAYMv`b`4#u2PcU=l)VEi6`8GLNYlITwH^i$5_X{!t_#tg8g^;f9@z Zme()VU&Yp(mVN)k0kOoy0eSNm{5NfSgbx4! delta 145083 zcmb?^349bq_J4Y&Cv->x2_z861i~F45yBZD$Am)$0RaI;EuV?&5c|}5Yc23ca zvu3@RoSdBGuPFW#gXg8i#>P4>xun~mn`Y0hSz1w1kH6s~M^*sQG5-qB=%m)ITledm zmp8dx`}Q5<F%E8%pZbk^)SwZQoe z&}~GVX_`jaf`uPd_{Xejp0>2S;=B2Gl>K??HPg1|7ZhCEIy1Ai%jGhFd~sfg{}SN8 z4D7_8w)dCP?3^4A$?^^KTCH1Wwkoe!_LG0~`nLY5%NsO@>pK=K_~_ahGj?A(bm+XC zoJ$HCCnd%Cs|sf%giG^Rj7oF=k_a{@h~}7i{rXMxkKUZ+pSCi!@v>$0OO}>@1C_QP z49N$!6RfPPtX_ANE%?OmDQes5mvv{ogMQH49Dn7NYy6`XFkRIU^lplbZ@#7UHS~^& z-l-}a5noVPc;%Avif=0JT<$L_>eTYWyjj_oNm<}=*gyIK;CpwPf7+6`bl{8r0sTJ0 z8W;dIV8={VVXvm>lhI?YSOao?LhnO3fUK^+Ad78y8EhDAHEx^~htBYieyF?H;lFx8 zlhmIVEnaeZ_MDp!j2J2L)Ewi<-CAk@2)+WfxW0ADlAE1xC0kev7J5yn(R}~tN3;FY zHiL!BlR;wZ_MrWD^KZZ7&r{gM&Ye5wwrSh8O%|lXM~o~-dH&I3(wtgIw+jgA+O=zc z2&-B&&4kdoO$$*VWK|3Qlm$cm)5a$WzDY<)@W8o_9Xs^^>;Y2n+UsWQ(%7wtrRrsT z0^x5N-`koxZF;a}%XDmx=uD3#jYcCM0Hm(K2xL)F=Y%O!r=988F{=W)2#e4wJcD&J zScc8u38;!_^i^@Ox}ihOX4nkk;^MH=IfmjJ^z7MdWW}9#`bX`{^-tTK>7TYXgC$!| z9e$|^b8apr$qf7xSUWf#TE|oX)?W}j)^t~B$#zZOe9PQ(g+-o<2 zF2D7*`SlQ`^$Qj)#wG@VxXeH53D5?u(b}XeShxrU)!$NjYyFT*y|qo7rsVCb8lGiz zY7D^$vH#WFTj$l=zuV^3&zpZca9vmr0ZqIsR!_rz=yzz5yu^H1#uP+)#h# ziWT*j4joq8tXcD7Q0ojvL0^cV+`)r~R7{(G?Ljd9G%)_zX3m08?fJKt)kB9D67mqJ zO+nKwr4&^4dWQ!`jvV#qO|xb_4Gp|_--e-HV^mzjhOy9nbtvFK;)z0qyppm!%+ zJ#qK+Yp<)FbMq}=&uw7OZ6NKo`s;6)`F6>TH~qPE?ycWT8K$>_6H(F~Bx$jB;*ypi zDczb1q1e7d$1xzuGW<^$nh+7)GY1YDbSwS_49LH_N6(&~&Rx261v}H4G-(n?9e-6} z+Sticr#^%#K@a>bG}1i7Fk-|ZFz}7;-KTG<+wJb>a5{~Yl+-4jyL25i2&&>5s)}1q zmxAi>s}KA6N0C}htr^$f@HWI~vZ$2+m6<(ym2b^AtJmILuYcCq{ffI+fY}v9IIv0LP_`jH@ zO`9gcSPyLo)Lfop4!QKwJ4DSS@KjcLYHDf%sPgmwq9&MEzij#P`o&9@f||=oRV)Kl zBYvwOAMx|8`Kfr|z}sv!+qP}n4b=p@{G(Rpn7#Y-87FEcK%8ZlL#NyRLKSLz5i2;% zlXxxOM3vB^)X|Vfm)EaYdDpM2NGh+X&o3yPZmS8gJsj1%ZQeZps8u;8j3RwRP3_Ix z9z6>GS5K1XKvjrO>Rhx(m)GC5YPGFugcohEuBivPMWALAs`T!;xie7B`M2L*kJGXi zFz0Auwr$t0ohYk)+OJ>#aS{IGMiNmL=F@P0in5q4TfU+mW}FlPcdl6ZE6T3HdibeT ztJZ0@Py6@pzYvv$j?O=7ZMN&@=FOWYiJsc2MIO)02%Vz!ya*j71{N(@g0mjd6fA8Wy=@K1-sVTiigvy-Mwz55r{y-2Ux zkpSKUr_{sj%#MUem8tgYue<(+tr6-@nL70lstdh{f0Vzo3HJOcq$W0g7^$irA;+K^u-x^TwNQI*n?=(BU7Y zI-B6Tr$x;q>PjIj{&1d}|Dz{GRa6DnSK`s-)U-lsLeH7QYBq{VNJy||&zbY%oLg?G zFZYkx+6g9TrU~Pmbr8NqaNrCGgH%?G-b*bQ4{@{RSt7=1N!KHMW`C)&ybopB(0@+Z|U5* z^|NNrhTj|*^lqhT-r^QlAgYyq;L? zrN9hl;q=on;~%vr)jw^cWlouT&3&Redbm9f{_&vFkGASzYG0^9t-Jf4di>&4^hNWvpnc@;?)tT0 zP52M36AN+9AaOEh&dv3cCQkhE(jkLW{@Lx4>}O#IVj8I~<}a)+s!X$N?tpRpV3|qKr{IioaXqRFTPFT)FLd%> z{zPm7PRXyj`f5LHPUVZr7KJs;Coj8@$`|tPnsw_UR6bwrNR`ps;$@Vfmw0C+8dvpkkhyNSzV(XNE zz?K-H=FQlfL8sg8a0|cZa8?2g-Cv1k{T0POl2eBaxpeNuYkPP7x+rb`TgQg?$t&+# zl|W9#g*8rLwWbzm+qo$$GB9?+{p;T_^jrVhfo;mijlXhvxY8Gj0C6$8bKO1b&r|%r zaWnM8;r(+G^>}xbmC=|D>kWU`!x^A7D&Eq6`BU-DS$Q-d zG2qvfMyyYYZW_<(9hSM zrb@UGxTGAyHNx;;tKH6xB8`PT($oalt@Ex#Yv={<^*%jl)ubMD%(mL4M z-3W8uE!WMs{{ERIH}04g&WNg|nI{Uz--^5LqDG8k znyl@AxpN}n?ILT~Zm$&5;6tdeIs1;y^cq)n?AWmbDso|ELS7JMFvTe@*21rNCEOFO ze_5HITC`}8Uuc$`*K{|gG?o-4#oxH2*&k)8&t1>*C7-*?l7nXu(N zZ`EpDGosJ=v3lVeLTBLYE!0**Js}E12eFfQibP@4IIO1N*=i1S1TXqmm251Bu5T^r z@?YpfIzW_Q`@!G&x?owT9pOBV^wNIP9U69O_^|MBoZoYhdg^%A5f&!+^q72wyC=IY zPCs3D*rY_S@btHIM13Rt2LXrr^*q=PhfCBAXJ<5Z$L3WIGonMbVi(~&?C>yf!j+Qi zi&0J-%0Xvh)WJfCv}*v`L4?hw_Eruz-otgsg|s_A%(UBeuZ!geO_u_NIdm8{($Z%g_=B8|4m%GX|pgv{o}rRqn5TshgnMMHS^27KOj;%=1)r z>+sYeNa2WH#i0n)_80AIg${)$eIEa@nF0UWsjJJAl9Dax8h$)a;fttwTiO3zX(uS` zzvN)^M$p5Dd$wp#stNng_(B5=eJ^h)&ur5s9bOWlMMq@1x}NgjU`#O%B2ypbQCBRt zQ*bclqf(4mEDxp2F>j({{oP*4@aMl`!8;4fhzR>iB*ylIDS5V{V4r{OtE#L z^t<43YLrr#zgVRPov#!s8l@EGBbCB@v46nP6jmzUf(Hm6!lvV_y&Lk3a(J1>kBXhI z+{GydL(hd3yEx_ieUGMzVrIuqovKKw4jnr_AWHqOik(-5;nf=DwJ4AIdmeSOQVlGa zxV{JLmXf_2dKu*~^Vsu$RqR(ib^))2Dd+EYG*c8~Z-G)U-QGWVh_1r(z4hP3*aZUr zx4q`?dbB+%6<=KZ*O0Ti8|4Lsg~4#W&e!eYLacb;uY{QBcYckEUeFL5n9z-F*}DOh z0%q?)qdWP_wRmw3`^{Rsuwuqv{aHslp}QJ@yP)QdkXA6GoCb@GYhhHlIW4WlQtU3= z85wI^wQ98i-kR9lrcK-Xu~EPS_=hg(*6qvSFPJj~~>SNeH}80=-|AF##`N@Obb4hah+lDvbH##)zDpoJapJjEf=| zK5GnydBD>DiXpotl2NUZ2d{Y@zF0=!o-nh5M)x+*@%$E8gR-i$qmLO`zvk#j;tvdW zwBv{%OSpYvq=+LTZ=5kK=v_8xnF;Zm*BO?HuLp0gG~B7)qnB^-l*hza*_Zy2(kq86 z&vU;wdYR@;5AX6Q!)2^@+?>5Jw@Ytd`z;Ddekp~wi|L>5@Kp~WU9j(^TRrNm%V?Td z{erm@i_$hjs*+=k;p2Vxd$qv(bSn8E=Pgd_V*a)Zq0y=Ly0_oOa``u5d%vxoz}{Hn z-_C}tXa`4(+PU6H&8TSI=RKtLT^2*BV9027s-ZEwz}of3CL}rWkWPIM>U099)=n;8 zKXyB@TCG#^pSm&LXy>Y{=>49yHzzo0h;{*|`;S`WW#4OKst_Gq(32FQlw9PRu&*b$ z2ECPIbv(EmsRkF1E6xO6MYks$`aN!IgRZlzzP04|3#w8QV@c^+JM?o*_j-;$;%e>MW8-k&vV@2|?A# z4UY5-DH4)8b}B)&0jO{*DHpo^OsDaxRgJS{hLj17R1{&=@kArtMMdgtqS4ev)GDr# zk)9(p*@V53#mvDm^p8xE2vB1hK}86OK+bUx2rDuXAle(nYs{2vrVvDs^TJ7-rJZA3 z08z;ZktK)|RC$M2pD&|?5hAND+-qvt1rT|R5Lx0=LaOA(#(8!~_=_wb%h3K^w$4m3 zk*C@@+H9IC?1hM`PbDWAO$&V7eB4|KK5j-*31p>s6jJgNq~rxPJ;})Fnn*3DZlO!J z*DBpEPjG5A`)n(<&lZqktanwO=0=i>=+$>gM(b1|X~jAOn!!5NPXGFct;pp-HD5Z zsb(B}L^G~i0zHCe>?Ow2|7PZ!WW?bg!Mmj6?iAx4C+LXKv5CGVpbLsAx1l9{P$z)) zRkg3jn{ncmf2+Np8J$#VGw=kteDku{l=fT~R6W2);zpu@st6n~1vA&d|e&CLlMuv%GYP#ESn{8p_ zQ+rz)!(B|1ZlrgRzE{{_KZ^gZ8VinxjIRx%iqk=EDarL=rwno>^|D+_QEoTYeTSK# zwq?azE+SGJTY~hSwsfWpmoChrrPD~Dk~2X1T#()}XWEkscc66nm&Mvhn#S5ts>f#E zJUxR=mrk5$52u)eEhSwY^Iw4yD008Y-kVbaoShYN-n{ zja_aou_@4GU`|NYuZ^)bqq@CjV4)rslm-bF_4xV*!*JQHovq{kknzQKp7CZ#JPU41E#qGoDm zTi}|ko{uc z^a0(;)?upK4s@!PD#3)_@scu1~ZB0v^$u<&PM5HJ}dm*1?ZirB=W`uC&6)oI~N7MJ_fbe-FyyTUus4gY- zv2aRB_?GU_df(_0A7>(|HayR6yi6A^TUbTQ_9me0W!*sbd~LXA1I-TWIGw<t?X_zcM*{?av-F7+tQgbT)HremTo;g0i+-A0n%^Rmfxf2q}DOrfn~9DN~x=8 z%tBgdFdH>Y?gd>daaYrO87T=2@^zmMKwR%41m={D(#NM9HVgC=fks9dkHE&=+c1=+Cl z{##>SXS+)8{uf^+S{r6j*J~BS9tVcziiE-!C?c#Yj&Jt_HV!k^8V%ovO2&H5aRxdL zHwqIIgLz|UreD3w3-aeqFebT5Ft`FRLGNWK*F@uiL~ECx^iO!I2OVW9RT4d!A10yO=R1CtGxOWSaGI@ZG9^|Ya` z4``z1ejAtGOp4+`Q`DAjm8&%k<0d8S20ekXm#B|lYow=oxk#u>0%(eHov}QFE`eHZ z5em@=Q9G|Q7P&MdsK%zTnp%Cf#aLt#`!+Kmq)ilgfEI zt@}@8w>@EZHMQd45`Ev=sMB-LLAko`dSgJM)n2bTf*sIxr>-|fw7+o0;zjWdmOn9nCwB!Sb^w1JM4K-EmcG3B zkKi>`0Qlf8n)QZH?~S$8Jgs+iUSx~QqGfwSvV*Nq_S{(@TVH}~2u>2dwZ<;9n~}!(v$q+O6Usm#U~G+m z&JH^*!%#ObZ_vY4hd0#5`A{F!?$lwt3}#b3&IhIS<@B4wcx;N|5wv;4QJV!hhqXe! zOKgQ^lz~DzkFCR2X!5~ug?gIAYuSsj*(SDmHD)11bM-P9*HLSTX1Z2q7a22Mx;Frd z0qXGyMy9J$dgQ)_s$JH=)CKCNB}U(l(z>68(E)1;68h&w*65hm(6j1EaGNSDhw1LR zrH19AyXwBB;1Xh>e!tXcmnyul7EIvcr5#*(Fa);4qrX3H(OOaBCNs~Yoh+<=W9Qw8raM)Q!Bu^#J!LK~#CQ&sDY zHrh7HX1YouZpW%V8;q7NuN3BD(Dl?9>lVK)W-FZ%fDGojZhWPerW>^(okR-x)a&)CF*Y`z3POEdM5>B68%;Ar-g(q-A@$tN zK&|T&riQZ;vv@8{DX)^SNaecXW+!~Fr&J}F@=Av;k8d&j@lx%#Nvy3~k3Js=rqmW#+fHK=%)Q{^xp^a`c0S%OvhJ9rk*3qohec>?df>IFdU~s{)=(qGs(>{w`yfs(r|8;PN%=0u#uMyNv4`F5k&- zGCm`#9RF;rjE;_bRML9Gl?hWg!h$H9mo;3^=un2X_Jc=^(W%}vV24q_vMr=Tl?qg= z-9|%eQ{jz8u}PmktBx%((yXe(d&oja$tRZIkQRWZEqD?1ATvY0v34f0;ON@*;5k)q7ywj8}n2_ZTS+-Rue5GgaAo zq!n*N9Gr?9q&}SONKCX^vU}uaR~HFE52m7rV%4_ijrIxIuW7SW?#?=>x(_qb%H!LX z7tQ|uk%O!I9)1yRoOxq)!DkDW7R68c1&1~0|0FtW^xiq(z>1=1Jn{(lA@Dm0{Az%o z?L&4{G2qppBgWz8Vcsjo>zU(+)C^1ZYfp~s^si5K@O&B_JnRzNMP_&HA_@*_DkDCQ zYp8a-U|gCQOb>Ta@*Bog%9Cm(smWg$@R;eT0Ywvbb*aIC$t>@fx~*qX<*Pl>mbX5C zwCAG@x)ct$b#V>mi$3|?zCpJxF4_ZSn2(9c>^(E)o!VZP9rvI=@OOLhi#;39crO?4 z=6~|Lo<)GIZqNm1xiRmpY4l7uKcttK()buP^oUW@EL7|QlANzk)aFzj^Qip&#$59q zJGefJb_u({c1c1H?GkjAZckr)5*Mcm4jMxfeHj;a$wy1TB_nF56}2w=SD|*v&9`}a z_Iz>6J~ZK#E4%c3srX!B)hE|b8yZx&z30Q9TvLN(cpv^f_hsDyPs;3do(s98xN!Tv zhX7kse2!eQx!uTp;rswob0L?chKfxfSyEE#*|cblN`DEO+fX}5K9BYYd%*TcUN7wt z^pu+WmxgZjPOUL2(cAih&e*csNHA93zX_8ygV$Y@#Ky-Q4H{T@^k{yiGruUauN+2PF|3D!e5;o)uq<6zbE zZJvFiVgG0F9?(Ay^aa?xVt!_uw!Omn!QkUL(cG9g3?%A`* zhOK*s9eVKAk{ZvI2kHKz*V=flxT8<8V~L;ajK<%$XINp?ttCZ8S01Fc70oZoPuQKl z6y~92u`4|r?%eKa)p9|xn*0X{oc>RI&AsXAXb-VRY!BtLhtPA{L$g1Ri&r(T8$%L( z?b$DVC-(R*mG>h@y1O6+(Z)W^Jzz+rd{fr-R{Swc|N2hzf{r#fQND^N7 zO4ePThi4{wGT+>yM-s2yXugWJoo%&kuPWl`03T@E6TSr7ulXa`?(G<5yBL2QpoUrgW>i-sqpQeEC#&`vIh=-c~jPI4a(&O2AqvwwLRUs#Y z7fyb{=XvIJkLP5;!a#~E*Z+nlXo3Bj!s9@cRmkat1UP9g6#QCiXZmn2awD8_H>Atr?t7|W>J<~i`d+z-ay7K>K z_m5w*FK|}c`55?HmJ*j6dbh)#X>$}*)3*HdQ^w1BX>q*Hctjohn=!?t6?N{%u*zCO zOQOqE!Y4+h%lFuIxc=N>Jhjo|4$S+zG2LOFi(Hgs{tXr-SQY?oreW$8HZF@AeP&#t z5*{_JxTP=#l@!w21eQgv+OZ$%Wl&d@G$1xjC3Q0LTzWqMRs(}vR@old#Q~|4GOAnZ z=i|Ogy+;*%S1*>VHzB2sh(t>kgt!G2NdCe|bilSneU&lQ{4P?}(yu^OQUlgcvlEK- z^2vv(ehGoDlFt}^7co`F_i^p?((Bk6c;_&SHo0~VcQnnI0Nxhew!<|zJjP1by2hwB zuO*GrxHFyOU2ZNHy6RQh7Q(9~XN|ELQY0kaHM}K2M%wq_yI(!F<(SJ8q zH@l2xp^zD_&U|OYnR0`R>RD|iUyAHPLnocph@*sP2vG? zXP7ok!|7WG+9d+LD@gBT9bRGfR?j2>U^zZl&Z*m`pCj+TPp3XkD>v)BRm~4Sx8w6n zSba`P6^Q-TD6+tgF;#t*>}ZtXW0rD%0_O>*4qgK_O=44f{1=p%YvQi&?_kfbpQLDdrAGG2;=q>ckbprT+KXBDWtsjzW}hUStVEn@+DNMZ6W2pu=m=N2D=AWC=pc*oa{gC8KVOwnJo5O8^<9oib1cQ-~e=Id9A2Hgt|G zAA^=hA$*({St5h9Q^!%OD8vNLi>x}1NNop&dlVvz^R_HTXghScM?ubUmv0MWh^}-B zccu{2gPa#((#CbAQ@BSVWLObdf*^wwhP#Of{qDQ4Cr{e-Oz*zSuw=jc{;(dVqWgnN z4#N^obt5sdT<{)tOGjt-_b`LQ+U3;S{WJaWy(gsj?)QLHDUuh`tsZbIaDBStAtQsX z0WSA~2!lLf0@K^Mwi+%fQ)6xf%LsY0m1CP>qCBa-vwvlN(<@9wxoktLk^db28h*^>MeE)iwDcqcHYEg0gWYXxtUrNM zS>$kwi$u?0f3yH5?rQ@{?>Ji+Zp;GFn5QWJsCNcndWR@d_;IiZoIt zG^7IXC9Im8=-T?ou^flt(yEQ=;z}`*3u>}lm3DJ{YOb)KX?!%mjH7Je?(U8QP7|$D z%gW73%5$}&B9PVFG0iLpvbV&0-W}R|QrQum6Z(i_Ru9In^aJm8(v|Gv)H@!$hAL0A zy(dLtm30-|3e4$G;fmK`o(oRUdBOy8^3f|&CU|0v${<$TUNO{>seFZwb1p5HzNtV~ zf$c>YHmIB`D0ciwzc2>=nxskxI=UB#!QucP&MASnIEMOh$crPSU!?Z0P7VYIbml0R zbShhL9crh;hl|93;5DdO!8~*TU57cqH(kRm!~}ktPocwQg7+e8R1*1+0|MZH7KTY8 zsmUNhf$bTAx4e#WSSw%10dG5VO`1b*yv1zVL0lmnxwI5%;8geOo8e&cC){Ery2}Lb+V7?4&;t@R2Xh97dp}c zSo;u9jYd@zIxJOsh2uMuG^B=uDDvHw9Mi4Zk8>O~WANb|JrJbEL)pWN%+`Uy;~m?b zCR$4^C;%~4DCAjX8A|aW;Bm~u~7by~wEG8i+tzHVGNJu0K1R7E>Ct_(r zbo!e{Vxgv7>qyU$*pbOiCC8F*A*VxN=vtlWTop4 zP-LCsFe3H%gIp#Ni1e8vOd#YnTJ4(HtLmw_@E0P|2tP|r$>%Ot26>C~(alH#S3*Sx zm(0vfl`zxM!Tl3Y&p8dw(W8=gE{-Soxo8TP$av(t1?~j4&vfiE+;|CfC$|U$d19hq za_$Z+xDkdllbF#!jtF(~HD^Yk$1EJkQ7p~UH+o{#=s!67MH}Z+JcD5)#VCn_6C4d> zB+k>Ds-&A?+0ljPahzJWX;p*sPys!rbCGCIw*n(un7a&Tn zO2A8CE4QqLI!{b+#syOkE)tR;@&yQSu_s(1 z%PqECJQC4}K%UeYg|vENF-*Nyu(Faa(fQz=kYY9Er*Mhr?kz{f#xFt3@iN@1M-#*@HO@vE zlm`>!eu>OAi4G4<7%xRak|#=WDt%#0%%}D)XC@R1o!~5{Cw_GN!+0qYk`pbsqmN?U zBQ}Mk$fQi@1Xs;C;-^M#g!!Hn2}v1~2voH05j!A4YoQaImvO{TO}_&+!lg(^(wKyx z>eMO|&b8noA*oB#h7nZdY{CgC7YRw(rVr@Y5`l_>?Ttv=g-&oK92>+>Z3osFQY0i2 zJ_J>VeP+6giuA0Js8ymLW{nbGGKvOIO`^CHU8KG^itvyMrVzybnF}H!^#nVDfaCt56>rLA&KlA&5NAi!2IqKxjM2yHSV| z&WkKTkal`)5rwGayvULe=a9yuOrj7$&WkMZl@52>&W%ExVoTZB>7fwLF_6=EWSC#DP*Yc&z=8B5nM6M~>$4+YUpmBJ6Jk3*iD z?o2ppBd-!BZ&P;bJ!4M2ck3Z7xB*fgGr34cJ!?IUXO%c+;w3PbTZDoilvC+a-mKGmTzurl4q(f zD;@djUMMwMjl>*5V_^MkI@JT-2DX3 z*0@MWyjwL1anZ9i_;?~M@X=H7M|a$OQ;10m;7@#c-o6(%N=ZA~21JC~`Me1mrO)7U z1?^D9`^`c4rl}c7>gzh4h0zT!qbI3m(_BUQ>?m=Z)l551sz0KK0@>8sA*C)tWqb%T z+}&(~q&sxp+J(B%5|T^A4qp}A3B2+lx(qMFT;_dH=Yt3dto#UF#zlfAzUT$wQt&qn z3KB&QK;pnRA7dfvgLC*d5(aWi(wj|l{^96l{(Kqqp1c3ySY99oivwud3hX6ze3N7$0bQ4I=wE)he#kD{)Lb?64X1hCw)_UJq@ z2^{?t-M~dc5=6eJCqh;7_hyEA@N>r>6Q)9|hGGj--L28p-XFrcHByPXHDnqXc^bCm zU8K1B@+(KaxgS2@#rT?}G9NNcweE}~k;($w&p3L*2Zc1Vr(JgOp0p<#`arz&5_)h* z{0_oo^by^(IQ2crCO(JylYh8GEc8B&cMi^XW~#e?fR16io;%56JYF)kK8P%D1-7~s@yNb`;aG`+B*Uk3{oT{)l8yUZM+Leq)13kFbP3b zn~^{wMM7eIp#>3CElG63D>_^xBw1f-5`l_idd7Yhu`Uui!IiPYh@bj0(diz?B|=fn zc|i*2@&Z9A$;Fy%SD#dhejO7`d|vNy!v~M5Lx0Y9d}e8 zOd*I$=^vPr)Q3jkO3XwGJ&hOk66u;qAA89Ci#;SJ>;6XKRrp5u3F@6Ztq#|~9&AMu zXG$)%D61^~J?vKGpY^*My*tXOH=ujm;P0?wrQ=tF&+Btfy|1TihQ4--(Yyt|_$HLn zS6eS2V&uIrJRF?v%!mC%7#?byI(szL60Ig}^|1$-VwXKAF$)jp17(7tGYG4f7QrWu zxDS^>4B@T_AeA6bg7w1TY>M-RcFaDN*-Ls254@OSKif00girACmf2?lTHlV+;`*wO zt}*8zxEK0+D*}N@hN<~7gO=z%j)sw z&ME2%znQ3-r8y^ylCi903LoY8m!xfov|fN(KyRlcysBTv_P&CzV{8BOQHH)faHJtx z(#}=gW_q~VDa^)RguD-IkuqJCv~ccH>jpcsah6${>4*qD=yAvvg|@})a>8C^H#_S8a{zy|!40mw)TsdR&o14F}vFpZ7bz>$f(G^RQO zFmHInFic}(HZlfzY0Umsfax{Zk-E{-TI$V+2_tpVdscNVz$o=tln(;^Q| zdmG7=ye}Sh`AT@7$*H{9zcTu`$~jgS=Gn1F!(z)&X>b^FA##`d(LiJ9L=P2JT=W zGStGlcLZURTLAFPQ(-_Rw1E#W5E*Kqr;~G=(cF$7Ca?ij3_wPxVq0}pmUFXuqc7AE z-?M3VGA;7Z%%^n*t?u1!^wI&q1UBG71|TD~aTnPCMHgqL(bCq232eYa3_wO&LPb|l zKivi}feqNj0A!>A8?r&A4?2PRe9xxc&9ulv(^lmG?H5@<%lB;BhnW_6XxgVQ0oors z11;aPX&+%)@e2!IJ}z>^F>MjFt)FZ!W3R1Dv< zX`f{(>8{>g7!>f zV>U5HZOKV?o4XWR5ofe>mm9iBI?V*&PQzN9YDI8Fv^+So@s6D7RHL? zB*gwSge10k2qfM(8YD86jZ%yf$xUs`zkC5KuNvx1agpWf>FXP(Z1lj=7o3^M&ddUH`dBhvX0;bj1-zTcIQXuZV*nCc-eZMZYpq^zEX^(V;X!=0aZU~V?| zKQUNTD9&xjouhRC8GhvL^kLIgGAz;1llngB;7m2(QKoq znJOCtIHt34e`cHrEhpTQV*r;h(wU=HUjfy_L^kLd4m=UMl0b*90Fe7~0NpnhKulzV z_Ay8#{(B+@!kc3Oq`y6!Vy3D`#{rTlZRE3z6tUkE^22d}oVNqSwHOW{CbB`#F-XMz zM4;2-0R&s9*(z%Uc!P;-(DMuuiOxx=U70r3`Ls)~RrWq;HgypMZ`J7a z6s{`qna2BbyklP?`So**m@3f^(#qZXL2cHR`Y=xHfc8VVmlwIR==F`SrA;>3Y?H;V zEW;x=B5={WWrh=8s+#U>*3}uYfHbt^^)aQa zNHt>nbmz&YT7aDIFuigf@GzWU7g1lAnBW9YKf1UH7 zFm&-k5mU|3IS8YF-8P7}JRA z!8P=X;I?H%hR(+WrictE269{tg);md<5T94t`ttGlYBAI;eFg)!;cE(@4D5Te%}2<5d0%0mU(1EIY3faF1*7JwfEhgo3Z7r^0p{QNg8@54`i!}1n> z?;FaO$N2Cg-%vq}h2Qsv=kcRn$YYd3eChM;C~w3#VeTST(kKQj2DgOrXmNNREe_A4 z!N4d4K#N0pJU$8>1%~qI;_$o{7`m?ohVm#doE|u$p&^0>5d@85bY2v6Q9cyq z4S_nm&h-(y5CeFE8Zb7QUaBw_PL>H*pb_NDu|NPWA_xhHjfsl_=zNGC^WpTUQpg}z zj8;($Y()8xJRmLC42I~w7z!wF4c7TsI5rsTR2aB05C2KN5#>V+Wz>*SLPiaGBm*9i z(Im7n+*I%8(l#p)&>pJ#X_m87E}p4qZP9F>oL1CS#O zeam&81gYz9cG`dByPU+76?z-vWdA9lH_Ds^5Ve;MXQwZRK-T992hF12Df z9;y-J88J8}rt}DUxz$Amr?}A&Bjmy8*BjyW z)l_wGp3`mOBQ*N+GCbVNc6eF%^AgZrZ;z+WcjiQm?pCmseq<==D(xQqC=P3?z{fRZ z;o%*?i~c$Xq!_{Y4}+-+Rb{AnF6hImg9o4|WlMWEzn*}puDTL59KE~Ac7T^0Kvjnf z;HEJ2t>LOeLHM9FO`V(%TjwphI6A2R+~J%oa;jMlraTKk{=mw&!ItC8VMph?nXkz4 zuG4a~0lgPMh~T=O!q$2brf9&3QvHA$OBAfWx^7wIJmqGr@UrgFyhwNT)1ok58P);j zbx@~Sd>RI&sP`;Yy2RNzg~{ysFp|@DH3*DXZ!dAaYf=$Sevw$UnF!C*|F+cmu1oVe zSnizRW=%vhs$sB%tW^aS&g<2i4;ZnII~%BbN?grUZ3RSm$nHa|E2gO1ZLUghJWP&o zgPryXO}c}tP?z=LJMY3mewlN4gORt~etpcmOf~9G=bDtTMKcDBjxl_f7l2wDlxc}wt598fiM^uDA2ZibFPFrp_^CKx0CtnMQrR@Kk*oz2v`70y%> z^9rADtCv?ev&&o0D5<&rkxm8Hfp_Q#rCCSbJ=AvAa|gS5XBHuk^q;pslmFV%q5*$? ztpM}AM*mP0{JHq>L$eZ~Iad^=0saQS{8+!9jrRI{M!{zI>C7`ktG-`&~Ct7qoly7v16 z_k8&jo$>W*`5glfjLLY)`|15hX8rg;?ROu|KeDXUJ;+mY|G;ggYSP5jq`bafpPPmX z%fBZbO?yH)8G&VZjb(T}spGoB?@|xee*KsC;eJKY@4Br%h~@CFg8mQx8+qBT+?$&? z=@>{X+Z^Ax@Uzuhp2X|Xy|?5)Hfn6m!8X(3euZ-Oi9M@IS2-)PKy?o9b6Z@>tOA6}be&tO47ndtu z_Le-fEipBFsw()OxJrwo$JIISl01IjZXL_;K>aQ&w zE#1%O>G>k3-utz#)=4R66nzBT}Zdkdo@=0S?w4{q0a!BJ(@Zcyd@ z9hd33-Rb_0E?Y)9(v)|wBSjtS?s_9zK*GfLfM!C%>>8amFs9b?vZ|foT8HQ8C-rju zm?4yc^zPJ1;;8oCZf;eh%Nz+RX{PJn8FEvI$xQSRic{C`b#8U#fxdb0_qJeL@`DoB zM=tFNdYcnD>sig2_u(PinSl<|IG~P?HB%hm&fMhqL3jf9O)krv3$qiNNzu3Nl*P%4 z^VScO)nA`=KGCj6$xSu4K02mm|Bf*=iESP%O8V|p;r8Ay6t>HLq44f6wj9V>?@&)Y z=WJ16by9`Cw5+21MeYM%Y*%}qUE1qVmzXCDHa7k}O$_!7@*jD-nPXtVgv=wK{qR8T zw~uTb*nUsUk#AM2fi2bH*{VkW z9)H1^0PhUaUy7qa`0Il(2>WOdKEZ=+*@r7>&`sO%3Z-RF=rs5@9)v%|n5FOX1tP;% z$u{hiLW3~np=#tloL5gQ38x2PDH0MNlW10REYt1g5~0}7c|zi6`R7rj?a*R~m--35 z?H?~i!o+$~lL#{kaQt8F$%yv>g-&oG=b)u?YT>OtD$*xn33Z6uWLT2v6UuO;7MIGv zFriAjR_MiFq!oVgo082Gf;h2LBZQNoar9}^NiC)jMD-&YA+jX+$m#kkdZrLW z-J`4(bDF?fF#^AdX9_`-?9m8Y7Dtke!dM9t zO+z1GbK8;;%lk>>I4xWyjHTLjE79ZhOU};jGx5}oTbu@W>3-B(jlCX?T3jNXr|)6B z1K(c5Nzku2zjI?YY#bmU8CwzZR3~AFJ5drxA8eWe_so|eq=M{(@VwVs5 z4&=x7M${pclSd%cQGlbJ`rr@F4({H(cO~g#T21d$s6CBv78i+O!9A$goY&!i6Z;YyY2mvEFy)!}gRZD+o_>T22=u_WEg8t+GSw7py;8V8?YP38O;%!eEOEVDpd zV92{@G#3dA@AI03SOtE14@tO4NGwzUxcU$pc<#?=Iq5`WD-s9hypM&bxH|i;tCxBC zA^1Z^Lryx!c6M3xXF_4z>7(9`HLrH8rg6u5lH1&bWa52dl1}%>{f_e1X^xq@Yh~OK zi1f-?Phk@ajXRVFHRb*UybpQ8@wmf9LgIT)lW0~n?r@1v)Q!=45i@-pj1&n;+7+6F znBm&bJ&sF+!pnIFiH}JH8e)C91FvzrF%wdu6Wo5r5kHmF5Lio*kkm1WK!FSW%XCBz z#6l-H-&I;`;-|JFYbg?vG7cz#hFH&v&|2sOSIs!$rxN2~_l%147%$WzZqLyr`T)mx z311l?s;6s3gUFo_7s^R%ZHEW*TeQcs_h!xVy;aJ5E=FhNk@ zY15fP5G9}9Kr%#@sHG7!Vl#yx&T(F3iRn5>$@C~h+G#CAWDzA)h^|7K-7tm7IKg?5 zB@IW*pxu!uM9EiLhRBlkpt~%xgDFHt))|cuS>h`~@^LXtA`su6?c^*GMvVsy(Ouec zoNqFPAj%%s2oXkA2M9tc`aqm11mSb)Zd+uDAsRt4m_iWyIWMxLy=tw-;K$oh2(QU9 zxLoYeEp{1B?3hAilyP2Ui42V(JE9Q{v<#6Y?Os<1A(%pBOyB`aWQhzy>fmJxLHGp0 zoTLZS-3|FF3L%4{$P({r1p3NEgx(mk*>i`ciD+X;2347u1=F6TiCJ_n6%n|0$kT-L z>14CB`z%j5ISsy`=Lg<{km?C1m&gpl_afe*3Fnz6=67z)0$;gJK*$p#J>hJVV#0)z z7}BH*5rKoLCd@KWYUG4d>=3)WQ)SHf`_Q) zRY5B=-+i$vO+ITV8hdYKjoA`uI?{PaNKikjreuL*AAOC2)8f?k zd)D(!)-ykaOGHiY>!^{dGpOmt%dp6{j_N!yv7f6Is=K%suAc91E_39wrDAyyXU^ED*dx+0$+TEJpgY5ZJ;3r~{q&Y1 zr@mvX{CkjM=;x);_>QI{ zegQbd5*8s`BqTmm0$5uJrSmHT-TRq_VUlvR>xu~N<755JPfaUwFORbHVQoUb2_M#? zk@hB8MZo7VuQi>x*uZ65M~NG0fa1M~&bnN+^1?w0`9mPO`*F9ysrS#U?)#_|bsJJ7 z7Fl>JaC8VpH&M}Y3UPtEhnicBxO4G(Fgl~=#+t1&^7wBtOK**HPk7ZNhRPNGF$z^N z3?8(?%d$1JEb}I6krRylv=;R`bXwL( zr@nhQsHPkNPthM45Qt2q^KMwKU;f}{a+HUPllwuu4|&4rWtkKSiFKWRRZz2{XL3>` zBqcFgA%f~>a#AED=a__`v>{k7MM9FrW(rhXtN+MAXo(|qf)n=$zYwl@#Hvf^7^i+n zG~!&uEbKuZyI7_NWt=uR<#MrKt44EMrm(f* zyvP#EHG(EaQHXP~T879Ht;i?(+g7F!8D5LEVoqYYM$iP0DFjgxrx7Ac>WL9}at>1n zqB21vM3#h}jz)Sa#}tC_C2EAo5?^WW(sYd}1R;$@WQh!oKwp{IoOrq>>^WMsBKkQV zH#X_feYw!+pykLv(ImoZxUZXy9)0oX^sjlk#%b^a-8FeX!mf$-2f0LgCf|qH3GHm- zf|Ho(8kovGLP4Im@N+!P38xcn5h*HGz;irLo0mo17|h4?S2M3P+*)+hKe+Nx)7TqFk3EqsIr-7rznP>V!- zxH_^5pS_ius208K#rjGY7*Wxnw{Ehyp_v%=_|6%lPPKHTxxeSpmQ&x~wW{9JtZIG= zmx!j`f8w3cXxkCYD~}S zEQZLyRrUOE-0DLNuiii9LMSd$3UZr)KxBnqA2s)uPUiJv|q zQHq45C3RDz~J|a=*1m|TOiO@$RN|BIAybx3$kw``SUJ)|T zM$v}33d5bPm<=W4*p~Vz}utsV(3n!^ba=W6JcbGyDd7Kwn5)<0t$+!;`g(%^? z$dW462--A@LR4~IWQkU~#%R!wLIgQ4vcz(YpjV2b5a&2AvLpaCf;JeV5LuUVv~#(% zRb7)~8W~M~!WRW(|aZ#-6N8nKii+e?pMLx0-6pBnC zc9d{lWRW%@1kNU-5S5%4S>mfQYEu+gQ3&a)MV8c{Mqrqjh~Rg;7%UB16VcpI`g)lv zS?6jZ-n$jP5n%|nP$27L_TY%briP(BW6V@{OoCoqOL}Y}<$Z5M%F`w;k|8{J9Bu`U zR>EKF=t|eXT<#GJ@)l!s|4~;QQ}GA2^?t{P3IF05DW>|}ZMuSYmY-7Xn>*7~-FUMX z9^Zf;0+^%(t?*GMo}Sn)u@k%s)g51lf`9R9t{>hf-nHGaJ>lQXxgI&gi{dE>CHm9C zEKJqeWv&$|Ok=;s{SDH>b3{64aTjiU!Lg0ko1ya~kO0iF0smnk$jCl?SLB(DnQC-Zm@p=^f!{F@8Acx0n5m}i3x$J7sFMyf_~yM5b&74OmV64wKhs$-jInwA#5|Cy2o__-c9qEHjQLl~Q zSj}dxYZe(Xk8jLPS5L2WSOwDD?dIQFzoIPNf;4;SkRnGsIb|~o{`?YeTXE`rM>l-y zJ-gvcku+|7>-=*z&$;v++QmXPc+e)k0Ew(={p9lEUNwHjd0RPMf(xU+)Ev#**|@od zUusJJzxh%VziN{&zJB3D&GO&)QWMskP2@vMd_o_dkNk+v6%+Xpohv5tBRc(|W;h-{ z%LB_p0wO=6)8Dj(-;eyJO@E^ny8l0Y>6wNuy3nVd_?K>*$I&Ni_@O6eo0k99x1PWC zT_5g=Axn{nyOxo8%!S{N_!hJrT#8N(CqO5M=YRcM(C7~fLB7Uc)VHBfSpxWtk3%o| z+fdC9Dv`gY75?%aq2zt^ogpZ2p>I3G!!i~>CIupis@SNojExG*So(fAoF2n6JRge6 za_sA(zr~FH)H0Sol@tZ^*RN1T{B36=a(H;2>)5`}RczBE|H$q_ZRFn;Rs;dcEf96F8912Fd8v<1~C3zJT4O&>qAXLSiNI{ zhX6lf!l0vKMvuVV`&J*D%(f1oD#1gayK zh#B6GH3c>p`(JHmRsMtHvOwa;rq>w26oRn+&N7&jMoosT$=V|}hZxMi`qIYStSvp@ zBb>GB@F!+h*E-{an04yxCuTeK(cc_tjUfkZ#)SW3V(`wX^^P_fmcesrOQ*q={MWbX z?{nks9nE1&#PbF1E>BOh)qXQ%W`aQy}AFn=F>e5YE$=&wz}JZL$VThHy=`?sFjHVw;S8VIf?T zZTrGJCI_^ccv~MCf^6O8&|m-bRXq#LItrU7%O0Qe_q?6qX6h<+hMR5&a`J>eN@}2sek3gcXG-=s*D( zfa9d`FN#vwVpHnH)G;xc#SklS)Z*HgVq&%o+8C4h^0N9FgHOcHd+Cad-Gj0qlyc#R zBko$2`!&o$2Y>Sah0gkXX<<2?|Hxf`+a{d&Yb(4 zI(6#Qsp{(K?%JNr6LPy}FUkNpbAB*$j~X2mYGCeNkllw*!57O9q~y&;p&U)}>oZ8S z{*Ck-f68te_;~iZ!8Iah3|Z2>m9ycC%%XngP&J2cjCT;(8GT5bE8(=e2P~KCT=Vkk z+D^Uvj7H7NdJdI+mxhPG(g)o4`XI(%rf8K(Uf>%P@fFrs`2@qaDNB5-s!JVbO>WL9 zybd|hdA%q*$C)xK3!8#3x^F{h)s#zKp!)%=r^9`+4nX z_K7v~FyUxHt}aCdnfF}F1*inh3(%fA7M1u#7{zP7lwX z4Cj{bGFxQq;quVX>HlYTBmb)z?J{2FLekXP+xu9*^X+$;xfwBus@AK?VWo{XtQ+pk z2>2zZ>gC!y|IN#_snajlmLXJsWTe+&bDqlA_w3BIfx4?8@7DfnirN66dH9G)0>KTD6h-_RxJ9^H;0wtw@;Q`>%v z-M-`31q}uvh(Y&U>}$Pcc+{gc)muf>j%wje{hg5s~mrmoSE7D!oA=3zkk7^?ZuPc>%aY9y$96m z)^HGe!+$3`-5dBvW^p1_Y%ti9-A~;9gRSe8kyg>8H`ASY) zzF$_H#J30W>|$dR|L6v~hPjJfNI7M@x5yZ9Q(mF%r6skmz^IH#l{QhXWM6?%8I$~5 zRXkEv?JF=UV-nUTQdRw}uTdG3B5fj7`M19KyJM{~CS_Wds`AIa&5g>KRB98c$_)d} znpsXvHl?O>2o~AQtGcl-)t%PO{Y|@=Y$xw@>g=o0#8yz9n0)$ITZgrUsZpwBH4T7%$ZuxrJ`ksMfM+OMEA5$SriMMsS`QEz_2XO65b{Lf0myBQY(T z#!S~$6?vR*)u_<2X-qnRuyiB5>2B4i(z0nQsMD(^mE3fUhN{7B33iP#UBk2`@uTN5?bOB+s||BFo3K)gfO174|t3d~!?9A1A zsneY_oiMpdpTx4Op})FI7tlQXw~8!~akJ@%QJG++NdIB7GL!pqtf;p&&{yiV2K)l0 z4$K59YcV<;(;YBVENvQ~T*lA2s|&VY?0r{#o6#&8syg&R8}}%-RLL8)Cm=*W~ww^)v8&;ZA&CXwq-PT|XyZtjD81ut2T!RktY~jwzmh zhnBy`_XZ9^n+5oD8SH)NgP+0%9xaD z6Xi;NzQm}ENkW@QRrT{FMrBNbx+7B6**X(n5sb>16lxQx>KvhoQ5ln%Hj%1MNB)AN zQ5lm8Z6a0G4hEw#CRN%*sycVUi(gdgdxTg!`=IS&vTja7MS2v>x-2Q-WRWb(DMeeD z8f98Go=oO~3_+bztQwVCHf@E%A-0R1JCZt1V1a5iOgxOjIf% zvZcVPQL1Irmg%{wA>W6r8VN0%wj>%vrE19cA*)8UmXmFz%_{jmWYs9VUG?0wWpX7M zP=Ab~Elkg2S~hJ3bQ^lm`Nu(4jS4L%+e)i3f?tQM8dX|0ZAEmADmCW(;$hV=N4057 z;zzDj4emk6=5f!j5e*vXx)O2HMm;3gi-I|!h2OnM?o62JYSNQ76mTJfnfw8gY{$LX z-=NF?@(Uyl^p^|68|kI_IIfBEj=+#zxw@+%2oKo*-7kc+KTr0P z@ecTE+4^J?R)mQHXEUK`#j zKdYTHdyc=eKX9WLTumKZHt%4lM2%1n>BCniAJS{1FX?1|hS-Eemn9-i_y0A`%W~YOWGcbq2g>a{>}UKmpPs1;!XFFftfverT)-NH6}wqS4ujm zt(};L7mb#;TerK+w_X#kYbHI_(4I_K#p0=Udw8n6A1@_q z*FUSLdM&rMOx9e{|6S>biDjwOY;inlR;~8ut2@C_!6VAi*ll!V|CoZVm~^yUcg;lhs5rW%GaQ8>E!oay=R4qb9Yzfb9e>`1h|SFEFoZ9HdTnbi^l{ z=JaPyhp{K-$>}hxPm|^}XwJ52--6gT=f$|cLzlo4)_chZsH@YM=HaIL)YP1(HCf*S z>u~~vhl&Kx+Q}24u{0;OfYiWy$zOK5?eI772iBt{eGY7pk(VvSavjSi)Jw+)?(|>j z{IU~=UuYuE3ww6@yZHm_lJ(r|(vDV~id3r6O46_)ee0DN5akG)v@zqKy_A(+SV|Mk8A{bKR|*2aLe zjRxuOX#Rh-9fdC*kN&&uD4ccp$LIKFtHeLG871Y#;%p8P>437iwIWUaM>eBGeS!bh zZj_Xa{O{jX{@>n=qFzpq7i*hIqBhf{$|?h1xypbitGybYtUP$K+N$BnYO97PV-E4f z+MXi)J>B+ux$W0#C+En2@mg-P0-6=itblU20CS8hV{18Iq+Vj7KrT4I)#cEkUH(p8 z0)6pKR?kbe8z^~4eUH*S(LybMiS}ms>lb-mU6zI0?v=l;h;3HCXKtSKF}&3fOjWZU z##+(ElHL9f{DEo7%K<);Jf0;8!dQme=tgzpGD&7X>0GkMzsnz(o~+AvWcSgwrf#5} zsw=G}JH`zVkEL&jn0@mLW<$ic&W@A)9gq3Y_gxkV%{kNSXEb*9@AhXqWv}@=*J9sD zf&R(HXJZX-rW-SjOP0{6bimp1x_@ql&sh@8Z0d~P>+j(Y3}9__4r!>r+mfqm8bRus z=EjLU-QK#-uYUEAKYCI#PjV{5Ah-G0G;i}YIQHIo%{WDr}%f`2eEU| z?b!n*`S{3k>W=ph$>tp?xo@aXw`muu=(;)G%GKzKtvMaK^MDLInSPcH4AS=!HIH@B zqt=zZVut!v=*!LO(mpadVo&}1X=bXLF$j003;BWM-dQ<)o#!%gaQ%65a@;s+n$ad@ z!UZ}hS$sLIvvP3#*&|s)Mp|2#RuY|64b|Fv**P3(nKU!}IR*Z}N!~~|(j!f-Mp}>> z>8OnKs+=4>()c-|nyqD|bpy!;7o8-t_G51${ZXsp}XY zF=iLtmf-*WySZB}3E`{%oBn)%pr_Y`X}_tq$@vZDI)BB>gmPb0cJfFGyOi>lZfEi_ zIisD2Zq4f1U{5buWz5nbfygy^HbYFg=en&Xv)4^`<2rwATpt`Vyi&%N58jGhQY)u( zwxAuga?XlQ>M%9_=#>Zhy)fgs?VPDcZ+mfjonfWhZ(1^L0Oh^cPTn>yaqWN``#c~| zx2fa56>nWAPq)XQ{x7KWHSDNg4PSYve+lYP-U+`q!q?5J{_Jo5xNpb6d;1KU-Y$kC z15dY4t#~=U^Y&)_XWsH$e+1EgaP1E9Mho8D{`EcM;s_%C$H_akjlHXEz)OQ4*p471 zNO4^6!a)dP(3$rg6Cbc-%Jv;~bGMB@XV}K#vmfa9<~f&azvk7h62PbBFAZ84z2f;V zIzF~@3EsGUSN2Oge|db$;PEAE2gUUpw@vi`-hu| z{KJq5+eUT1X26lDThfwn-NV&8(1`(`@4P*JX7rxai4j=KVj*kpDCvx}pw!@pm z;Um6&?)GgP8b31N^qE_>!$-0Y3-f;+2p<^(oddt*9F})(x9o9w%k4`(`la8f%j(5f zeSB7&ePn<6ukY0_s#kjQsP`VV^9|dtmwy<_&d#oN(Ye@gft5BekPmcrG|DN?T-@2o z=#X)yb5G-(;k62H>LXJ)P|e?}$GwKePM!Q5f3}D_s`H97i*d&tyWHCI_a6@A=ZtQ4 z6qZqV{6q1C-jgkyJAx;1qtS5LXynvslH+fnE6hR|_^&ED9h>AlTPxg69YBGTz&UG& zIv@X@S40P=$uBlE&<5DvuIh?m-DWxKviK!_N3)!#{ikiA(IA zDXn!}BWlzbiuFDxR^(rb6HmzrnX6R8ZoL}*Y$~0)ZFAcCRkeX#YSj0OM`uJ^1pF4> z%0E3?!AlOpvNWI zN1f|TPA&Z7;t~RvDdM#5kTWuS53ZY??z?k(I_o>+jLIyLnbgnudv{Jwc5h^=d_*wk zN^B-0c1E0+GdlYk?CCE*Ff-6ML!dL^q?{qy?-5fZBZo<~L^R>M(D9I5npj*eNe?mojLsG}Dm|W??3YzMeVw1z<(!{+PilHzqnjn`b4CXmG*(}Icx1-7 zsI$m9(g)E6CVJ^2bk}jc^2gi$Qcnw&Ti24arhHDt#8WcoXt3$34L=_>pS{#`b#0( zX7J9Dou=-AzFdK%t~AX)IcqA>v~i8lV^S_nv#-vM7ff~4wTRcYGA^zyKjXY5Av zwe@%wXWpAOwLXF0@;P5}Ec4UHGR7jc*vU|C++q%A8A)1mB<~&?J^(|We?L_`@tNYW zFBA_~>GH31`PaJqTV4J=ILEKPUtFmXN=ZY|O9PuwBa~7eka8IUHtlSD7HOF2jS!(D z6Mzw6U#%&gev}KQ6w4qmP&GzUTaA$v%NQ_zHAYgb#vmr;(m4C&$QY!QhgCVJ0Q>9g z7@RgcgHkN5OB&|ot4|q`QnS5^D^&CJtU97wI0Uf(uXm?A|8^X zvt=07df^?BH0L;;?zH+LXXMbt4>0G!_>vG>l_>+T? zp43=e?~Mha8Vfey9N3DuOfhG?luJ6;Fv~CTM^X#~J2D)MNToZaJS+}mI2frjusXeg zpepBZum|dBp5etu=t%qQnA19>M@vl=DV4_AT{TstvYIMVENx2`WKWM{lk{Z7jyZ}aautu|DIPvX zm)FwewRL$NU0x4dAC7dT#~`I25$T7dfo*WX9i5$09+q;+1KU=|b4qzom2(UjlQSYi zFPVDEORTs4~HAYe_jk9Cwcr~>-!&EsNXNT3Ano=H-a%o)> zvGLTj<25YBGKQTwh67K}?d`nLGWWvF)v3p01Gp}q-YS>hJ&E->agujVBvjw8dL{j2 zc7mTZ+K+tsY)C(AI^|+{Zkj$H5-d{7vv^fsD8#F*&op&0UkxpjrBq57R)M%EYTmnS>`( zp5~nLcMlDWe_dvKVuIqaNs5OrRXlLHE|2K)D|Go(U4AvVS_8$EGvcO>YTd`mA&z$ImfrH zQ+ao8(a_j*m~%gzVcRLjb5ELYwMRpX3aO`M}%^)RuT*6fvX z|A$u|Bvz+Q_Et^Il=6rw=fsjM$i({7s~;eCWMZAF$Fex{@zgoB5^nX9G2=^~5?ZDY zW|#(Q$&kTRONKX?G2^3}Th0bTx(E`J1EpAzUw z4P>N?$~Be%LX``)po*{Wo-8I*Bf*B%h0p#|k|Px(Rztyn97)vyuRK7khJt~rH6o=v zCgm~{*a7vW*_0zXRm_oKzm)rfDej3?^X#u0>6G%Il*>GnJdEH?kk52|xF=KtIYbZS zDNe~BxrLceq#l%y!gYD~KY45?h@F8CrhU`6Ecs329PI^nv2p_!XRgy;)Ypx*bTc6k zfSVYxGkv{wvv0lmo*}mi3zJ^HuLm#dQ)kxWbh4yAorH>}WwZ0b*z03py4x6}>J^rI#f`0|m~Aj)99ZH>4(JJ-r<17{F>Z z4H00PnmcL<7U`>p%Nd;dPDZHisL`Iw)#=Xn9di79=@8zz(<9JhXlw&&a^ZSP@xUg< z6Pp!}mFx1Yy8KyPzD<{J2UiOhJ*f%(r8ne+YR0eu^@ZnT_;IvT$78jlgH#@Q?7{d-*w?}X}DWoOm8 z)v6$QFh+>g!753R+jdf}R$VEUWoxD$)Z)yIsguivSG{btJ3D}7YkK;qhH0QK-egeK znavwinmap&2e54Ige8})=M|5=sCf8g#RI!^`EFglN0+~*%MW+Nw3C}_;!2Iv>T~gj z*XqkffLP^%O{k0cHC}m`SmlCE>$?H#Jc9_a8VkmxlDR&moLG$oV|Dfo#MOS(Ykxej zYM)(DE6)V4JV>nCXV=tsCn;BBA;t3Dh&@&d+eEK=fLOIInUH%jDdjOKm$6*kP931V zoB%MVQCVV)p%CVZg}^BrH9C1=hFxkIy(KCZb6KAzS-)VlQ}oz%Tr z)-7Un`&}l0S}bG&$m4)b^dn2oeMMMuHl0 z>VjX~sN{HVPEES`?j^W+HZ3_BC&15=mnAvG>ZzajQOOZMa<&?h^wZ)E_}P}4oGiN8 z@rERaSS9BQFFAxNIp-wZobwUfJeQgrKiwSpNRmUWk|SR`!r!eW}mMXZ}o|>E- zx@mn#l0&SLBW_f3#7*}f1B3mE`uwZAjiniQ(EB6&#Q9hHwE~lHaAR?-nl=XqIUa`N zeS1Fz`bLd@h<->P)OLJ`%zvrxP|AmF%8h+Y+Z#WDk}KtfEj%gH-jo~rz+@GN_JggF zdM~D_U<^!!psrvXnXQz@-jpZpZ=0>QIOuwToH5C73DN;wuIxMLj36_{QQ)PCvX##? zpfa}a=Rke@8K3t3hB6sE5F0e`$UXMhBbJl!f4Bw>r~ejMhV4cyKaiI+kw zAWwoMu)yysFyYReqk(4G)JUSlnS>R--U~~xPE~z2*FBI|oc97ks_M=L(n2~ryFoG{ zRV=wme6Ly+?(BO2AyK1pRnVKDj*L-kjeA3LE(4IXt2Od59fza-^7KQNZ;?9%x^IAJ&MrUqP+jch8 z!;6Ky-eaBfsdw*z>v!~-ck}U(--~kTCwg+g*)cn#A$K&LmuJ$F>8v>&KVu4AxP_z! zcC6=iLp_~3gyEZ(Sw5&y-p;IO<`2d0-jM-!+Nv8ugBNx<{J6P<#HZI_XSKknNZsvP$&uQfI zy|A*L`%&fGP+`+qN!{&zN4b%yi=&}B(>e?^hSzR>+MP1}i}*Psj!)`dJ+Z`nBN%Xf zbG-nc$lT=KnDs^c=owysf4wux{p_~Ip=}W_z=H1e-HU&k8>;iy&B*{qw<>Y>o*Z!Z z#~5H#ML42fefRzE=7y@Wya=0CjB+R6x;WJ13NOGuKR)fwJnoD5w6nYbmtR%lR{oLe zmR#utI3u*lUGVtl@m52;0E^GN#65WL;?VwyUVyuzPt| zH_8ieMqUH=%_j3gfw#Q?Pkr(dcl`Rrp;=?S0QX$I$&F3ZaVfMC7Zt3rz#Ulk?fKQz<+WmOf;!yA+FTkn?8@MBS%?r8ZUVxk4D{=Qfnd`;| zc>(6kZ{WVsZC!6%DD=Zx?Iys>3NclfY*q2a5&0B>r%#636{LlW)e zMd7YaV&ML6b>(eCK?7l(G9=LLAlSDW0swtg1R?BNBtY4Q^Ht6{nB-dbLO zD^A($u089s_=e72fcrvY-1mQ89GZ5P4v@$DF?Tm~&z?9hv_IxWIQW7kZq-G(ZdrXV zz;?45y049%7phq71^8X-G480ti$hhzya3w;H@lBa_$=P8s~6zE9$4ZYX_f1a|7B+K zP#k;x=BT^n$4}#L9q&araoZU8onwka%ZGX?EN#@t9ac0iG;O*UV9jMq+^;+3x&?pC zOdb(ier@RPxprPCe1jL@?0d(!7v&U(YMkx``0b^e-KXcdJ&$se~J6!PdV=4 zkG%*xJiXa{_U=#P)vde$e>!EX`)2FnP{jZ*z>Z5Bx#7k0LcUR6fN$?bkN?hb6Q6kj zo_<{;_vP5UP~|usU=+(^-Q&i(Bbyb6x()Oq-2C8Xw_@X`@u_XR0Bg5c>i(9k$sjMlduuOsqt$QbxP`BJ z5x)0bBlo5I=7l0*FNOCnAM1`dsW^0AA1}aJ2R6GeUi@jiq?s4s+m|eL|F|c|t+T-k za7))M?w+p?#zPIg02`e+&VBvt;*hULhiLL-GHhXEcgQpILajP^5neWIseAO%9Jgw- z7vL3FGqS`h*f@93q~cJ!u3id1&dzrS@0}OgP~Qvi#M_s;zF8QO`@8^u z{k*ZebN9Ru{+c~GF?ZZC&K)+kIJD|SFTmPkwz%&^*B*>l*6|{|{N1H)_Rt)++Z+?2 z&v*J`TilQP9E`{Eya0P1Ki=JaV{s@P^a8wQcD@_>VqPfp$4$vY?AMo>_>+`w&K zfD0$&yW98A3*~3t9EzG#@A>+SKo zZpaI;-&@DI&$gK#N<8ZYn03h2Ndl z)=ObzO}Sg+!~OC6AG`o>XfV;;xvw}>S;q@-vQ~J*j&A!hIuu&X6UhQ|o9lZc| zpWDRUQZPRn8vl?N;qsp+xS>78q2cws2!CBt?&kckKfd@!FTmk7m%GiT_+4L3FTn1f zl)H`Q?T`2U#tSe|GSPLvEDrrq!wYcGS54d=Bj<KpHYKbE;oXZYR9x?Y5% zUuoiQI%j^UYLOS<@zW=|0}d94uC3_>=)PX=)?c+h{?xZ#fXAJ=+-=*>@0R>@eezH| z+N{ED+IfF`{1;w;tD?tDa-aRPIMmATMfldGP2Fx+%nz-;#!F$@smtBgVZR$WdVTVU z`1Z7>?#9XULq*qn0hWI=(d}Pd94gK60$fn5!p$GFKmN{_UVsN~Tkf{6>vyBAKJp@T zM^(7Nw?2vAy5Ebi(`}R7XX=-PhWzav+m{|_>UNnuKh&+z3vgP|a<^SGzgvCK3oyE~ zsk{EB`JupAFTgV*liWVFOG3~1BtZ53@7%L0-1c965y!8+?|T7m%be_%cPt4-e)9tSVRSRM^UC=lH{=C)%9iEs35T=Y*ehOub^1q} zx$8>ihe}WLB7Eo5Np3;AlFv@0|+w z)OMf5_q^o=c+M@8-7N!3LW_R%0-RUb%zfE?Zx}YTV)VE%Q4M#S2gFEMkD(iXy?(V+AJ-Ia7ExX4H@Wh_Y-Lh@- zLlup^0DpUbvfFcbNhtWe7vS3Lt?uB1AIBqmy#O<#E23_n3EA%Ws2AaZ5nJ7nGd_+t z*yW}0s_QRxH(ps1dh1Isz(-$i?jBz`KQ!&=jmbl7$u;QlR1C>{FFJ~QpINs}d zFTlSJU+S)(QxZCQzzeY8tQKzD@8*Z94|)NPTDQXO8_ISQSLp!x{qMZaE!+pHkm{-% zlgDD7&s~ao`Rd4kI zJayM)?g?cjp^A6C0C)es)xGA{kK(^nm;mwpukFm0?%5l&+|{kU2(!<4#=W7zNAU+X zdMR8#>2mjx=SxD9_j&<-_FPN1S+@nD4fl8fZn|uxd)Brrx2S^`V9xz5-Fr@05Q;tE z1-NI({v{?jHxpYNNeSGwoU&vLuf@B(~g!87j7+dhmZ z9`^zaeR8?`@Ovep*lsVtn|il$o1C^FR50HQ@Lvz1!zEd6pw9K)_rGOLTDf7crFT%kGSGvO|XSt=-Gm=L{`<1QS(hC=a z%C7SQ{Ju}bZTnS8sLe}WfNeHE7~E6;3__rP&c-l+58p1-+qcc$E^!@d7| zUzB%;@a7=@l>tkxwB*F97o%yDtim!Vv*c1sj#+Y%B}Xi|(2~QeqUjMASO!5$&bQ=% zC0E~-?yt&{D=j$@wGB1?`~a-k(h!KP$aFY{?at zoS&U;Um$Wy0Ab6Z$dY50Tw%$TmYnZTZ?Mdg6Ohx+|5cra%A;>HhQU{EPLsoyTxiKf zmRxGdWtLp=%FSx)i)k=n8B|(wl_ghOa^=hE{;DiFl1MKvN<`BYG0ULLk}E7ZVaZjN zTy4quyVBbWMlD65B}Xi|)RHSKxzduWEV*!ZdH~Ugr6{%Jz$@t$!j_z{?8b~2dyMV1`1>q3TxiJ=OD?kHm?f8{$ZX$NmZG3sVaW+guC(MTORl!$ zKz%C%o-FPAf}Voy`wA>MY{`X|9I@mgOO9D`X;N10`^u6EY2R02$q7rYwB#yFuD0Yr z11keY*6sU(MxomG6!N6P8?Q$yJtIZOMT~Rt7{)2_R@0 z6j*ZDk_#<4V#!689JAz7$Z6;QGRvUCk`tC(X~|WVTy4pL##ROz&q+Ty1TBNomgyDB zEV;sx6P8?Q$yJtI{Y^BSb|De`HeD{W-6%XHtBLKO~&C@nx??n(2^@Hxyq8OZMj`~gMs$xa`5;Rnd^T+sseJ@k_#<4V#$>q zQXHawl_ghOav!zS82&rmRxPgffZH;EIDY& z1zPsb|CT|aB}Xi|$dY50Tx!W>mRzA^@BE*z3@RdQ}8_=1*PV98-iF0|x`B^Oz8EKSDYSDL24^}i)oSaQOWD=oRolB+E_a9T5H%;j{1N>&0Px0zAnO42i4r#q{^!V zN}PfuPC*i@*QL5_4@&|3QBh9G4q zdxI2|Z9xjkjv!T?dx3O0cj+i7JAkyQ($cF}E*pMSeNjrIUa{=&QN8ER9u=J+$%E|X zQQm{xC!-tkV4;GN9hS@BiB2*qNct{F`YuSq5Tx4ipzOzSq?|i%REx3+M-3Nu!>DvC z#6?QB+^AlNQd$%wEqaEsw??^?Z8Zw!bAyY5K@S!Rlqn)ex+X~63z9Gescv{sHp!@n zxf@0$Mi4A9m69#WW*C)sPboWKbVS_jqM+=1QQhQ*7p0WFE(*#v7X@X9i)x-*NmRlV zl7tDA9to1c5+r>SB&ic5y%eN+=|S12!WNrlbH9daJKuvr4;FYZ?7>2Tl4PaiO!A6j z0wqpm$a9w?Toha#w|p(}O_|7I-l1!9sx&r&2ObuQ(=9;#7u= zQ;@_dNa7SEaSBp#dQkR!s5rUzLC5LApa%;)81`VHK#5Z+8K+kq6DV;iL&hmc;uIut z3X(VlsW?3-J2Owy9jLy+I5XVhb}Q_;Ygrw@L=CLR0za92@c)|rO}j& zfw&F8*)`Ung%=u>#~M;9H3TiZAgN=!sxI3VB<(6YwjpTBC?GzFR}l!xV;h1No}WbY zCpw8rkVK{Ik~JhMrDH6DBnPSnV-X~=C_BcYO4&<3^moLIpoMIg5B^mS_(a~390(FS zh3G|)FKPKruG79@_98HZPpBwV49rYgr-sgh2lKcbWT2tvv+Oqn1_nL?bSs+2iXx}+D$lqyZyNvinhRHaIgq)L!P zrAm36Dnx&RBq~7?l`3Uaf+Q-1*qSP3R7#ihA{i2$#HSEv5+As#<3%BQ5hQDn($R|` z@ghjP2$H_>A*af-AnB1H$+JTAB1n29NO~kl`k@db5F`;OU9zsUD>`YHk0MpOf}~wR z(ykzBO^~#vN|`@F(yl^mSCuk8uNzVmI1cD?2KHOCKQ%Kf-(b1n=yGcLPRUG{Z z5`TikpR!BVkh#I9m}-6C^Gip(@WG>+_kzTWAn_tdjsRsxe|!|F>I#yW`EX9nL_yM; zAjzL9;1lwGoh#K#9)Dn3CHpCE}(l`=ks z=vk1&CrIK`rHoII#HSEjQ>Bbg>5^U~KG8{h$}U+$;#2o4xc;fT6r7WSBtBKj_!OdN zK@y)JiBFX>K0y+n(lIKzKPqQFK@yc9iAvo)WmJMBDn1%gSra5#6C_coQbwf^qY@-h z36iK(DWei3Q7OdM6uQx%Dg4GLx{gVtz8xw!D zO$B*tRL~SQsZi3V+(RuD<=Uj7y0I!sxhX72!W5*!RCR_kH69G`8Hux&+I$ZN1*%9r z7&Z`ZT9sNe5S}0jRM4)ZP8uy$hD@g_W{(6(oPs1yWhZyJ1L z@+6<46j&foZeI&JqbOO2ZHrEZQXxj6YOuvp1(QmNyh4<_n0G-_t~W@MEl*mUL&;)9 z(JWh@J)l@46{ILtkRA*R>?nh-YB6tuBuqh)OV3aql{jk|rYO%~ZFxT8NHUcrj|V|~ zu+fePPkPS4!xcVy zI^!j%1@a=)HojBAduKZD%+KpJZ~*W?t=|g!XFxt*8(#@NmuQ@W=5rYW^o#LXtn~%p zy`6mv@w}!lU_WPHabA6=`p&$X(Mus;rp*GVdW^0<4Z7)Ce*${sK2KxWGHKeg*hSjUNJkSmSQs-8DW6{yScG z8!gWBcYF)N+qz&L_-z_jgTn~_+W7Y1^Ht{nVs8E(;QQ1KA}t1kuEgYMcnf8}a#+GacTY(%bTC zHlG6d3KpSkBqmdHjoI5roPn4XbuR?GNUJ{s|J+%E*6MBpd`_#EfG>5uMn^PSenQ{CfJDu$pQ?6h8j zA^#lk3lOar;L~KAQ}=SJp`V$Cm74C=?^P;F=EYtFV0+=y^2rHT;d<_`J=|1 zYL3RUz@r);1~)dGvX5!~a&Tim3>ZHYkAH3CFndGeB5=goMheE`a}tO$kAucKpr4@m z)ycRmul~UKfXpRLnxVL*Hu()2PIc-(#OEg(bGE;u@l5a=oOO%xT2A0JZL6zthJT<< z)`LH(ajO)YL(qMt^_Aepej>1mxFv8a5JULI8B>zi*a={@YTg2VOqc~I?W1iz0{_@K zQo?y&l2@~CHtcvDu>K}|Zgw(mM_B|u{0AT(bh^XVUjn$y*@5{T?k^9POJ0)JQI?ci~Z z&jvpSi#C{AIbYWWkAOew?872<_Kko%Bx&+9K7Y}8KlrB_?*un-o&kKO)^mA%MdNwk z^PPPQ^6Fn)4agZ!m+#=ygmyjfOsb*hs{6ghFM*qhG8%Y{)^kdKt#K8x(;ZW;?xo1y z2%W)?q5j0F%hfo6S=w}*G)b9e` zO%vEOKs}!0iM!*IhY0ZnsCSO8y8)V~eZCq}Fbkjmat7i%Q1iopoRPGD4xgNb#9@4% z;cUeD#{VJUN6vIuN4czW-qGSGd~)6q@4)9yjkzRq{!-7Sw7HIq>)U%;{}ec)!M`@X zi}5*1W3E-^OWO?SIPqu`!RHjSGH_~KNIeRs;`1tvkD&4oy0HZKE{#Lr12ujL{AG=& zflt?X2>4KqXMkU?@o?}F8t=)7;wy|6?ghV3y}A5%4J**F-zDbX(h?i^g?9XYei>XT!j+jp~Be(>NdeIF0Xu?J8|w0=`UR zAIdYdO&Gc}w01VEl(-<1Ncu>;2RA-M&qU6rh!AiUuk_1yrafzz#q_< zJ^xta#o)yne+&Md#?269^Gu9CC*7hHqo06()<(0y)h_EcGWm9E{Z8=bHLd`ER%1@A z^E5sTenjI!@QXFx0$#513v_N~?=8TlF;2b1+@zF8#zC#$18!{Q z0pF(e{lQfb(Kd42*3eElThG)+8^BEuN`ddz`scuzB?eIi&Iw6;DtI4_8^B*Mf`IMc^!`~MyeLeu431SHF z=^TGn;Gr=}S4e=rqA?Gp^ELh#_$?a$0sgnfGr>(`!-0+cRN!m0&1v9hOxoHC{*1=E zx&E8R%AkB)7mNhINMjy86E!{w{A7(^1b<26ZYlb!flb3aN-onjJHU5p%=5)D%nH|k z9_Oa99>Aw)qsPEaKnH<8)%q*Iuhe)L__-SMcy6gvT?yR>S|0&7_Wgi4`##|#z0|S8vX*~~Hv*7T|X6C^tlwYE4t_Po~@lW8)w5kKY{GT_L zQ(-)?sW1ze$3AV=g7c^#j)5=Kcry6q8g~chVM?19zm8Yb_Lj_tv;0IA<*@JOR#GOS~F_+ts6TF_zJC`2;N5PS@$%pXG14yJ^e92TAl%Zrp6tip)aLJ`)q^) zqc=w90C%7o`u6xVxD_xjQmG#fjvfd;51bdW)bsYLv0+_am{QM-unzG>;3p9BB*#eG zQ2;IkzE~SEN*Yqnbaf#F?u5_I8jpsa8Ka&-j@6jg>?Vs0Y`oS_05>+wV$>8&N-<)@ z$I~aAP6lT0h?!=SQdTy426m~oxeVOQiOYc*EbCGq(KZ}1jib^lP8b@ox2#0WaWa_M zF;1B_GY>d7uGIF#oP?~)@iv%QFmr-gGj%!KSDKR?$2-WnsLY!Y%m(pPF;bXmGd8WD zGBcT(GJ4_(x-Q4wVD{DwaU1BFRr+ti`EMLu1ErZDEue2n8yImy8O*GhvFC6wt+ZhV zS)Z75#b8cuc7l2y9h_gpoHxX1ALo9k%%tNHU@9AEquBZq}jA z0N^GHM@2YJ7m$ZgNF#D>B+vVrYMVjOH%q~$E^Uns%Z;C|u&<--$xqb&$-86*Sb`zX zblxvTHoBw~=ITl(KzFRhoq#)Q8$Wa`V}0rk?g?z{iCIP))?*#w0$`RIT$|9>ChFrk zjpr;D)Wzqi8dKLtW1i2-N+?_Y5nfk3vd0dM_&R7gXvHSWpFtQVbobY}lQ{>~mi-^6_K zOT6!*I(<`ds*S<4NyWxK)z5$MA5Au99HmzH|Db{Y;6M6*-Gl$oz<=-`)oD-dy-DN$ z#1No;Z@g23F!&!Hf~ZWi)W%Fe{|A%k|6&NDs`sgrF16u*dPmzt^uh_KIh+mNRfAj{0A}= zO@7JzFH`i7W(fUHZ8&wzQpYlN%u@BK_NjhS?Njxs_Tr~&%2)6I#$i^TwLWj{G4iue zvvJiF2&-@SgE5HwwfWY#l$Z^||KvYj9r9}OUs^v09HwH!vRhM(sh+6{yUMk-V;^p%7AYLxd%EX}2kO~&m1@XH31`w~v7zD56?t{#$yVW3G!SNcLS9SM; zcvbh1*0Y>;Ye2m0ybHt&OxDTK#7oeXTEB{^$%BHInxwlS(~uRYzXvieNlQVzUcDD& zY$-b+IyBB%pXIb;{Z-%$fPpZenjre4UtWGjAH)ZH!iX6;d&(X^0M5(FCqTTUECVss zOgU5kBshD{;p4UJBOqpsnPKqE2=53m2wwHaAoH%k0ub*AFeuy+h|1$m-aeQQ;_ZT3 zAl_!U4aBkJm~w0%1M#}I9*Eb%kAm3n!yxvA0W)w883SQJw4*)iF&K7)9b(7Uf?9L@ zIh)xF%to1&91>2l8X%^OW5pCR)l4~uf+=JwnE}oLW{{a=APk6s(Pvxm8$q0GoKu`z zMIdHr2Ke!8>=+OYsbIlP;GC^9LCnPMAf}EfWGWYd^JWS&#CojHSC}0rh7Yh<3Hnz9^bPL5FnAigZ8&8qxt9U;qq+0o4c5 zAstg@AgoV6Y=8~1oOT01i$T0iRSX^im4JA=>Q0XTK+qBp?_F^Q^WN1`$b&%nAXcOU zI^sm6J@qVK2BQ8>5FIWDryu&G9qrj58>S!HvmX7ko#+YxR%Appq|5>aLPvBs5_Bdo zZ)aWy%v+k1!CQh~s>{hKF9Edzaoo=Z^#ENBY7M#yG!ex5^aFoU-*f<0U`0BhV;azq z6-H}L2Xyoc%IKI4v;t;117t(gvz&JH%YYg98NgjY!$6#iY?vbLa$fhU0mgT{k6tkkodb|-^akM*N; zG!4W88jc5Xg0Mk4rXed(Plt5;3>>uqF(BH}o_aRShUkxe8E6~Gv}a>nluiR(4!R6< z7LWf30DBn*od9AZG$OGAE4Br-gOlOlLqN?zw4*)i6@cgm4#hFENjuuJ9)l;R9qs9l zeur`VS<&>4j#-fo7$GAy!L)~io{%p9(T0yU#)7k#<3Q(tP6Ty;o@)ThI3I$L3&CkO z5JWx8Y1fV8PsemXhhxB5ffZ@U3am&>yKdmD$cEV9@4yVm1V)*9Hb_78N52fXBY0?IE!a>^_?1#|)`@DS<*;>4r_V@H{Ku5z8hnJw0%V>WO+=nBvX5dF{} z^$dW1XpeePd0s+8R-i*R$O^1T{e>Vlz=n9p^Z|8&%tL7kh{Jb{#f=au|Za*BRZtM61H?id)8w>w4*)iGXOTghG<87 z)}vo8R{cO6mR6wCIsR9II9^jhU12-`d>p79h=#1diVvZTcC8V?!*ssarKtpS||x)^ji=sZvul#zi$9Q+luFDHnrA)E!84jKju zz~F4~=RxOy7J|+N-3%HI`UW%t)CNSSSAot4jRB1WeFVAyR0n=81gEcyK=e@vdJV*& zYI0AMt%;x#&?L|;pvj=`L6?G>fGz`3 zcR7f<24LXbFh(U@7QP5VN-$v>cQVS^??~;>2ba91uIpY#s*P#U6D6tpaiU z?*=iw_kg|y-3w|5x(~DobU%pWwi?tDv|K5Ys&o^aY5+^(BaHRe_>md>jHT z27Lu$v|oc5?Khx-AWlS%+jpQ}LEnSe+ryy0K}SF?=m*gCpdUd+pr1fF=)lk5O!qIK zr6Bs44XWn&Go8PI=7EladVqchodWs;v>C*;;7ZV6pc6rCv@MA9g7bsx`E}r#;2pr3 zwG+U(daeTJVlxz+!PE!me5nNra8K_BDDogo0Ival95`okQ}CMLmxI%|1vpnV_Lj>h zv&HqDY3FL$9=sm-W#IL}uK;fV&dxOi?*iTk98JpKAYKce&+%u}$AOr>Cg2^xn}T-+ zZwAibnuB^nZUMdmye0Tt@K)eVb8GMc;BCNf2X700CwMz>4sUz#M&QSTj|1-jej#|2 z8%bXWaWm;25cl!jFZJ@!Rd7wd{H$ekIO#cwjV$kUz2Xq?f1JF=VV~&3qAPzbUv<-A7Xd37Y5ThOj zS_?WC^fc%k&}h)vAZBkkh+8br2XVXPc_8{40phTZ1lLJ-R?05yx^qY(5y z=n~L7pi!V=(8VA&!p3%k#(~}dabNFEpfMn3XFTY05VLduG!b+UXab0hP6izUT@E?| zx(u`ibSWrGXA#g7pesRTpesPXfTn=DfTn_0g02Cr25}e;g02E_LNZ%(LDzxifUX67 z1ey+N1eyW519SsuIcO&6T@Z#FuLTDv0x=6WgP2D4?kN!G#SfraAdVli#dO~SS_=9X z=nK$n5PQcU*xOq{FM=4%@1S`g274Qbz7~L<1%=r5tMtO z{0j=UelL_EP(FrI0%ac*^dfo-`}yBcu7~mol%7xyK*8?AZv8({K7}&pm+;?zpcF!B zfN}!LAtha*BjYmE~d4f#bw-fYPAhK!>}a1w_6jv?{(2&awd6*%`40)s>B-RkR$dqQ4cRi}bVH6Ba<(CNFyvfA zE->UmLoOm2>IX6@CB})~hTPAP`y28=LoPSuVTK$tlCP;|22H!+0lTnZNzEU>v2?~ zt?RqQ2friI0S=*~o-ryi#iu=Xh;J?_i`e3jy zhheQw3f?Nht($SwH{4yC=L@*w_XYd=GTr(6g8#}9rHf&9gnucC&PV|1F(Qibb)N($ z`AX>=Fc4iQk1ODcz?}XRLoyt>9}PuO3}aoCp#ZjEc=!MsilP`=U6r8#wqSVwr(ifp z6tyAw0G!7)CmBMM65W^)ZrvY_`|SAihG2m&KquUt{|Xj%lDZ3(YV1t49rC*y+@nW> z1LC32gWY^N4xg5qNliIaVQsn2pB=y9Q1BPNfI0`g+g6(iF{MjBO#cE}6rf&ocODLA z7cvo1m4T7y$!)-``|&r>hQnV{8|VPG!H;erGVzf|f)jm_QA5<{L1*Y97fu`x&gqzs z(~|MG74D8WU$5jr8>o2f8xWU$6C9uY1 zFPMX718&{AMKI8nxa>RY`iRqKIHgL{KE<;${~PR_BZtC(jiXYX8uLVGo}ZMKb%XIq zO74&o!P$Of;%+$+T#%Zei>&<9Z-uXQMhg6p!zUfm#@>)e0ze{V8~{TYGuv20v9j`QQEld1M5R5)i5b_Nh*{>s9`2 zcm9vTYOz1=Ck{vd7RvThbw?i!WIr-IRNZRV?sB)RS7^AK?+c{`Vz=S9q>ni(w4BAA zzEFuDJ>bsll9uhq7SpJ3ORf$r%}exFEsR~kExpp%Vw28s^D9Gd=7^rKb^7QgXI~R~ zkXVihg)VlF_(T4HLnM|>4XyAiDG(~mMGK?7v3_cwkQJlN!BEKkF%WX7O?7QUm$dF~ z*UY8{)dChtb6W!z+X@@&T!p1r;g#e9R@nVl>(D*oALsxp6!71!-P1tgk$^boD-hzQK$e8TQ`B9*42|?Zq}xRjw5xlb z7zs#h06Pi670B!egJfj@$Rh|c`42#ZBytYh2!=ICVGy>$sLW)HqnV)*ftsf@6OziF zh1Rf(H4&1?Cu}1a&czCY2q}yuofzYjdcYW{F-TG_ zVIu*FU7|pUkOG;V%OF{K(3+ap@w@BC;6+4IFduq{jReFRp+Ja{0;$YrkfZqk((qRV zp;1rL!7c#8Mgo!;$u2=~1v0RJL3S2k=WIm~>Ku~hP67}%5)fy!0wG2UB)1!b)O7=p zA~MZ-9h##+=-Oc`L5Wo;6r$t~sSRYiKXixr5+~&9LO_{DwnL(!6+{Z=rg@mc<+zWv z4ux~sTF|Vq3XQlaw2#l=*>~m~K&we;7n5|fFs*x@SP4pEoI)XPs%4w2xMgGJ0!o5x zY1olO?qMSVaVD^Pkdgvf(vv~T?nL)&BPtjJl$cc-D$Wx#fsrYnI4KwyG$HqaVxE8@ zs6eNCSV{z}5Jlu4$3j;99+jbV z&XFt!HSyg&KJ{I2YP_ILc)CC7|JqAiUze(LC2JVvN~1z^I(BK2D{X^ZDK-Go8ESo? zcH^y2a;~&dr5nT!{yXtNa;~I|woLY2ADQ-zN|tD=k|iaoWa$K-J>n%xd`Krtbc&KC zl2o#UN-9}GDk@oei;|^^&rg{wy`WfIuc>W}lO@`!WQjF&vV@vOvXr}}(+jybSTt?Ee z0OSE=VYJuzyQ+zh6{D7uC4!)No+K45*jVVq-dA9X*3V>1{($w4zKWFy=~8i?00^M< zfdV9!nw^m^6%h=zktE2MU~Xh9K}qaUD1@$1yo4zo=SH%nxsfEA8`(%eoPV&R5L|)i zglWqL2&eC2gK*AQl5!9m2}tZC1wxDzNOHzhv|aZZNt9u*k$_lx6$mj>Ajuh1j7%wa zBMGtta0*)qO5$G%g(xYM4F)}483WVY*TM0^R zKYIny6-si-R718j_ynaemyHC(`i}x3N(#hGnMMShHTZio^wEJNKN#F!-V z3L6QC^OXW2M$NOPk^bct1Q#S?p#*c3mo$a)#9Gi|M->`TYmzl}eFrYb6^KTcG)a^+ ziIIRv-SM4&Brjh<<5QIiAN#q;05sbuf_6-tJ7|A(P%^C!u&&^8Ax*I+ivX!97 z#7~SAN((8IbyHZNl!)n9fNUxE2@n}&o}4r}e`L!Qev&BH!XWc=In#3i6{9I>;^=L0 ztdWZ!M8X*^;$gWlOR5bhadiBwJFamQ}#5 zB~qeniIh~fghW)f^bTc9OaFS^1~pg$O>Zqd2tWA=W8ZpAZ5_F_G+p0XVhx=wEyf=S zgzSaEmGSlcJC~!&cc- z4`ZvdrmfkmCe62epvFm)pFbvecbF2lBO&nJ)PO}kpBxAc2&kjWu7!`3Xl?i*k*fBI zj3U=^0yQ)PuU-70OcG6zY%9zhzrs=sesAMgro56$lYhAj!E?L#bv$lFGo?N>E}Eg+i1RN^*faPMR9Xltu|je;}DNBD2qhA zCS-S;tmL`pj!y9*+ng%a4$rMsV*>X)S~NZ+VA@tOTYo&9qp z!@+ml@G%_?88DJRi?acW{&3vkC@;y5nR(&@0I?T5isEP|nUrJ`3ir$u@wtrirhqC9 zfF!u>AipZ{NQYJBYRP{<#tx#IN|G(Ki*fSZzV$zAP62c&htXM|OkrWS_x z+zlx&G=BFzQ{BwQ&)iNZno%&uSCC)gNi7>iYrK->}+R zRPH|7E)2o{1x(8iwhP}Bak`$N*x^>Ov(8Cor?iP()g$VIg~3i8`k4*2eoEL=|{P)7^4$YN=aU60S^r4@P32h;zXhI!D`hV@ddG zUs#U8TRHBs1-_hiF-)S7Skg9r-&x^*`^w}bz7a~!W+fqFEm5BYtnbwJ+3GTwhF~ZL z@k%F1cT4YZ+l~Tcon(U_)iy2$?!G?ZKq13@&(&Ecl$Ne;;cJhT$IHsX8-0a*N~0v(hpA(?dZx+HrykPKEK;xRyh3((Z2wuMeHK$gtFKC z(3m1qskIq=0yy$F6ohgp$NlFFMpOAq+;2hTsGb!rEMzbZ{+$AsN{JbRR}H3!DIfxl z`>pvPR&s*CyWRre45q=qXK=361b?_?@Y_Cn58nr-KWKkS(R^e+W)6TemfxxoWV4B)hOySOIl!nZ%zis6=t~d2wsb=7v{L<5cp06XD|VG z1YBBRfR`s{BLe=@PakM-tmH-I7N-U9JD9mtVt|it8Qck9g|83OANssOx#dm(XE4qD zP6e)8V1UPZCXE(cW~TnCl7?c32e3oC-T~kYrorbixU|3kU)cM!;Mjr~fsaAAFqnW_ zcQH6uY7WIErw2#3)DZa5+W?%w1l$pDX@S9fTC&eC1fYRXR$M%1uv|p2o3e+%ccRam zfLnKShe{;|`0SR!d))EpAROQLhiIJ%`j zf!DPJeh)L3N(}JvErSE|Om( zCMkw8n1DOHuUlY%&ps76y~Rz{&=qEB9Nm&2aJufAfLnJnb7_IWJaKw( zbjt|>r%8puG;`i}qy+|eEP3u83P9yhFs316`Ag8~ql>Z$xOERRmr4xq%2R=>Y!kuh zqWmphl*<-i?xw&rbKZAa0H1MsaCA$Iz{?gk2e%w%E|nO}=bav$E=mI5g5V6Mne)EW z3>+@XWbg}sWq)^a5rnj&hxA3+1kbvc$qKGPc3lg2=v(-cKE&-r0;h|T!8BRkcUl0S zaYNF?N@NMz14lPI1Wp%a6L9N3W-gT&%ooCALF2B(ISkx%^feGTU6c$a%&k8uaHj?E z-cKz&9XPsW*2Cy?atnhAxWoI>0>@xpTR^wYgm6pD(JeIuPHt%eZr#srkxGiZNI5Ur z=R*OgoN8)vQPSwEdl*I^gK6fxuUlY%FFqA`^358n3NOkbk2D9j<}-6?fdRhm)Zj7{ z(Je6o--+N1rkV4;(*k(?>A~ruB=E_LnuA*ln7On-GtaShC4(Cm$g3wp{$8L(c1?8NQ)7^J^Ni?GjVK(M~pJ7UkcmSLY?3-&Le{Y0{-K5t@g zJH8TzJcs1m1KRfcX(g(F!;yN{?|*u zzJrVHuLki9F%ST25jQ}941miKpb-IL1km*f01yKKa2P;_0H_ODU+f*;7hIFT5g1?YYP8=&_SA(4oP+kkr@_8I`ESe9V9)xx{-@Y~&Fy37>Gn_a>{(yzt);8g%*eP#{nq)q{U^x2 z4C`lov3JB?c$Dh?vogDZ(_dN+{1?;vj@14p_SQ00zvf}s7jAwArhpabzZLjkmimwN zb^W}rc^LLb&W5L|ACmo3XixPwvA5Q8{eolIcSZiceg^7qsL}PazOH|*j}k_w1^bKf zMbSpIPf-6;|FOQd-`t1ng@@zS@5Ipl-j!f)-GSqm>{(yzt*_V6Z3ahpc=pz%Xy0)a z*vH78`j7Rs{c*Mz9%o7am0G3Hej{CluYI9!a>sNP6A#I790I4#VK4!Acwb0b2Kd~n zQ-G^mbO??mLEzMLO~9>h6mv@|F~FB^JuNs!M(a*JEijm7&ilFr2KXzd2S@kB2%MNV z0k^(o=F$QW+?lX5i8;R38-#*?rq7EW#R-)Fw`W zoC}6S<6Gk4YqQ+KIrxi{Rw4>jA>W!dhIh0zXf?^~jNs#(2-(WGX6$wJjUdEfs>&FhYZ zJ6KpVzM$dOFN_v>RjYS2npDlNV5q9=j_axm)6$#yd`4Qj>GRsO^#2#1tG773>KEg> zV17vhs~-^e1=D|(iB8UPk1R;_yR$nq=aA@-#KG#=oWsP9>Dj5rrn)zFOz-G*doB(~ zdSe186lYQG{1%6*9sJ(U7oVG(-X{aCa$M;5CN40WJHEJS&AH@wd$n>{EZvFIV|A2Y}#CK)-neF`e1|%u-3m(ms)f*k4T%1LE{H{hbJ@s-1 z>CMQ3%K5bm)Vt7yOa8KW|6ipakGgyEfq{D2qWb>y^Rh^pU!x%9_~cvC?JT#p1oYH< z6P_Nw5urfgLcT0sG#^1pS-l70Df1f+3Utg;4XR#gAibJ&V9GBmpk8Tw+lKVp(pxo_ zed8{uPcL;VO4F@?dQGA1HE;nL@Cyja;D*=0zybq%6uf}2C=e+^qoAK&5b$jHy#i&E zwG(XoXyf+Yncm**@@-~bK)q5x7UhtQS^Tm9S`=aLt!)*bv_E}XYt@J99f8S>z=^c^ z>HjIT)kA+zn;++&LR&q>C+!!hE7c=()E*qKPK*303wyDjTU#FS2h>yfEgd5Rf~1Vk z+ugbkGp>kNc8Uz7ek9F+pPoO0;<@fu<&l8W#^>isdrzsU?GLC&=1tV`iMUc9KO|XQ zJp}jEk6_Q@Gw!&rIOBbPeEVIQZ~Ee!e;w(ahNGpQyKf4RSC6`@XGYErk^w%%K9xcJ zgP8$8J-zny@wxP=^r-^%M4Aj7>{NW#9DjE#F{(%hMg>=9RQTeRPGnXq?AU(pjIB@& zJqL!ybaNk{ABhCX6dyDHylHgLDNOMR^Us^sHZ(QOh{D&2Tl{PpyZ%P(`t_~chP9DB zxwobT@m&Y_8)S>TyZAzq-Kv80qAtC5U1MmHC}O<2pji^q9QcguGGp^qj=+b7s1_ek3(*i(KW zLdE%)YZ~xv+FIUSJTZyVM0?j~ZJ5$k_V*v2$&{|LbI$CiC|zwAURBO2mD)$grdHa0 zZk{sOtP(mvuRYueHG^{pI$^f;UNStXposRZx4OTmD|8D6jSQ z<#sG@z0yiqq2o-O zVpTOBvAUXMV%uvxVkxV&+*k&(;jz_*$5tC2TkUyl;RhzMlrKeYZR_4l#;&)HA;|9&Bj)!f|m26az9lv69z%l86Qt-WPU zDi57Hd*k0bs$oC1&c1wDPa5{UI@M_&@FnD0KJ>`*Ca32OP8$qP8%$0c4NjhXC}&d= zr%iV5%P;Zu^Mc*>%`a8+roLcTW(5_eycg^@D%vyexaQPY7Pr5;`7(9&RQ)sJZ&lxL zlbd;GMvmM2-i&-@W>}OsElWfOWF5(en9Q$aQA~Cz2_CpD zas<+ciIG@t>vwt9g}^K_24<8co?d8Q_sdJUv&-$N15|v$z&xc(4;2cA*cYy$pX-3B zd8n2#FynCnvhBgu-5F@O9hr14$p^L$w+|g0N!=1~BVN?IR4#18({FLJG|JmG;WFTk%zXjg}!WlkC>^h!n+Z zc1G?`&3$QjL}5W-zV&OBrW}L7d~)=38KukZ2i~2^O3Ud4@`J$azWQnyqWp$PTF2$~ zh6OX2)Cw&_SVo=FF0Dteus`T^HG{0MOHYg<86)zYe=SE}tBBlDIABB;`4~jxTiv<$ zLv+WGocD~~X}+?DAAhi4yX;zp1tGaz-LD9%Gsa`h2;#BG5RaMB_LcT-VFaPLL>NIR zzC##cDE1gZDAtT16f+}?#d$RzBZ$SC5yWDT5d>mk0l!nBWeCLLqt%9wRvSKA?fD2} zu*V2uux11?*!0mFj}Zi6%?N_9#|R>@W&{yfWQf4xqqQC*2)?@4Ao%KD!{F;Ng5WER zF!(YfjJ}<{GZ=kE3!|^_R^j)x!WfT}=j^Q4Rho|B_wf=)J26%41mRb>rc`+{gkRzf zp{3T|Jy)i_I(uEAO^C-J@-FGR1z2yIY|zsr23VLTRjm+UWh%k|D>4RHJuOjy)iWgoSeYp?z`{(a zdZkP5Aw550fR(ut1FSb!Qh@d5$}jX>i2)YpN(!(-1Aeo^prm9kz-lcBurgC(fQ6Y- zC>^n1{9P80rX$)<5Mb?1xBW9t8OfSCjTgmD(@3MoDd;GcY zzB5v-NPws+GDcOD6+8U6d*YGpo7FsCu4Rm>c$_BSg53T?>{}K-$67;er44J9A+TP3 zICYTf#$LN@`{EzLQYnis~_w`QdgRxkI=o#A$VjHYl`HN~v zg_aL&Rk8w`lm%b|dVIzWA8RyxoIU-TQr+-z_K+#k@CjNzuvN(l>t7#sfkao7mCiME9A%8I zN(ZBB<*~>`shz6MR9a61l0$N1+0*u8kKTJGeV%o9of~PBQALaMFzCV$q!j5-!=amw zsz$-5VUh9EFv^QYM0({fx65AY!tGuGw)KRAABExgU#Nlt47|>oRjS=po{WJPj}y=e z`#{kr+#AmT5EFu^d!T6YASBc){~5dDI_3j0SL8;BxhOAcm(eSKr9E>4^MQz~`M@V& zI4*o3>}oy`c13Q4uuFUpXqCqYVy@-`F<1D&?SdLjA_YROCIlgu2%&>&JVFp~H6i%q zYY-Z}T9Zhr^5n)kC6j|zdxRk5YC;flg;1~jHJStbERvQRA>e8Ut@ZdoxYc~%1Fykn z`&y3=#9YroN+wUQ(;QMD;0hlMxF`eVl3Y26u~uY^wJ6hIhgtnuyF>9eJjR~WGR9gw zuCy{B*#2@{I%};5do|4Pvu^v_$8xt~#9emXS~bj4>a>gz7mxGh)fq0Yg)gPD8hond zp@tuKuV^=HkQ%c&pFgk3q*QIt^0EC&7GfLi83V#hY@H-?LC>`qk#XKtWO|@B>*|#;A;QumY>-0bt%-`=!C`OJlCh`TR>gzotNJ zmU$OrGs+5VAAq?t?oE%mvsz~y)&Usq^*4#YymZI-gu5b?0iSRW&&Z7BR(!u?plZ?} zd%IZ?R#Il`7f%<;abLEjK>A*B0FXEC2AQue9#qQ7>wJ0aUK!tm4C5)=eFCpzL=IV zI^%Kgvu^H^2{XCE5w^$}o>5l5r0|>=H3`?J!`~=fBZlYWISZ)9qJmz#M%yns+qupP zEn|4b;|h$z^B+HZjMc^(t{7+U`sNqf731s!6X!9r30lVRjK>uih36gPHgH6}!eBPh zu739k&1|CGv!9(ccX1H7NQBv=tbMegSBczLbMebqbq+xYJ(!Uv*lmhgdSD>6n~lnH2+T_}7Y+G;)!ZSQ106m5kB zMq7~^A=(ll6>V#T5JX!|2%_x?j}Sy#aSBFTkuln82d%a}2d(i4LA3Q8v_^BlXsh`^ zv?V^6MXa?oABeV^4@6so4@6tx0Ka3U9HJ#P?u-hO}P=*?cV6*3rYMaF1r65D8Zem=&;HX6h>*=OFhNE6#+_nY@M z*Z6{#G1}sBbs1B%6)$156&a%~$~Y_oB)VVaX5{!Mti8Q2P3H05c^M^^|K8dWn-}$r zWc!zW-EDxH<;#0QY}NBAd?pqdBd|B0QV5ng6y6Hd^C^a4Z$70E?9HbK^{j;<*qcu= z1nc<}La@jfg1z~aLa?4sAp}ck!4T}trx=30`Sc4dV+i)`P-l#SpCL zQwYH#V+i)%}H#f68y`0mJ#)MjhIrmUTU$_2;j6gcCuWV6QEvoc%dAVeZx@wIi>Si@$00&&J3tt<@JMXabHGvU%Y5|X1VzWjaq;=J(I@)FA5|J-M87^V1Qn2 zV!k5U60%w~H+gy{yfU*jGom_|7sa(?5%AMuwI&9<(5;yPUA>;c zKN~XJ_;KA@{AfewhzKuS8}e;tZ$GX^`eVdu@hD)RQep(q;S{l6~zOGAjV1(C)fhnKIgd{v zqqEa^Wfv*D90P1zvK9Y07Tq7_HCvxdiuU&7LM%S2R$|dnTwcXT)%q$pS{%e5zjbis zRJ`nl=8H2+!if#OJ_z4{J1D8K4xb04WFMDrO=r{H^CWP?i8PVQ}UTnzlSrp zkSRXow+N?JGLcc@M(nbPhx_UJ^v7Xq^w88hHnuqSZcd zYPfr?6HN=^FO^!jm?sWOfT~vW$oa4z*XhLPu8H0T-XfpCsWLbJzGz!NF2UhbY7LH@ z3c6qYDH`(Q5*t3R*4WVb=jKN>t&0xxJ+h@e^J$ zNS+oPAo;U>Zo%)P0k!C4%O<#jXB~{dPbRL9h64_+DnLr0bmYcUC|S64Kq)Pn*`iLm zA6Ex3PV^?wp(O%Im9;LL1p|S;7;a8V${1h>|5E6yzhGbfC6Tr!PprEq|whgUhJhFSbF`MMWAy z%PO%FhH_+CH!gd1Z+{EDg)2{uT4*I8n&66B+{y}9Txsb>-UeQ{*3Yn@<#n(xNP0~r zuI+Q5Knq;2WmwQEAGBa3y-*LAV7aC5fCa8YGAw9e3GC~-c(E3(KXU(q7P$1qu#f?w c>ynj5xP-+W^=`ECo^9Ks@on3)9$NZ;0j=X=`~Uy| diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d index 44494d1eca7367b2a44f3b56d3ce6fce35c6141f..59b867574058fb8df8952ec7fa6b10ff6c84aed6 100644 GIT binary patch delta 98570 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 Oi{nvLF~h;#?*9Q#(49^I delta 29481 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 z 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 K@5{M=;r{?q?i88; delta 145249 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 u{IWSkg?mkR?$G!lvI6;>1s;*b z3=G^tAk28_ZrvZCAbW|YuPgg~E;b$w-N64IbAUn;C9V-A!TD(=<%vb93~dIoxCe|nPd1J#`Kba4!^@ZTGt$j4+T@FqS>T0}!gL_>wi^N_kg3%f#~#k>RZ zKNx1s4^a?HJ3M7?Ua_U)jFd}zZ@zr}2MiSpcQdSM|K4=P^VJ6v<^x9` zF7owTl&5~!`7Y~+qWi)YvTqvP?3&dky*9ql=(Z-p|4~|AZTGD?#d=b&tgalKwQ<$l wHmO;>r3uN~>|csm{N8e~;{RW@`WAsWlhlp6t7RA$1AWHe>FVdQ&MBb@0LG|^GXMYp literal 0 HcmV?d00001 diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 8c8b784b2..5ba73cd60 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator("mcl_playerplus") +local elytra = {} + +local node_stand_return = ":air" local get_connected_players = minetest.get_connected_players local dir_to_yaw = minetest.dir_to_yaw local get_item_group = minetest.get_item_group @@ -190,6 +193,37 @@ minetest.register_globalstep(function(dtime) player_vel_yaw = limit_vel_yaw(player_vel_yaw, yaw) player_vel_yaws[name] = player_vel_yaw + if minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}) then + node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}).name + else + minetest.log("action", "somehow player got of loaded areas") + end + + if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true and is_sprinting(name) then + elytra[player] = true + elseif elytra[player] == true and node_stand_return ~= "air" or elytra[player] == true and player:get_inventory():get_stack("armor", 3):get_name() ~= "mcl_armor:elytra" or player:get_attach() ~= nil then + elytra[player] = false + end + + if elytra[player] == true then + mcl_player.player_set_animation(player, "fly") + playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", 0.1) + if player_velocity.y < -1.5 then + player:add_velocity({x=0, y=0.17, z=0}) + end + if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then + local dir = minetest.yaw_to_dir(player:get_look_horizontal()) + player:add_velocity({x=dir.x, y=0, z=dir.z}) + end + if controls.sneak then + if player_velocity.y > -5 then + player:add_velocity({x=0, y=-2, z=0}) + end + end + else + playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") + end + -- controls right and left arms pitch when shooting a bow if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) @@ -208,7 +242,14 @@ minetest.register_globalstep(function(dtime) player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) end - if parent then + if elytra[player] == true then + -- set head pitch and yaw when swimming + player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) + -- sets eye height, and nametag color accordingly + player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) + -- control body bone when swimming + player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) + elseif parent then local parent_yaw = degrees(parent:get_yaw()) player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}) player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) From 421ab9f6609ee168e9a402c08abe81eaed22b9e7 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 13 Apr 2021 08:42:17 +0200 Subject: [PATCH 163/164] Add timeout to static hudbars --- mods/HUD/mcl_bossbars/init.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 8ed08a613..f1d99e013 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -39,7 +39,7 @@ local last_id = 0 function mcl_bossbars.add_bar(player, def, dynamic, priority) local name = player:get_player_name() local bars = mcl_bossbars.bars[name] - local bar = {text = def.text, priority = priority or 0} + local bar = {text = def.text, priority = priority or 0, timeout = def.timeout} bar.color, bar.image = get_color_info(def.color, def.percentage) if dynamic then for _, other in pairs(bars) do @@ -119,7 +119,7 @@ minetest.register_on_leaveplayer(function(player) mcl_bossbars.bars[name] = nil end) -minetest.register_globalstep(function() +minetest.register_globalstep(function(dtime) for _, player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() local bars = mcl_bossbars.bars[name] @@ -134,7 +134,12 @@ minetest.register_globalstep(function() local hud = table.remove(huds, 1) if bar and bar.id then - table.insert(bars_new, bar) + if bar.timeout then + bar.timeout = bar.timeout - dtime + end + if not bar.timeout or bar.timeout > 0 then + table.insert(bars_new, bar) + end end if bar and not hud then From 78d387e2df2557b30888946dfbb11afde6abd22e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 13 Apr 2021 09:59:32 +0200 Subject: [PATCH 164/164] Rewrite mcl_torches API --- mods/ITEMS/REDSTONE/mesecons_torch/init.lua | 145 +++++---- mods/ITEMS/mcl_torches/api.lua | 287 +++++++++++++++++ mods/ITEMS/mcl_torches/init.lua | 338 +------------------- mods/ITEMS/mcl_torches/register.lua | 27 ++ 4 files changed, 393 insertions(+), 404 deletions(-) create mode 100644 mods/ITEMS/mcl_torches/api.lua create mode 100644 mods/ITEMS/mcl_torches/register.lua diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua index c7c4a4ca2..9aefae96c 100644 --- a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua @@ -117,83 +117,90 @@ minetest.register_craft({ {"mcl_core:stick"},} }) -mcl_torches.register_torch("mesecon_torch_off", S("Redstone Torch (off)"), - nil, - nil, - "jeija_torches_off.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_off.png"}, - 0, - {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, - mcl_sounds.node_sound_wood_defaults(), - { - mesecons = { - receptor = { - state = mesecon.state.off, - rules = torch_get_output_rules, - }, - effector = { - state = mesecon.state.on, - rules = torch_get_input_rules, - action_off = torch_action_off, - }, +local off_def = { + name = "mesecon_torch_off", + description = S("Redstone Torch (off)"), + doc_items_create_entry = false, + icon = "jeija_torches_off.png", + tiles = {"jeija_torches_off.png"}, + light = 0, + groups = {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + drop = "mesecons_torch:mesecon_torch_on", +} + +mcl_torches.register_torch(off_def) + +local off_override = { + mesecons = { + receptor = { + state = mesecon.state.off, + rules = torch_get_output_rules, + }, + effector = { + state = mesecon.state.on, + rules = torch_get_input_rules, + action_off = torch_action_off, }, - drop = "mesecons_torch:mesecon_torch_on", - _doc_items_create_entry = false, } -) +} -mcl_torches.register_torch("mesecon_torch_overheated", S("Redstone Torch (overheated)"), - nil, - nil, - "jeija_torches_off.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_off.png"}, - 0, - {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, - mcl_sounds.node_sound_wood_defaults(), - { - drop = "mesecons_torch:mesecon_torch_on", - _doc_items_create_entry = false, - on_timer = function(pos, elapsed) - if not mesecon.is_powered(pos) then - local node = minetest.get_node(pos) - torch_action_off(pos, node) - end - end, - } -) +minetest.override_item("mesecons_torch:mesecon_torch_off", off_override) +minetest.override_item("mesecons_torch:mesecon_torch_off_wall", off_override) +local overheated_def = table.copy(off_def) +overheated_def.name = "mesecon_torch_overheated" +overheated_def.description = S("Redstone Torch (overheated)") +mcl_torches.register_torch(overheated_def) -mcl_torches.register_torch("mesecon_torch_on", S("Redstone Torch"), - S("A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything."), - S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."), - "jeija_torches_on.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_on.png"}, - 7, - {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1}, - mcl_sounds.node_sound_wood_defaults(), - { - on_destruct = function(pos, oldnode) +local overheated_override = { + on_timer = function(pos, elapsed) + if not mesecon.is_powered(pos) then local node = minetest.get_node(pos) - torch_action_on(pos, node) - end, - mesecons = { - receptor = { - state = mesecon.state.on, - rules = torch_get_output_rules - }, - effector = { - state = mesecon.state.off, - rules = torch_get_input_rules, - action_on = torch_action_on, - }, + torch_action_off(pos, node) + end + end +} + +minetest.override_item("mesecons_torch:mesecon_torch_overheated", overheated_override) +minetest.override_item("mesecons_torch:mesecon_torch_overheated_wall", overheated_override) + +local on_def = { + name = "mesecon_torch_on", + description = S("Redstone Torch"), + doc_items_longdesc = S("A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything."), + doc_items_usagehelp = S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."), + icon = "jeija_torches_on.png", + tiles = {"jeija_torches_on.png"}, + light = 7, + groups = {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), +} + +mcl_torches.register_torch(on_def) + +local on_override = { + on_destruct = function(pos, oldnode) + local node = minetest.get_node(pos) + torch_action_on(pos, node) + end, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = torch_get_output_rules }, - _tt_help = S("Provides redstone power when it's not powered itself"), - } -) + effector = { + state = mesecon.state.off, + rules = torch_get_input_rules, + action_on = torch_action_on, + }, + }, + _tt_help = S("Provides redstone power when it's not powered itself"), +} + +minetest.override_item("mesecons_torch:mesecon_torch_on", on_override) +minetest.override_item("mesecons_torch:mesecon_torch_on_wall", on_override) minetest.register_node("mesecons_torch:redstoneblock", { description = S("Block of Redstone"), diff --git a/mods/ITEMS/mcl_torches/api.lua b/mods/ITEMS/mcl_torches/api.lua new file mode 100644 index 000000000..ced566bbd --- /dev/null +++ b/mods/ITEMS/mcl_torches/api.lua @@ -0,0 +1,287 @@ +local spawn_flames_floor = function(pos) + -- Flames + mcl_particles.add_node_particlespawner(pos, { + amount = 8, + time = 0, + minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }), + maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }), + minvel = { x = -0.01, y = 0, z = -0.01 }, + maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.7, + maxsize = 2, + texture = "mcl_particles_flame.png", + glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source, + }, "low") + -- Smoke + mcl_particles.add_node_particlespawner(pos, { + amount = 0.5, + time = 0, + minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }), + maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }), + minvel = { x = 0, y = 0.5, z = 0 }, + maxvel = { x = 0, y = 0.6, z = 0 }, + minexptime = 2.0, + maxexptime = 2.0, + minsize = 1.5, + maxsize = 1.5, + texture = "mcl_particles_smoke_anim.png", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }, "medium") +end + +local spawn_flames_wall = function(pos) + local minrelpos, maxrelpos + local node = minetest.get_node(pos) + local dir = minetest.wallmounted_to_dir(node.param2) + if dir.x < 0 then + minrelpos = { x = -0.38, y = 0.04, z = -0.1 } + maxrelpos = { x = -0.2, y = 0.14, z = 0.1 } + elseif dir.x > 0 then + minrelpos = { x = 0.2, y = 0.04, z = -0.1 } + maxrelpos = { x = 0.38, y = 0.14, z = 0.1 } + elseif dir.z < 0 then + minrelpos = { x = -0.1, y = 0.04, z = -0.38 } + maxrelpos = { x = 0.1, y = 0.14, z = -0.2 } + elseif dir.z > 0 then + minrelpos = { x = -0.1, y = 0.04, z = 0.2 } + maxrelpos = { x = 0.1, y = 0.14, z = 0.38 } + else + return + end + -- Flames + mcl_particles.add_node_particlespawner(pos, { + amount = 8, + time = 0, + minpos = vector.add(pos, minrelpos), + maxpos = vector.add(pos, maxrelpos), + minvel = { x = -0.01, y = 0, z = -0.01 }, + maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.7, + maxsize = 2, + texture = "mcl_particles_flame.png", + glow = minetest.registered_nodes[node.name].light_source, + }, "low") + -- Smoke + mcl_particles.add_node_particlespawner(pos, { + amount = 0.5, + time = 0, + minpos = vector.add(pos, minrelpos), + maxpos = vector.add(pos, maxrelpos), + minvel = { x = 0, y = 0.5, z = 0 }, + maxvel = { x = 0, y = 0.6, z = 0 }, + minexptime = 2.0, + maxexptime = 2.0, + minsize = 1.5, + maxsize = 1.5, + texture = "mcl_particles_smoke_anim.png", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }, "medium") +end + +local remove_flames = function(pos) + mcl_particles.delete_node_particlespawners(pos) +end + +-- +-- 3d torch part +-- + +-- Check if placement at given node is allowed +local function check_placement_allowed(node, wdir) + -- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed. + -- Special allowed nodes: + -- * soul sand + -- * mob spawner + -- * chorus flower + -- * glass, barrier, ice + -- * Fence, wall, end portal frame with ender eye: Only on top + -- * Slab, stairs: Only on top if upside down + + -- Special forbidden nodes: + -- * Piston, sticky piston + local def = minetest.registered_nodes[node.name] + if not def then + return false + -- No ceiling torches + elseif wdir == 0 then + return false + elseif not def.buildable_to then + if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and + ((not def.groups.solid) or (not def.groups.opaque)) then + -- Only allow top placement on these nodes + if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then + if wdir ~= 1 then + return false + end + else + return false + end + elseif minetest.get_item_group(node.name, "piston") >= 1 then + return false + end + end + return true +end + +function mcl_torches.register_torch(def) + local itemstring = minetest.get_current_modname() .. ":" .. def.name + local itemstring_wall = itemstring .. "_wall" + + def.light = def.light or minetest.LIGHT_MAX + def.mesh_floor = def.mesh_floor or "mcl_torches_torch_floor.obj" + def.mesh_wall = def.mesh_wall or "mcl_torches_torch_wall.obj" + + local groups = def.groups or {} + + groups.attached_node = 1 + groups.torch = 1 + groups.torch_particles = def.particles and 1 + groups.dig_by_water = 1 + groups.destroy_by_lava_flow = 1 + groups.dig_by_piston = 1 + + local floordef = { + description = def.description, + _doc_items_longdesc = def.doc_items_longdesc, + _doc_items_usagehelp = def.doc_items_usagehelp, + _doc_items_hidden = def.doc_items_hidden, + _doc_items_create_entry = def._doc_items_create_entry, + drawtype = "mesh", + mesh = def.mesh_floor, + inventory_image = def.icon, + wield_image = def.icon, + tiles = def.tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + liquids_pointable = false, + light_source = def.light, + groups = groups, + drop = def.drop or itemstring, + selection_box = { + type = "wallmounted", + wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16}, + wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, + }, + sounds = def.sounds, + node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + -- no interaction possible with entities, for now. + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Call on_rightclick if the pointed node defines it + if placer and not placer: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(under, node, placer, itemstack) or itemstack + end + end + + local above = pointed_thing.above + local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}) + + if check_placement_allowed(node, wdir) == false then + return itemstack + end + + local itemstring = itemstack:get_name() + local fakestack = ItemStack(itemstack) + local idef = fakestack:get_definition() + local retval + + if wdir == 1 then + retval = fakestack:set_name(itemstring) + else + retval = fakestack:set_name(itemstring_wall) + end + if not retval then + return itemstack + end + + local success + itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) + itemstack:set_name(itemstring) + + if success and idef.sounds and idef.sounds.place then + minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true) + end + return itemstack + end, + on_rotate = false, + on_construct = def.particles and spawn_flames_floor, + on_destruct = def.particles and remove_flames, + } + minetest.register_node(itemstring, floordef) + + local groups_wall = table.copy(groups) + groups_wall.torch = 2 + + local walldef = { + drawtype = "mesh", + mesh = def.mesh_wall, + tiles = def.tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + light_source = def.light, + groups = groups_wall, + drop = def.drop or itemstring, + selection_box = { + type = "wallmounted", + wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1}, + wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1}, + wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1}, + }, + sounds = def.sounds, + on_rotate = false, + on_construct = def.particles and spawn_flames_wall, + on_destruct = def.particles and remove_flames, + } + minetest.register_node(itemstring_wall, walldef) + + -- Add entry alias for the Help + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall) + end +end + +minetest.register_lbm({ + label = "Torch flame particles", + name = "mcl_torches:flames", + nodenames = {"group:torch_particles"}, + run_at_every_load = true, + action = function(pos, node) + local torch_group = minetest.get_node_group(node.name, "torch") + if torch_group == 1 then + spawn_flames_floor(pos) + elseif torch_group == 2 then + spawn_flames_wall(pos) + end + end, +}) diff --git a/mods/ITEMS/mcl_torches/init.lua b/mods/ITEMS/mcl_torches/init.lua index 451a8dfad..1102731c1 100644 --- a/mods/ITEMS/mcl_torches/init.lua +++ b/mods/ITEMS/mcl_torches/init.lua @@ -1,338 +1,6 @@ -local S = minetest.get_translator("mcl_torches") -local LIGHT_TORCH = minetest.LIGHT_MAX - -local spawn_flames_floor = function(pos) - -- Flames - mcl_particles.add_node_particlespawner(pos, { - amount = 8, - time = 0, - minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }), - maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, - minexptime = 0.3, - maxexptime = 0.6, - minsize = 0.7, - maxsize = 2, - texture = "mcl_particles_flame.png", - glow = LIGHT_TORCH, - }, "low") - -- Smoke - mcl_particles.add_node_particlespawner(pos, { - amount = 0.5, - time = 0, - minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }), - maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 1.5, - maxsize = 1.5, - texture = "mcl_particles_smoke_anim.png", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.05, - }, - }, "medium") -end - -local spawn_flames_wall = function(pos, param2) - local minrelpos, maxrelpos - local dir = minetest.wallmounted_to_dir(param2) - if dir.x < 0 then - minrelpos = { x = -0.38, y = 0.04, z = -0.1 } - maxrelpos = { x = -0.2, y = 0.14, z = 0.1 } - elseif dir.x > 0 then - minrelpos = { x = 0.2, y = 0.04, z = -0.1 } - maxrelpos = { x = 0.38, y = 0.14, z = 0.1 } - elseif dir.z < 0 then - minrelpos = { x = -0.1, y = 0.04, z = -0.38 } - maxrelpos = { x = 0.1, y = 0.14, z = -0.2 } - elseif dir.z > 0 then - minrelpos = { x = -0.1, y = 0.04, z = 0.2 } - maxrelpos = { x = 0.1, y = 0.14, z = 0.38 } - else - return - end - -- Flames - mcl_particles.add_node_particlespawner(pos, { - amount = 8, - time = 0, - minpos = vector.add(pos, minrelpos), - maxpos = vector.add(pos, maxrelpos), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, - minexptime = 0.3, - maxexptime = 0.6, - minsize = 0.7, - maxsize = 2, - texture = "mcl_particles_flame.png", - glow = LIGHT_TORCH, - }, "low") - -- Smoke - mcl_particles.add_node_particlespawner(pos, { - amount = 0.5, - time = 0, - minpos = vector.add(pos, minrelpos), - maxpos = vector.add(pos, maxrelpos), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 1.5, - maxsize = 1.5, - texture = "mcl_particles_smoke_anim.png", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.05, - }, - }, "medium") -end - -local remove_flames = function(pos) - mcl_particles.delete_node_particlespawners(pos) -end - --- --- 3d torch part --- - --- Check if placement at given node is allowed -local function check_placement_allowed(node, wdir) - -- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed. - -- Special allowed nodes: - -- * soul sand - -- * mob spawner - -- * chorus flower - -- * glass, barrier, ice - -- * Fence, wall, end portal frame with ender eye: Only on top - -- * Slab, stairs: Only on top if upside down - - -- Special forbidden nodes: - -- * Piston, sticky piston - local def = minetest.registered_nodes[node.name] - if not def then - return false - -- No ceiling torches - elseif wdir == 0 then - return false - elseif not def.buildable_to then - if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and - ((not def.groups.solid) or (not def.groups.opaque)) then - -- Only allow top placement on these nodes - if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then - if wdir ~= 1 then - return false - end - else - return false - end - elseif minetest.get_item_group(node.name, "piston") >= 1 then - return false - end - end - return true -end - mcl_torches = {} -mcl_torches.register_torch = function(substring, description, doc_items_longdesc, doc_items_usagehelp, icon, mesh_floor, mesh_wall, tiles, light, groups, sounds, moredef, moredef_floor, moredef_wall) - local itemstring = minetest.get_current_modname()..":"..substring - local itemstring_wall = minetest.get_current_modname()..":"..substring.."_wall" - - if light == nil then light = minetest.LIGHT_MAX end - if mesh_floor == nil then mesh_floor = "mcl_torches_torch_floor.obj" end - if mesh_wall == nil then mesh_wall = "mcl_torches_torch_wall.obj" end - if groups == nil then groups = {} end - - groups.attached_node = 1 - groups.torch = 1 - groups.dig_by_water = 1 - groups.destroy_by_lava_flow = 1 - groups.dig_by_piston = 1 - - local floordef = { - description = description, - _doc_items_longdesc = doc_items_longdesc, - _doc_items_usagehelp = doc_items_usagehelp, - drawtype = "mesh", - mesh = mesh_floor, - inventory_image = icon, - wield_image = icon, - tiles = tiles, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - liquids_pointable = false, - light_source = light, - groups = groups, - drop = itemstring, - selection_box = { - type = "wallmounted", - wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16}, - wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, - }, - sounds = sounds, - node_placement_prediction = "", - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - -- no interaction possible with entities, for now. - return itemstack - end - - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end - - -- Call on_rightclick if the pointed node defines it - if placer and not placer: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(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}) - - if check_placement_allowed(node, wdir) == false then - return itemstack - end - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - local idef = fakestack:get_definition() - local retval - - if wdir == 1 then - retval = fakestack:set_name(itemstring) - else - retval = fakestack:set_name(itemstring_wall) - end - if not retval then - return itemstack - end - - local success - itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - - if success and idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true) - end - return itemstack - end, - on_rotate = false, - } - if moredef ~= nil then - for k,v in pairs(moredef) do - floordef[k] = v - end - end - if moredef_floor ~= nil then - for k,v in pairs(moredef_floor) do - floordef[k] = v - end - end - minetest.register_node(itemstring, floordef) - - local groups_wall = table.copy(groups) - groups_wall.torch = 2 - - local walldef = { - drawtype = "mesh", - mesh = mesh_wall, - tiles = tiles, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - light_source = light, - groups = groups_wall, - drop = itemstring, - selection_box = { - type = "wallmounted", - wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1}, - wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1}, - wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1}, - }, - sounds = sounds, - on_rotate = false, - } - if moredef ~= nil then - for k,v in pairs(moredef) do - walldef[k] = v - end - end - if moredef_wall ~= nil then - for k,v in pairs(moredef_wall) do - walldef[k] = v - end - end - minetest.register_node(itemstring_wall, walldef) - - - -- Add entry alias for the Help - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall) - end - -end - -mcl_torches.register_torch("torch", - S("Torch"), - S("Torches are light sources which can be placed at the side or on the top of most blocks."), - nil, - "default_torch_on_floor.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {{ - name = "default_torch_on_floor_animated.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} - }}, - LIGHT_TORCH, - {dig_immediate=3, torch=1, deco_block=1}, - mcl_sounds.node_sound_wood_defaults(), - {_doc_items_hidden = false, - on_destruct = function(pos) - remove_flames(pos) - end}, - {on_construct = function(pos) - spawn_flames_floor(pos) - end}, - {on_construct = function(pos) - local node = minetest.get_node(pos) - spawn_flames_wall(pos, node.param2) - end}) - -minetest.register_craft({ - output = "mcl_torches:torch 4", - recipe = { - { "group:coal" }, - { "mcl_core:stick" }, - } -}) - -minetest.register_lbm({ - label = "Torch flame particles", - name = "mcl_torches:flames", - nodenames = {"mcl_torches:torch", "mcl_torches:torch_wall"}, - run_at_every_load = true, - action = function(pos, node) - if node.name == "mcl_torches:torch" then - spawn_flames_floor(pos) - elseif node.name == "mcl_torches:torch_wall" then - spawn_flames_wall(pos, node.param2) - end - end, -}) +local modpath = minetest.get_modpath("mcl_torches") +dofile(modpath .. "/api.lua") +dofile(modpath .. "/register.lua") diff --git a/mods/ITEMS/mcl_torches/register.lua b/mods/ITEMS/mcl_torches/register.lua new file mode 100644 index 000000000..4218889d9 --- /dev/null +++ b/mods/ITEMS/mcl_torches/register.lua @@ -0,0 +1,27 @@ +local S = minetest.get_translator("mcl_torches") + +mcl_torches.register_torch({ + name = "torch", + description = S("Torch"), + doc_items_longdesc = S("Torches are light sources which can be placed at the side or on the top of most blocks."), + doc_items_hidden = false, + icon = "default_torch_on_floor.png", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + -- this is 15 in minecraft + light = 14, + groups = {dig_immediate = 3, deco_block = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + particles = true, +}) + +minetest.register_craft({ + output = "mcl_torches:torch 4", + recipe = { + {"group:coal"}, + {"mcl_core:stick"}, + } +}) +