From 23f69dfd1e8bac7469a00ecb6a1de5161f2475f8 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sat, 20 Mar 2021 17:47:04 +0800 Subject: [PATCH 01/52] Core implementation of MC-like kelp drops. Highlights: * Kelp should no longer be able to survive without water (by decreasing its height) * When kelp is destroyed, each segment now drop a single kelp similar to MC. * Significantly refactor how kelp grows and dig. Possible optimizations might be included. --- mods/ITEMS/REDSTONE/mesecons_mvps/init.lua | 6 +- mods/ITEMS/mcl_ocean/kelp.lua | 270 +++++++++++++-------- 2 files changed, 169 insertions(+), 107 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua index 669edbcbba..8cd5ae872a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua @@ -74,6 +74,7 @@ function mesecon.is_mvps_unsticky(node, pulldir, stack, stackid) end -- Functions to be called on mvps movement +-- See also the callback function mesecon.register_on_mvps_move(callback) mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback end @@ -405,17 +406,20 @@ mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_brown") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_light_blue") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_pink") +-- Includes node heat when moving them mesecon.register_on_mvps_move(mesecon.move_hot_nodes) --- Check for falling after moving node mesecon.register_on_mvps_move(function(moved_nodes) for i = 1, #moved_nodes do local moved_node = moved_nodes[i] + -- Check for falling after moving node mesecon.on_placenode(moved_node.pos, moved_node.node) minetest.after(0, function() minetest.check_for_falling(moved_node.oldpos) minetest.check_for_falling(moved_node.pos) end) + + -- Callback for on_mvps_move stored in nodedef local node_def = minetest.registered_nodes[moved_node.node.name] if node_def and node_def.mesecon and node_def.mesecon.on_mvps_move then node_def.mesecon.on_mvps_move(moved_node.pos, moved_node.node, diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 2e0dfe1a51..9d6c092793 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -9,29 +9,67 @@ local surfaces = { { "gravel", "mcl_core:gravel", 1 }, } -local function get_kelp_top(pos, node) - local size = math.ceil(node.param2 / 16) - local pos_water = table.copy(pos) - pos_water.y = pos_water.y + size - return pos_water, minetest.get_node(pos_water) -end - -local function get_submerged(node_water) - local def_water = minetest.registered_nodes[node_water.name] - -- Submerged in water? - if minetest.get_item_group(node_water.name, "water") then - if def_water.liquidtype == "source" then +-- Is this water? +local function is_submerged(node, nodedef) + if minetest.get_item_group(node.name, "water") ~= 0 then + local liquidtype = nodedef.liquidtype + -- TODO: is it OK to optimize this to: + -- return nodedef.liquidtype + if liquidtype == "source" then return "source" - elseif def_water.liquidtype == "flowing" then + elseif liquidtype == "flowing" then return "flowing" + else + minetest.chat_send_all("its NOT OK to optimize into return nodedef.liquidtype :(") end end return false end +-- Is the water downward flowing? +-- (kelp can grow inside downward flowing water) +local function is_downward_flowing(pos, node, nodedef, is_above) + + result = (math.floor(node.param2 / 8) % 2) == 1 + if not (result or is_above) then + -- If not, also check node above (this is needed due a weird quirk in the definition of + -- "downwards flowing" liquids in Minetest) + local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + local nodedef_above = minetest.registered_nodes[node_above.name] + result = is_submerged(node_above, nodedef_above) or is_downward_flowing(pos, node_above, nodedef_above, true) + end + return result +end + +local function get_kelp_height(param2) + return math.floor(param2 / 16) +end + +local function get_kelp_top(pos, node) + local size = math.ceil(node.param2 / 16) + local pos_top = table.copy(pos) + pos_top.y = pos_top.y + size + return pos_top, minetest.get_node(pos_top) +end + +-- Obtain position of the first kelp unsubmerged +local function get_kelp_unsubmerged(pos, node) + local x,y,z = pos.x, pos.y, pos.z + local height = get_kelp_height(node.param2) + for i=1,height do + local walk_pos = {x=x, y=y + i, z=z} + if minetest.get_item_group(minetest.get_node(walk_pos).name, "water") == 0 then + return walk_pos + end + end + return nil +end + local function grow_param2_step(param2, snap_into_grid) local old_param2 = param2 param2 = param2 + 16 + -- TODO: allow kelp to grow bypass this limit according to MC rules. + -- https://minecraft.gamepedia.com/Kelp if param2 > 240 then param2 = 240 end @@ -41,30 +79,6 @@ local function grow_param2_step(param2, snap_into_grid) return param2, param2 ~= old_param2 end -local function kelp_check_place(pos_above, node_above, def_above) - if minetest.get_item_group(node_above.name, "water") == 0 then - return false - end - local can_place = false - if (def_above.liquidtype == "source") then - can_place = true - elseif (def_above.liquidtype == "flowing") then - -- Check if bit 3 (downwards flowing) is set - can_place = (math.floor(node_above.param2 / 8) % 2) == 1 - if not can_place then - -- If not, also check node above (this is needed due a weird quirk in the definition of - -- "downwards flowing" liquids in Minetest) - local node_above_above = minetest.get_node({x=pos_above.x,y=pos_above.y+1,z=pos_above.z}) - local naa_def = minetest.registered_nodes[node_above_above.name] - can_place = naa_def.liquidtype == "source" - if not can_place then - can_place = (naa_def.liquidtype == "flowing") and ((math.floor(node_above_above.param2 / 8) % 2) == 1) - end - end - end - return can_place -end - local function kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then return itemstack @@ -74,8 +88,9 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local pos_under = pointed_thing.under local pos_above = pointed_thing.above local node_under = minetest.get_node(pos_under) + local nu_name = node_under.name local node_above = minetest.get_node(pos_above) - local def_under = minetest.registered_nodes[node_under.name] + local def_under = minetest.registered_nodes[nu_name] local def_above = minetest.registered_nodes[node_above.name] if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then @@ -93,56 +108,56 @@ local function kelp_on_place(itemstack, placer, pointed_thing) return itemstack end - local grow_kelp = false - -- Select a kelp node when placed on surface node - if node_under.name == "mcl_core:dirt" then - node_under.name = "mcl_ocean:kelp_dirt" - elseif node_under.name == "mcl_core:sand" then - node_under.name = "mcl_ocean:kelp_sand" - elseif node_under.name == "mcl_core:redsand" then - node_under.name = "mcl_ocean:kelp_redsand" - elseif node_under.name == "mcl_core:gravel" then - node_under.name = "mcl_ocean:kelp_gravel" - elseif minetest.get_item_group(node_under.name, "kelp") == 1 then - -- Place kelp on kelp = grow kelp by 1 node length - node_under.param2, grow_kelp = grow_param2_step(node_under.param2) - if not grow_kelp then + local new_kelp = false + + -- When placed on kelp. + if minetest.get_item_group(nu_name, "kelp") == 1 then + node_under.param2, new_kelp = grow_param2_step(node_under.param2) + + -- Kelp must not reach the height limit. + -- Kelp must be placed on top of kelp to add kelp. + if not new_kelp or + pos_under.y >= pos_above.y or pos_under.x ~= pos_above.x or pos_under.z ~= pos_above.z then return itemstack end + + -- TODO: is this even possible??? + if pos_under.y < pos_above.y and (pos_under.x ~= pos_above.x or pos_under.z ~= pos_above.z) then + minetest.chat_send_all(dump2(pos_under, "pos_under")) --DEBUG + end + + -- New kelp top must also be submerged in water. + local pos_top, node_top = get_kelp_top(pos_under, node_under) + local def_top = minetest.registered_nodes[node_top.name] + if not (is_submerged(node_top, def_top) and is_downward_flowing(pos_top, node_top, def_top)) then + return itemstack + end + + -- When placed on surface. else - return itemstack + -- Surface must support kelp + for _,surface in pairs(surfaces) do + if nu_name == surface[2] then + node_under.name = "mcl_ocean:kelp_" ..surface[1] + new_kelp = true + end + end + + -- The surface must support kelp + -- Kelp must be placed on top of surface to add new kelp. + if not new_kelp or pos_under.y >= pos_above.y then + return itemstack + end + + -- New kelp must also be submerged in water. + if not (is_submerged(node_above, def_above) and is_downward_flowing(pos_above, node_above, def_above)) then + return itemstack + end + node_under.param2 = minetest.registered_items[nu_name].place_param2 or 16 end - local submerged = false - if grow_kelp then - -- Kelp placed on kelp ... - -- Kelp can be placed on top of another kelp to make it grow - if pos_under.y >= pos_above.y or pos_under.x ~= pos_above.x or pos_under.z ~= pos_above.z then - -- Placed on side or below node, abort - return itemstack - end - -- New kelp top must also be submerged in water - local top_pos, top_node = get_kelp_top(pos_under, node_under) - local top_def = minetest.registered_nodes[top_node.name] - submerged = kelp_check_place(top_pos, top_node, top_def) - if not submerged then - -- Not submerged in water, abort - return itemstack - end - else - -- New kelp placed ... - if pos_under.y >= pos_above.y then - -- Placed on side or below node, abort - return itemstack - end - -- Kelp can be placed inside a water source or water flowing downwards on top of a surface node - local can_place = kelp_check_place(pos_above, node_above, def_above) - if not can_place then - return itemstack - end - node_under.param2 = minetest.registered_items[node_under.name].place_param2 or 16 - end - -- Place or grow kelp - local def_node = minetest.registered_items[node_under.name] + + -- Play sound, set surface/kelp and take away an item + local def_node = minetest.registered_items[nu_name] if def_node.sounds then minetest.sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end @@ -154,8 +169,36 @@ local function kelp_on_place(itemstack, placer, pointed_thing) return itemstack end -local get_kelp_height = function(param2) - return math.floor(param2 / 16) +local function kelp_drop(pos, height) + local x,y,z = pos.x,pos.y,pos.z + for i=1,height do + minetest.add_item({x=x, y=y+i, z=z}, "mcl_ocean:kelp") + end +end + +-- Dig kelp: +-- Each kelp from broken stem until the top drop a single item +-- Kelp's height decreases to the height below dig_pos +local function kelp_dig(dig_pos, pos, node, is_drop) + local param2 = node.param2 + local height = get_kelp_height(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: invoke after_dig_node to set_node + if new_height == 0 then + if is_drop then + kelp_drop(dig_pos, height) + end + minetest.set_node(pos, {name=minetest.registered_nodes[node.name].node_dig_prediction}) + + -- Digs the kelp beginning at a height + else + if is_drop then + kelp_drop(dig_pos, height - new_height) + end + minetest.set_node(pos, {name=node.name, param=node.param, param2=16*new_height}) + end end minetest.register_craftitem("mcl_ocean:kelp", { @@ -220,19 +263,16 @@ for s=1, #surfaces do sounds = sounds, node_dig_prediction = surfaces[s][2], after_dig_node = function(pos) - minetest.set_node(pos, {name=surfaces[s][2]}) + minetest.set_node(pos, {name=surface[s][2]}) end, + -- NOTE: whenever it becomes possible to fully implement kelp without the + -- plantlike_rooted limitation, please adapt the code accordingly. on_dig = function(pos, node, digger) - -- Drop kelp as item; item count depends on height - local dname = "" - if digger then - dname = digger:get_player_name() + local is_drop = true + if digger and minetest.is_creative_enabled(digger:get_player_name()) then + is_drop = false end - local creative = minetest.is_creative_enabled(dname) - if not creative then - minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_ocean:kelp "..get_kelp_height(node.param2)) - end - minetest.node_dig(pos, node, digger) + kelp_dig(pos, pos, node, is_drop) end, drop = "", -- drops are handled in on_dig _mcl_falling_node_alternative = alt, @@ -314,28 +354,46 @@ minetest.register_craft({ minetest.register_abm({ label = "Kelp growth", nodenames = { "group:kelp" }, - interval = 45, - chance = 12, + -- interval = 45, + -- chance = 12, + interval = 1, + chance = 1, catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) local grown -- Grow kelp by 1 node length if it would grow inside water - node.param2, grown = grow_param2_step(node.param2, true) - local top, top_node = get_kelp_top(pos, node) - local submerged = get_submerged(top_node) - if grown then + node.param2, grow = grow_param2_step(node.param2, true) + local pos_top, node_top = get_kelp_top(pos, node) + local def_top = minetest.registered_nodes[node_top.name] + local submerged = is_submerged(node_top, def_top) + if grow then if submerged == "source" then -- Liquid source: Grow normally minetest.set_node(pos, node) - elseif submerged == "flowing" then + + elseif submerged == "flowing" and is_downward_flowing(pos_top, node_top, def_top) then -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source minetest.set_node(pos, node) - local def_liq = minetest.registered_nodes[top_node.name] - local alt_liq = def_liq and def_liq.liquid_alternative_source + local alt_liq = def_top.liquid_alternative_source if alt_liq then - minetest.set_node(top, {name=alt_liq}) + minetest.set_node(pos_top, {name=alt_liq}) end end end end, }) + +-- Break kelp not underwater. +minetest.register_abm({ + label = "Kelp drops", + nodenames = { "group:kelp" }, + interval = 0.25, + chance = 1, + catch_up = false, + action = function(pos, node) + local dig_pos = get_kelp_unsubmerged(pos, node) + if dig_pos then + kelp_dig(dig_pos, pos, node, true) + end + end +}) From ebf9f8c918f74255ae0f4adfc6440f7cd81cd9a0 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sun, 21 Mar 2021 12:16:56 +0800 Subject: [PATCH 02/52] placing kelp now creates water sources, small refactoring. --- mods/ITEMS/mcl_ocean/kelp.lua | 118 +++++++++++++++------------------- 1 file changed, 52 insertions(+), 66 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 9d6c092793..4d5bf094c3 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -1,7 +1,9 @@ local S = minetest.get_translator("mcl_ocean") local mod_doc = minetest.get_modpath("doc") ~= nil +-- NOTE: whenever it becomes possible to fully implement kelp without the +-- plantlike_rooted limitation, please adapt the code accordingly. --- List of supported surfaces for seagrass and kelp +-- List of supported surfaces for seagrass and kelp. local surfaces = { { "dirt", "mcl_core:dirt" }, { "sand", "mcl_core:sand", 1 }, @@ -12,22 +14,13 @@ local surfaces = { -- Is this water? local function is_submerged(node, nodedef) if minetest.get_item_group(node.name, "water") ~= 0 then - local liquidtype = nodedef.liquidtype - -- TODO: is it OK to optimize this to: - -- return nodedef.liquidtype - if liquidtype == "source" then - return "source" - elseif liquidtype == "flowing" then - return "flowing" - else - minetest.chat_send_all("its NOT OK to optimize into return nodedef.liquidtype :(") - end + return nodedef.liquidtype -- Expected only "source" and "flowing" from water liquids end return false end -- Is the water downward flowing? --- (kelp can grow inside downward flowing water) +-- (kelp can grow/be placed inside downward flowing water) local function is_downward_flowing(pos, node, nodedef, is_above) result = (math.floor(node.param2 / 8) % 2) == 1 @@ -41,10 +34,12 @@ local function is_downward_flowing(pos, node, nodedef, is_above) return result end +-- Converts param2 to kelp height. local function get_kelp_height(param2) return math.floor(param2 / 16) end +-- Obtain pos and node of the top of kelp. local function get_kelp_top(pos, node) local size = math.ceil(node.param2 / 16) local pos_top = table.copy(pos) @@ -52,7 +47,7 @@ local function get_kelp_top(pos, node) return pos_top, minetest.get_node(pos_top) end --- Obtain position of the first kelp unsubmerged +-- Obtain position of the first kelp unsubmerged. local function get_kelp_unsubmerged(pos, node) local x,y,z = pos.x, pos.y, pos.z local height = get_kelp_height(node.param2) @@ -65,20 +60,32 @@ local function get_kelp_unsubmerged(pos, node) return nil end -local function grow_param2_step(param2, snap_into_grid) - local old_param2 = param2 - param2 = param2 + 16 +-- Obtain next param2 if grown +local function grow_param2_step(param2) -- TODO: allow kelp to grow bypass this limit according to MC rules. -- https://minecraft.gamepedia.com/Kelp + + local old_param2 = param2 + param2 = param2+16 - param2 % 16 if param2 > 240 then param2 = 240 end - if snap_into_grid and (param2 % 16 ~= 0) then - param2 = param2 - (param2 % 16) - end return param2, param2 ~= old_param2 end +local function kelp_place(pos, node, pos_top, def_top, is_downward_flowing) + -- Liquid source: Grow normally + minetest.set_node(pos, node) + + -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source + if is_downward_flowing then + local alt_liq = def_top.liquid_alternative_source + if alt_liq then + minetest.set_node(pos_top, {name=alt_liq}) + end + end +end + local function kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then return itemstack @@ -89,9 +96,7 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local pos_above = pointed_thing.above local node_under = minetest.get_node(pos_under) local nu_name = node_under.name - local node_above = minetest.get_node(pos_above) local def_under = minetest.registered_nodes[nu_name] - local def_above = minetest.registered_nodes[node_above.name] if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, @@ -109,59 +114,52 @@ local function kelp_on_place(itemstack, placer, pointed_thing) end local new_kelp = false + local is_downward_flowing = false + local pos_top, node_top, def_top -- When placed on kelp. if minetest.get_item_group(nu_name, "kelp") == 1 then node_under.param2, new_kelp = grow_param2_step(node_under.param2) - -- Kelp must not reach the height limit. - -- Kelp must be placed on top of kelp to add kelp. - if not new_kelp or - pos_under.y >= pos_above.y or pos_under.x ~= pos_above.x or pos_under.z ~= pos_above.z then - return itemstack - end - - -- TODO: is this even possible??? - if pos_under.y < pos_above.y and (pos_under.x ~= pos_above.x or pos_under.z ~= pos_above.z) then - minetest.chat_send_all(dump2(pos_under, "pos_under")) --DEBUG - end - - -- New kelp top must also be submerged in water. - local pos_top, node_top = get_kelp_top(pos_under, node_under) - local def_top = minetest.registered_nodes[node_top.name] - if not (is_submerged(node_top, def_top) and is_downward_flowing(pos_top, node_top, def_top)) then + -- Kelp must also be placed on top of kelp to add kelp. + if not new_kelp or pos_under.y >= pos_above.y then return itemstack end + pos_top, node_top = get_kelp_top(pos_under, node_under) + def_top = minetest.registered_nodes[node_top.name] -- When placed on surface. else - -- Surface must support kelp for _,surface in pairs(surfaces) do + -- Surface must support kelp if nu_name == surface[2] then node_under.name = "mcl_ocean:kelp_" ..surface[1] + node_under.param2 = minetest.registered_items[nu_name].place_param2 or 16 new_kelp = true end end - -- The surface must support kelp - -- Kelp must be placed on top of surface to add new kelp. + -- Kelp must also be placed on top of surface to add new kelp. if not new_kelp or pos_under.y >= pos_above.y then return itemstack end - - -- New kelp must also be submerged in water. - if not (is_submerged(node_above, def_above) and is_downward_flowing(pos_above, node_above, def_above)) then - return itemstack - end - node_under.param2 = minetest.registered_items[nu_name].place_param2 or 16 + pos_top = pos_above + node_top = minetest.get_node(pos_above) + def_top = minetest.registered_nodes[node_above.name] end - -- Play sound, set surface/kelp and take away an item + -- New kelp must also be submerged in water. + is_downward_flowing = is_downward_flowing(pos_top, node_top, def_top) + if not (is_submerged(node_top, def_top) and is_downward_flowing) then + return itemstack + end + + -- Play sound, place surface/kelp and take away an item local def_node = minetest.registered_items[nu_name] if def_node.sounds then minetest.sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - minetest.set_node(pos_under, node_under) + kelp_place(pos_under, node_under, pos_top, def_top, is_downward_flowing) if not minetest.is_creative_enabled(player_name) then itemstack:take_item() end @@ -169,6 +167,7 @@ local function kelp_on_place(itemstack, placer, pointed_thing) return itemstack end +-- From kelp at pos, drop kelp until reaching its height. local function kelp_drop(pos, height) local x,y,z = pos.x,pos.y,pos.z for i=1,height do @@ -265,8 +264,6 @@ for s=1, #surfaces do after_dig_node = function(pos) minetest.set_node(pos, {name=surface[s][2]}) end, - -- NOTE: whenever it becomes possible to fully implement kelp without the - -- plantlike_rooted limitation, please adapt the code accordingly. on_dig = function(pos, node, digger) local is_drop = true if digger and minetest.is_creative_enabled(digger:get_player_name()) then @@ -360,25 +357,14 @@ minetest.register_abm({ chance = 1, catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) - local grown + local grow -- Grow kelp by 1 node length if it would grow inside water - node.param2, grow = grow_param2_step(node.param2, true) + node.param2, grow = grow_param2_step(node.param2) local pos_top, node_top = get_kelp_top(pos, node) local def_top = minetest.registered_nodes[node_top.name] - local submerged = is_submerged(node_top, def_top) - if grow then - if submerged == "source" then - -- Liquid source: Grow normally - minetest.set_node(pos, node) - - elseif submerged == "flowing" and is_downward_flowing(pos_top, node_top, def_top) then - -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source - minetest.set_node(pos, node) - local alt_liq = def_top.liquid_alternative_source - if alt_liq then - minetest.set_node(pos_top, {name=alt_liq}) - end - end + if grow and is_submerged(node_top, def_top) then + kelp_place(pos, node, pos_top, def_top, + is_downward_flowing(pos_top, node_top, def_top)) end end, }) From ca635b69be351a8cd8dfcaafa2536f659932e6c9 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sun, 21 Mar 2021 14:06:54 +0800 Subject: [PATCH 03/52] Various fixes. --- mods/ITEMS/mcl_ocean/kelp.lua | 39 +++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 4d5bf094c3..73b2aaeb42 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -2,6 +2,8 @@ local S = minetest.get_translator("mcl_ocean") local mod_doc = minetest.get_modpath("doc") ~= nil -- NOTE: whenever it becomes possible to fully implement kelp without the -- plantlike_rooted limitation, please adapt the code 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. -- List of supported surfaces for seagrass and kelp. local surfaces = { @@ -25,11 +27,13 @@ local function is_downward_flowing(pos, node, nodedef, is_above) result = (math.floor(node.param2 / 8) % 2) == 1 if not (result or is_above) then - -- If not, also check node above (this is needed due a weird quirk in the definition of - -- "downwards flowing" liquids in Minetest) + -- If not, also check node above + -- (this is needed due a weird quirk in the definition of "downwards flowing" + -- liquids in Minetest) local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) local nodedef_above = minetest.registered_nodes[node_above.name] - result = is_submerged(node_above, nodedef_above) or is_downward_flowing(pos, node_above, nodedef_above, true) + result = is_submerged(node_above, nodedef_above) + or is_downward_flowing(pos, node_above, nodedef_above, true) end return result end @@ -114,7 +118,7 @@ local function kelp_on_place(itemstack, placer, pointed_thing) end local new_kelp = false - local is_downward_flowing = false + local downward_flowing = false local pos_top, node_top, def_top -- When placed on kelp. @@ -136,6 +140,7 @@ local function kelp_on_place(itemstack, placer, pointed_thing) node_under.name = "mcl_ocean:kelp_" ..surface[1] node_under.param2 = minetest.registered_items[nu_name].place_param2 or 16 new_kelp = true + break end end @@ -143,14 +148,15 @@ local function kelp_on_place(itemstack, placer, pointed_thing) if not new_kelp or pos_under.y >= pos_above.y then return itemstack end + pos_top = pos_above node_top = minetest.get_node(pos_above) - def_top = minetest.registered_nodes[node_above.name] + def_top = minetest.registered_nodes[node_top.name] end -- New kelp must also be submerged in water. - is_downward_flowing = is_downward_flowing(pos_top, node_top, def_top) - if not (is_submerged(node_top, def_top) and is_downward_flowing) then + downward_flowing = is_downward_flowing(pos_top, node_top, def_top) + if not (is_submerged(node_top, def_top) or downward_flowing) then return itemstack end @@ -159,7 +165,7 @@ local function kelp_on_place(itemstack, placer, pointed_thing) if def_node.sounds then minetest.sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - kelp_place(pos_under, node_under, pos_top, def_top, is_downward_flowing) + kelp_place(pos_under, node_under, pos_top, def_top, downward_flowing) if not minetest.is_creative_enabled(player_name) then itemstack:take_item() end @@ -175,26 +181,24 @@ local function kelp_drop(pos, height) end end --- Dig kelp: --- Each kelp from broken stem until the top drop a single item --- Kelp's height decreases to the height below dig_pos local function kelp_dig(dig_pos, pos, node, is_drop) local param2 = node.param2 - local height = get_kelp_height(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: invoke after_dig_node to set_node - if new_height == 0 then + if new_height <= 0 then if is_drop then - kelp_drop(dig_pos, height) + kelp_drop(dig_pos, get_kelp_height(param2)) end - minetest.set_node(pos, {name=minetest.registered_nodes[node.name].node_dig_prediction}) + minetest.set_node(pos, { + name=minetest.registered_nodes[node.name].node_dig_prediction, + param=node.param, param2=0 }) -- Digs the kelp beginning at a height else if is_drop then - kelp_drop(dig_pos, height - new_height) + kelp_drop(dig_pos, get_kelp_height(param2) - new_height) end minetest.set_node(pos, {name=node.name, param=node.param, param2=16*new_height}) end @@ -264,7 +268,10 @@ for s=1, #surfaces do after_dig_node = function(pos) minetest.set_node(pos, {name=surface[s][2]}) end, + -- TODO: add ability to detect whether the kelp or the surface is dug. + -- Currently, digging the surface gives sand, which isn't ideal. on_dig = function(pos, node, digger) + minetest.chat_send_all("mo2") local is_drop = true if digger and minetest.is_creative_enabled(digger:get_player_name()) then is_drop = false From ce123d4676e5aabf6a878509dc7f933b346a2b22 Mon Sep 17 00:00:00 2001 From: AFCMS Date: Sun, 28 Mar 2021 00:02:35 +0100 Subject: [PATCH 04/52] 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 0000000000..79b9770b5d --- /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 05/52] 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 0000000000..d9f54e4bd0 --- /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 06/52] 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 d9f54e4bd0..7ebb4cc87d 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 07/52] 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 7ebb4cc87d..0542e45190 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 08/52] 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 0542e45190..f3282c9752 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 09/52] 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 f3282c9752..20e85036b9 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 10/52] 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 0000000000..8d9df6ca50 --- /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 11/52] 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 0000000000..71cad335b1 --- /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 12/52] 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 0000000000..cb0e9252d9 --- /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 13/52] 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 0000000000..a5509431c2 --- /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 e76a0ba6e859a4aba665a849864f9799b87a8b87 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sun, 28 Mar 2021 14:11:08 +0800 Subject: [PATCH 14/52] Added kelp API and additional refactorings. WIP: register nodetimers for kelp --- mods/ITEMS/mcl_ocean/kelp.lua | 499 ++++++++++++++++++++++------------ 1 file changed, 318 insertions(+), 181 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 73b2aaeb42..fe2266789c 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -1,94 +1,163 @@ -local S = minetest.get_translator("mcl_ocean") -local mod_doc = minetest.get_modpath("doc") ~= nil -- NOTE: whenever it becomes possible to fully implement kelp without the -- plantlike_rooted limitation, please adapt the code 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. --- List of supported surfaces for seagrass and kelp. -local surfaces = { - { "dirt", "mcl_core:dirt" }, - { "sand", "mcl_core:sand", 1 }, - { "redsand", "mcl_core:redsand", 1 }, - { "gravel", "mcl_core:gravel", 1 }, -} +local S = minetest.get_translator("mcl_ocean") +local mod_doc = minetest.get_modpath("doc") ~= nil + +-------------------------------------------------------------------------------- +-- local-ify runtime functions +-------------------------------------------------------------------------------- +-- objects +local registered_items = minetest.registered_items +local registered_nodes = minetest.registered_nodes + +-- functions +local mt_get_item_group = minetest.get_item_group +local mt_get_node = minetest.get_node +local mt_set_node = minetest.set_node +local mt_add_item = minetest.add_item +local mt_sound_play = minetest.sound_play +local mt_is_creative_enabled = minetest.is_creative_enabled +local mt_is_protected = minetest.is_protected +local mt_hash_node_position = minetest.hash_node_position +local mt_get_node_timer = minetest.get_node_timer + +-- DEBUG: functions +local chatlog = minetest.chat_send_all + +-------------------------------------------------------------------------------- +-- Kelp API +-------------------------------------------------------------------------------- + +kelp = {} -- Is this water? +-- Returns the liquidtype, if indeed water. local function is_submerged(node, nodedef) - if minetest.get_item_group(node.name, "water") ~= 0 then + if mt_get_item_group(node.name, "water") ~= 0 then return nodedef.liquidtype -- Expected only "source" and "flowing" from water liquids end return false end +kelp.is_submerged = is_submerged + -- Is the water downward flowing? -- (kelp can grow/be placed inside downward flowing water) local function is_downward_flowing(pos, node, nodedef, is_above) - - result = (math.floor(node.param2 / 8) % 2) == 1 + local result = (math.floor(node.param2 / 8) % 2) == 1 if not (result or is_above) then - -- If not, also check node above + -- If not, also check node above. -- (this is needed due a weird quirk in the definition of "downwards flowing" -- liquids in Minetest) - local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) - local nodedef_above = minetest.registered_nodes[node_above.name] + local node_above = mt_get_node({x=pos.x,y=pos.y+1,z=pos.z}) + local nodedef_above = registered_nodes[node_above.name] result = is_submerged(node_above, nodedef_above) or is_downward_flowing(pos, node_above, nodedef_above, true) end return result end +kelp.is_downward_flowing = is_downward_flowing + -- Converts param2 to kelp height. -local function get_kelp_height(param2) +local function get_height(param2) return math.floor(param2 / 16) end +kelp.get_height = get_height + -- Obtain pos and node of the top of kelp. -local function get_kelp_top(pos, node) +local function get_tip(pos, node) local size = math.ceil(node.param2 / 16) local pos_top = table.copy(pos) pos_top.y = pos_top.y + size - return pos_top, minetest.get_node(pos_top) + return pos_top, mt_get_node(pos_top) end +kelp.get_tip = get_tip + -- Obtain position of the first kelp unsubmerged. -local function get_kelp_unsubmerged(pos, node) +local function find_unsubmerged(pos, node) local x,y,z = pos.x, pos.y, pos.z - local height = get_kelp_height(node.param2) + local height = get_height(node.param2) for i=1,height do local walk_pos = {x=x, y=y + i, z=z} - if minetest.get_item_group(minetest.get_node(walk_pos).name, "water") == 0 then + if mt_get_item_group(mt_get_node(walk_pos).name, "water") == 0 then return walk_pos end end return nil end +kelp.find_unsubmerged = find_unsubmerged --- Obtain next param2 if grown -local function grow_param2_step(param2) - -- TODO: allow kelp to grow bypass this limit according to MC rules. - -- https://minecraft.gamepedia.com/Kelp +-- Obtain next param2. +local function next_param2(param2) local old_param2 = param2 param2 = param2+16 - param2 % 16 - if param2 > 240 then - param2 = 240 - end return param2, param2 ~= old_param2 end +kelp.next_param2 = next_param2 -local function kelp_place(pos, node, pos_top, def_top, is_downward_flowing) - -- Liquid source: Grow normally - minetest.set_node(pos, node) - -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source +-- Grow next kelp. +local function next_grow(pos, node, pos_top, def_top, is_downward_flowing) + -- Liquid source: Grow normally. + mt_set_node(pos, node) + + -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source. if is_downward_flowing then local alt_liq = def_top.liquid_alternative_source if alt_liq then - minetest.set_node(pos_top, {name=alt_liq}) + mt_set_node(pos_top, {name=alt_liq}) end end end +kelp.next_grow = next_grow + + +-- Drops the items for detached kelps. +local function detach_drop(pos, height) + local x,y,z = pos.x,pos.y,pos.z + for i=1,height do + mt_add_item({x=x, y=y+i, z=z}, "mcl_ocean:kelp") + end +end +kelp.detach_drop = detach_drop + + +-- Detach the kelp at dig_pos, and drop their items. +-- Synonyous to digging the kelp +local function detach_dig(dig_pos, pos, node, is_drop) + local param2 = 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: invoke after_dig_node to mt_set_node. + if new_height <= 0 then + if is_drop then + detach_drop(dig_pos, get_height(param2)) + end + mt_set_node(pos, { + name=registered_nodes[node.name].node_dig_prediction, + param=node.param, param2=0 }) + + -- Digs the kelp beginning at a height + else + if is_drop then + detach_drop(dig_pos, get_height(param2) - new_height) + end + mt_set_node(pos, {name=node.name, param=node.param, param2=16*new_height}) + end +end +kelp.detach_dig = detach_dig + +-------------------------------------------------------------------------------- +-- Kelp callback functions +-------------------------------------------------------------------------------- local function kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then @@ -98,17 +167,17 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local player_name = placer:get_player_name() local pos_under = pointed_thing.under local pos_above = pointed_thing.above - local node_under = minetest.get_node(pos_under) + local node_under = mt_get_node(pos_under) local nu_name = node_under.name - local def_under = minetest.registered_nodes[nu_name] + local def_under = registered_nodes[nu_name] if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, placer, itemstack, pointed_thing) or itemstack end - if minetest.is_protected(pos_under, player_name) or - minetest.is_protected(pos_above, player_name) then + if mt_is_protected(pos_under, player_name) or + mt_is_protected(pos_above, player_name) then minetest.log("action", player_name .. " tried to place " .. itemstack:get_name() .. " at protected position " @@ -122,23 +191,24 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local pos_top, node_top, def_top -- When placed on kelp. - if minetest.get_item_group(nu_name, "kelp") == 1 then - node_under.param2, new_kelp = grow_param2_step(node_under.param2) + if mt_get_item_group(nu_name, "kelp") == 1 then + node_under.param2, new_kelp = next_param2(node_under.param2) -- Kelp must not reach the height limit. -- Kelp must also be placed on top of kelp to add kelp. if not new_kelp or pos_under.y >= pos_above.y then return itemstack end - pos_top, node_top = get_kelp_top(pos_under, node_under) - def_top = minetest.registered_nodes[node_top.name] + pos_top, node_top = get_tip(pos_under, node_under) + def_top = registered_nodes[node_top.name] -- When placed on surface. else + local surfaces = kelp.surfaces or surfaces for _,surface in pairs(surfaces) do -- Surface must support kelp - if nu_name == surface[2] then - node_under.name = "mcl_ocean:kelp_" ..surface[1] - node_under.param2 = minetest.registered_items[nu_name].place_param2 or 16 + if nu_name == surface.nodename then + node_under.name = "mcl_ocean:kelp_" ..surface.name + node_under.param2 = registered_items[nu_name].place_param2 or 16 new_kelp = true break end @@ -150,8 +220,8 @@ local function kelp_on_place(itemstack, placer, pointed_thing) end pos_top = pos_above - node_top = minetest.get_node(pos_above) - def_top = minetest.registered_nodes[node_top.name] + node_top = mt_get_node(pos_above) + def_top = registered_nodes[node_top.name] end -- New kelp must also be submerged in water. @@ -161,48 +231,193 @@ local function kelp_on_place(itemstack, placer, pointed_thing) end -- Play sound, place surface/kelp and take away an item - local def_node = minetest.registered_items[nu_name] + local def_node = registered_items[nu_name] if def_node.sounds then - minetest.sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) + mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - kelp_place(pos_under, node_under, pos_top, def_top, downward_flowing) - if not minetest.is_creative_enabled(player_name) then + next_grow(pos_under, node_under, pos_top, def_top, downward_flowing) + if not mt_is_creative_enabled(player_name) then itemstack:take_item() end return itemstack end +kelp.kelp_on_place = kelp_on_place --- From kelp at pos, drop kelp until reaching its height. -local function kelp_drop(pos, height) - local x,y,z = pos.x,pos.y,pos.z - for i=1,height do - minetest.add_item({x=x, y=y+i, z=z}, "mcl_ocean:kelp") + +local function surface_on_dig(pos, node, digger) + -- TODO: poll on whether if players like dropping kelp in creative + -- detach_dig(pos, pos, node, + -- not (digger and mt_is_creative_enabled(digger:get_player_name()))) + detach_dig(pos, pos, node, true) +end +kelp.surface_on_dig = surface_on_dig + + +local function surface_after_dig_node(pos, node) + return mt_set_node(pos, {name=registred_nodes[node.name].node_dig_prediction}) +end +kelp.surface_after_dig_node = surface_after_dig_node + + +local function grow_kelp(pos, node) + local grow + -- Grow kelp by 1 node length if it would grow inside water + node.param2, grow = next_param2(node.param2) + local pos_top, node_top = get_tip(pos, node) + local def_top = registered_nodes[node_top.name] + if grow and is_submerged(node_top, def_top) then + next_grow(pos, node, pos_top, def_top, + is_downward_flowing(pos_top, node_top, def_top)) end end +kelp.grow_kelp = grow_kelp -local function kelp_dig(dig_pos, pos, node, is_drop) - local param2 = 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: invoke after_dig_node to set_node - if new_height <= 0 then - if is_drop then - kelp_drop(dig_pos, get_kelp_height(param2)) - end - minetest.set_node(pos, { - name=minetest.registered_nodes[node.name].node_dig_prediction, - param=node.param, param2=0 }) - - -- Digs the kelp beginning at a height - else - if is_drop then - kelp_drop(dig_pos, get_kelp_height(param2) - new_height) - end - minetest.set_node(pos, {name=node.name, param=node.param, param2=16*new_height}) +local kelp_timers_idx = {} +local kelp_timers = {} +local function surface_register_nodetimer(pos, node) + local pos_hash = mt_hash_node_position(pos) + if kelp_timers_idx[pos_hash] then + return end + local timer = mt_get_node_timer(pos) + table.insert(kelp_timers, timer) + kelp_timers_idx[pos_hash] = #kelp_timers + chatlog("added a timer. Currently " ..tostring(#kelp_timers) .." timers") end +kelp.surface_register_nodetiemr = surface_register_nodetimer + +-------------------------------------------------------------------------------- +-- Kelp registration API +-------------------------------------------------------------------------------- + +-- List of supported surfaces for seagrass and kelp. +local surfaces = { + { name="dirt", nodename="mcl_core:dirt", }, + { name="sand", nodename="mcl_core:sand", }, + { name="redsand", nodename="mcl_core:redsand", }, + { name="gravel", nodename="mcl_core:gravel", }, +} +kelp.surfaces = surfaces +local registered_surfaces = {} +kelp.registered_surfaces = registered_surfaces + +-- Commented keys are the ones obtained using register_kelp_surface. +-- If you define your own keys, that keys will be used instead. +local surface_deftemplate = { + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "leveled", + place_param2 = 16, + --tiles = def.tiles, + special_tiles = { + { + image = "mcl_ocean_kelp_plant.png", + animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}, + tileable_vertical = true, + } + }, + --inventory_image = "("..def.tiles[1]..")^mcl_ocean_kelp_item.png", + wield_image = "mcl_ocean_kelp_item.png", + selection_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.5, -0.5, 0.5, 1.5, 0.5 }, + }, + }, + -- groups.falling_node = is_falling, + groups = { dig_immediate = 3, deco_block = 1, plant = 1, kelp = 1, }, + --sounds = sounds, + --node_dig_prediction = nodename, + after_dig_node = surface_after_dig_node, + on_dig = surface_on_dig, + drop = "", -- drops are handled in on_dig + --_mcl_falling_node_alternative = is_falling and nodename or nil, + _mcl_hardness = 0, + _mcl_blast_resistance = 0, +} +kelp.surface_deftemplate = surface_deftemplate + +-- Commented keys are the ones obtained using register_kelp_surface. +local surface_docs = { + -- entry_id_orig = nodename, + _doc_items_entry_name = S("Kelp"), + _doc_items_longdesc = S("Kelp grows inside water on top of dirt, sand or gravel."), + --_doc_items_create_entry = doc_create, + _doc_items_image = "mcl_ocean_kelp_item.png", +} +kelp.surface_docs = surface_docs + +--[==[-- +register_kelp_surface(surface[, surface_deftemplate[, surface_docs]]) + +surface: table with the specifications below. See also kelp.surface. + { + name="dirt", + The name of the surface. This will appended to the surface's nodedef name + + nodename="mcl_core:dirt" + The nodename of the surface kelp can be planted on. + } + +surface_deftemplate: modifiable nodedef template. See also kelp.surface_deftempate. +DO NOT RE-USE THE SAME DEFTEMPLATE. create copies. + +surface_docs: table with keys related to docs. See also kelp.surface_docs. +--]==]-- +local leaf_sounds = mcl_sounds.node_sound_leaves_defaults() +local function register_kelp_surface(surface, surface_deftemplate, surface_docs) + local name = surface.name + local nodename = surface.nodename + local def = registered_nodes[nodename] + local def_tiles = def.tiles + + local surfacename = "mcl_ocean:kelp_"..name + local surface_deftemplate = surface_deftemplate or kelp.surface_deftemplate -- optional param + + local doc_create = surface.doc_create or false + local surface_docs = surface_docs or kelp.surface_docs + + if doc_create then + surface_deftemplate._doc_items_entry_name = surface_docs._doc_items_entry_name + surface_deftemplate._doc_items_longdesc = surface_docs._doc_items_longdesc + surface_deftemplate._doc_items_create_entry = true + surface_deftemplate._doc_items_image = surface_docs._doc_items_image + -- Takes the first surface with docs + if not surface_docs.entry_id_orig then + surface_docs.entry_id_orig = nodename + end + elseif mod_doc then + doc.add_entry_alias("nodes", surface_docs.entry_id_orig, "nodes", surfacename) + end + + local sounds = table.copy(def.sounds) + sounds.dig = leaf_sounds.dig + sounds.dug = leaf_sounds.dug + sounds.place = leaf_sounds.place + + surface_deftemplate.tiles = surface_deftemplate.tiles or def_tiles + surface_deftemplate.inventory_image = surface_deftemplate.inventory_image or "("..def_tiles[1]..")^mcl_ocean_kelp_item.png" + surface_deftemplate.sounds = surface_deftemplate.sound or sounds + local falling_node = mt_get_item_group(nodename, "falling_node") + surface_deftemplate.node_dig_prediction = surface_deftemplate.node_dig_prediction or nodename + surface_deftemplate.groups.faling_node = surface_deftemplate.groups.faling_node or falling_node + surface_deftemplate._mcl_falling_node_alternative = surface_deftemplate._mcl_falling_node_alternative or (falling_node and nodename or nil) + + minetest.register_node(surfacename, surface_deftemplate) +end + +-- Kelp surfaces nodes --------------------------------------------------------- + +-- Dirt must be registered first, for the docs +register_kelp_surface(surfaces[1], table.copy(surface_deftemplate), surface_docs) +for i=2, #surfaces do + register_kelp_surface(surfaces[i], table.copy(surface_deftemplate), surface_docs) +end + +-- Kelp item ------------------------------------------------------------------- minetest.register_craftitem("mcl_ocean:kelp", { description = S("Kelp"), @@ -214,86 +429,11 @@ minetest.register_craftitem("mcl_ocean:kelp", { groups = { deco_block = 1 }, }) --- Kelp nodes: kelp on a surface node - -for s=1, #surfaces do - local def = minetest.registered_nodes[surfaces[s][2]] - local alt - if surfaces[s][3] == 1 then - alt = surfaces[s][2] - end - local sounds = table.copy(def.sounds) - local leaf_sounds = mcl_sounds.node_sound_leaves_defaults() - sounds.dig = leaf_sounds.dig - sounds.dug = leaf_sounds.dug - sounds.place = leaf_sounds.place - local tt_help, doc_longdesc, doc_img, desc - if surfaces[s][1] == "dirt" then - doc_longdesc = S("Kelp grows inside water on top of dirt, sand or gravel.") - desc = S("Kelp") - doc_create = true - doc_img = "mcl_ocean_kelp_item.png" - else - doc_create = false - end - minetest.register_node("mcl_ocean:kelp_"..surfaces[s][1], { - _doc_items_entry_name = desc, - _doc_items_longdesc = doc_longdesc, - _doc_items_create_entry = doc_create, - _doc_items_image = doc_img, - drawtype = "plantlike_rooted", - paramtype = "light", - paramtype2 = "leveled", - place_param2 = 16, - tiles = def.tiles, - special_tiles = { - { - image = "mcl_ocean_kelp_plant.png", - animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}, - tileable_vertical = true, - } - }, - inventory_image = "("..def.tiles[1]..")^mcl_ocean_kelp_item.png", - wield_image = "mcl_ocean_kelp_item.png", - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, - { -0.5, 0.5, -0.5, 0.5, 1.5, 0.5 }, - }, - }, - groups = { dig_immediate = 3, deco_block = 1, plant = 1, kelp = 1, falling_node = surfaces[s][3] }, - sounds = sounds, - node_dig_prediction = surfaces[s][2], - after_dig_node = function(pos) - minetest.set_node(pos, {name=surface[s][2]}) - end, - -- TODO: add ability to detect whether the kelp or the surface is dug. - -- Currently, digging the surface gives sand, which isn't ideal. - on_dig = function(pos, node, digger) - minetest.chat_send_all("mo2") - local is_drop = true - if digger and minetest.is_creative_enabled(digger:get_player_name()) then - is_drop = false - end - kelp_dig(pos, pos, node, is_drop) - end, - drop = "", -- drops are handled in on_dig - _mcl_falling_node_alternative = alt, - _mcl_hardness = 0, - _mcl_blast_resistance = 0, - }) - - if mod_doc and surfaces[s][1] ~= "dirt" then - doc.add_entry_alias("nodes", "mcl_ocean:kelp_dirt", "nodes", "mcl_ocean:kelp_"..surfaces[s][1]) - end -end - if mod_doc then - doc.add_entry_alias("nodes", "mcl_ocean:kelp_dirt", "craftitems", "mcl_ocean:kelp") + doc.add_entry_alias("nodes", surface_docs.entry_id_orig, "craftitems", "mcl_ocean:kelp") end --- Dried kelp stuff +-- Dried kelp ------------------------------------------------------------------ -- TODO: This is supposed to be eaten very fast minetest.register_craftitem("mcl_ocean:dried_kelp", { @@ -308,13 +448,13 @@ minetest.register_craftitem("mcl_ocean:dried_kelp", { _mcl_saturation = 0.6, }) + local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way end - 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."), @@ -354,39 +494,36 @@ minetest.register_craft({ burntime = 200, }) --- Grow kelp +-- ABMs ------------------------------------------------------------------------ minetest.register_abm({ - label = "Kelp growth", + label = "mcl_ocean:Kelp growth", nodenames = { "group:kelp" }, - -- interval = 45, - -- chance = 12, - interval = 1, - chance = 1, + interval = 45, + chance = 12, catch_up = false, - action = function(pos, node, active_object_count, active_object_count_wider) - local grow - -- Grow kelp by 1 node length if it would grow inside water - node.param2, grow = grow_param2_step(node.param2) - local pos_top, node_top = get_kelp_top(pos, node) - local def_top = minetest.registered_nodes[node_top.name] - if grow and is_submerged(node_top, def_top) then - kelp_place(pos, node, pos_top, def_top, - is_downward_flowing(pos_top, node_top, def_top)) - end - end, + action = grow_kelp, }) --- Break kelp not underwater. -minetest.register_abm({ - label = "Kelp drops", +minetest.register_lbm({ + label = "Kelp timer registration", + name = "mcl_ocean:kelp_timer_registration", nodenames = { "group:kelp" }, - interval = 0.25, - chance = 1, - catch_up = false, - action = function(pos, node) - local dig_pos = get_kelp_unsubmerged(pos, node) - if dig_pos then - kelp_dig(dig_pos, pos, node, true) - end - end + run_at_every_load = true, + action = surface_register_nodetimer, }) + +-- TODO: test if nodetimers are more efficient than ABM +-- -- Break kelp not underwater. +-- minetest.register_abm({ +-- label = "Kelp drops", +-- nodenames = { "group:kelp" }, +-- interval = 0.5, +-- chance = 1, +-- catch_up = false, +-- action = function(pos, node) +-- local dig_pos = find_unsubmerged(pos, node) +-- if dig_pos then +-- detach_dig(dig_pos, pos, node, true) +-- end +-- end +-- }) From 24da94ec3b413b1b41121e2003573cf45b810ed3 Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Sun, 28 Mar 2021 20:29:29 +0800 Subject: [PATCH 15/52] Disable ABMs in favor of nodetimers to check if kelp is unsubmerged. --- mods/ITEMS/mcl_ocean/kelp.lua | 164 +++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 70 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index fe2266789c..a4de943b71 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -1,7 +1,11 @@ --- NOTE: whenever it becomes possible to fully implement kelp without the +-- TODO: whenever it becomes possible to fully implement kelp without the -- plantlike_rooted limitation, please adapt the code 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. +-- +-- TODO: Currently, you lose kelp if the kelp is placed on a block and then falls. +-- This is most relevant for (red)sand and gravel. local S = minetest.get_translator("mcl_ocean") local mod_doc = minetest.get_modpath("doc") ~= nil @@ -25,6 +29,7 @@ local mt_hash_node_position = minetest.hash_node_position local mt_get_node_timer = minetest.get_node_timer -- DEBUG: functions +local log = minetest.log local chatlog = minetest.chat_send_all -------------------------------------------------------------------------------- @@ -130,7 +135,9 @@ kelp.detach_drop = detach_drop -- Detach the kelp at dig_pos, and drop their items. --- Synonyous to digging the kelp +-- 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. local function detach_dig(dig_pos, pos, node, is_drop) local param2 = node.param2 -- pos.y points to the surface, offset needed to point to the first kelp. @@ -159,6 +166,72 @@ kelp.detach_dig = detach_dig -- Kelp callback functions -------------------------------------------------------------------------------- +local function surface_on_dig(pos, node, digger) + -- NOTE: if instead, kelp shouldn't drop in creative: use this instead + -- detach_dig(pos, pos, node, + -- not (digger and mt_is_creative_enabled(digger:get_player_name()))) + detach_dig(pos, pos, node, true) +end +kelp.surface_on_dig = surface_on_dig + + +local function surface_after_dig_node(pos, node) + return mt_set_node(pos, {name=registred_nodes[node.name].node_dig_prediction}) +end +kelp.surface_after_dig_node = surface_after_dig_node + + +local kelp_timers = {} +local kelp_timers_counter = 0 +local function surface_on_timer(pos, elapsed) + local node = mt_get_node(pos) + local dig_pos = find_unsubmerged(pos, node) + if dig_pos then + detach_dig(dig_pos, pos, node, true) + end + return true +end + + +-- NOTE: Uncomment this to use ABMs +-- local function surface_unsubmerged_abm(pos, node) +-- local dig_pos = find_unsubmerged(pos, node) +-- if dig_pos then +-- detach_dig(dig_pos, pos, node, true) +-- end +-- return true +-- end + + +-- NOTE: Uncomment this to use nodetimers +local function surface_register_nodetimer(pos, node) + local pos_hash = mt_hash_node_position(pos) + if kelp_timers[pos_hash] then + return + end + local timer = mt_get_node_timer(pos) + kelp_timers[pos_hash] = timer + timer:start(0.5) + kelp_timers_counter = kelp_timers_counter + 1 + chatlog("added a timer. Currently " ..tostring(kelp_timers_counter) .." timers") +end +kelp.surface_register_nodetiemr = surface_register_nodetimer + + +local function grow_kelp(pos, node) + local grow + -- Grow kelp by 1 node length if it would grow inside water + node.param2, grow = next_param2(node.param2) + local pos_top, node_top = get_tip(pos, node) + local def_top = registered_nodes[node_top.name] + if grow and is_submerged(node_top, def_top) then + next_grow(pos, node, pos_top, def_top, + is_downward_flowing(pos_top, node_top, def_top)) + end +end +kelp.grow_kelp = grow_kelp + + local function kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then return itemstack @@ -171,6 +244,7 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local nu_name = node_under.name local def_under = registered_nodes[nu_name] + -- Allow rightclick override. if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, placer, itemstack, pointed_thing) or itemstack @@ -222,6 +296,10 @@ local function kelp_on_place(itemstack, placer, pointed_thing) pos_top = pos_above node_top = mt_get_node(pos_above) def_top = registered_nodes[node_top.name] + + -- NOTE: Uncomment this to use nodetimers + -- Register nodetimer + surface_register_nodetimer(pos_under, node_under) end -- New kelp must also be submerged in water. @@ -244,50 +322,6 @@ local function kelp_on_place(itemstack, placer, pointed_thing) end kelp.kelp_on_place = kelp_on_place - -local function surface_on_dig(pos, node, digger) - -- TODO: poll on whether if players like dropping kelp in creative - -- detach_dig(pos, pos, node, - -- not (digger and mt_is_creative_enabled(digger:get_player_name()))) - detach_dig(pos, pos, node, true) -end -kelp.surface_on_dig = surface_on_dig - - -local function surface_after_dig_node(pos, node) - return mt_set_node(pos, {name=registred_nodes[node.name].node_dig_prediction}) -end -kelp.surface_after_dig_node = surface_after_dig_node - - -local function grow_kelp(pos, node) - local grow - -- Grow kelp by 1 node length if it would grow inside water - node.param2, grow = next_param2(node.param2) - local pos_top, node_top = get_tip(pos, node) - local def_top = registered_nodes[node_top.name] - if grow and is_submerged(node_top, def_top) then - next_grow(pos, node, pos_top, def_top, - is_downward_flowing(pos_top, node_top, def_top)) - end -end -kelp.grow_kelp = grow_kelp - - -local kelp_timers_idx = {} -local kelp_timers = {} -local function surface_register_nodetimer(pos, node) - local pos_hash = mt_hash_node_position(pos) - if kelp_timers_idx[pos_hash] then - return - end - local timer = mt_get_node_timer(pos) - table.insert(kelp_timers, timer) - kelp_timers_idx[pos_hash] = #kelp_timers - chatlog("added a timer. Currently " ..tostring(#kelp_timers) .." timers") -end -kelp.surface_register_nodetiemr = surface_register_nodetimer - -------------------------------------------------------------------------------- -- Kelp registration API -------------------------------------------------------------------------------- @@ -303,8 +337,8 @@ kelp.surfaces = surfaces local registered_surfaces = {} kelp.registered_surfaces = registered_surfaces --- Commented keys are the ones obtained using register_kelp_surface. --- If you define your own keys, that keys will be used instead. +-- Commented properties are the ones obtained using register_kelp_surface. +-- If you define your own properties, it overrides the default ones. local surface_deftemplate = { drawtype = "plantlike_rooted", paramtype = "light", @@ -333,6 +367,7 @@ local surface_deftemplate = { --node_dig_prediction = nodename, after_dig_node = surface_after_dig_node, on_dig = surface_on_dig, + on_timer = surface_on_timer, drop = "", -- drops are handled in on_dig --_mcl_falling_node_alternative = is_falling and nodename or nil, _mcl_hardness = 0, @@ -340,7 +375,7 @@ local surface_deftemplate = { } kelp.surface_deftemplate = surface_deftemplate --- Commented keys are the ones obtained using register_kelp_surface. +-- Commented properties are the ones obtained using register_kelp_surface. local surface_docs = { -- entry_id_orig = nodename, _doc_items_entry_name = S("Kelp"), @@ -353,19 +388,12 @@ kelp.surface_docs = surface_docs --[==[-- register_kelp_surface(surface[, surface_deftemplate[, surface_docs]]) -surface: table with the specifications below. See also kelp.surface. - { - name="dirt", - The name of the surface. This will appended to the surface's nodedef name - - nodename="mcl_core:dirt" - The nodename of the surface kelp can be planted on. - } +surface: table with its specific properties. See also kelp.surface. surface_deftemplate: modifiable nodedef template. See also kelp.surface_deftempate. DO NOT RE-USE THE SAME DEFTEMPLATE. create copies. -surface_docs: table with keys related to docs. See also kelp.surface_docs. +surface_docs: table with properties related to docs. See also kelp.surface_docs. --]==]-- local leaf_sounds = mcl_sounds.node_sound_leaves_defaults() local function register_kelp_surface(surface, surface_deftemplate, surface_docs) @@ -403,7 +431,7 @@ local function register_kelp_surface(surface, surface_deftemplate, surface_docs) surface_deftemplate.sounds = surface_deftemplate.sound or sounds local falling_node = mt_get_item_group(nodename, "falling_node") surface_deftemplate.node_dig_prediction = surface_deftemplate.node_dig_prediction or nodename - surface_deftemplate.groups.faling_node = surface_deftemplate.groups.faling_node or falling_node + surface_deftemplate.groups.falling_node = surface_deftemplate.groups.falling_node or falling_node surface_deftemplate._mcl_falling_node_alternative = surface_deftemplate._mcl_falling_node_alternative or (falling_node and nodename or nil) minetest.register_node(surfacename, surface_deftemplate) @@ -496,7 +524,7 @@ minetest.register_craft({ -- ABMs ------------------------------------------------------------------------ minetest.register_abm({ - label = "mcl_ocean:Kelp growth", + label = "Kelp growth", nodenames = { "group:kelp" }, interval = 45, chance = 12, @@ -504,26 +532,22 @@ minetest.register_abm({ action = grow_kelp, }) +-- NOTE: Uncomment this to use nodetimers minetest.register_lbm({ label = "Kelp timer registration", name = "mcl_ocean:kelp_timer_registration", nodenames = { "group:kelp" }, - run_at_every_load = true, + run_at_every_load = false, action = surface_register_nodetimer, }) --- TODO: test if nodetimers are more efficient than ABM --- -- Break kelp not underwater. +-- NOTE: Uncomment this to use ABMs +-- Break kelp not underwater. -- minetest.register_abm({ -- label = "Kelp drops", -- nodenames = { "group:kelp" }, --- interval = 0.5, +-- interval = 1.0, -- chance = 1, -- catch_up = false, --- action = function(pos, node) --- local dig_pos = find_unsubmerged(pos, node) --- if dig_pos then --- detach_dig(dig_pos, pos, node, true) --- end --- end +-- action = surface_unsubmerged_abm, -- }) From ecdbc30b63998e4fdcb3004ca892707b54bd7d2f Mon Sep 17 00:00:00 2001 From: iliekprogrammar Date: Mon, 29 Mar 2021 14:09:09 +0800 Subject: [PATCH 16/52] Overhaul kelp interactions. Highlights: - Added locking system to drops. Will be removed after testing. - Expose more variables and functions. Will be finalized soon. - Implement MC-like age and natural growth mechanics. - Implement correct piston interactions with kelp and its surface. - Implement correct falling node interactions for its surface. - ABMs are now nonfunction. Will be fixed. - Various optimizations and fixes. --- mods/ITEMS/mcl_ocean/init.lua | 2 + mods/ITEMS/mcl_ocean/kelp.lua | 484 ++++++++++++++++++++++------------ 2 files changed, 320 insertions(+), 166 deletions(-) diff --git a/mods/ITEMS/mcl_ocean/init.lua b/mods/ITEMS/mcl_ocean/init.lua index 2a103b8d05..f723a1f3ff 100644 --- a/mods/ITEMS/mcl_ocean/init.lua +++ b/mods/ITEMS/mcl_ocean/init.lua @@ -1,3 +1,5 @@ +mcl_ocean = {} + -- Prismarine (includes sea lantern) dofile(minetest.get_modpath(minetest.get_current_modname()).."/prismarine.lua") diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index a4de943b71..741d9e59aa 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -3,9 +3,6 @@ -- -- 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. --- --- TODO: Currently, you lose kelp if the kelp is placed on a block and then falls. --- This is most relevant for (red)sand and gravel. local S = minetest.get_translator("mcl_ocean") local mod_doc = minetest.get_modpath("doc") ~= nil @@ -14,19 +11,28 @@ local mod_doc = minetest.get_modpath("doc") ~= nil -- local-ify runtime functions -------------------------------------------------------------------------------- -- objects -local registered_items = minetest.registered_items -local registered_nodes = minetest.registered_nodes +local mt_registered_items = minetest.registered_items +local mt_registered_nodes = minetest.registered_nodes -- functions +local mt_add_item = minetest.add_item local mt_get_item_group = minetest.get_item_group local mt_get_node = minetest.get_node -local mt_set_node = minetest.set_node -local mt_add_item = minetest.add_item -local mt_sound_play = minetest.sound_play -local mt_is_creative_enabled = minetest.is_creative_enabled -local mt_is_protected = minetest.is_protected -local mt_hash_node_position = minetest.hash_node_position +local mt_get_node_level = minetest.get_node_level +local mt_get_node_max_level = minetest.get_node_max_level +local mt_get_node_or_nil = minetest.get_node_or_nil local mt_get_node_timer = minetest.get_node_timer +local mt_hash_node_position = minetest.hash_node_position +local mt_is_protected = minetest.is_protected +local mt_set_node = minetest.set_node +local mt_get_meta = minetest.get_meta + +local mt_is_creative_enabled = minetest.is_creative_enabled +local mt_sound_play = minetest.sound_play + +local math_floor = math.floor +local math_random = math.random +local string_format = string.format -- DEBUG: functions local log = minetest.log @@ -36,109 +42,218 @@ local chatlog = minetest.chat_send_all -- Kelp API -------------------------------------------------------------------------------- -kelp = {} +local kelp = {} +mcl_ocean.kelp = kelp + +kelp.MAX_AGE = 25 +kelp.TIMER_INTERVAL = 0.2 + +-- The average amount of growth for kelp in a day is 2.16 (https://youtu.be/5Bp4lAjAk3I) +-- Normally, a day lasts 20 minutes, meaning this nodetimer is executed 24000 times. +-- Calculate probability via 2.16/24000 and we get the probability 9/100'000 or 9.0e-5 +-- NOTE: currently, we can't exactly use the same type of randomness MC does, +-- because it has multiple complicated sets of PRNGs. +-- kelp.RANDOM_NUMERATOR = 9 +kelp.RANDOM_NUMERATOR = 100 +kelp.RANDOM_DENOMINATOR = 100000 + +kelp.leaf_sounds = mcl_sounds.node_sound_leaves_defaults() + +-- TODO: is this really necessary +-- Lock drops to avoid duplicate drops, set after dropping detached kelp. +kelp.lock_drop = 0 + +-- Registrar of nodetimers, indexed by pos_hash. +kelp.registered_nodetimers = {} + +-- Pool storing age, indexed by pos_hash. +kelp.age_pool = {} + + +-- is age in the growable range? +function kelp.is_age_growable(age) + return age >= 0 and age < kelp.MAX_AGE +end + -- Is this water? -- Returns the liquidtype, if indeed water. -local function is_submerged(node, nodedef) +function kelp.is_submerged(node, def) if mt_get_item_group(node.name, "water") ~= 0 then - return nodedef.liquidtype -- Expected only "source" and "flowing" from water liquids + return def.liquidtype -- Expected only "source" and "flowing" from water liquids end return false end -kelp.is_submerged = is_submerged -- Is the water downward flowing? -- (kelp can grow/be placed inside downward flowing water) -local function is_downward_flowing(pos, node, nodedef, is_above) - local result = (math.floor(node.param2 / 8) % 2) == 1 +function kelp.is_downward_flowing(pos, node, def, is_above) + local result = (math_floor(node.param2 / 8) % 2) == 1 if not (result or is_above) then -- If not, also check node above. -- (this is needed due a weird quirk in the definition of "downwards flowing" -- liquids in Minetest) local node_above = mt_get_node({x=pos.x,y=pos.y+1,z=pos.z}) - local nodedef_above = registered_nodes[node_above.name] - result = is_submerged(node_above, nodedef_above) - or is_downward_flowing(pos, node_above, nodedef_above, true) + local def_above = mt_registered_nodes[node_above.name] + result = kelp.is_submerged(node_above, def_above) + or kelp.is_downward_flowing(pos, node_above, def_above, true) end return result end -kelp.is_downward_flowing = is_downward_flowing + + +-- Will node fall at that position? +-- This only checks if a node would fall, meaning that node need not be at pos. +function kelp.is_falling(pos, node) + -- NOTE: Modified from check_single_for_falling in builtin. + -- Please update as necessary. + local nodename = node.name + + if mt_get_item_group(nodename, "falling_node") == 0 then + return false + end + + local pos_bottom = {x = pos.x, y = pos.y - 1, z = pos.z} + -- get_node_or_nil: Only fall if node below is loaded + local node_bottom = mt_get_node_or_nil(pos_bottom) + local nodename_bottom = node_bottom.name + local def_bottom = node_bottom and mt_registered_nodes[nodename_bottom] + if not def_bottom then + return false + end + + local same = nodename == nodename_bottom + -- Let leveled nodes fall if it can merge with the bottom node + if same and def_bottom.paramtype2 == "leveled" and + mt_get_node_level(pos_bottom) < + mt_get_node_max_level(pos_bottom) then + return true + end + + -- Otherwise only if the bottom node is considered "fall through" + if not same and + (not def_bottom.walkable or def_bottom.buildable_to) and + (mt_get_item_group(nodename, "float") == 0 or + def_bottom.liquidtype == "none") then + return true + end + + return false +end -- Converts param2 to kelp height. -local function get_height(param2) - return math.floor(param2 / 16) +function kelp.get_height(param2) + return math_floor(param2 / 16) end -kelp.get_height = get_height --- Obtain pos and node of the top of kelp. -local function get_tip(pos, node) +-- Obtain pos and node of the tip of kelp. +function kelp.get_tip(pos, node) local size = math.ceil(node.param2 / 16) - local pos_top = table.copy(pos) - pos_top.y = pos_top.y + size - return pos_top, mt_get_node(pos_top) + local pos_tip = table.copy(pos) + pos_tip.y = pos_tip.y + size + return pos_tip, mt_get_node(pos_tip) end -kelp.get_tip = get_tip -- Obtain position of the first kelp unsubmerged. -local function find_unsubmerged(pos, node) +function kelp.find_unsubmerged(pos, node) + local x,y,z = pos.x, pos.y, pos.z - local height = get_height(node.param2) + local height = kelp.get_height(node.param2) + local walk_pos = {x=x, z=z} for i=1,height do - local walk_pos = {x=x, y=y + i, z=z} - if mt_get_item_group(mt_get_node(walk_pos).name, "water") == 0 then - return walk_pos + walk_pos.y = y + i + local walk_node = mt_get_node(walk_pos) + if mt_get_item_group(walk_node.name, "water") == 0 then + return walk_pos, walk_node end end return nil end -kelp.find_unsubmerged = find_unsubmerged -- Obtain next param2. -local function next_param2(param2) - local old_param2 = param2 - param2 = param2+16 - param2 % 16 - return param2, param2 ~= old_param2 +function kelp.next_param2(param2) + return param2+16 - param2 % 16 end -kelp.next_param2 = next_param2 -- Grow next kelp. -local function next_grow(pos, node, pos_top, def_top, is_downward_flowing) +function kelp.next_grow(pos, node, pos_tip, def_tip, downward_flowing) + -- Optional parameters + local pos_tip, def_tip = pos_tip, def_tip + local downward_flowing = downward_flowing + if pos_tip == nil and def_tip == nil then + local node_tip + pos_tip, node_tip = kelp.get_tip(pos, node) + def_tip = mt_registered_nodes[node_tip.name] + downward_flowing = kelp.is_submerged(pos_tip, node_tip) + and kelp.is_downward_flowing(pos_tip, node_tip, def_tip) + end + -- Liquid source: Grow normally. + local node = table.copy(node) + node.param2 = kelp.next_param2(node.param2) mt_set_node(pos, node) - -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source. - if is_downward_flowing then - local alt_liq = def_top.liquid_alternative_source + -- Flowing liquid: Grow 1 step, but also turn the tip node into a liquid source. + if downward_flowing then + local alt_liq = def_tip.liquid_alternative_source if alt_liq then - mt_set_node(pos_top, {name=alt_liq}) + mt_set_node(pos_tip, {name=alt_liq}) end end end -kelp.next_grow = next_grow + + +-- Naturally grow next kelp. +function kelp.natural_grow(pos, node, age, pos_hash, meta) + -- Must grow first, then get the new meta + kelp.next_grow(pos, node) + + -- Optional params + local meta = meta or mt_get_meta(pos) + local pos_hash = pos_hash or mt_hash_node_position(pos) + + local age = age + 1 + kelp.age_pool[pos_hash] = age + meta:set_int("mcl_ocean:kelp_age", age) + +end -- Drops the items for detached kelps. -local function detach_drop(pos, height) +function kelp.detach_drop(pos, height, pos_hash) + local pos_hash = pos_hash or mt_hash_node_position(pos) -- Optional params + + if kelp.lock_drop > 0 then + minetest.log("error", + string_format("Duplicate drop prevented at (%d, %d, %d) with lock level %d! Please report this.", + pos.x, pos.y, pos.z, kelp.lock_drop)) + return + end + local x,y,z = pos.x,pos.y,pos.z for i=1,height do mt_add_item({x=x, y=y+i, z=z}, "mcl_ocean:kelp") end + + -- Locks drop. + kelp.lock_drop = kelp.lock_drop + 1 + return true end -kelp.detach_drop = detach_drop -- Detach the kelp at dig_pos, and drop their items. -- 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. -local function detach_dig(dig_pos, pos, node, is_drop) +function kelp.detach_dig(dig_pos, pos, node, is_drop, pos_hash) + local pos_hash = pos_hash or mt_hash_node_position(pos) + local param2 = 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) @@ -146,52 +261,77 @@ local function detach_dig(dig_pos, pos, node, is_drop) -- Digs the entire kelp: invoke after_dig_node to mt_set_node. if new_height <= 0 then if is_drop then - detach_drop(dig_pos, get_height(param2)) + kelp.detach_drop(dig_pos, kelp.get_height(param2), pos_hash) end mt_set_node(pos, { - name=registered_nodes[node.name].node_dig_prediction, + name=mt_registered_nodes[node.name].node_dig_prediction, param=node.param, param2=0 }) -- Digs the kelp beginning at a height else if is_drop then - detach_drop(dig_pos, get_height(param2) - new_height) + kelp.detach_drop(dig_pos, kelp.get_height(param2) - new_height, pos_hash) end mt_set_node(pos, {name=node.name, param=node.param, param2=16*new_height}) end end -kelp.detach_dig = detach_dig + -------------------------------------------------------------------------------- -- Kelp callback functions -------------------------------------------------------------------------------- -local function surface_on_dig(pos, node, digger) - -- NOTE: if instead, kelp shouldn't drop in creative: use this instead - -- detach_dig(pos, pos, node, - -- not (digger and mt_is_creative_enabled(digger:get_player_name()))) - detach_dig(pos, pos, node, true) +-- Set this to drop kelps when +function kelp.surface_on_dig(pos, node, digger) + kelp.detach_dig(pos, pos, node, true) end -kelp.surface_on_dig = surface_on_dig -local function surface_after_dig_node(pos, node) +function kelp.surface_after_dig_node(pos, node) return mt_set_node(pos, {name=registred_nodes[node.name].node_dig_prediction}) end -kelp.surface_after_dig_node = surface_after_dig_node -local kelp_timers = {} -local kelp_timers_counter = 0 -local function surface_on_timer(pos, elapsed) +function kelp.surface_on_timer(pos, elapsed) local node = mt_get_node(pos) - local dig_pos = find_unsubmerged(pos, node) + local dig_pos = kelp.find_unsubmerged(pos, node) + local pos_hash = mt_hash_node_position(pos) if dig_pos then - detach_dig(dig_pos, pos, node, true) + kelp.detach_dig(dig_pos, pos, node, true, pos_hash) end + + -- Grow kelp on chance + if math_random(kelp.RANDOM_DENOMINATOR) - kelp.RANDOM_NUMERATOR < 0 then + local age = kelp.age_pool[pos_hash] + if kelp.is_age_growable(age) then + kelp.natural_grow(pos, node, age, pos_hash) + end + end + return true end +function kelp.surface_on_destruct(pos) + local node = mt_get_node(pos) + local pos_hash = mt_hash_node_position(pos) + + -- on_falling callback. Activated by pistons for falling nodes too. + if kelp.is_falling(pos, node) then + kelp.detach_drop(pos, kelp.get_height(node.param2), pos_hash) + end + + -- Unlocks drops. + if kelp.lock_drop > 0 then + kelp.lock_drop = kelp.lock_drop - 1 + end +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) +end + -- NOTE: Uncomment this to use ABMs -- local function surface_unsubmerged_abm(pos, node) @@ -204,35 +344,52 @@ end -- NOTE: Uncomment this to use nodetimers -local function surface_register_nodetimer(pos, node) - local pos_hash = mt_hash_node_position(pos) - if kelp_timers[pos_hash] then - return +function kelp.surface_register_nodetimer(pos, node, pos_hash, meta, age) + -- Optional params + local pos_hash,meta,age = pos_hash,meta,age + local timer = kelp.registered_nodetimers[pos_hash] + + if not timer then + pos_hash = pos_hash or mt_hash_node_position(pos) + + timer = mt_get_node_timer(pos) + kelp.registered_nodetimers[pos_hash] = timer + + -- Pool age to avoid meta:get* operations + meta = meta or mt_get_meta(pos) + if not age then + if not meta:contains("mcl_ocean:kelp_age") then + age = math_random(0, kelp.MAX_AGE-1) + else + age = meta:get_int("mcl_ocean:kelp_age") + end + end + kelp.age_pool[pos_hash] = age + meta:set_int("mcl_ocean:kelp_age", age) end - local timer = mt_get_node_timer(pos) - kelp_timers[pos_hash] = timer - timer:start(0.5) - kelp_timers_counter = kelp_timers_counter + 1 - chatlog("added a timer. Currently " ..tostring(kelp_timers_counter) .." timers") -end -kelp.surface_register_nodetiemr = surface_register_nodetimer - -local function grow_kelp(pos, node) - local grow - -- Grow kelp by 1 node length if it would grow inside water - node.param2, grow = next_param2(node.param2) - local pos_top, node_top = get_tip(pos, node) - local def_top = registered_nodes[node_top.name] - if grow and is_submerged(node_top, def_top) then - next_grow(pos, node, pos_top, def_top, - is_downward_flowing(pos_top, node_top, def_top)) + if not timer:is_started() then + timer:start(kelp.TIMER_INTERVAL) end + + return pos_hash, meta, age end -kelp.grow_kelp = grow_kelp -local function kelp_on_place(itemstack, placer, pointed_thing) +-- NOTE: Uncomment this to use ABMs +-- function kelp.grow_abm(pos, node) +-- -- Grow kelp by 1 node length if it would grow inside water +-- node.param2 = next_param2(node.param2) +-- local pos_tip, node_tip = get_tip(pos, node) +-- local def_tip = mt_registered_nodes[node_tip.name] +-- if is_submerged(node_tip, def_tip) then +-- kelp.next_grow(pos, node, pos_tip, def_tip, +-- is_downward_flowing(pos_tip, node_tip, def_tip)) +-- end +-- end + + +function kelp.kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then return itemstack end @@ -242,14 +399,15 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local pos_above = pointed_thing.above local node_under = mt_get_node(pos_under) local nu_name = node_under.name - local def_under = registered_nodes[nu_name] + local def_under = mt_registered_nodes[nu_name] - -- Allow rightclick override. + -- Allow rightclick to override place. if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, placer, itemstack, pointed_thing) or itemstack end + -- Protection if mt_is_protected(pos_under, player_name) or mt_is_protected(pos_above, player_name) then minetest.log("action", player_name @@ -260,86 +418,89 @@ local function kelp_on_place(itemstack, placer, pointed_thing) return itemstack end - local new_kelp = false - local downward_flowing = false - local pos_top, node_top, def_top + + local pos_tip, node_tip, def_tip + local pos_hash, meta + + + -- Kelp must also be placed on the top/tip side of the surface/kelp + if pos_under.y >= pos_above.y then + return itemstack + end -- When placed on kelp. if mt_get_item_group(nu_name, "kelp") == 1 then - node_under.param2, new_kelp = next_param2(node_under.param2) - -- Kelp must not reach the height limit. - -- Kelp must also be placed on top of kelp to add kelp. - if not new_kelp or pos_under.y >= pos_above.y then - return itemstack - end - pos_top, node_top = get_tip(pos_under, node_under) - def_top = registered_nodes[node_top.name] + pos_tip, node_tip = kelp.get_tip(pos_under, node_under) + def_tip = mt_registered_nodes[node_tip.name] + + pos_hash = mt_hash_node_position(pos_under) + meta = mt_get_meta(pos_under) -- When placed on surface. else - local surfaces = kelp.surfaces or surfaces - for _,surface in pairs(surfaces) do - -- Surface must support kelp + local new_kelp = 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 = registered_items[nu_name].place_param2 or 16 + node_under.param2 = 0 new_kelp = true break end end - - -- Kelp must also be placed on top of surface to add new kelp. - if not new_kelp or pos_under.y >= pos_above.y then + -- Surface must support kelp + if not new_kelp then return itemstack end - pos_top = pos_above - node_top = mt_get_node(pos_above) - def_top = registered_nodes[node_top.name] - -- NOTE: Uncomment this to use nodetimers -- Register nodetimer - surface_register_nodetimer(pos_under, node_under) + pos_hash, meta = kelp.surface_register_nodetimer(pos_under) + + pos_tip = pos_above + node_tip = mt_get_node(pos_above) + def_tip = mt_registered_nodes[node_tip.name] end -- New kelp must also be submerged in water. - downward_flowing = is_downward_flowing(pos_top, node_top, def_top) - if not (is_submerged(node_top, def_top) or downward_flowing) then + local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip, def_tip) + if not (kelp.is_submerged(node_tip, def_tip) or downward_flowing) then return itemstack end -- Play sound, place surface/kelp and take away an item - local def_node = registered_items[nu_name] + local def_node = mt_registered_items[nu_name] if def_node.sounds then mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - next_grow(pos_under, node_under, pos_top, def_top, downward_flowing) + kelp.next_grow(pos_under, node_under, pos_tip, def_tip, downward_flowing) if not mt_is_creative_enabled(player_name) then itemstack:take_item() end + -- Reroll age + local age = math_random(0, kelp.MAX_AGE-1) + meta:set_int("mcl_ocean:kelp_age", age) + kelp.age_pool[pos_hash] = age + return itemstack end -kelp.kelp_on_place = kelp_on_place -------------------------------------------------------------------------------- -- Kelp registration API -------------------------------------------------------------------------------- -- List of supported surfaces for seagrass and kelp. -local surfaces = { +kelp.surfaces = { { name="dirt", nodename="mcl_core:dirt", }, { name="sand", nodename="mcl_core:sand", }, { name="redsand", nodename="mcl_core:redsand", }, { name="gravel", nodename="mcl_core:gravel", }, } -kelp.surfaces = surfaces -local registered_surfaces = {} -kelp.registered_surfaces = registered_surfaces +kelp.registered_surfaces = {} -- Commented properties are the ones obtained using register_kelp_surface. -- If you define your own properties, it overrides the default ones. -local surface_deftemplate = { +kelp.surface_deftemplate = { drawtype = "plantlike_rooted", paramtype = "light", paramtype2 = "leveled", @@ -365,55 +526,46 @@ local surface_deftemplate = { groups = { dig_immediate = 3, deco_block = 1, plant = 1, kelp = 1, }, --sounds = sounds, --node_dig_prediction = nodename, - after_dig_node = surface_after_dig_node, - on_dig = surface_on_dig, - on_timer = surface_on_timer, + after_dig_node = kelp.surface_after_dig_node, + on_destruct = kelp.surface_on_destruct, + on_dig = kelp.surface_on_dig, + on_timer = kelp.surface_on_timer, + mesecon = { on_mvps_move = kelp.surface_on_mvps_move, }, drop = "", -- drops are handled in on_dig --_mcl_falling_node_alternative = is_falling and nodename or nil, _mcl_hardness = 0, _mcl_blast_resistance = 0, } -kelp.surface_deftemplate = surface_deftemplate -- Commented properties are the ones obtained using register_kelp_surface. -local surface_docs = { +kelp.surface_docs = { -- entry_id_orig = nodename, _doc_items_entry_name = S("Kelp"), _doc_items_longdesc = S("Kelp grows inside water on top of dirt, sand or gravel."), --_doc_items_create_entry = doc_create, _doc_items_image = "mcl_ocean_kelp_item.png", } -kelp.surface_docs = surface_docs ---[==[-- -register_kelp_surface(surface[, surface_deftemplate[, surface_docs]]) - -surface: table with its specific properties. See also kelp.surface. - -surface_deftemplate: modifiable nodedef template. See also kelp.surface_deftempate. -DO NOT RE-USE THE SAME DEFTEMPLATE. create copies. - -surface_docs: table with properties related to docs. See also kelp.surface_docs. ---]==]-- -local leaf_sounds = mcl_sounds.node_sound_leaves_defaults() -local function register_kelp_surface(surface, surface_deftemplate, surface_docs) +-- Creates new surfaces. +-- NOTE: surface_deftemplate will be modified in-place. +function kelp.register_kelp_surface(surface, surface_deftemplate, surface_docs) local name = surface.name local nodename = surface.nodename - local def = registered_nodes[nodename] + local def = mt_registered_nodes[nodename] local def_tiles = def.tiles local surfacename = "mcl_ocean:kelp_"..name - local surface_deftemplate = surface_deftemplate or kelp.surface_deftemplate -- optional param + local surface_deftemplate = surface_deftemplate or kelp.surface_deftemplate -- Optional param local doc_create = surface.doc_create or false - local surface_docs = surface_docs or kelp.surface_docs + local surface_docs = surface_docs or kelp.surface_docs -- Optional param if doc_create then surface_deftemplate._doc_items_entry_name = surface_docs._doc_items_entry_name surface_deftemplate._doc_items_longdesc = surface_docs._doc_items_longdesc surface_deftemplate._doc_items_create_entry = true surface_deftemplate._doc_items_image = surface_docs._doc_items_image - -- Takes the first surface with docs + -- Sets the first surface as the docs' entry ID if not surface_docs.entry_id_orig then surface_docs.entry_id_orig = nodename end @@ -422,9 +574,9 @@ local function register_kelp_surface(surface, surface_deftemplate, surface_docs) end local sounds = table.copy(def.sounds) - sounds.dig = leaf_sounds.dig - sounds.dug = leaf_sounds.dug - sounds.place = leaf_sounds.place + sounds.dig = kelp.leaf_sounds.dig + sounds.dug = kelp.leaf_sounds.dug + sounds.place = kelp.leaf_sounds.place surface_deftemplate.tiles = surface_deftemplate.tiles or def_tiles surface_deftemplate.inventory_image = surface_deftemplate.inventory_image or "("..def_tiles[1]..")^mcl_ocean_kelp_item.png" @@ -440,9 +592,9 @@ end -- Kelp surfaces nodes --------------------------------------------------------- -- Dirt must be registered first, for the docs -register_kelp_surface(surfaces[1], table.copy(surface_deftemplate), surface_docs) -for i=2, #surfaces do - register_kelp_surface(surfaces[i], table.copy(surface_deftemplate), surface_docs) +kelp.register_kelp_surface(kelp.surfaces[1], table.copy(kelp.surface_deftemplate), kelp.surface_docs) +for i=2, #kelp.surfaces do + kelp.register_kelp_surface(kelp.surfaces[i], table.copy(kelp.surface_deftemplate), kelp.surface_docs) end -- Kelp item ------------------------------------------------------------------- @@ -453,12 +605,12 @@ minetest.register_craftitem("mcl_ocean:kelp", { _doc_items_create_entry = false, inventory_image = "mcl_ocean_kelp_item.png", wield_image = "mcl_ocean_kelp_item.png", - on_place = kelp_on_place, + on_place = kelp.kelp_on_place, groups = { deco_block = 1 }, }) if mod_doc then - doc.add_entry_alias("nodes", surface_docs.entry_id_orig, "craftitems", "mcl_ocean:kelp") + doc.add_entry_alias("nodes", kelp.surface_docs.entry_id_orig, "craftitems", "mcl_ocean:kelp") end -- Dried kelp ------------------------------------------------------------------ @@ -523,26 +675,17 @@ minetest.register_craft({ }) -- ABMs ------------------------------------------------------------------------ -minetest.register_abm({ - label = "Kelp growth", - nodenames = { "group:kelp" }, - interval = 45, - chance = 12, - catch_up = false, - action = grow_kelp, -}) -- NOTE: Uncomment this to use nodetimers minetest.register_lbm({ label = "Kelp timer registration", name = "mcl_ocean:kelp_timer_registration", nodenames = { "group:kelp" }, - run_at_every_load = false, - action = surface_register_nodetimer, + run_at_every_load = true, -- so old kelps are also registered + action = kelp.surface_register_nodetimer, }) -- NOTE: Uncomment this to use ABMs --- Break kelp not underwater. -- minetest.register_abm({ -- label = "Kelp drops", -- nodenames = { "group:kelp" }, @@ -551,3 +694,12 @@ minetest.register_lbm({ -- catch_up = false, -- action = surface_unsubmerged_abm, -- }) +-- +-- minetest.register_abm({ +-- label = "Kelp growth", +-- nodenames = { "group:kelp" }, +-- interval = 45, +-- chance = 12, +-- catch_up = false, +-- action = grow_abm, +-- }) From a14959ac706db635e59733f2b44fe2999385a0b6 Mon Sep 17 00:00:00 2001 From: epCode Date: Tue, 30 Mar 2021 09:53:55 -0700 Subject: [PATCH 17/52] add player death animation and particles --- mods/ITEMS/mcl_armor/armor.lua | 1 + .../mcl_armor/models/mcl_armor_character.b3d | Bin 335992 -> 343384 bytes .../models/mcl_armor_character.blend | Bin 1099020 -> 1187156 bytes mods/PLAYER/mcl_player/init.lua | 27 +++++++++++++++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index a879f72403..05a0200167 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -367,6 +367,7 @@ mcl_player.player_register_model("mcl_armor_character.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}, }, }) diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index c6a1274c5554bb3438b068638c5be98fb4ba4438..a658f753c3b423573cd735f196876364467c87c2 100644 GIT binary patch delta 58161 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 delta 52591 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%0Avr35nMc=Ni^_989E>nIXG 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ⅅPIgBHhVCj+z3HOkfJ zsMrb<&$Uzj`c3r)zjZ4fHexl07N*#Iw!J)h1_&_?Cmmq)rG}Z?Vs12(wHf@v4owL_ zVv4(yaA^8l8>aDFJ@d_8rac{Uq_uXZ!^|0dk6BMt0`JT9&(*ou7Whono-0UtlNTa6 zv=I|O9}l44bAMXK{V?%M`?- zC%6v+ZNw^9ox>`FZlga9W8GhH2lLHp(*EzjDSU0%D_45cx`)T}z5hG#8Tw7h;yi1p zyJ4O>m;0U#hTXBh6%zpbYZF~F9sTwvjr^8t`x)nOIDI5AEk64^l&XU6oay7o<=0UH z^!`ED$RjW#a9Rb`XNUC_PAlzu&u8e@sd|9Yz8$mN+yY2yNf}DkR#?zd z;}(X8-8@d$Y&-e`4;l8PH$0)@`&A74tCM!!X@6@x>`$L=x4-7*$nE1{WPk7`*cZpJ zKhWD*_SY=+pd$U?YJ2cyyLe!KkYB9!2fK;I{_3bmj3?^pn(acLD*f|O>KvlO>}+Yx zGwk-)T2vHbJ7-+AUll%~>U9ViANx&67OPloP}8!q!{oEF=sCzt!#+{o&a%%s-#)`C zNWeZJzgX;Z9hFokcE$E-wJq44exb5IeW1iwtXJ)3t;DM&E|a)f+SMXS=Lp`rlDc!I+qQm$$`5$7-*q$X{zE8j z`hC8Ka0EBrOjrW^0(5qkUljX(0g+Q|ZPTpR77&YmxT%BuV(|-xhrO8Xw%Cz=j@aQQ zWq+_cJnuCUuEjiri`b$_ct^6`@lOKE#q(to-H(J1JhwO!UOz6AI}8aZ7tgaB>3$@9 z;JL+-@Q&hgF;J&V_!*vq;b-x_Z|rVx>pebCll?1h{O)`AtiENvZYv4a&uqF4`LUnz zJT3>C!=Ue#7~d_K@T2kj^PH|$bMuM`AD+3+xTd5$2WT3tht9}?72$DwV^ywR+b20D)rVMQCTG!ysrLz!LQ{&U0kJ^OKN*eLih z$QpE$k~mLb8W@N30LSHU^HnGF8_&=+c!d38ZVmQ}e5Mn=248Js;X9Y%xvtK&6KVdK zL5W7>qwIm@X#H70llV0m)6S5wgp6&u z+zMLoi@hT!krA*R^p?FObQx0^GGy@J@c+DE)uQThe%F)*8s#Z9M<;Tqfp85WCG`D3ZLUKRip|QjC^1@Jrj; za5osf7mbeI)a7XY)?~C0jZVwPc<4l!qumr69Xr3)XMXFo9g0(|ALIF7sr`8VvHVfeQ8q{%!8*BJ6pbx$XFtk=JfCYjuHFEKe;9d#cS;AKyhEqnW+@k*1ey0XjWjYf=3Ma zcw;?vgt4E6ZOE9%l=`g}Ic||O=)SDIV*75Qb6uI&cjiDJ^gustjFJ!J_pnpDAoz)M-7WBW9+Q3D_#}Mll)Ti6_I*M| z|E=;f#3%=C4BK^xZX!PtUmd#M{2|3xv&3F}A>WHHuE%a!KP~N7l}CF$wWKUKE13A` zhud0for@@q_j`~P$NIoWjrAd{$1F;t-M-g@ueSTaXw@tQwDX8z$DoV*UUZwUQs)2~ z#Ed`gZ;GvSQ%QN?XA)h*Cc`wmuO`o&M*IJQm9!PGl)se5-=T~%@arPiaJB2**lxDS zm;tdDRw`vc7G5xJ_gNo2_5uBg9&&>|rt)__$rfNIcX`-_TUmT>>MX;OtCy7qy+C5R z@21;pV#16B#N()}ETNs5oThAu(`u}u_7#~FvieOjSGLPdhE@1X%RLBv_sl))?z+3x zz6iu@PsLORq<`*VAF~P;SG4ErKWh9L%9JrAm6)2%qMM#WV^Ye*IBYfDi$~tmbFwSx zGqiNDu9omOOPLS1GOwlkf!Ex}wJ#iNKNn9=`sa2&f6gnY@3MR4?)v+6U#wR9Tk4$c zHp?QsD~09q4gGApLUuj7wi2^!saO+u=5qSE*L^EpHymp|Ut3|U*UmiPIbkBf#RCia zh#9v-@Iyk8WBM61`5GZ)xkuMVpx7wCaomRWk6hUQ*tLAOSYmvC?(A2G1B zRVPvVKrKV>Y=)sG3871pT0N5T3f)Q4=*SF;v$U=R;;bjqh(V%#v3_<Y@LOW<3lUlhAw;0yDiC?!!yNei<&`yId7U|{ zrhoQcYV<4cTQ5f0KfUr|zR&*2jRJ+hP0Bw}t}cA2+(iDucD6LNw!YF-cfdK+=ez5T z&YUuQ`QrEfHVoHJp9tjjUi)D3!NZfpZ|R!G2%$_Bb2UPZe9dr*+t5h8_x2I%7px!2 za87(DJkusPra>`>EzI)>x-jsKTf6lSVX{(SHJr%$!gd7r~Zb! zf8K7bRwuY-|1{ns3{~$HPDB4$eVXB)tB6N-oz(`fVLk9Y-MAO|57Xy|DP8DIA;eXL z((-2d=ndD+q7%1wWHE&=-yJcg_37F5Ev=sz>A8>peN2}=JL+pCJ#I?&*r8{fwPE)6 zDu2;i$%W%)Tz7iI zQ}3yC*1}(mo6!B@hSdL4>HThBKki50-O@1kFDm`~fOp5eRr802`gJOO$CUjtwhw-~ zq06sS`jK0Y$#{3kYYl1FtMvQ>MrJ(s@Q#K+txC^s3}jp|EUEE^LY1z6^M@J3Zqpl6 z&s6DN&n?X8Q{1a@TeeCsZT(Tk)|>h?-Y`m~o6>7Dp6dOB#x+A!`iSg{GM;(s2aR(F zskFYXHsdwQ|CQt)*{3>V?9E~P@|mR>|FqCQZ)HJ7#R|Q#pOpWX6J}?mj!0^}R`@HL zmzRP7w;eXmWR{oH=sdE*Y*`r(FV z(ci|ePaLOz9@g*gul{!I_Bmnw-}<`;$6kD7*gg(9`uwq<{WWYqpPcyjF}b&d?Th>B zZq!b~-p(2H_b0|%@;^D|{3pM);IDk(!6&WsU%KYoCqJ~5zxbOI*Y9uPui*Ie)*ou& zfAP&%uea9k+VcC?TkGHJjOW)|<&*W3PuG89k>9_r>rsENMZVAc=a~ANE%IOcr(yM} z7XAF+yuA8J7X1a%X4m((==Y741@)B{{eL;LwBBkT_w}i+&#>6fFV@x8TkY$Vt+sGH>Hb(VN!)d#2uy^|s`nyL$cVA3wZd z^hYY)FX@W)gX<@4sQ*l*FaJES{`k4K)zAJ)rN2JE&-xpd_8eCy?aiVgo1PpoYfi?x z?^OO9znc5x`jYaDfzn&ce`d(v~E>n zgnQd}`#tq-9bnBo^W7E!>ldi(qr0qicd}H?FTBUzU?cu5;cGPeCPNk2g_Hg*~v+GxgJ#l;ZKk9G4lC;zQ z=2Lsv<@#{`m((7PwBX-K?cp63`ma%Y7_yXKPVM1K7XAvUJ+$&)M(v@se%DibXs!Q& z)E;)X$S0H9L#zB=q4v-!-#=4(XqErN)E-*(^D4E6R{c$;_Ry+dZV#>c|AN{>t9|^M z+C!`TaC>OAFK!R5_Q&nvQTv7MkK4m`{)r8mv=7`KUVrh-4IybixINr4 z{QmlMXYdtRmd^T=O=XF>ga}qRn}moV$}pVBY6@dOyVUCgt_!xf$*EG7pq{ zcQVaoaM;o`;DPpGwZd~yAEBYGNj+r{%XFS*a#+_9_0 z8KpeaKgAzS|LiCJDSqokhW&FYudi2sy}%;hxAuXl@o3V+eHv3cOL)StF3Crn{iUAgfP`#o!YaGgS9gk3$p zt()rZpLgvlF~(Sq>7U|{rhooQ{8RkaiyW=OQ{&tG870+)#fdE;u=uBb&u;b4#-z}Q zQ^*g}x@e)_sXE(juQ|8(+I5!kZIAEz82&`}C|2(!`5waw{>V|?dA?ospL~DG#%~@8 z`)??d;D^(Fg3+`-La%n?H---wu}4E z?e62-yOq*9&0o_$#UD-oTqFJ|e(S}s>7QB$J%6qe|BO^0`K>qn>@lW_W!HBfmB6eW({uwENcnvqF8JU5`?3G?L-`w)V93>gAdEh2i+BEv)n2 z(@DM8)-?7R{%@ke7=L-9&m-IDn(i6?MAwafrF#s=`J?g|)N8#~jn$g|IF4xz>9ckC zQVagG1p5ZzR|`H}H~w$XW5Y)f9OF;h{J*B3|7&ojvSBy=7;0ArHy&cYXRQxkzdrMd ztOWftN~M`6>(36Z2i(WEYJH3yc6X*s{}g{T{d1f6r}(WGj{#agEEBjL-d=ZPGgP#7U|{rhmRI{waRz#U77udH&Y% z_&GSPDI-h&S@*zhef~81M0;KBJ{$l0Pi>TQ{`Mlr^Cz!?CA!A*=VS7IO{!h7bGPeLc6q4s>oDvuV8;!0@K7?&mBY$`!KnkECB&+u`6tPX7tt|Lx`{GcP;;Pmi4c_8P~y)eXl^-QI87;eWE`vI%{@Sjx1GIh+fQ zdVRz8L*L4{W#MH;ITx2K$sFJ3(uM_7-Zs8lZm$FQi&P%+?B%Mv>K!V*pP_dyn)I<6 z@nPII_@S-6{5gZ)gx}$4BMJ6IO0QwKD~SK|iRX)mPof#>O?7D@{xgVYF5~;wKM%i| z>Qboq4=uTET2s!5BQ~DWKWP)=fAT8NjlDYjsweg{>ZjfO^0=XgUz|B;`eXzDz{9$4 z=vz8@!j{i3GUV~M^lKWgx%}>|shRg~RD4n)(h$?9Pr1mHm+24o&C^MQbkj>t4Bl}; zpLek9b7;qv(77m?{gl*uPw1z}mOC)4%3@+>KPBhXt)_d1C30pAVS3Jt(t>65&E_DT z@Y0UpR_66YFL0#&d%`GU+vV}~Q*QJ@E0GxI;Ut1<#nDsM_g<~{IJ48tMh-G0ZzlSx--g08^}-{TNcWf}MA+6WYfGCzKG zd1Ln{xsR$f`pIu@etG?H>Z68HU&T;64(&dk`=~>xuj2G8>DOdF+;m6wpPKTs8QL6L)OAr$^(6rx8_n+zhWu3 zL-u}H$^(6rr%O5DqeIrRTgn4{lxOz!Qcq)TF2T1qz&=4A<$*5v=#aG%M3l=j=8~k% z-xJ2@d^SbL1vN%zIcy=K7`v6wHMc``jxikfya&@yg(QvqNS(ZhTkVXUC&oq|?WliJzMu#>SnHca5PAh@a1EDP#-@?! zljf5i)Lh|#Pj9LpPd~!zyj!dk1k7qrjW?P;H_vQXE~_RX1QDC<4zwKGpqOh@}HbzoXfdhRs6 z;W`9A#HCUQ@lW_S`x9&XtYE_JGtZGNd3saEH2P7VwvFb<<~=jJ@$)l#8Tg;l9NEC( zy)vI&tJ>==G)LCu_Vnyue%3#W>tyjwzkOx_?!sWU&+;vq)l{}cA5l3$`#dZvWMlxh zGH;B4vTaf*u6OO7b^KiS$lf-7=5HT_=&Tj>4TP`?(at&Bs_=b`pWpt=tyy6_zH-B{ zL)c;L@Ppr&O6D0pr z?{BDod!X?S`Ji@s?{)3-M)GOe&ysli{OWrYl@r#Ln=2`d+F+a@zmGq-hIDLY( zeg10hS!=EB^H6%fOzm^#2Kq5qL+SnUs0-2?kJ&KHNWV(&m!EulV8fc+_s4VoT6(`c zx-Qr>czHIfMfk22PP^`>k3A9I*BGrO#WUN!JH-pmQUn6blv zZe`va&W?K3Tz0EkXBFkac9Jiq~O#fJ69S|QK_ zUQTyA9^intrBUI59`Lko%x9AE9xs({0uFf1+HHnDKrf8P<%RJ82fSjz1HCZbVKzL# z0k3beDi8F4m(!i`)ceL%iU9|_HG&6v46DMihRH&nfCFBw;DH{nv~G+St{>ol7ZCde zJrhqGVqBs;zyWWr*gNQ%c-&_g;kIc%S4bQ6BxNBnPv*bCs{7f!olxiUWBfnO~31YOv< z)Bb=Dc;E-b4nP<7=T$!7fv*eypbLDj@&OP0uY`Zl1^>kkxqyGb1Am3!gD&Lfg%5b( zuhEr#fiCcxJ<10>@V5v)=%Rgc`W5&GJn-l4ugV8q_?4IZ01x~X-4s6PqFm5{U7>uy z1Aj|bg%7%D&z*h>e82-=m-0au<$K`+9{6jde9(oTd+`r=;I~M-0=mHWvR}Xhe~Z{Z z=mOu1f4~F3xmvX|pbP)+D|DUm2R!iC%~SZG3w*Eo10MLbH=k>aA3zuOhjz?aKH!00 ze7@?BK^J&l_6K+qU&b$>Yw|DcqqBUBcYu$4(1rcE>2DnYW1Q4a+RwTV?c*ij!GGb; zXctgk5)Gnq=%dI#pc{u$58H(n+T|oAr*P-s_HAAL5w*4xap2r@jkU_n7pNF?V~yFL zxF-UgqoqFj`EK+M%2jk<$X4-cM>=w;*<2|K#&<+RR}yY>wuabvwo}h{$y!QE7p+H^ z{Yer>7(aJeFfGXMJ6ib9@^c2J!2P-u?aba|)6g6A1iirypifo77Sh*0H-{_B>9J3R z(~+U?PyDT<)$}MO9{R!N4^%&h{t^8j`f;yuHQMpMWXtvROQBy*(ytA^T>HVCCB}F|m$+`8>aPOx z-TE!BT7>VzFF^->=}IqjeXhdnfPPRrm1t2vXvX1r%0&9Xdr59AKWEt6`$6aldPDu8 zPa_@LNU~1bggn~SPw4|TbNVCteNR7X2Q^-^%>m<;{Z!ISUoB~Sr1W+>$)5G5(fFks zS@1Q+&$~Uf+WkF*KKvtS@R`yQ~Wx_;+(KF?ww|?wC7nvWT5>kC<#fc6z%X68$Ok1ijTQ z6nhYT8k~mm@)XDDPjyE+a(&o7IT+8C^KK$s>Q527K3AqDA3;{kPll27#&o^~ZD7`_SstSGR`Q)dY!`0#R=SKQxbn_<3m?(m|OVW5g!Md*& zcflFYm6qodI+5olZF>^`BI}Kd;r7a{KUEs*Y8&yo7cb22ArbTjJwb11ccD*J9r}*> zyt|$XS8aewhpyjzFWsb<)<$@V+ItT7s7Qm}kVd{_BQo^1KM9rQ1B~%hH=_7*%DwdS z)*Jg8`WbJ%b0Gb>_?&2 zz}U=V=G`%2;@G1IoXL2T!;xduTTCkR9q#KH=+?mrl5`-^FWR z_-p@%Kb)|C!;v$RCp^@p(ct&-?gwvLGH?H!0mnYQ@!gm2Zupfg(>ML;znilE zp0+CMpstmfJN}rG)$)g}8Qb!^H|Blv_X)!vdcI-ZU1u8nPg+`%`Sa5zO&D;>6NbF* znf=51`}zknPa6L=(>Fu^7t0NKJod~%nWru+ZLIw5nTzjXr9b_3BcXflywepi}JG_p;C`^d#l9{YnKXKQt1y~p-r#f$$sl=;~6 zlQZ|f>AwvN9y_a{;-Uu{tUBnP^sBK}niqcbP&Pl0SOd3H=S?^@bM%wj8b12VFB(!l ze80f~Vt}*%rgbI%mFE=RJM0E$rOnr27-wBmv-xbjWa%>%EKRPu2H+xg1&aG-m^VgE z(zQ-cdejvSLeG=F4zdM*71Us$oQMblpim*y)F8-1vf zxtjmi=smdBjpi!&7jeFV>FOjqmS3A-VB6;_+Q96AH=sA@33>}uh&_m1sHz2WNkW^X zny1pL2TIS~>{abQO9tluk$%M$fpr$j&?C38hV4Cptol6U+8mpSJkcUVV>C6&|bOeO?jGqzG8RRr6bCR-k>Mw4YZ+8P3ygp zPOz}}8`8?(hLHS5(~ns;mc#bS>!b$LPmPOs zB;ao2b(3UVgt$if!HZnRF$R^$f8g(RLI?gHSn5JAG}bW=>OA8j$gfRp_wsQO^aQ=> z%aq=rPbClAxQK4?d${v3PHH1EW86x2F)l)SR2xXX;WjQhLOWICpSulP$*|tk9ESBS zw_WUUG}4Nx6|>`Z<`n!5dV=1X#ebpC-CYN-{uSe*$a>q0$3>zi=nZ;;KE209>Rmt? zt*=~4Ka7DGe+i{I;2zTIuKF8!T(q*d>X~L z2=--Q&*n@RgaKJj_KIq08qn!pF_Fp! z+qBf4jx0RwjT8kC`?{p9w40QF?l#QSVE10@k`%Ump3ml+ilsg7FZ>O9g5H|@E4@LV zs$%nUG;O72UXRnMPjOx>>ymg}%3-3IX}G0Bna(vu)^$n4YZ}Ia8e+F~Nyv*7^Ek&?mn6?C{5~U={v-_JPm&9$F(XR1WL4MA5PI)-aY12PV z^qjWb^2HV9RVCFWW$jtA7H*HjEzd8)mr<|!-m1=1NxMnKD`u$kS<(VCjq~T4TV$Qp zJN9!&oP?PVnLc)AMND%)lu8ib1LsSvD_4B9MYf-}1~}lQovrXd5BSb=+5iW>I&riIw?1dH`Im)IN+rXRd^^Dcsbn}FMLiL;DGnlkCa?M4|sG=rEzJ>Q{aGC zENRdKUQRbV9^imiTcpZExxmvL=d=M1cJkT@o9OtwF4tVev&@=J0L554Bet-iW z;6M*)tsCPh{Tb(;i68bc?$S5$#6JNKJ9XLtm&^Eo2Y%lfN{{ew*p<`%fDd@!>t`x_ z(1ksCl@EB}r(LMW zxlol4y5Qfde82-=7r8Zq4{3+c4m;%sc;E-benA)h__+jzE}Bx2mYFA z3LkV~zwmD-|9}TR`cu#a9`xYE2R!hR54yldJ&@1#!|Q_3Z{z)!F8w&*pf{%-JN*IY zM)3REbZYU{xnccMxRG<46VunqxnU9qj#KmI&1vm>{{=djAJk89qjzYos^1IQDqihK ztGix*v$;|fjQ1!wFATA)FX4Q(UOK*W!}wHFmY*~1?dPRHPtY6e0Qyw&Xd!($&J7D? z8Shb?@^VY}lbcB{@}(>u$G15*EIH*UjrUNw*)Wr1yT`d9HLPF8yL_A*7D;cG_g}Qm{Wvk$dp`(0L2sx(^l7AB&kZ|hGv~!~ZrBYVZi{&yE0pOxH|$2T;u{Ih&4wA> zYWJH+cg~=&op<;AH2Yf?`5XM$KQ}BsozA0Gq$EDIl+@+iFto#Hm+RhD?K0YHJYVAZ z4$nz=Zn1I`*S>`*vTs3ReXz94!`s&`gAV+=d58-=f8T;tZM*dv{VDVWz10m>dV@X{ zlm5Pi-Ks20;m{lO1ib~sf1ytc%5J&z>QAxGEAskx`#P`PQh^RG6ncZ6pf?l)eR}U( zXxYfH)_n_j?#Dg_=e`BxGhVcP3r8^!1uwm+T(v*Wd!Gj6MR?G*73n5#keG7xBV18bugLmi!?H>)} zbhB|iL;5|$BUL&u)@2-HEyUv*{;mrh_0|n76ge|Izw_wc0Jo{PS+7 zr;^RX?%keO6*l*;dsl$opeN`J{tJDoTJt`I6pP*{9f#hqZy|QQjV7J(&s%TM2Devk zdQ+aZ7oVpp?JV>Lc|f0<@qN|T$lqE>cg?xi%^CF686RAq_ri%~n-`xpFfW(vo^7A^ zN<%NFQToTa{Np2BG4B2&BGlFYxzdSkj?dQ;d; zZtn{0Zy~Z(^qZeh^=y5-M|IVDRFBL~aNBvl1=~Yfne(j1Q0BbJt8Fb{*+A+d%RS)y_N53ww*s3ww)l-E0_Sa9$X% zL2(9!&F5n5T><_EJwb1}_%HOiyKC*GH_R__d*!A#HICYQ=a---=nZ;;KE3Ccl)qWe z3xhx5d@#%}A&q=4Bl7&x=&tN*9K7^qJul2nZ($0G&ffBu{f+0Bbm=es`K9+%Qa<>=y6(VSwLZ2js+uhZ9^imCSJvf&9`KjbcjY+%4{*R+cY&-&ZBy=c zqe})J;DEP6zF!M^;qvTwfCFCh0#zR90dE+6SDpjP103**FH&*=y)d4=Jiq~OMNrlo zOSxgZaklya4tT|j6dvdSZ+Uk+9^imCSJnrE9`H16J#DeH?5hws;OS>5xqu$U&Yvda^2CLY!?OSxe@yF6PQe8OKqFN|leAK*|P;6M-QVcpgn zp2K?Q{RZ$u?z=c+U5VWvpnupu=l~z^CO-T^{2O)$`)Y$P@W3C9b>6}U%6HlY$_G5~ z*UT4t$G#b{Loa;51HV@AK^Ocx?F;1t9{6i2l>9&!a`VCmJn#ck)P5$=1)dlGfCs)V z?F8teeS#f3uk3mKfnWjU6$xi_yE4A z{RlkpnyAMn6mQy}f1@B#jveu(k`5BwJCA3zuK z_reD}@Y4hzbb;r^Kj4ACMeHAR(XM#OAMn6Oe-669_p%?r10VJUy5Jvlkk9ht`67%P zFkcjS+dh6kx$qzO6Z{hNhSR$7<=xeL;<40I@qUSENymHdmsl_RB_wXnQ}Y9XfXn<2 z3W*SNeO6He3_5rYs+;6S@4{R~>V<404&7%@M<|E0rgB41A@={x!zps>|bth#nW?3rok4SIs!U-m-SHl2RFt|irluEJLPCDe6f9`#4XFC>l(z58-mZ^pWN;qwRN6XF&T znVK{x$1GT&!UpE)&; zO}MbUtU6d*oxilavb1Q|*6Ov^*4A{gg@IHo;`VZ2%0udJ%441AQ{?0QLjyTNc~NDJR$P%uoH(omXw#) zERI7Q+MIY1TxxQH$b++39xBklOoH*Cjzo;HDG#Z?DG%{;UF75>XIjRRlHk&c^2+M` zqLQkL(t>49K#%ksK}*ex3(ZFDz$o%?>Ar3FZV6K!Qh&$;u)4?zX~d>H3TvvW%NOTY zRF+p%Av1XKkQxFG*u>IY#Lh>hhB0uZ(oU__5idC0ha@7a&XU+hbk zF-~|jL#+Gp@LYxGth%>k--pcG;`s{CiC*(2cuvS5V{M@y@5h^#^m~IZw=rtnRN40- zv3{DohdtfxxhOXMuA;UCbTH0ocBALqkJp~(EbY`><2znvjCDNLed)13XZ=m&=dAJG z{+tCpL2sx(^r_NUkgQMMj6BWI+rdUUk90px`jVRj0MEmCFOM|xO*+Pf(%bD_mELG& z35`#uCEaZNyvL_jyZ9}n#?+U4dqRlAJ#+ByG;`83QcTDj!2aCsi!Ns7DC^VGnk z`{*jkb?!jlcDgz*U*fuHsy(io-M)4ibl~5C>2CC{%~5>I{Fio9u03t7RoiQ>CkHkE zbtB=@_Z34Dw>d9_zppru=Dzsn?cYp~>8_?9%g-4UwmL6gT{|K6%ryHq_ovVk^roLF z_8@j))GqW(ho0J_x0gk461P)tKczZwJ)A-5O3hnBZ!Ta?v`(Lf-k>Mwt$C)>8}zxm zE8;dLWS-d9&|Y2Tq7b+BQZ8V-yLxe#54}N8&>Pxa=reA@9gN_mHx$GDjJMwQ-u(j5 z6Z8goK%Xidl6I2g8#d5aDQIrLn9f=MEzj{s4LG0Y+5`+flHTBN?(Jl_w1G+C>!{3j zA^@%*hf0gw*xzbTq~}E$=WM5ZOSS>;_J@W~u7T$yiflP<)P_5zE_P%y%Izyx8fVcn zK407E*ogWGUjn`adIN{;1z_#UsvG|mZ@eJvLV`HBHY`bYn9(X;CjB#lV>ULZfOeJ=`It;Sc^iibV@FZ2dIL2u1J z6#Ec;s(Ri}>$vaV9Ii8ef8h&DI-KKnh3_qFcXJFm_vMNd_L1&dA0oitTX;W-f9^KS zWw6b|?%mdNyX~KF<84p72faa0&|97OFZ8MERZRQLtlwLpbZB$TdK)9caoguWS;l!i zmUB)>Z)3HeCh^Z(Z|raU98L4 zUf&q|XK`m%aY0dV7kz7i%VfP6=jS=bQ2{xB7yF2DZXnJ<^g7RwY4ZM=diwFX4qeH| z1||)nBU*IV{lj(rercR%j9AZ?ezVAB+{4791hng*gZ80$o*TU*a}~J`*gw4O6B$QI z>^hF(oug{^Xte!RUgtWv?L&enmRos5J}|zQVpdm46-K=H+M_Vi`v%y`|9jm(Js0 ziUaBV=g4|vy6kUmdQ&`gAzSF8^-Y=-X2#=6ub1<*B=!K??YCKP#<_>Wr}MlgF9s(~ znL06N=Jc~?O`OT6#ub%R1`DgpE0^V06jT>`AzAL{0U>opYzP)yTs}z#zk3R-{cA=@|%xg8aA zo5i|gepBgVJ}B>PDu6kdRj?$Onq8HeQyMIz0buH+lG0#DmCba96qhd!4hfc)Tv$*% zL>r>fagPg177o!=aYMAhqtl0Ia<6JgN0#i<@+II)U@wqBdF7(23OWq6YVdq+HTHrU z`Bm^Guf>7647{suikZ-GThZ_uaWmcK8)ax*wj(v0to zKgH>v(GTaLs<{zOyGsD^EjxT)`~dTbQvg(?=GW*OE8+RI(OM7szIYFU_js2yXLhdz0RvC+JO=b{G0o;-L4*^X@YAq|yUaI&}T!d+Eknk=aWkzk4JNy&;W! z$wp-8ZGRGKSZ`~!ms9SgpSRxdemSzyGv2HlNh9 zYj{4%dcC{q5v^Q(>WjwvIV&9A?|yADIBqA`kUazbAB4c!{r>zA+rKR=s+^l;yFrQT zy77Frn$zaI174g;=k;mYXCG;q55MxehNaJ*ZqRw|#Pc(Mdrn}&qql!#UGv0*motvZe5LS|M_;de>EThC zf7x*8SEb|MTYe4m8`}Enb(^l-cyvzM%>y^(e0z7(wWnR1Q}J=XO&fa-$f@kIDvNng zKjxO^!9Mx>gy9c8->~kkGY$SHEiK9X`Dv3T3^?TpLmv0c{$c%n{ezh&jepyahr-gd z{x6mr@_6i-gECKDSlU?m+cO)9Mq|(Z_hdfw&RY}i9Qg#(m~h>Px7IiRE+uPA;Oz#Y zVbEk6$Na7|n`n?s_O0-f$Npf**;?yZ?^*R`#gF|ul-cvM(U~b1ebI2z{?|2h{pmj& zE`IyxrVd7YedE}1k9V7papK<_NTyt0L9Ie}c# zVHmbkYe>z0{<*0WlBLh&9Pa=0tiK$^-#4@e;3Br?CYlQK#uWHXR1aN!xgn6lx_SP& z=f-Q=MKablOG!yd=}OBO_oo|Se)!uD9H>s?Z(n)%gf3LCgND-RiEiTy!NI{7RxC82 z_N_k)$}59a)q{hzmD)a8|Ma4Q!u0v+BMX8fMiiwNjUF{>cwzd8F@;4%!7=IchZP2k zP7N*?IdV+?(EO3<>9zFR>kNf_X{z~C*3Z6U_>ZGq&?K$$*`M%J@M;ZnM|)6!J};b= znNI%8J`Wza6vc;%v%oXMQU8fN1D^Rd^BL0`@SX9%`H6mKd}_h6@|tRGaC-VME8#e= z?QNbyzBLk!u~+Tjbyx^<=c@0=7Rz^**U9&k*U5LA>$b`F5#F$WClvVMIEmI{hC|?| z_W7x-UtjFTs`))_@PY3!Z#mcgUF9(4gN;k>zf$Q6aKIZ~tnfh30H#07yW8;q2fQsS z&o$OpfgbQQ?R}$1Gs_b=;OW(>JkSH)^6qv#zyWU!%99v)!@Jq}1RU^ct5kWQ7sj)f z2RPu3K3(Y<^ul<*H#$1h4{*R+A$9?Jz+2wkjt4m4!Ja@5c$)UIaf$K(2Ry)m9@4|R zh4J`1+_2L=WL0cfTV|;G0Ur8y%8AQme88Ld=gD`J#r|Ojp7;U}eEl4S54w=E(=Jdx z;DH|)Cip@Z_^?aV3;2Ks{@gRvcbq{N`tsr*@W3w?`v6^(4?52B0T28Yf)Bdj+o^x> z4|w3umG%a7fd@S}%LhF0*PN#02fD!b;vew9-y-;+3;Tl|Im-t;@OAhX_z=JG)W5(3 zzfS58x{yEo!&yGyfsghYd;rf&|9}TR=z}isAqV8M{`mb0`h|Ytf6ZI%{R7H{{Gku0 zK1Wce!QYXl?pk|*S|a|A^wgx4$?VhoETh+6V|-s6SR#5_UF#l9n;YP1CS7E)7t>XB;BYnCQs=lLhCDG#dD-wst9>#hm zdUm0C`l+-ImVe&!hLGRQBs-R$GcY#K`Et>Ul7i4LQgYS1-SfV&E?Z(Je!S`CH=i)% z-SU=-qv03Nf7qtqXz<8~-k>Mw4R!#1D)<(X^Rt_QODnFkwWeb%^S|L7w<~-{`Z5>! z58tsj*z{Icn7H1)BBpfV(`!AY{?M;KvyM|c!*`??$#cBCF zo+^s#uP%Cn9m8&6#~=p#HqxQnX#MtIOgm1ZbduQd@x%+h6Ae3cen)z+@QZwuA+ce{ zmi<+^W?PkY}EyWttKto?9cKqKjTa5N+tHcdr$G>!If9b0( zr&WJoz)w>#=pn9qSK05H_hPf-=3qPRSonn<>y3(k@Z*f9=bSb%ceeFI(&h6nq@}@5 zxSg5i??|()45UI3TgyviStHxA;nz}sQywp$Wjt@{A}4D(d>xiYb!9v9>D@R3<2iA$12r*ok@{szQ@<T#@{-!(zi#$Y5PD-Xc76q5l&?CPp7@xXNH_%dN#ffHP<1`m}&`hd1 zUO(9e9b3Ybht%Jc#}JW+$jM2~lt)2LQAxQoH+nidF*F0-I|&$EPQWJf0-d+`n*a4aZs&FO>wQCnrg(JQC?*I--9mjv|i}oJ_}%HsvApH|24)$V24h zBsC*@=IklCQ;kPDI?JFsSX)g~LY37eg{28St2*h&l3pe4={y2v`{39b`dbq*UYqie z`kV5&R^%aaa*|^_?qwI37nLk130B6~Y?x%GC5UGdpo`0-J-veF)>$4LTSKZf5#zNf z52?Q?kLyGpA}1%g8G#?pnvy$!8$0q@C%5#XdeFIxG*4t>GAJBF1Y|9#Vf( z9@mRJL{3g}un+jk;$T&=6J}?p`TZQrf%{d&)-n&VCStrc$y`)XDMUS^3BidDPKOmIueyz-N2L8%%jf{Y`m1_^{f)Epl?w zg*>W?3o3&7^w1w?148E(Rs>V&sXtCUD<4lu`!SDhvOGAphC{817_UuvNc~NDJS6fE zIXTHe9yLqyxo@edjCEitgwC3iI;|isi*j;6>z+g&oWt@^Aw2##47cKlO?gQDO?f;l z@(?*WNkSgtFZ7bGJgz=Q{DofA#fN9*;}=on(bozbC+9eUBBW=lMkjR^pSTkNE>hOiDDpTm60%30 zDG#Z?DUZiQ9wH|vI^o_Mp9@?fnr2eKn zo)meAoSZZvkE%t%(qMIYnKM6HdRBsXR=R^^ynY+qblrV@R9wkoueQs26#NoSdW}kBaiD zV18-I{K|sLxR!v-AiUJ6@#9(f_%2HO!DqwA8%%jf{Y`mn5P684oOB_N#8yjbT1Tvx zdMAoJdODeoA#KV->Tk-ULF6HFa*~2P5?dYAG3$e#k0Os=PNri>oAQwQoAPKBd5D~x zq#%!yMOEdc^iY>yQe9A0=!Ei4PbniLa+%Xh%7XMpFM$;kn)YZEc^v3nyl0Ln52?Q? zj~mpwdtKz@Bmj9>=hpM%=yW?`{BdU#c^vFyI)=0<52?Q?j~hiEA}1#)$b(<+FIYzJ z_v7ql`2GHZW%Po-9oEJj%{E!aoA zcve1+6L|#aCXYWjwg&nJK-|HUht%Jc$1g-4u#lphB8Lq z?J)=a9fv%m{-!)uh&*5?|8SQ_Q84bUVg`?Nc2m4t%-Ym#rO1ObU>^rs?1Q#M#vJq( zhdiYIraV@PJYXj;d&ncf<@g=3{^N2Nd0730wnoPs^p73#koueQxLxD{J9*7r9@g<` z%!LzRM~qKPJmk?++7CSrhIH85ZVpI*7e$5QHdC0 z{j`1`@_uNxk7k0${^-L<&fISYPIuoYZLX6#Ybw2#tF9_7udd3Ep*%Mb>MmQkPmD*8 zZge8uL;X-6)GuwSsvqhN8s@qusvp)nO?Bdf!1qkgCl>Zi*- zchnmNPMbI@kWY16qE=)isybsV!}a4fDV}y3e8d`~ey9)X2Yl2UY1A*g&LZI|(m67_ zMt{cscR81apR?HiqJ?3)J~b#Z}vk z^MhI6>nI=R0^yt>UCs%@`9U}z2 zk z$c)W13KKdf=mnA+%g-4+&k6d2lB+&X^}C3j`0=KTTh#d+Y1?Bvr=w+I;^%a%B1eRt zpf~UfeX2BnukPf{$kQ}F-|0pp&1(|BrytLi+$jJ!&k67MknZp5_)2fLQzOgYtD~nU zI$vdK(y>YW6M`<0)$aKl8qUDjK(|uTe=mAlo@&fD=n^~e<4w1SzSg`So8Hn&64zT6 zRSf?7Ix&iRM&j8;M3KOEd7l2QSTX zCkFu8wp! zTbkdk8Sug{__Ll{&G~f~zGbWnHS^^=)@C|&gFRoqcg<~sL0{nc-M2N(_G(S@c)*_K z6xB!YyHM+4PfPvHe5t>gmin7%slTMDI7P2PeV5xzKUiuXJOeZy&I% zXQo-c1aGFLJToojnQ1A{OiOuYy1R{DFB)ZA`RQt;!}hvA2Oi~hRN z*RZVo_Ci|VyBg^*{cbXrL;ZRoZNl?d&kD~Rh2_ze&PliC_cGF9`4XtgzgKBM=JIKL9-P%<9~!^jAD4gE{> z>p_#4!@F%V%4A>EZ@tboj;x!m#*t>cRK}5)xQ`>ZoUF!=Yfg+jj;s?p7>@*&xzKAG zlc#u=apb(G?P-7c0F% zpNd`}m%bvjDNLKwX`91o`_-Q%iE$*-|Igl+09I98{of=k*L@diT|&h+ZC!$Z1S5G_ zKpz$r0k>+!m;{4H!aoE>?I*8l{hrpnZrCa))#6fHw-yx=7QfGDt6#0QmAbUF+7>M? zpS2bJZ26xvbAESw_r7=Edqg43g_oJRbI!Rlzcb6ZGjnGS^pi?8uCD zkorY#)8|Oya{r_gay?pOBvENjw~-ucFYwm~mt)KDL2u9#^p=tO3w?gpxrrK~;JSwP zDq3&uxlmm1__A;7A9{nHpf{a6%AeFb%c@^t)lZ_fZMLd!FYo?N(?!z;QCQcvuMmDC z>Bn^!7c(7>?PPk*oPeBY_N|&&n}l&p5x{5As$qqvk1s%S^Q3B z|2Qzd)*&Bp?|Q#*9d7dj__b52Xq8_qX{o2572Kb?`*Xh-$0oGvc+Kc$i$Hom6y=C^0L%-W+w zZ=GV#imUTk{NJkgwZ4}8J)Yjy-CKM+&3c2LptsDWQjdN0uD#K+e&n%Vl?~dR*orF8g+!Z@9Q0*R_B9^LKb2wq4w~e1+0+JE`WGB)!3T?z>UcoNrrv{%kf?E)V?go-1eZ~jV{O9zJJwQjz>h4<2xkZ3$5d{G|ywydMDKnN;-q}1^o8!PwS~+SZMEVd1-k2~zAO?RxLjYbKClpRnAb%)M!7{fhAfnCgg+}cpB>KS zINT2ZNZD|l?vaB&Do6V5>hN-m_+s6frjOJ(aaF^6q2tB&2Y&m!{Ql|(F z=lS}BlX|^wPo1MJ^e<98*UzwXv{#%yww|JV*VPf{X#Z-#{NBe8oAl(16I;hI!;rgM z#|=5Ub@|Un&gXWfW9UAI_Z|Lv;@HcEuWVi4K=x58@jUS}4@IT;_Ylb% zO#F18`BT3lxzCWSuM5q-`(IN(>(08yo31^sf%(6fdZ>5UA9h=I$qB8?DGkd%e)^7a z+Z=m9&&&1mdnpaQ4`02{L#uWlTVM82>vBrN^2N*csV{4IXXX4aH#AZj8u#6%rnhrYF9{bj+$39-TV#5&+ zHT?D1bDJ(%_^rmjmM^O3H0U2w^L)nqUhQ-LK3KlnNV>1^5Sj$vWB-L0WfJ8V4O{t# zoBm%t%Q@*kU*#zezEbKh{keJj0V8JZTHy@Kp7DO$xVNsj`9Y5V{G$hsTff~dy$7B7 zA;oiAwyrDgnb~1o|Ch;6=n`?B^I59uBE&e-0L>Blxg1Iu1L_wb7@%Jlw` zbX!3>=KIbf8X@9#s^b@XCeC|tQ14ngZ~MRAeY1z_W$@y5SDm9R<6vuuAdD`^=h6hr z#^!jAwjK8z?IFdSqaDO%YYBVK(cW6J?8~P)N857F(B|{BU2s&J;0dc33G03hXK1sl z+snQ=N1Kix{8Y}-PM==vIoh-%XIn>sr~bG|!{@fgxRbqai5rvcTY8c{mpOg?Y3hBW zeZ^zieeD;@4ottM=R53I{pX}+OR{|DXotmz-Q#|!k|K}}oTr@mhF+JQ&7*gb1RvXK_2)T2mARz2fmD)vkQ6P zvj*)>{cxFczBuT>mz;T`(huahe9J4me4qm#^b2_|-w+=k=)ea$$V0es@DK+VUR#NB zgL8SS{-nzh=#k!_UX&d|M4$)%txr7ZE05q0>IeLw2mjJ1H9zDc-$6ZrAN1h2S3aZO zpCA|fL4AQA^x(hsWnF(D7wHe;2!7Cmf61$wA9C^hD1Oj`e~s`%F47JCLN9ne=)rGG z{fAuO9>ouO@Ye`GP;d?3<7Ay<+ z{fovL7{B19x%DhrFm6i@LvPR%^oDW(ed;{YIndUxSG)P;@ZnFn;oQExCHk*~amdB? zTGqMH>*!qQbwnRE4#s-hhkjh{KM9emx%IiwAc%aanI_ z9A4VpS1D@(Z_Z3obH15h+tSK*z4qOk(2eJoIrBW;`|vX!+z+DPLq7<+AN?cxKlGzf zb_Lq;q11*iqaS}c)>wA8!Z@rAv5%MU9>q;wBmLq}!ul$=?51Je!-mf_kIw1g5HpS=u?GLE1T%e!D&w|i}kkMYK{y0?h*D1 z)~h3YC4~E2t+(3y9?-2V5E`t)@mKj{s6g5EMqwcemlooi*Q^tuSR;l*_GQHl7C zfOMCH3t1m}C5>sxI%m=w*Arb=qUsyhHS{xKdehwQ_g|c({-ihP33@|+34Ll6@V*@_ zt3@5;aJW^4KlJSVL*9)pjqBsRi1>P4JHfxf`bPHa(6TqwFS@?fkQDw!)i`!`wo}f465&A^NySi$5Ls%Ux|2>njf8tt>OInPCs#Y=Ayf0*Y8{%q zU#_9ZIQ@xB!{yX_g|9>NQn-Hb!gXUx@wsVZDP`6GYtyYmtDshVml4zplMPOL0yod? z=q@FxTQsj(ht}LueP;FO=C)CzTB}=Y4m)gQOZBL+Ev>C>W2?_Rw56?eOxujnqsLAk zF@1D(^*s6=eD>_KwrG_H6K~d`9cx+D)ZirN>wU;}CcnS^2}0%%Pn|M_cAjtR;)Q5q z{ZR#l!k&3+0TOPN^&Uh2px3=5#Z7-rujfj>qSv2gewTY48mEJ%Gz-4ij;tguqyy`p zGLo)rf&TSmpab6q;e$Nz2iKv24t!O=*ZGG$@LASt%6>;WK?lB*g%9$;*ErbE2RiUA z6+XxVAFo5>3(o@`_|^#@{2iXZggw~vzbj3Ni= zM>;r9eBt?^2mjKf=7(IAkErK^9{lqrYJSK?c}70;)7|HT9{e>&OZp`p;1B8%=?6Xd zZxw#XMf#)oK@a{7!VkH~H_BHq{h$Xw+8@Y8zN7d-4}QppT%V;$O$LhvO@ey__~hxTB_KGuUoAN79eU5BL^IyA&*i zZlK(t-R(c?(6oxAC^`CyyABQg9{NGp{pcTqb_DuU^pDO1$%Aq6Q_0W!rdorJQqf^; zNP3Fwn+kWO^n?E$)^8~>Isc#^Op6@U%jD`1d8xw#^W-JWn`6IJxSsJ`y$+4{O^rWq z-blG*{IV`J>#k>ovf{Sj8_*l{1ijh+rS%4V>MZg;skg3jv&-R8p0FFkzNaOKb!Z45 z=qHm9k4>f$Hih&$w7|Zp8$+3#n{5AyQRUoYkJcDTBwv5Jpf~6Vddo=tg+4#)JcqSC zoF?zQd9>dA^X8v*UN*(^p*QFWdV_4}lh)6#w5&_0e%VsL5Z3kWLtZ;X13lxuASR+KN^dHTo)cByTnS1{zxl&@Q~Rb$e|Z8mCvjR7?uNI7 z>oeImb+Wr}DzIdnd3*qN5bPpg2zv?R3m7NCI05V<(6h_+;v3}h`|TheG#!*8Uw9d} zult(Xj}2}*BmLknL+lt9lIKEwhaA-R5D_07AE55~Rcl5C|H9iI7B`&QDzsN&;{%$T?IQO=+v(of@_c9~ zp(p4qE$uG!sdILAlVv^NdGDZb{n<)yeTKxD(reQcYKK6-m>nk;9s=f@Eq=E z!t|!!L-c;PpzTk3gPx!_?)X69)7ypEJ6tE?lt;`t+Z|6h=Swjj<@9T1k8_1d z8|gG#&5G{526m_{)FuCTVS@SD&+esrU0S!~>cbM>N?E?2s?uSiSLX4FF!lxH#@bB`QqufDL?Zv zExSzHGO%;Z4tuOsVWw}I_@JU~nD;HmWk2(L^VoaGynXUQMa%LU=9SfO96yianE#1? z{7c2((!O)eg0aiTeAW73%=fo_YYc~*CLT;_Z>*V7mL7Zb%xQ(*kcqWV{jt9Gmp>e@e)}9hq4xL78fu5!P+z-fZBy-2&otH^ zcyWF0_Rk(s`^~45wcEdOc}-(YNw=T z)ZX>b?Aj4Oys$R)!R57YFTSjH#7pPZ?z;E%+Vj^ORZE!GPW|?7wL87AYweG=-?R3m zM?Y8lqYsAEK6BC+YTrJ2zuLy@t7?D0+ZSu!y7!>kKi_q5?Vj(~)K2@$sM<46{Yvfn zMW3tvjwy!`fuug zKPbi~3q>Me>c6S~MHU^yW)Lt47zDOZ1n?cB-c#E@?iepish4=flJ;xkKQx~B^8Q!X znV-SHlmSx)Oc^j`z?1<~222?+Wx$jHQwB^KFlE4$f&N_vc-@To84OGr*qX}#4+aL; zG3t9c{sz{r%HqUby&QU+GHlr*?oE~bjnb)N_cxl_(lv8-H}7vW!u#j~{Ya0OZGktC z$Df>}_d%I=f@IfBD+O5KPAwC?^fZ1Jn%IRK2}Wt;CY|}Uq<*K4}6v7{_+Ak@TI5e{6U_}=hq+T zz&BLt3*>>%vd;0P6LjE93LoTwud>|F2RiVfenKAjEbB4l1umciALt+t;mUHCkN1~C zy~qAQ8EFSVk9rm?cl=!D2R-;V2tVYaoCnJv_(2c;ljZzR$VK^!;s-tW)4~tAD2GS~ z@`dMv9{lTsA99`NOFatmgC6`#PS)iLa)Db^`auu=HNp?Mwv=zk2|ge6;I~iF&xc&3 zA98~Hpa*}u@I$VHpQIzm4|?!deO*5va@&OuApqwohk_%p%}xf#iSu%E#5K@a{7!VkINk19W)2mid&b^0L} z>4%&kexL{c65)qjv{zB-2R-=L2tVZFxxw}e`3F7tYo_b;LoS{l#SeP$XM`Ve(f&p0 zAN1f)pP`=*xp+S01n~ns_=h$N{*n%)8|`zDAN1gd{RO$uUlc#+!4LV6i*$$a^Y`1f z*m?MVJGsWczZ=TEE#+d|_CV!>FnO|!c`H1Us zd0IpdgB*O{X1^FFZ}Z*XZ4_b0_yw{gUnn(LchDh8>3Y3E0Od8t4c2qqk)KPPu}9jb%N&bS<j1FJTafO^Sx){QJt{zto zo-_IbD#bq_x?KHWBlVqJ?!)#~(A>TU^@{-4w|c7FsK@4<(ZbYv2JM1I@I{_8igp<7 za^|T|-g$FA+4=IGg7>=Mdk)^4ys2S(fcHatlzxM$tX7sUif)$|JgoPZg8Q;=k29~7 z)-Ky32lYE#US*?B_wxo-4(@nh`x7rgYoDg2jvy8d&aKZTy4H{=ldRN)naMNcm@>3Cbhl}$qkyGqf^LNEth z#+R?~c-<~DNf}ucrTTV7*mSPHd^aya!aAl1a^ix(0~L za@0O|((a%gvaitdVrZW*KH}JkGG2`F5)o&?K0J;TxDWM}+CKcHiVo{r(rPvEVOa2UfZqVZ zj`0g#{oXzlJwb2CKlG`>%09ehHRAL+^rKaHELDO=`te@BXvd)^zQ-5Bh}U=VSGPk~ zk_^57uRe$VF_OwNOZoK1<(|uY@Y3ADyIX!3_95zVzqb!JvC7V{26MX|X&<5;M!TGm zb{Tde?7$4ht!4flFe;b4zZmzE{NBC|Rfa!QWK>BFE7SHJFTc%psN?=o+U38L z)-Ky32lYGirx1CmSDJLXrCnZezStRPr;)30_xDo&w0#(7AIm>f>_uqMndXu88~8=N zw`=bHW*zEth89r)g`S|d^cz}l&}XM!*9 zS?455Z(QH_$L&?vc#E!S{dZq>=m~m*o}f<^R(tc3ul}O(+s^${(|rg0Z2Y1x-QTeK zFLR~61Xs9=b~5Z-nQdR%{|L*vP|2b9F&04YV}Gc4u!4X2+sP=sY3}g!Y{_@IzTHaY z75(MkC^OV-=DlE(h7)dY>G!mqZ--$KUugf`-yV8`-qL@Q@*w(D7^P+g-UBfH81KCRQQx2^=q>rS)*JMx%k~+KmbGBD_VZr~r|wtb zYbb>A;I)J!Uw3H7+C|(k;+_}|T!NzOJ?kTAy?%{#QW^iE?GzEI+N)^$vj6Ur4n09{ zwzRv@r^aVglXb=&PXQ~-+FyrL*Q{PlH!*(p8*1f+m>`h>ya$} zOl1&B{B6Zz`bF!F>l*r*XubL03&M*HlCfpDsBh2{^oGF{1n~U_a>_Lgl!k_HeCd|Di-%SvUY)!5vK#h%_t10SO!lmKaOJog|K|@X zy(4e`&Z-B_{YS$uXEm-`|9=Zt>{WJUWBR7|S5Ev%edFf_EUM=;=%316;dp2^YuF2& z3J=cDn6o;3`FZHiulw?oxxbu(i}o8x_D4a@QpMEG4AE~nnBvf;UBC)JfppUE-Y|Ak-Rg&R&)=v_B$%voj)ux$G} zB_!F%x_R!|XUAde$0NI@WRMkBlQ!XQ?l&5jGE%;nr1?6j(5oGUDKfSeI zGdjE4=5!z2Hm_^zM54O2xuyEd>e0<@qeit>x7HkX*vOXZQDa+LTieD~pLu9YTkDv% z8KXy!ojzjv=<4cu^gHsJ3*SM;chRPKS2uRhsxN(NX`5I7QFtcH)`FdvW`z)|be*62_T8gZWIXZ^L*K z#+QQM^)MgXkv}E(Y;t#{7YF+0Q#EN}ZMuDutUnev^PYY`O}}5)YVEI-nM~qJqYW3mUIDp0H#5f>+phMUZAo3`1|w6ZD3>K%Xk?taF90-rsb%&w%u5m65J8CEEFVYIPuCA^! zi)bslG5dn<_Rd++8D2nu@(+8DWWH7W-Xn86^xh+fMn5iZ49bU>@HTHCk3S=2b;CKj zEVj?m?wa$ooBUp8pSR}I8t>QMRcmTNNj}hlZ_Qbn z5AqZ-{R!?p0y^;7?V1nrz-L*@)!PrA2RiVbJX7;Q9{3su`}sfzzBOlSKF9+f?>)j7 zo(DSc)rg)T&*k$!4|L#zej(508{*3!=)ea$$V0esu*=7LPoUiFN(GY3WL2lmALxN= zFx{L_<_A6a=grpqkPDoG=?6dP!M{fMAs5dL<^%ko2mi@k`uUKH=SJ~^9{g$Hhg_r| z_yQL^AN1f)&e6|@T;LbQ4|?#|bZdUdMY^N-K@a|R;fGw*r(iip`auu=q_iK93;cm& zF#n(jKiVJ2#dD+hK@Wb&hg_r|=|DWEpKX4$bFlf-4X^szJMaZ@gkB&IYod8g$(~fR z^tborw7*Zdy=4DD<_^V8ejsyFAC_kGLk?_5`=4R*IvRDlpKs9aonk{GtnWts#oA;w zN16II@$#B-akFfGo}-Mvru<)IH!^;~tG}-)hn}FfjFbcDQ{%CY^!4l2E;bxK+%xy( z#)SFs?fqXvY;&ULcjWpM4fA=wyLa{oz)T+Q8&zr7bdL2tkv z`cz^5_P&0Yt0(m>zSbMJI|tB@FX$!e+k3=oYUi)gn`dsB_DndSY#n`jpG$AvZ|}qO zrn#MG^cxSi`x_`XXn*_9xA!~JyWWmj@0}aZEwdKo&>s3h^n2(BVfUkdME{3=ILfX; zKRA@y@MZMlvG&HYyH&cv+K}|g@@*B|k92>P{J*e%D@R5oiu1FG>Qh?epk9W`+l;@x zUo7|qbKKwiLFfs3L;j&p6%PIOe!JBiSID>bS3E8sB)qqP zo?U!f#qF}1YaYa_KElhieX*>4h5Ikv9%lwVuGYjdUm+LTWn1K+erNt&TsvRLvkRe( zs^9Ts^y9U!q9^DrZRv6VeJXrXqsMEU@E*A$5YCMvmruUpuYI)!(YjauMYhWR$31<=)r=eP}14C+N){p!J4&r?aMPm0mZSZg?@>%(wQ{=^0(0{zX+sKXw z{NkQL1Jme zEj>3({gBhp^ZBPoB#zINC;nW0VuI3;xa-239@*wE+t)vGg^EXsJ^7^S?J?NtA+LwQ!{h4voK3P-u@t2N%WW?{jv+|o` z-*33(^*vU8Oly|MRiqmpzVUA>_kVhqhOdOISuPb1&d(zcU*XHowyAgOy!kof0?U`5 zhaXtrWePH{TQ&D^dIp#4 zQS?jk{gT%#%lqXTmc;_|TrN#8ubbnV|01$LOtn&GMPeb7rY`W6kNQQJ@u35%9H2cz`*P*pHxAF;C)zu?Q$aWZZ-zz}g$@BDjm323qs`he9 zepkDhTeNGxq1T@!cicbcw``n_Qr4j%9a#UgPSTZ~mEF}XeowC?ALziBJpENQJ_>n? znEuQk?B@d=_|m78zsGx7K_2)l>rG|V<9VP1-%{a&Jn+pQ?B@d=_=Y||L_H7kz;|e1 z9UADsck;YC#RqvVpZ|HF1K*N;zoGab&*iK2` z10U)O5QJ@Y^?Pd?6Rl4VDY=gC6`f!VkH4ZWKT0!GEjpLoU)EEMIs&=)s>6e#ixWQT(6> z{|4cQT%r3J^0rN zKjeZRdPKPdKj^_f?`EBU$VL8x^&I@52mcb`hg_sPiXZggx1~RWT%pG7q`y#LFEDIZxv%eto zV&bL;OL#l<+4_^RtK^200j?Ol}h<@9ZWm_xT3prta~F^E`Bt>H%c_4eL4KhOX;8 zhV}~PU-Y;#@Eb|}VI=8Rb$J(Cg!^$u}gY|Zttm~`{k*m4&x=!t9uIS6YThH^u zji&r;V_0t+C<#dC9#ki!TI5XFR+GM3JbINgrb!*cA zDaT);G*t_bD5t@7u7?ET@eFZQIrgt}tuEWXf`8HFc(SMc4lBo+TR*|;4?Nom+V@B~ z9v0UA()-&n-G5W>apF3RpR&g($C6%@WBZ4>*V~+Q+>}Y93D99%D%3^IFf<@GywNd6r>?iD;D%1Ho^^Ex}`o?8GM)`^8OgyiH) zf(J)29{M7~Os?Gfm4eFeI(SI_9X#$6JOn2{mt{F6Ym;@bI$CJ<_m&^ z5#bYst#W)pY(8l_<-vn@Ln-uf@R0mFc-${|2u?w{4jwIY=X7_TJAHOn=j=H_q8#BS z#a20)*xI_fXSNl>3$Y(kKZtSxmn?TgTiZFl_#Ouj$-jfg1A>R(6qKmz%P|epCQO;w zFv;7np4;5r)-|)aBgnDo!_%dF+)1Jt4|Yqv96Tid4jw-eJOroUbG%5*?rP&&6C}wQ zo?HY^P~cH{>WkB)1Q~OL9Xure4jvB*9)eR)M0WWotc%$c{mb-EbbWcAMmV{Au-@&6&#s>ta zAY(QjbK1JQY2GGg!#K4d>fqCL__Y7i<>N&PG9K)DFSlj&-p%cI@R0mFc!*tX3r;~P z-u44sZjdHdcvJMZ;{^|XPFVREm@5GhaSk4mf8YUfTW~@ct{0DDy4+3C-yWC;4|)YF z_+mUV#D({%Ayn>iwaX3;Crp}7J?or~&h9zW3x29*pzdKK*YRT7y||Bb^ey9r{pUMG z-ffT8sVE?5<1V?TUsPs2fIx`Lc<{I_#%VEbo8DH>`(iv7Y^s&msZ=axiWZDlhmQVkzUc)|e*s zJ-*|*Yb5j@T>L$L{Bhe~3Vy!KQJ}w%+d@y!8}bi*>hL9m^;cIT&Qf~YO@+sk?vIfM z>jojf_&VNC5k|ZtM|rf~Zllh`J>%_|vhR}A?^1kN8D=(bx&I&1UGUP}`mWa>q}$TM zT;J*mZ`9-d`W<3Y&eF8{;5$SrYN2PmaVw7J^0|dvtdEl4WJwR>Kbs6egn5q;rs1^& z%wZ@0TkWgzMG0pv*Xx!zSi$ihRI2qooB*B;LYU(@oV>!NSMg~bW?PHXV>@9zm*j?Z zU*v}QX6jDFEzr6DPfhxbEf8JrjALjZ+`E%k$zfM^6>x4zWPFVEoghjtj znA7W(PjilgykSnS8-^VTyAgJzy}i~S?91T#53DB$uBYJgwLbyG^Z!qfJBV~MyzCzG zm4)`fcKz2>xq_SAS=*1vA*I=okOO}SpWV07J7o-(C$K?o2%ZCF79Wd_12HidXoMTdIKKNrw*s2on-gA<(72? ztqE!Gv8;P}ZAjj0xYUQMLh406=BWC{e5h~X?WFs(;bpEr-}5%7c+MYRT^`)Hot*b& zvP;F@d6VKj(TYCo58JN#8|g+X-+K-0(04uRTU_R6zh90bG=B^N1_6VB zLBJqj5HJWB1PlTO0fT@+z#w1{FbEg~3<3s$tq=hoWi;c3TcP4jmJI?10fT@+z#w1{ zFbEg~3<3rLgMdN6AYc$M2p9wm0!1QF*m$Dav)uC}S@*bWz2{yk!FMIbbKkv(?_Tho z3%+|v@1VbX!S^uuz6IaAVE;_)hY8_)Ch-VbtcmYl=zs!ihk^XvOZc}QcD1aJhx+o%ngLT1~y+Y)z`0{uySN6SJbf-U@=b_unh7Ibwm$kPNFMam{H}w07 z9R}`2Xyp3t1^7jM_oBJ=YJBa_lgKS38hV4CpttniQa(hVIy#8#Tg_mI#cOsPql>4yt+?t!epRklPNkXJ!?=SiOiguU0 z^7sL~5AC{_wHwL!DMzs0)V`OJUhF?&9}rUCJZU@jxbYKsSF7fh?wRMcO`p}-+BW^H zwpp~ZRf~rz+IuW9M90R9`7Z6(!Fz?AKtFcJ1=v_uxa{Gg4{>on=sI`^9q{#h*k2SprQ8IihT*|`!o}U( zt)z|MBrz9B`QRY%@a_jE&3`cIIl~Sfl79z}F9{wI^#*wG-kNi}+Gwwu*|Yf+j=0w} z%~yF$fqY*1EqU;W`bNVmBj|VVko-G%R0$q}Q;-jMG|!sV*{ycW4N~L|H#mHAaueo= zT^E9fx4u;5;EjrM@R0mFczjv#5S)Vi4j#Ha?e6R>Y=giC#aB74P(E)u77-r2A5oHi zaJ})x?2F{!A^CUkkbcn?oV?Frzrv%0P0%*Q{%3ng`QUxexcy+a)XTv`@((;9*A|=* zhO6*!HoKyZx4=!%HpTvD|Dydh(T>9Pwx{9d7;+HqG9HsD3ii>SB!uN8#a;r}akF_> z?c(b?o&&jfPFn0SJinw0M2W?7AQ#Vp-G}G1K9IL!Ts#MI@f^s)^Cxz2TM`>t!KSwA8^|7;&AIf%lH>< z*Yo=r|M-12%&ymOV*U90TG12qCJ;ONw5-YoYVDh>)OScvH#c2xRX+8tjjiL?4C-Dz zWuLp7s>p~QK|kKR3h!IhVpwB8D};4C_8t59NXz>8$o0oB9k=aEyVdKxh*giOBwkfE zVnD9^tqc>T!Vmg;hSOHtl2uJSHrgo1f5-m7U#xUgT$_LSH$cRU{W zemj-;ed}pD!;{=@h%RE`E!g*40+>n`FMH>2{s>Da5!M#@TQ_9md~qt`5!# ziaPIypUB@=FQXstQ#g>y`tY)Yl!+Dg&3V;6-&5!0!Oe^idvc6+^XI@%fp#5o&_1L` zhROSUljfFjHmihvO4hzhy5(^;aYM)1cxMs4yGR%o$O+>YwNIhu_U}^yzAf2>-k>Mw zEje224f@o1RBdsun_oA)fo$72?TX8r<BQ>eN9{c+Zl zx4;|F8}tOd*;0R@Pn|WcUsrm@M>%|z3V)t(!+sVMB5=UI4Lbg6;vG+R8C;(oRk14> z@PkO=k?I$1NAaUr?iCf`dSeOvE>K24?T<*D+_t|e?U%T@sXx0|)|(n1m2?K**P>E( z;HFcW2iH(`Pq#w?{E~?vDpU<>Yt_9$t8#pgPWFg*5{g zamBhQ$0)Zb$B>8et;1K5T{+|_#97>Lr2ev+!`^cIETxgJTeYKXP4=Q3BVMA#(RL{-mia2QSU7?|S_~x-BitdSiTHKm3*a0(;J^kXa&^ zrnVP_*$1F0-K8Q+m$tVmZL)*qd2f(tPQldX^V%vK=2SLzw9O&|u=2>69c`sQ)s=8a zd*``rhqQIfJiEF55bF?&jzgL;^Q=QG{kTJ{gKMe}vE<&ILtH-NGYA+23<88eXV*D% zX47F|a}GX}TMdJWLBJqT1Oh2-3+TV#uP2Xf*>skB1^u(EoykVSFiry+ zjNf1#6vk(8t_0RafgbC5Fit}crWHWZ<23eVkLi7Y#m&^ndwHTby9xF-#<1~5=l->upKdy&@o}jnn5mFwcTxfljZ#uo5 zaf8+y+$_EEIUw=%_E^OGzSfluMKv_*J!@0#@fD|f6?!^nD65D z>d}z*+pzJq{-ihP33|&&y9<44m`62PXWXImq{I8`aO#@Xi|NLrqKn@Mes@V2dP5lT z5)DV`ZCe6W#zjeQk6OR2SWLfYz46*Z{^izN|J}bCdV<~nCiIE$XXQqXCwc9Iu<`62 z2JYt6Zm<8d%16HE+V5?r&SUY?VV(3xo`!#p8E^&Hgui;kah z8hUPi`k=$U`s*X=Pd)DA9!f*c`ge4){}} zRk5g^)1ZGuP1mJ&+|cvzsXN#G^Lt$ik28*%+k44(4_v^$;=o(CWJ*2;k=?a)Xv8g(kRp1+s<^g%8szANrMuiktD zVh2)*6Q6&#ZsFxu^<3NXySkqL7@OF&dJjhjBR{(S@b~I=Uh%ijU6%Oz^lMkJSbiVz zUQz9omxldZf2(M47w;=;=w3inkVS=E8ZM{atFqy_XD8K_OP|Rx-2ZvcH*%@L3)hV) z#pkAtrSMGD_O@OZkt7ULiRYeumX?TLD7Loqq>74)f%KURuTXK*!)F=tMR^)`+k(&4 z4WNAOGJ>opx;?&aM)TZ`ZmaF!vuDR&!K=jei$60uyV~Y-AKW&t%i1dQU)|c=QhjFi z=;pRjqgtz5YYsbXWJ~p^u`R8wZDXs?JhY{)bxhlg(WA#sA2EG&b@e>@^}B*Xb!n3G z(}kMrj;cR_cEOUcj_3M>pQhK}xNYi+k=&gY3nr?m{&Jm18u%$X9onr&nwgIJPsAyD zPPY@!oZf5dvHA?)TLhiDOk}zxq0TS?regXcfy|e{g}K=w&9jj z^}3?(Y4>DttM1U@%uaF+YyI#nyD<0|dVMMQ;(n--xR8!r1jmza)z8lsNQ$Kke4qng zTKFIj{EdVCe4qp0I^lyn@LAS!)uZ8gpaWlWflepnfv<6}pAU54tGP|{K_2+5LAz5q zDs%D&I`Fj%ALO}w%PYKmpaWk<_#n^a8{*>w9r!i~ALN0raqtiyE}#Qnm6RjM1K;{` zzaBsbKF~oP!t2XjJgev?%IU6BUefYB&_j{ASPsDtdhln2A9C^hD1Oj` ze}nKtF7jO!DA#yC=)v!_*T{#|+bDj}gCF=nF47&w&+{wj7cjq)-q}4TlVu_Q!E%6d zh3D~^myI;W$?LrLq!wks01B6tQ=1e%R%Rcl$6?{78zekIyO0~#Wjq(r!ypIaPsye* zc^&dD_I!hue`k|+5zhV82F?^+`kcjY6EDxNi0j%OYCRLZyU;j&BdvqwUpN*l3;6wu z-b)z2;HA0ssBbWCOAbSC&=d4#OF4i(bspD|zJ9&h%`b-!_l*C#F=4*F<>p`YD`Aj? z?Zo<&9;cV}l>1og%K4XDZ~IW$=W_o^h+NH0XP#PH%F6yAEa7434SIs!Kn;DWaEjNx zUh3*ig|*%`5`iuC=>x%Uu!J#Ak9n6|dh>iwMC%6+C|g&~zi7Sf>uImT^rpFyoBrdn z-Zn7i(*E-Ip#pc#Oj2{cnO{3v{4bc7jpvqGi*lr#@!)W7*v*U14K-=~K^B?`?21N9z76oeb-@a%4oJP%j||^)ggm>Y66a zhJLSve$X02vZx<)T<0CUsD5xU;l}s{um0W-LQl{e@(+EgaB3xCU9}2vbUHJIw_DBO zx9Rt9`qB3Q*6sA;3-$`W^F#Pb9Ub_q^>!O!&+D-*vR?*K3I2}yMYpHka(@?b1uvG+ zA1|(N_0;H~{=P<;47NdG`3`|7jBN9}H>a&~YRlY?*~Jfa`SNszwG-pDle#(Zs40j< zyNq_&X_saE3hg!C?}G1Hc<+HccK=590NZKYuJAeV>&ur!zn{E!v|j%uZt`f|9w(14 ztzCv3)NgxIaq_(R+LZpVJ}SO^z5Xjc{pL@J{uFwG-ZIBXd606Ub5bF5Qs_@>1L55H zp(Ef65ZL#qzdUUO)41i5K(+Jwb2j zd+%Udq0nb-3H01fs&nAQ&Uup(9j82!`4oB$pu4TUm@sK0nap#& z*T4aD4!j2v<248v1PlTO0fT@+z#w1{FbEg~3<3rLgMdN6AYc$M2p9w$1bCFuKkn#6 z8IM80AYc$M2p9wm0tNwtfI+|@U=T0}7z7Lg1_6VBLBJqj5XeFx-gx4zv~E1LLhm`F zMd%fevhH!$dXL-!&ViTjT=3lsgy4G^eBXla`te;NzSjr++q718Bkd1{?_PMHvE3^4 zTGp_&u=bU*?=jq|dcAz+)Z)HV!8&|f4afURXkZ z{_X{Og5HuROFj10yXfyHt|4?5ir&`Bdiy&hjPLUM;`<5K+i)rmTkZD~q9^Fh{<_v1 z^r=;#zR{)cC2+an#dPaYxs82|?~*X|2CfK~zQwTWuk`I#&0iboFOH(xN$z9N&xC#V z(%-*Vf}Wr^^p~i28ta-S%UZh9#l4ckD^&PHby|{+;gb?v8rO&VIK;i>^(nnwLUqSI z$8V7}ly*NDN>t$z=}cXs=U-HP(|WUM2hbgyXNhIwgttTw>=Nh+dP82IPlP`!H%f2l z-(c4T(+3+bcz<&Z+aF}_R~?pC)|=X|TIjJ~^$ndba{2dNVS89#9kE~a_;-I*H}aw9 zdY0aCypnU|`7;yO9(`op{s%tZ!$R+xcFMAQhP5TWGVTr9U(&sv{@qbje^ZGgi9bm^ z4-*~5rbd&j>xh2|@o@MFk~^Ga9jN(JkNsf(hL^6nZpBXzdbpnXA8k1(k$P#z-mZI( z@1->K?)2h{#M6&lQFr_3$2kpk7tDWT*@gQqOsq-1(L-raY2s8o{*&9V}{gZ_&UY<0u z@%|ScTDkARuQW6bSftXx>0p_B6^qBP7djOlKYeDG#F(=>oc!!C?5@N^e}3J`&(-U1 zUY5DPqCS|P{qFB*AQ=rh6{Y^S;$CXsSMY z!YW3>9LIace>(eB^EQ8<#(vf5Zx_2?^$90dPH3IkJ#$t`Ti*NIJgo`rH|6Rj+IO<- zOMUW)R<-}xQgPRf(&3DZf7(sC_p9b~M16}M{dCX1(~=JCTb!0~Hm`rbW6*(bDe@EG zUpUau2RiU27s|fV0Y1wbOK)XvIzb1%dBO*INbkadem>BFuf1C13whwXXMlgdYS4l2 zR^fv@mv5|Z-)Yc+FC%=A=kncG&hM6N4^+}k(1CA*@IfB<77n~mjYfeFbl^jIf;{k@ z64{A ziXZggUn=~Ni+rPg1k(?C@UIho$VI-R_(2bT$cJ2{JB*+A=|sPPd9ieZzkfjfgXI9_ z3eWrD02<$xd9iz`MdAIbKeBG3HYt3p%s%l6y&s&o>2Jt9NV9e!H?GV2Ttp9p9E?9D zr-#T(UEZYSKHoqt4ZC094d;F22BC<*U-d`UUW7)j{i=cAb%Y(`7rZpL9zE3lAjOs$ zhTfnj=*^aL0DbD*@&45Jt#)%t;T8Kn<%VmvnP)Y3&+MEv{mkaByv#&!tiw^+7>^@c>I47YxN#r4J&h6!H=C-kJ1EB} zw#sTA*UQ~+<0me%JDymV52bc-t~M1_wUC3c)7~4f8OF%D#QGXF2_$% z8AkgZR*p5dPLJ2G?_~eA50-L#f^O%tDK?KgPC1tJq8!_Yg!CJpBr_kE;Fiu=-EH%_ zr#E+<>xunzysy%{7Vo7voPKaieX@gx%2Q}8*!W6n8k9c|s6vx4#Y!c&Xn z^U6I)@VJF;G9K)DuQ=_Km!AC&9+H0tkK+Z8h;jlv&g`7kHvO!w&bhPa1V!fzHxggv zQHAq)h3+AE@IA&uUsTcM3hAy873n&7Nd6r>rU)K_Q&0f#nB6(2ZFvmn>C>q{8vV_c(Y+{vAA~3Lb(}P$KX+w^Q|gvzxoy3o0PT zD89xT`(*zH}DJTVaw9cF}yQ8_FqM<~cIJ52i*_~b8 zmE(&PKvJH|g9p9d6nr^&Nd6r>q+hfJr=VcqG4q@`ogL@3bxohy-8`oyNEIEPIE$F5 z%6x6+thRH>!fGj~bZNPd<-w!aaYAJ`O8$Wda$*Zk2*U*)Epz8|cb+?ac30=@IfZn( zO^UB_GV!%_bGH&MC7V z$RU^U;Bg6zLttDY*{H`QFkXT22#k+Jjg#TM`hM!{YN&zd6Bs_Su2Jakb4f$7%V_Fz<&I6sR>p^$_3f>3$>^FvA-mvGJv!8sy&-iFi3=TPW#wBnCT>_@mU ze!;81k4r#L&>Qj(ed_QfO_uf5)riyMN$XZ|_&xf4L_a<&1Z@t+k8pkn!iXnQ&!zQt z8YW2bS zA!O%-o*zO}u@;`&NEp+9>p=NkC+T7QS5RAvFrSUXG(6YCm!16YecqaHSzpvaD|5M? zcjX`#Q~QHTb)GIKfaN1hUKLJW;nJ)4v<|Z^;t$J8ODDcO5ML1p>%Pi%=m!Sk2L-}| z)fs~>z3q$V)tzDK_n!OC@#(W)*Lno~()I7ZN%-)k_$!zD;&qJvtKt{E@1sXNw=F7O zDk`!hyDBmsCDwk3%(*Bwt($~1z#sD_&Q<2m!1iF^6GF; z0H2>M^WkGZ<&RHKdeR^N^FaI~0sim1=XI**|4hfjE`c2ay9D#;uvakO6rA_LJPhXp z*U3~*c-)x#RX#uGl=9)x=jSYv^K-;a&d~Nq^4!ww639XSX19mQt8UV1R`Vs6RlnzW zUl1eS=nZ;;-qPo2 zy+NNkpEN&U-M7lkGtU=X^pqRU?Zf=Q+k|n*#X74Go}cp$ouBg#(MQ>nT-VTE4G58| zHHKDRKea#U4SIs!(C$K?I>+semUZQ77jq6Dq4efGKj%jw_%Y8|VSJac4!MGQqjLlg zx85t~U$ov>4$I|!CQNUdTc4k!{korJzOc(aNyhQS4Wro{?s0un<4lsy;5buM8Ydpp zaMT2z*y--WpwVuYAc!ButRDs|Y!XHM9_6Ow_`o|q}lAB0_fI+|@U=T0}7z7Lg1_6VBLBJqj5HJWB z1PlTO0fT@+U@J$Uu<=CwtpY=)m!-C&@knE$0?|>i#-v{A)AMCq^@078h z8tA`H3o`E>;C=_h`#?{k?|?WyY%Q#PhOEDa+bQ1N_BKc}vqI z^aedaZ^>@0H|SI6i@qO8y|CKNqx(Hcob!bG;(HRVZ{MZgCi|Y`WNFXDb@RG;`B-o2 zdlE@!-0w+FoH*g6k>iX1pkz~gPjae!PjWX^ApV|&-BK@Q9kuu)V7o-Ij4vAuYT0}ZN*~xMfV%r=c3;Y z`!1@#f6oRzL2tkm`b7A%a>HyNP7C^bZhykQ1DfRd_Q&i0tn!iXx%LMCIX&EF!%hl* z2c*vF5&9R2j;rw=WB4nU#j^c*{6YU8u>o>)2Zr9U??|C~S9 z`_AdP>aySZ&guE$Lr;gE)3g8OsYXgez}NB{Nw6h4ZX2v@l!k2 z9lk-%>3QqY)#vT}X5;yH?X>!`|691?f6|vWjcHl8>X9)!H9bdtSX22UYetJzSx~8Pb9d>xNI8+K z)8pM=#7#JO;kq%U_}sLyludq4kA-u3N=ajX;5Fy;G`CcrSv|VBZPcjN>eiaW4jb80 zJ!))AYirxs>N5{*X=@$RHe>YYvC~IPA6;ENkA4TAJ-ejSST?&-v(=x|bJB6NX$3Vn z>C^T8eD|pqC%&FeI_{*-u8!9D3=x$6Hcu1b9N#dO$<>#?hy9$w;)D0PS|*Rf&+Xq* ziAoJ#5lV5XssiOVIPMg}^ z+}hSvd2DBETX$DmA$ui=RC*H&zZQny&Ux29AawxmFQ!w)iJDeaqM{yR57Ic=+iEu> z`<}sNzC!Sedd{bHpY{Jd>tFKqP0>H{hjiG<`o~TpTyd?~`FA_A-^Ka3x!tqpb{AU9 z6n&-Uh3rDyCPMo^h~eL~VchF?e?Ea<`T{+kmb@rz9J`PwfcEAl%i`bm^vjTqSmoG> zpxB&UjMo5{i$u>seC(0;jyTz)=c#kMW;C}HQL6=vQu%>tg*BcuU1r($T&n6f*X*gC zE$6g#>kN@SJ^b=@TAqVZPeYC$_UDUWH(5^N%x17TV2+S(Tcqxtxsk5xzNNbl+aATldwf{rr zDK6G-I^}m=32}XFzij#KDsVyl%m_X}AzkmUpG}<|ov{wQfq;NpDnG=PqkjG%*shlL z1pCUp-_dq&-?ppBN1-m)Pu|ZK>AXz(L)hNzvR#e#7y5*L@jU1~eWYK%Q^^*dbyjyf z=n8d9<#(Sa?eFu`0{!NZ9i7eY9?&j*Jm0!2wha9uo!=7u>fFiu((vwy&@bAtpnidd zo%HLs)b_Phex!@-qK!M1Z?Sd}@=>VEdaEHO*i{$%^y^B)dkp$p=oxlXxsbBFdX^{e z%e#<2tmPVL@xH}jF(N47G)}RsYTAt1e&8YX{{2csIsrbQw53b>VE+RXX7|1SiS0-j-&m4~IA>o0zm^~z4q)I+AG#&`&5vcq(Kb)Dw% z(v<3FiNR;#9%SpMy6M;V`x3wG(u%a`v~E85AzeYta35}1Ja9FxLBJqj5Xg-{nYBF= zB=)C2d{!}E+3lod@wo|Kqu-1fGiVOxS@llfZ@ZZ@?v+aH9znWl>BEVz=X=Oif9nlX zdZZ8Y+$C?69L{D`oL@rx&@dv!kGv{9u&J)UXuS_F#?UKShk38zTtCgh_F0+|4}0T9 z^3#7OKX|65*8Q5lFXot3LaW-@-#D@3OBeSZwtUq%b`K`kzD>?m(So+}zvyp+ZZ<5e zpK7`d{C-8sk!nSE9evd8_w93}4AdvKeQ7b3555p@S&qGYpSCNDu$SrJyXLb>82XH~ zm+#bxE%vXe zSwrXG=j~(R_mGGe_A>B`vX@_4JX>^ApSX6_+-Q6G(PHi8#*WT2trCWp>EJ)QP=>uZ zy~`UY+^_O&UuNuOT`y6VigS&`ULLU@!Z|mt_t&F>>TcO2-*uA6tQNuCZl|16vmC zW!M{G_Od$@t?(f*vfX_4a@yF-x)7d%350dwFh`Me8v}WhXM; z9c3!JWyxh)?0Spwsk)f?w$4{yt|!P&oL7gN)A%x{)LTb`euP2i=A$q1^R%A=rTbjI zVb)^^EXFYi7zDNw1UAR@7{RaoeX8);z7*rw%RVX!WViR4;?uU5`(!oHy^#a^zY&wppmo?{jD(VrS$R)3H=aqkX<3k<5dn7qQ+%i(1z ztei#PGxl;cHu3N+u=E;ogMdL`D@MR$FAvvNl*i6=a2Z6tsPFysIs=E)=UIPzO~|)+ zx$Wg$eG;+)w4UL=#s1~C(zTa^eY+!4f{Jf zUuHc)SRM7=L)in+2y55i=f#6D@`i){uz28VT!Vl?z#xzh0p1;N^V=W89V5+3zt8sN zv}65pkkVr>`=a{VUZ#in)-U(PdJNbbVfM0{S?(|R%65bHa&SFH+Stn)ItRaC-wRAV zWaNdt4E&<(<=E>n{!+BP+||}Rrxb%Z(q8_dKg)%NRGG|NWyY6t+je2)E&HAsU(Uv) zFkA~QzJ}f)U=Y}P5#Vl7zV{oXt*9_NGxvIoRLB@|E<|&WFDnZ^nw|SwuN~;v%fWPe z!a}cwe%khOUyLuq-Uzdo2RhhsU&2?m8?={$>oGFMUe?e#_=WY$9uo1wUIuA7>cg@V8Sjp=mpygJ;acMOit?y3nZBm)$CtBH=hfln^t~FV z)LTb`euP2i=EICHyI5#_d&5D0Hh!AN{51#|1PlWC5g2IpU(OFw42oeygCBYOe0&-9 zMwq?qCYSpQzOvn*y&N20w!d%IFKg_8U$E~5rY;rxU@rr|D0?~f`0{N<+sj?e=kxv; zoBq6#d;M81G^EO8^18mam$PksuMUm9oJ(F5D3~~dfI+|@;6=dQ zAHy1875Tkixb5J5ir=4md^x+H^Kpv}=-hM0mz_J}iIVeak1u0A2KHQzxBqf*e>t5g zw#WFq64)DI_OiQ{1$xPLgZ46yFCQ%XFL&|&%f?>z6sKUni?D}8ys(#nUzEKZdwlr^ zrP#}rbcl7=?Cey=x)Zq`7`bgbl(F2dS&xw$pZpj{mQxd95HJWB z1Of=eTaUqW{88WgQB=@|4LlslvzPH)-B&QL!pY}`*~{MZO47z&c0rFEv+|IL7xpsnE7@LtuvmL} zLPztQ?wKu>B+}!r^9=X{)HZr%B?z4mG<}l|j_&wmKFutsE z0J~M&%er01`F?1}J>e$0=lLlSS$|+J!`|pCdpTq5We@gRchH&ZdPu|zdl~qZY%eb@ z+FtIW&;7b8lg(YN*~yG^M-|^-onpoZ;&4aPsJ0?~ld+fGauij*^4~Z1a(;|*;~ZU3 zO^iXnAYc#(AV6JWDzPu!956tSI)?R;L3{a?kN!<-bW;hq0hxJ%x$R~Bd{~=VqJp-0 zFzhgd<%1(XD|@-H^%zbzl*c|r+fA^SVQ+-l%Wl58FX1cO)tbh+fvH6Bdq4Yjvwm4) z2mHeNWtRdz*vr7LSbLe}tR5L<)?A)vu_)J&=blu(h8r(N>wPl z`Sg%Pc$2qiyVqWz-OO#;P5*M)yKl~?^#Agex7p1+uif+u+D-miyY_Fj3-Ku5kc;vi zeI$ac#EXhA;Q%oTgT!|5^?BjDA!*Po3J>t`t427X+=vs-G&@SH~~<)g3knf}6U zs=Q^Vcx$`^{DW>b7SJc~i>pu6^S;t&d&NygpN_hMdPLYEa6Hf_@QbTYwAaP!(@8?8 zr+xVpuAPkp7& zg@L4QFP@vaMf0>8NWgdN;h`m8egbd^+ueGB~J>J#rXeWg#^=(8k!0>8NW z#CvI9>2uv7r<(TG(P*%pMc5&5JZNu$Up{>{PO+?N8u+kRl{oJ>xpU^MZYLRqc+~50 z_B*m={iqNr*|chGFa3Qp?-)IPfpV1JHS>=7G0Kf|b^$ea3<3rLgFplVG;+LI&O4Tu zhjrGTb$OB>)&GX&Eou&Ci=21-dSKpB>c9O@83VcCp5q2^>At<@*kt<*X$RTlBuE=Nc+%rm|s^Ng=)H}iXmU#nd_g!8TTIS{!h-d@GgX^#Ebd~{Nm~}E&Xm^>9c*#LkGNN z*6oOvygKyyqxA{=;_5Rg_ETT!Gt+JK>1xZXL$BYZfX}I)f?r&H+F}Ryl|GluHTr~( z{O>gJ^a=dp>J#rXeWlOz1xBBx=o9$G)n{7XOZ!Tn_Ju~DrRWp*<sF&rsV{&e;A9TIN`1HKv>pEX%-pt#s7w$Ls6^@y|UoEBx8ypHJexgs*Hj-@Iem%sXo69Q?xi zWejSCE@|FT^u8(P9o6RYl1`LO9h7-Tl~8X!g*bBv&=L8RlCVICH`;P#UoI@As6L)lg~SzUt`vr0`wy0HPV7#zV|-p6Xm1N z^tpVj(Pt_86#U}q6ZO2$^!bVTp2|^YG4)gMi>ptx*Tw78O>LO3-Hfw&VDa{`UcZM# zyxe~B_vOGZu0Cz)cl%18X`@e%vb;L<`aL88eFDF@`pk&^)K~gUUS!6>U2S=F==Hl4 z@S%PJzqtBLiyhoo`mB270J9DYN-CoN1b%V#iT9bl(&v&tn{{=LI*ZUJ@QbTYTi#3i zN}m~{Pgk8q=o9$m)2B1<_**?L@d}N{V64oOfJkrSlnHvD)v4WGo#(Vg(&dOyLoH#? z{BaJZ7*TrO@hzP%GjHbYrwjKR{0hg+%sa-YrG~^HU=RpHfVxC8?-&M5A@_z6F@E5~ z+|DMMcRWqo7Z}G+i@gE67~Yc}J*`+^9a;Ln2<*56?RSKemfYns*evZ;E+G z-YXdwmlKpvN^N7&-#f0?<zT`%*D@5nskdos`XzIHQzm-v5Z7wJOzPKsQV z?@c}LxTJeWGfxH33oPF}4i5bCz4t+%C?9>L&&&!Tt2bRL@32twJUtE2rrQhuC(=S!ML;sfhFP}c0dB@35s{M@$pLaZRW=Dr7sfByhFpE3Z;tKeQ>n+Bo=N8an23#uU>74l{7m?@j+hhrab1mXj`JPwFy}i0bB&+3UxweMfDiMIw&2Hhv0IiM{PXU! z>e$O)FU4N2Z0KrhM$!s(Bkkpf3YFxiSM@ddcVjO{mn)R7{I0Q=^JA17XMf=|A%lQH zz#xzV0qW6H+D6TD9(olCnK5HV;<;y^9fxz!;pUJZ5*2MPGqJY!%IFGV-CEBj_=dJG zU@ybo=qr0UY3yZB;fv~%JtX3Vy$t+{wU=4WT9Rpt-my-P>z;lTrz!g?liI^{6%vhV zG}uFqd!AcXG3OH4|B!Wg|I}`JgLac2%DTLdWL@6JvM%ov?I!;%@z$&AymX`kC^tJ=|5eC7T(?hzqtCu`%GWyv&!hxRc8_Q5b%quPg~wg z`%0flqtBA`3HIZ?y!!^fcsLa@RuoZg&258#L13##fV;&~*XdcIb0E>sM$bF)I=yY8899cZCC}rw z(&Bm0I*tg=rFg==^nD8J^i+D3!9nQ?+aH86_paNca8vFd=g_h+j-M2J19ma;%Fo1n z6F);Sg}C|F>7~uQqlQlXWgNqP9uo1ge$=@Hn`)ijtfKAZj^^&}wpoWXbtq`&He|{L9$O@$9*%vZwDGdpS2g`7tiM02>a2fI(nuMSw>mQ;Dy6vX8M!&n=7h zu4Nj0*Wzu5Fuv=h&+X4WzC18D^A>9_GiE%d%oqYcPq?7*W!M{iWiQ(c&3E8#F^uYy zT?+VMF9W}l?d3~~wU;N(nn5GXZL}mqxrLj~k@oUq$ZT=0vX|2vjlGOEpcL2G%TaYR z?)~BlvEecZ7zDOP1UA3%Wp_L-R3BTYy=)~$jvPs8KO>>-`pRBT8hhDO z_@eq=4~ckTF9W}l?d7YAx0lbUoJ?z%i@ub-9QN+~)1pNxMrAK2%XGesy%$xs;@vm+ z#ltE3oustFY`6^q27#>#0qPP{i6bb>`Suz8boWh))Pd@6J+Z;C6BX9ibL6M6ep#hK z864ybTfdC8%Z$B@HwVU-l?dmLeYzfxV|y%38H2qMW-q(>=DvilY&Y-vWn(XE=p6jQ z`ehG^cwsN61;1kLWtOv+WJ2$S?wgdIGVi+fuvp7Fz~=kje1_9`@7fjG?#&F)ZhDY} z%k+Lo=?d*82WrdPudUfvgXQRRT8BVu>AD3_UdkIaSJogLK?yOMXaJc2k{q_Q7rC8mTXML&SPv;V| z=Z*&uuRgtg4~ckLx9aRl!H;!|KFpW;e9$NGi>uF! zwB5z)6DbIH+s&Q<9$=uqpz9$KucJ@FFRnh(2ltge(?*{jWd-$!u!kg|Pv93*dq z^cQqJBmsQ_zqtBL%R6dc>C^tFIh)>_IJ7z7Lg27yon zXr$51L53nzz|CPqiyzo9e!EHLAg2fBAjRH*T}(<;7e5nz-6!yE?o<43zB$N@nS<1j zIk<)O%N`Q(vR%x3C;>mVi#66v;OHUmS%)lVEpgbQ_k44ZdOax58MxZ#Cweb89p1aH z{{WtVD0B{TTbXm*PP^$Hw42;s<{WpFImex3&T$v*CU=wgJ+zBdaK3qt-4?kh-vt*OgFb;@TzzK5mg+No zeq!_q9Tn4mRtbJ_^_do%xUclNqpjQLt&?7VHY%u}z%Q;o@ov*s`fML~ zlhLQ6F0T%~euu#EK%c-bu0CyfN9`+p+JlTf9VHdC>5mT%^Y+3ZH|V)OD!9M(&Z%u7`%(w@2?>S^+czXB_6F=?%sjC+-8lj7OZdum^UXop?`eBR z^Kb2cqx$4*T=+eQ=OBR}+r{qOpQDGobC8a`d|%P_^31c^=^Phpbao=+-BG48%9WSp zac`h-zbcdVE;?UjIp$0Y7wvMCmAkdTz3bJZWxcY~Gxdnm)Q)~Aji6-;_*2x@ObX1c zxp7{)!u)s!+^BST>f;R(%8!`j2?T*t49xkD0R(Z_qs`F*WM`7y~=NkNq!_BS7!QyGc1_6VBK_C(V zG96Qi$rNq&*^9&|Zv<>*c5x|#g94l68y9PtTGs-58TLk)y-W&~3-(vG8?=|#Zk*qH z;Pj18usfuA;}dCPF9Sq!qxxhIiFjcz1HUMH`K86P9eerORdciKWtOv+WZI(lsBc_e z*=ZulNhRL-X0Lij%QfDZXWqst<{Ovv?%M86?x|gSsCF}Z$~P@T<(rnhE%B=fy6k1q& z#rgz(arKFM-dFlu^5_A7H|uht(8Bcz{Nm~p?RD|`L|Vh$v{}dL0j6+$0>8NWOiRDp zXZjp$*5$eiEkd7yUtE1A#eV8DeQs;?S&}{lzqtCe#SZQ(eXe`N*h8i06Zpl|C*EiJ zN}p9-JDTr&9fcO&-U7e4`b^7vX>na#hG^$y<^@HPsCn&2*Y)Ck2|hA(DjD;zEs5dUg^(kyEnOycJ2Kn zJWS>p_m_Fb;WE$oMeQc5B>pSfMS?I-1-U5Sn|j`H$p$m;2+Vc4j9N6?rb@BRiQyb>1nq$UIU0lN2 zTG$3I75ljTROFq`-$}va6{jGN%P5j>ZHk~`q9E?N5F+30CiPOX- z{vAgA_(7Ead&hc8gZ}CLK!V}mejvfHmWpxwjMy8ni;*9GCZ4PN2Ls zzMmfKjWB!J%}=(Stm9(rr)TVC7sgOq8Q6Nr$P0Tpna5s^y`SEzMcd1BJGy87fA+ou z+^H)2K2oEiV#kiyVg-9_Z~;qHRP3=+H7W`!XzWh~jAh`7Ew&MRbR5S58tc3EsHj** zV+Y&BI*w(Gjx+w(O3uzb*-1FOr}&%sn|$BN-fORY_T8u4d(TU9?i)AeAyywFVFXS`QwhRmv^5q z>WI+`7Hvold1f_7X5jMg^hnX@Ne*YjH>mrJb#+`E_27z{muVpK~7b8 zFz`G|Id}OzhO9U0t(Sw}obsN)SFLpY9wXOWFPFQn(tmP)wWZ}^R9P=e|20}KyPiK? z`8`I@^8Ww!|9*KW{%|PIJ9nJ}>S0)PB9WUT%M%RrmWZ zo6ODH%^qm>!0)ODu&ituuqv9|d~Q<5$DN-mOOYt01qXnvm$_D!^|I*f`}+UiP@_vG4sk@d3lUq{!=j57z}W!&Yt zNzc!kRr9}H>@4Q>{k+Ua+uznZ^xUL%%kw0*ep!Y$EX&;b<~d0ln&%|-HP1=fxGZy< z7=E*|lsx3`!IX(B^ZVC+Zc^^9=5uzW&#Tvu_FNAR5?GT|K@i*<$B%m z@vP0owiKGr39!1u9z$EVT#Q;7&-r{#K;`~v?z;DpW_jXmOX~H9(af*<0<_& zzvpMnte+Otct%ccj;D-KNA91}fAc$@VY3ciP~(}IzHRe4JCy;o&q-UaI8+olKc)ZX zcRc0qnFTeTg&UjWSsA2`tcOhh&F^@o%-^L8YCI#iHplaqjHmRUYdkC8JFfT(zIPmX zw5e3X8*On&#Ko+9ht(-I?Wzv z_Q3D72k@zI%YYTo_~!SH9iIWKqpB2%BA>_qD&ISHR^L0C^@gmAF^HuXk12ZjzCbhY zDb>>Ty<@ETy<@q{D*aaPzHGS|m4CPLxk=K0To;%7nhuq5nE(IRV#Zy6?|9`EE0{4g z2R33}-#Z5LqPmWt4t?*~&wTH=iTU1fGlRD<-!n$d_l#Sa?-{o#%h+~?A5fN(L*;W* z6IbT