From d592cf18cefbe1e34ade9102793fa6dcbd7c589b Mon Sep 17 00:00:00 2001 From: AntumDeluge Date: Sun, 28 May 2017 16:47:54 -0700 Subject: [PATCH] Commit original herobrine code --- depends.txt | 1 + init.lua | 488 +++++++++++++++++++++++++++++++++++++ init.lua~ | 269 ++++++++++++++++++++ peaceful.lua~ | 174 +++++++++++++ textures/celeron55.png | Bin 0 -> 1143 bytes textures/herobrine.png | Bin 0 -> 1143 bytes textures/jordan4ibanez.png | Bin 0 -> 1143 bytes textures/mobspawnegg.png | Bin 0 -> 1267 bytes textures/spawnegg.png | Bin 0 -> 151 bytes textures/steve.png | Bin 0 -> 1143 bytes textures/zombie.png | Bin 0 -> 1143 bytes 11 files changed, 932 insertions(+) create mode 100644 depends.txt create mode 100644 init.lua create mode 100644 init.lua~ create mode 100644 peaceful.lua~ create mode 100644 textures/celeron55.png create mode 100644 textures/herobrine.png create mode 100644 textures/jordan4ibanez.png create mode 100644 textures/mobspawnegg.png create mode 100644 textures/spawnegg.png create mode 100644 textures/steve.png create mode 100644 textures/zombie.png diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..fc14e0d --- /dev/null +++ b/init.lua @@ -0,0 +1,488 @@ +-- NPC max walk speed +walk_limit = 2 + +-- Player animation speed +animation_speed = 30 + +-- Player animation blending +-- Note: This is currently broken due to a bug in Irrlicht, leave at 0 +animation_blend = 0 + +-- Default player appearance +default_model = "character.x" +available_npc_textures = { + texture_1 = {"jordan4ibanez.png", }, + texture_2 = {"zombie.png", }, + texture_3 = {"celeron55.png", }, + texture_4 = {"steve.png", } +} + + +-- Frame ranges for each player model +function player_get_animations(model) + if model == "character.x" then + return { + stand_START = 0, + stand_END = 79, + sit_START = 81, + sit_END = 160, + lay_START = 162, + lay_END = 166, + walk_START = 168, + walk_END = 187, + mine_START = 189, + mine_END = 198, + walk_mine_START = 200, + walk_mine_END = 219 + } + end +end + +local player_model = {} +local player_anim = {} +local player_sneak = {} +local ANIM_STAND = 1 +local ANIM_SIT = 2 +local ANIM_LAY = 3 +local ANIM_WALK = 4 +local ANIM_WALK_MINE = 5 +local ANIM_MINE = 6 + +function player_update_visuals(self) + --local name = get_player_name() + + visual = default_model + player_anim = 0 -- Animation will be set further below immediately + --player_sneak[name] = false + prop = { + mesh = default_model, + textures = default_textures, + textures = available_npc_textures["texture_"..math.random(1,4)], + visual_size = {x=1, y=1}, + } + self.object:set_properties(prop) +end + +NPC_ENTITY = { + physical = true, + collisionbox = {-0.3,-1.0,-0.3, 0.3,0.8,0.3}, + visual = "mesh", + mesh = "character.x", + textures = {"character.png"}, + player_anim = 0, + timer = 0, + turn_timer = 0, + vec = 0, + yaw = 0, + yawwer = 0, + state = 1, + jump_timer = 0, + door_timer = 0, + attacker = "", + attacking_timer = 0, +} + +NPC_ENTITY.on_activate = function(self) + player_update_visuals(self) + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_STAND + self.object:setacceleration({x=0,y=-10,z=0}) + self.state = 1 +end + +NPC_ENTITY.on_punch = function(self, puncher) + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 5)) do + if not object:is_player() then + if object:get_luaentity().name == "npc:npc" then + object:get_luaentity().state = 3 + object:get_luaentity().attacker = puncher:get_player_name() + end + end + end + if self.state ~= 3 then + self.state = 3 + self.attacker = puncher:get_player_name() + end +end + +NPC_ENTITY.on_step = function(self, dtime) + self.timer = self.timer + 0.01 + self.turn_timer = self.turn_timer + 0.01 + self.jump_timer = self.jump_timer + 0.01 + self.door_timer = self.door_timer + 0.01 + self.attacking_timer = self.attacking_timer + 0.01 + + --collision detection prealpha + --[[ + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 2)) do + if object:is_player() then + compare1 = object:getpos() + compare2 = self.object:getpos() + newx = compare2.x - compare1.x + newz = compare2.z - compare1.z + print(newx) + print(newz) + self.object:setacceleration({x=newx,y=self.object:getacceleration().y,z=newz}) + elseif not object:is_player() then + if object:get_luaentity().name == "npc:npc" then + print("moo") + end + end + end + ]]-- + --set npc to hostile in night, and revert npc back to peaceful in daylight + if minetest.env:get_timeofday() >= 0 and minetest.env:get_timeofday() < 0.25 and self.state ~= 4 then + self.state = 4 + elseif minetest.env:get_timeofday() > 0.25 and self.state == 4 then + self.state = 1 + end + --if mob is not in attack or hostile mode, set mob to walking or standing + if self.state < 3 then + if self.timer > math.random(1,20) then + self.state = math.random(1,2) + self.timer = 0 + end + end + --STANDING + if self.state == 1 then + self.yawwer = true + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 3)) do + if object:is_player() then + self.yawwer = false + NPC = self.object:getpos() + PLAYER = object:getpos() + self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z} + self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2 + if PLAYER.x > NPC.x then + self.yaw = self.yaw + math.pi + end + self.yaw = self.yaw - 2 + self.object:setyaw(self.yaw) + end + end + + if self.turn_timer > math.random(1,4) and yawwer == true then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + end + self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0}) + if self.player_anim ~= ANIM_STAND then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_STAND + end + end + --WALKING + if self.state == 2 then + if self.direction ~= nil then + self.object:setvelocity({x=self.direction.x,y=self.object:getvelocity().y,z=self.direction.z}) + end + if self.turn_timer > math.random(1,4) then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + self.direction = {x = math.sin(self.yaw)*-1, y = -10, z = math.cos(self.yaw)} + --self.object:setvelocity({x=self.direction.x,y=self.object:getvelocity().y,z=direction.z}) + --self.object:setacceleration(self.direction) + end + if self.player_anim ~= ANIM_WALK then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_WALK + end + --open a door [alpha] + if self.direction ~= nil then + if self.door_timer > 2 then + local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name + if is_a_door == "doors:door_wood_t_1" then + minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}) + self.door_timer = 0 + end + local is_in_door = minetest.env:get_node(self.object:getpos()).name + if is_in_door == "doors:door_wood_t_1" then + minetest.env:punch_node(self.object:getpos()) + end + end + end + --jump + if self.direction ~= nil then + if self.jump_timer > 0.3 then + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z}) + self.jump_timer = 0 + end + end + end + end + --ATTACKING + if self.state == 3 then + if self.attacking_timer > 0.25 then + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 2)) do + if object:is_player() then + if object:get_player_name() == self.attacker then + if object:get_hp() > 0 then + object:punch(object, 1.0, { + full_punch_interval=1.0, + groupcaps={ + fleshy={times={[1]=1, [2]=1, [3]=1}}, + snappy={times={[1]=1, [2]=1, [3]=1}}, + } + }, nil) + self.attacking_timer = 0 + elseif object:get_hp() <= 0 then + self.state = 1 + self.attacker = "" + end + end + end + end + end + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 10)) do + if object:is_player() then + if object:get_player_name() == self.attacker then + if self.player_anim ~= ANIM_WALK then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_WALK + end + NPC = self.object:getpos() + PLAYER = object:getpos() + self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z} + self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2 + if PLAYER.x > NPC.x then + self.yaw = self.yaw + math.pi + end + self.yaw = self.yaw - 2 + self.object:setyaw(self.yaw) + self.direction = {x = math.sin(self.yaw)*-1, y = 0, z = math.cos(self.yaw)} + if self.direction ~= nil then + self.object:setvelocity({x=self.direction.x*2.5,y=self.object:getvelocity().y,z=self.direction.z*2.5}) + end + --jump over obstacles + if self.jump_timer > 0.3 then + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z}) + self.jump_timer = 0 + end + end + if self.direction ~= nil then + if self.door_timer > 2 then + local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name + if is_a_door == "doors:door_wood_t_1" then + minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}) + self.door_timer = 0 + end + local is_in_door = minetest.env:get_node(self.object:getpos()).name + if is_in_door == "doors:door_wood_t_1" then + minetest.env:punch_node(self.object:getpos()) + end + end + end + return + elseif object:get_player_name() ~= self.attacker then + self.state = 1 + self.attacker = "" + return + end + elseif not object:is_player() then + self.state = 1 + self.attacker = "" + end + end + end + --WANDERING CONSTANTLY AT NIGHT + if self.state == 4 then + if self.player_anim ~= ANIM_WALK then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_WALK + end + if self.attacking_timer > 0.25 then + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 2)) do + if object:is_player() then + if object:get_hp() > 0 then + object:punch(object, 1.0, { + full_punch_interval=1.0, + groupcaps={ + fleshy={times={[1]=1, [2]=1, [3]=1}}, + snappy={times={[1]=1, [2]=1, [3]=1}}, + } + }, nil) + self.attacking_timer = 0 + elseif object:get_hp() <= 0 then + self.state = 1 + self.attacker = "" + end + end + end + end + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 12)) do + if object:is_player() then + if object:get_hp() > 0 then + NPC = self.object:getpos() + PLAYER = object:getpos() + self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z} + self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2 + if PLAYER.x > NPC.x then + self.yaw = self.yaw + math.pi + end + self.yaw = self.yaw - 2 + self.object:setyaw(self.yaw) + self.direction = {x = math.sin(self.yaw)*-1, y = 0, z = math.cos(self.yaw)} + if self.direction ~= nil then + self.object:setvelocity({x=self.direction.x*2.5,y=self.object:getvelocity().y,z=self.direction.z*2.5}) + end + --jump over obstacles + if self.jump_timer > 0.3 then + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z}) + self.jump_timer = 0 + end + end + if self.direction ~= nil then + if self.door_timer > 2 then + local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name + if is_a_door == "doors:door_wood_t_1" then + minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}) + self.door_timer = 0 + end + local is_in_door = minetest.env:get_node(self.object:getpos()).name + if is_in_door == "doors:door_wood_t_1" then + minetest.env:punch_node(self.object:getpos()) + end + end + end + --return + end + elseif not object:is_player() then + self.state = 1 + self.attacker = "" + end + end + if self.direction ~= nil then + self.object:setvelocity({x=self.direction.x,y=self.object:getvelocity().y,z=self.direction.z}) + end + if self.turn_timer > math.random(1,4) then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + self.direction = {x = math.sin(self.yaw)*-1, y = -10, z = math.cos(self.yaw)} + end + if self.player_anim ~= ANIM_WALK then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_WALK + end + --open a door [alpha] + if self.direction ~= nil then + if self.door_timer > 2 then + local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name + if is_a_door == "doors:door_wood_t_1" then + --print("door") + minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}) + self.door_timer = 0 + end + local is_in_door = minetest.env:get_node(self.object:getpos()).name + --print(dump(is_in_door)) + if is_in_door == "doors:door_wood_t_1" then + minetest.env:punch_node(self.object:getpos()) + end + end + end + --jump + if self.direction ~= nil then + if self.jump_timer > 0.3 then + --print(dump(minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}))) + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z}) + self.jump_timer = 0 + end + end + end + end +end + +minetest.register_entity("npc:npc", NPC_ENTITY) + +minetest.register_node("npc:spawnegg", { + description = "spawnegg", + image = "mobspawnegg.png", + inventory_image = "mobspawnegg.png", + wield_image = "mobspawnegg.png", + paramtype = "light", + tiles = {"spawnegg.png"}, + is_ground_content = true, + drawtype = "glasslike", + groups = {crumbly=3}, + selection_box = { + type = "fixed", + fixed = {0,0,0,0,0,0} + }, + sounds = default.node_sound_dirt_defaults(), + on_place = function(itemstack, placer, pointed) + pos = pointed.above + pos.y = pos.y + 1 + minetest.env:add_entity(pointed.above,"npc:npc") + end +}) +--[[ +This causes mobs to cluster together DONTA JLAFGJKAS USE IRT +--use pilzadam's spawning algo +npcs = {} +npcs.spawning_mobs = {} + function npcs:register_spawn(name, nodes, max_light, min_light, chance, mobs_per_30_block_radius, max_height) + npcs.spawning_mobs[name] = true + minetest.register_abm({ + nodenames = nodes, + neighbors = nodes, + interval = 30, + chance = chance, + action = function(pos, node) + if not npcs.spawning_mobs[name] then + return + end + pos.y = pos.y+1 + if not minetest.env:get_node_light(pos) then + return + end + if minetest.env:get_node_light(pos) > max_light then + return + end + if minetest.env:get_node_light(pos) < min_light then + return + end + if pos.y > max_height then + return + end + if minetest.env:get_node(pos).name ~= "air" then + return + end + pos.y = pos.y+1 + if minetest.env:get_node(pos).name ~= "air" then + return + end + + local count = 0 + for _,obj in pairs(minetest.env:get_objects_inside_radius(pos, 30)) do + if obj:is_player() then + return + elseif obj:get_luaentity() and obj:get_luaentity().name == name then + count = count+1 + end + end + if count > mobs_per_30_block_radius then + return + end + + if minetest.setting_getbool("display_mob_spawn") then + minetest.chat_send_all("[NPCs] Add "..name.." at "..minetest.pos_to_string(pos)) + end + minetest.env:add_entity(pos, name) + end + }) +end + +npcs:register_spawn("npc:npc", {"default:dirt_with_grass"}, 16, -1, 500, 10, 31000) +]]-- diff --git a/init.lua~ b/init.lua~ new file mode 100644 index 0000000..e99016e --- /dev/null +++ b/init.lua~ @@ -0,0 +1,269 @@ +-- NPC max walk speed +walk_limit = 2 + +-- Player animation speed +animation_speed = 30 + +-- Player animation blending +-- Note: This is currently broken due to a bug in Irrlicht, leave at 0 +animation_blend = 0 + +-- Default player appearance +default_model = "character.x" +available_npc_textures = { + texture_1 = {"jordan4ibanez.png", }, + texture_2 = {"zombie.png", }, + texture_3 = {"celeron55.png", }, + texture_4 = {"steve.png", } +} + + +-- Frame ranges for each player model +function player_get_animations(model) + if model == "character.x" then + return { + stand_START = 0, + stand_END = 79, + sit_START = 81, + sit_END = 160, + lay_START = 162, + lay_END = 166, + walk_START = 168, + walk_END = 187, + mine_START = 189, + mine_END = 198, + walk_mine_START = 200, + walk_mine_END = 219 + } + end +end + +local player_model = {} +local player_anim = {} +local player_sneak = {} +local ANIM_STAND = 1 +local ANIM_SIT = 2 +local ANIM_LAY = 3 +local ANIM_WALK = 4 +local ANIM_WALK_MINE = 5 +local ANIM_MINE = 6 + +function player_update_visuals(self) + --local name = get_player_name() + + visual = default_model + player_anim = 0 -- Animation will be set further below immediately + --player_sneak[name] = false + prop = { + mesh = default_model, + textures = default_textures, + textures = available_npc_textures["texture_"..math.random(1,4)], + visual_size = {x=1, y=1}, + } + self.object:set_properties(prop) +end + +BOAT_ENTITY = { + physical = true, + collisionbox = {-0.3,-1.0,-0.3, 0.3,0.8,0.3}, + visual = "mesh", + mesh = "character.x", + textures = {"character.png"}, + player_anim = 0, + timer = 0, + turn_timer = 0, + vec = 0, + yaw = 0, + yawwer = 0, + state = 1, + jump_timer = 0, + door_timer = 0, +} + +BOAT_ENTITY.on_activate = function(self) + player_update_visuals(self) + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_STAND + self.object:setacceleration({x=0,y=-10,z=0}) + self.state = 1 +end + +BOAT_ENTITY.on_step = function(self, dtime) + self.timer = self.timer + 0.01 + self.turn_timer = self.turn_timer + 0.01 + self.jump_timer = self.jump_timer + 0.01 + self.door_timer = self.door_timer + 0.01 + if self.timer > math.random(1,20) then + self.state = math.random(1,2) + self.timer = 0 + end + --STANDING + if self.state == 1 then + self.yawwer = true + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 3)) do + if object:is_player() then + self.yawwer = false + NPC = self.object:getpos() + PLAYER = object:getpos() + self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z} + self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2 + if PLAYER.x > NPC.x then + self.yaw = self.yaw + math.pi + end + self.yaw = self.yaw - 2 + self.object:setyaw(self.yaw) + end + end + + if self.turn_timer > math.random(1,4) and yawwer == true then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + end + self.object:setacceleration({x=0,y=-10,z=0}) + self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0}) + if self.player_anim ~= ANIM_STAND then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_STAND + end + end + --WALKING + if self.state == 2 then + --stop NPC from walking way toooooo fast! + if self.object:getvelocity().x > walk_limit then + self.object:setvelocity({x=walk_limit,y=self.object:getvelocity().y,z=self.object:getvelocity().z}) + end + if self.object:getvelocity().x < walk_limit*-1 then + self.object:setvelocity({x=walk_limit*-1,y=self.object:getvelocity().y,z=self.object:getvelocity().z}) + end + if self.object:getvelocity().z > walk_limit then + self.object:setvelocity({x=self.object:getvelocity().x,y=self.object:getvelocity().y,z=walk_limit}) + end + if self.object:getvelocity().z < walk_limit*-1 then + self.object:setvelocity({x=self.object:getvelocity().x,y=self.object:getvelocity().y,z=walk_limit*-1}) + end + if self.turn_timer > math.random(1,4) then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + self.direction = {x = math.sin(self.yaw)*-1, y = -10, z = math.cos(self.yaw)} + self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0}) + self.object:setacceleration(self.direction) + end + if self.player_anim ~= ANIM_WALK then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_WALK + end + --open a door [alpha] + if self.direction ~= nil then + --print(dump(minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name)) + if self.door_timer > 2 then + local is_a_door = minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name + if is_a_door == "doors:door_wood_t_1" then + --print("door") + minetest.env:punch_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}) + self.door_timer = 0 + end + local is_in_door = minetest.env:get_node(self.object:getpos()).name + --print(dump(is_in_door)) + if is_in_door == "doors:door_wood_t_1" then + minetest.env:punch_node(self.object:getpos()) + end + end + end + --jump + if self.direction ~= nil then + if self.jump_timer > 0.3 then + --print(dump(minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}))) + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z}) + self.jump_timer = 0 + end + end + end + end +end + +minetest.register_entity("npc:npc", BOAT_ENTITY) + +minetest.register_node("npc:spawnegg", { + description = "spawnegg", + image = "mobspawnegg.png", + inventory_image = "mobspawnegg.png", + wield_image = "mobspawnegg.png", + paramtype = "light", + tiles = {"spawnegg.png"}, + is_ground_content = true, + drawtype = "glasslike", + groups = {crumbly=3}, + selection_box = { + type = "fixed", + fixed = {0,0,0,0,0,0} + }, + sounds = default.node_sound_dirt_defaults(), + on_place = function(itemstack, placer, pointed) + pos = pointed.above + pos.y = pos.y + 1 + minetest.env:add_entity(pointed.above,"npc:npc") + end +}) + +--use pilzadam's spawning algo +npcs = {} +npcs.spawning_mobs = {} + function npcs:register_spawn(name, nodes, max_light, min_light, chance, mobs_per_30_block_radius, max_height) + npcs.spawning_mobs[name] = true + minetest.register_abm({ + nodenames = nodes, + neighbors = nodes, + interval = 30, + chance = chance, + action = function(pos, node) + if not npcs.spawning_mobs[name] then + return + end + pos.y = pos.y+1 + if not minetest.env:get_node_light(pos) then + return + end + if minetest.env:get_node_light(pos) > max_light then + return + end + if minetest.env:get_node_light(pos) < min_light then + return + end + if pos.y > max_height then + return + end + if minetest.env:get_node(pos).name ~= "air" then + return + end + pos.y = pos.y+1 + if minetest.env:get_node(pos).name ~= "air" then + return + end + + local count = 0 + for _,obj in pairs(minetest.env:get_objects_inside_radius(pos, 30)) do + if obj:is_player() then + return + elseif obj:get_luaentity() and obj:get_luaentity().name == name then + count = count+1 + end + end + if count > mobs_per_30_block_radius then + return + end + + if minetest.setting_getbool("display_mob_spawn") then + minetest.chat_send_all("[NPCs] Add "..name.." at "..minetest.pos_to_string(pos)) + end + minetest.env:add_entity(pos, name) + end + }) +end + +--npcs:register_spawn("npc:npc", {"default:dirt_with_grass"}, 16, -1, 500, 10, 31000) diff --git a/peaceful.lua~ b/peaceful.lua~ new file mode 100644 index 0000000..89a0476 --- /dev/null +++ b/peaceful.lua~ @@ -0,0 +1,174 @@ +-- NPC max walk speed +walk_limit = 2 + +-- Player animation speed +animation_speed = 30 + +-- Player animation blending +-- Note: This is currently broken due to a bug in Irrlicht, leave at 0 +animation_blend = 0 + +-- Default player appearance +default_model = "character.x" +default_textures = {"character.png", } + +-- Frame ranges for each player model +function player_get_animations(model) + if model == "character.x" then + return { + stand_START = 0, + stand_END = 79, + sit_START = 81, + sit_END = 160, + lay_START = 162, + lay_END = 166, + walk_START = 168, + walk_END = 187, + mine_START = 189, + mine_END = 198, + walk_mine_START = 200, + walk_mine_END = 219 + } + end +end + +local player_model = {} +local player_anim = {} +local player_sneak = {} +local ANIM_STAND = 1 +local ANIM_SIT = 2 +local ANIM_LAY = 3 +local ANIM_WALK = 4 +local ANIM_WALK_MINE = 5 +local ANIM_MINE = 6 + +function player_update_visuals(self) + --local name = get_player_name() + + visual = default_model + player_anim = 0 -- Animation will be set further below immediately + --player_sneak[name] = false + prop = { + mesh = default_model, + textures = default_textures, + visual = "mesh", + visual_size = {x=1, y=1}, + } + self.object:set_properties(prop) +end + +HUMAN_ENTITY = { + physical = true, + collisionbox = {-0.3,-1.0,-0.3, 0.3,0.8,0.3}, + visual = "mesh", + mesh = "character.x", + textures = {"character.png"}, + player_anim = 0, + timer = 0, + turn_timer = 0, + vec = 0, + yaw = 0, + yawwer = 0, + state = 1, + jump_timer = 0, +} + +HUMAN_ENTITY.on_activate = function(self) + player_update_visuals(self) + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_STAND + self.object:setacceleration({x=0,y=-10,z=0}) + self.state = 1 +end + +HUMAN_ENTITY.on_step = function(self, dtime) + self.timer = self.timer + 0.01 + self.turn_timer = self.turn_timer + 0.01 + self.jump_timer = self.jump_timer + 0.01 + if self.timer > math.random(1,20) then + self.state = math.random(1,2) + self.timer = 0 + end + --STANDING + if self.state == 1 then + self.yawwer = true + for _,object in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 3)) do + if object:is_player() then + self.yawwer = false + NPC = self.object:getpos() + PLAYER = object:getpos() + self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z} + self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2 + if PLAYER.x > NPC.x then + self.yaw = self.yaw + math.pi + end + self.yaw = self.yaw - 2 + self.object:setyaw(self.yaw) + end + end + + if self.turn_timer > math.random(1,4) and yawwer == true then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + end + self.object:setacceleration({x=0,y=-10,z=0}) + self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0}) + if self.player_anim ~= ANIM_STAND then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.stand_START,y=self.anim.stand_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_STAND + end + end + --WALKING + if self.state == 2 then + --stop NPC from walking way toooooo fast! + if self.object:getvelocity().x > walk_limit then + self.object:setvelocity({x=walk_limit,y=self.object:getvelocity().y,z=self.object:getvelocity().z}) + end + if self.object:getvelocity().x < walk_limit*-1 then + self.object:setvelocity({x=walk_limit*-1,y=self.object:getvelocity().y,z=self.object:getvelocity().z}) + end + if self.object:getvelocity().z > walk_limit then + self.object:setvelocity({x=self.object:getvelocity().x,y=self.object:getvelocity().y,z=walk_limit}) + end + if self.object:getvelocity().z < walk_limit*-1 then + self.object:setvelocity({x=self.object:getvelocity().x,y=self.object:getvelocity().y,z=walk_limit*-1}) + end + if self.turn_timer > math.random(1,4) then + self.yaw = 360 * math.random() + self.object:setyaw(self.yaw) + self.turn_timer = 0 + self.direction = {x = math.sin(self.yaw)*-1, y = -10, z = math.cos(self.yaw)} + self.object:setvelocity({x=0,y=self.object:getvelocity().y,z=0}) + self.object:setacceleration(self.direction) + end + if self.player_anim ~= ANIM_WALK then + self.anim = player_get_animations(visual) + self.object:set_animation({x=self.anim.walk_START,y=self.anim.walk_END}, animation_speed_mod, animation_blend) + self.player_anim = ANIM_WALK + end + --jump + --[[ + This was a test + if self.direction ~= nil then + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" and minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.turn_timer = 100 + self.jump_timer = 0 + end + end + ]]-- + if self.direction ~= nil then + if self.jump_timer > 0.3 then + --print(dump(minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}))) + if minetest.env:get_node({x=self.object:getpos().x + self.direction.x,y=self.object:getpos().y-1,z=self.object:getpos().z + self.direction.z}).name ~= "air" then + self.object:setvelocity({x=self.object:getvelocity().x,y=5,z=self.object:getvelocity().z}) + self.jump_timer = 0 + end + end + end + end +end + +minetest.register_entity("npc:npc", HUMAN_ENTITY) diff --git a/textures/celeron55.png b/textures/celeron55.png new file mode 100644 index 0000000000000000000000000000000000000000..6341b183937dfe805685c0ac0e5fbea1e89ebdee GIT binary patch literal 1143 zcmV--1c>{IP)5GnJxfH9s=j)L2b#Qp&Hi3@K8Ia>GO;%@2gdx=2DR$&aAA5)>;40*RuF zzAnNpyYfHzHqV^%p57hi>@kzv)&mbSJM+x!JkQKK=RKiNz*AnZhk(+9yGYi7!kkRH zdoG$3q5u71!O_CK8qxp&B8M8Q=t)l;LZDq9y=sX<-2Gz8MDGmi7in zu{Z&M42KiAJ5Oyb=>}@0XC$K0W4gCPsV@$8jOT92!N<#;Y=;| zTF zcXN3jHI(nyJQ%_pj6oaEBMnHFM{K(RdeH}+U2}vhVPWiahG)drxe;1@7N?&JQ?&Xt zuIl6T{$4lL9?jDna51LBHBXzM=EU4Vc|>ZQfJ5pi7i2rT8g@bf^=L^hy?bz*K2MM8 z^25|9Eyr)r_qjMN-|5f*2V9K7Sky5W=EU!yJR)U6zzKsaI&xq)&0MRa<^EQxi|o_l z*Voqx&zFe-EglcrU%Og_a4!}ZjZ2MZG^m6DDE%l%EK4@O_ zv?zg%)Kr{B^Bt!(T1&F&dCwVo*mX*Cz{MDh#T+^W+;9lWBevZD{(584%LC{2j?Q1N zr}6Vq8f&ej(Ux*;KyyKc77skWQcw3U)@Tm6uLs-p*ri(+oYI|-jWqKJHZJAzf~)Oo zBoT>35)e4S+M0h-r20a=y~z>utgJZm0IH6Vyj*?MD^tP%ztnh33}EptcD4cP1W57j zN7>E_fxkAODiSB4tT?92wz{_okbP!ynm0CirtYl0`97bN+B6fME?NG=QHF>I*W zzZnDk1O^&lTOcnI3&e?#A|)TNiI;QO43?a2Hvq?;7l69_b2dP>`SFu7+Aa%&2?^oBeb(;YTV=+%4w{NKde|!g+2FTr)H?}lD-T{VaX^0eO8i3MffNpm=8-5LL z+5j^KgA6d=0yeIX0p<>y2G~MmOAJWXpY#$k-vFiowoA)^6z69^vO6NsfQE(!0)h-+ z-th2n0z5&Si16;2yYFX!C0GDJ|C26`EzFu+W_ybG1X zM1e11KLc2#?SyQb0k#vAV1g1Bm|822Y%_N_;Q~~!-4TCcz%NFq+UK`3m6HGf002ov JPDHLkV1n%(3IYHC literal 0 HcmV?d00001 diff --git a/textures/herobrine.png b/textures/herobrine.png new file mode 100644 index 0000000000000000000000000000000000000000..6341b183937dfe805685c0ac0e5fbea1e89ebdee GIT binary patch literal 1143 zcmV--1c>{IP)5GnJxfH9s=j)L2b#Qp&Hi3@K8Ia>GO;%@2gdx=2DR$&aAA5)>;40*RuF zzAnNpyYfHzHqV^%p57hi>@kzv)&mbSJM+x!JkQKK=RKiNz*AnZhk(+9yGYi7!kkRH zdoG$3q5u71!O_CK8qxp&B8M8Q=t)l;LZDq9y=sX<-2Gz8MDGmi7in zu{Z&M42KiAJ5Oyb=>}@0XC$K0W4gCPsV@$8jOT92!N<#;Y=;| zTF zcXN3jHI(nyJQ%_pj6oaEBMnHFM{K(RdeH}+U2}vhVPWiahG)drxe;1@7N?&JQ?&Xt zuIl6T{$4lL9?jDna51LBHBXzM=EU4Vc|>ZQfJ5pi7i2rT8g@bf^=L^hy?bz*K2MM8 z^25|9Eyr)r_qjMN-|5f*2V9K7Sky5W=EU!yJR)U6zzKsaI&xq)&0MRa<^EQxi|o_l z*Voqx&zFe-EglcrU%Og_a4!}ZjZ2MZG^m6DDE%l%EK4@O_ zv?zg%)Kr{B^Bt!(T1&F&dCwVo*mX*Cz{MDh#T+^W+;9lWBevZD{(584%LC{2j?Q1N zr}6Vq8f&ej(Ux*;KyyKc77skWQcw3U)@Tm6uLs-p*ri(+oYI|-jWqKJHZJAzf~)Oo zBoT>35)e4S+M0h-r20a=y~z>utgJZm0IH6Vyj*?MD^tP%ztnh33}EptcD4cP1W57j zN7>E_fxkAODiSB4tT?92wz{_okbP!ynm0CirtYl0`97bN+B6fME?NG=QHF>I*W zzZnDk1O^&lTOcnI3&e?#A|)TNiI;QO43?a2Hvq?;7l69_b2dP>`SFu7+Aa%&2?^oBeb(;YTV=+%4w{NKde|!g+2FTr)H?}lD-T{VaX^0eO8i3MffNpm=8-5LL z+5j^KgA6d=0yeIX0p<>y2G~MmOAJWXpY#$k-vFiowoA)^6z69^vO6NsfQE(!0)h-+ z-th2n0z5&Si16;2yYFX!C0GDJ|C26`EzFu+W_ybG1X zM1e11KLc2#?SyQb0k#vAV1g1Bm|822Y%_N_;Q~~!-4TCcz%NFq+UK`3m6HGf002ov JPDHLkV1n%(3IYHC literal 0 HcmV?d00001 diff --git a/textures/jordan4ibanez.png b/textures/jordan4ibanez.png new file mode 100644 index 0000000000000000000000000000000000000000..6341b183937dfe805685c0ac0e5fbea1e89ebdee GIT binary patch literal 1143 zcmV--1c>{IP)5GnJxfH9s=j)L2b#Qp&Hi3@K8Ia>GO;%@2gdx=2DR$&aAA5)>;40*RuF zzAnNpyYfHzHqV^%p57hi>@kzv)&mbSJM+x!JkQKK=RKiNz*AnZhk(+9yGYi7!kkRH zdoG$3q5u71!O_CK8qxp&B8M8Q=t)l;LZDq9y=sX<-2Gz8MDGmi7in zu{Z&M42KiAJ5Oyb=>}@0XC$K0W4gCPsV@$8jOT92!N<#;Y=;| zTF zcXN3jHI(nyJQ%_pj6oaEBMnHFM{K(RdeH}+U2}vhVPWiahG)drxe;1@7N?&JQ?&Xt zuIl6T{$4lL9?jDna51LBHBXzM=EU4Vc|>ZQfJ5pi7i2rT8g@bf^=L^hy?bz*K2MM8 z^25|9Eyr)r_qjMN-|5f*2V9K7Sky5W=EU!yJR)U6zzKsaI&xq)&0MRa<^EQxi|o_l z*Voqx&zFe-EglcrU%Og_a4!}ZjZ2MZG^m6DDE%l%EK4@O_ zv?zg%)Kr{B^Bt!(T1&F&dCwVo*mX*Cz{MDh#T+^W+;9lWBevZD{(584%LC{2j?Q1N zr}6Vq8f&ej(Ux*;KyyKc77skWQcw3U)@Tm6uLs-p*ri(+oYI|-jWqKJHZJAzf~)Oo zBoT>35)e4S+M0h-r20a=y~z>utgJZm0IH6Vyj*?MD^tP%ztnh33}EptcD4cP1W57j zN7>E_fxkAODiSB4tT?92wz{_okbP!ynm0CirtYl0`97bN+B6fME?NG=QHF>I*W zzZnDk1O^&lTOcnI3&e?#A|)TNiI;QO43?a2Hvq?;7l69_b2dP>`SFu7+Aa%&2?^oBeb(;YTV=+%4w{NKde|!g+2FTr)H?}lD-T{VaX^0eO8i3MffNpm=8-5LL z+5j^KgA6d=0yeIX0p<>y2G~MmOAJWXpY#$k-vFiowoA)^6z69^vO6NsfQE(!0)h-+ z-th2n0z5&Si16;2yYFX!C0GDJ|C26`EzFu+W_ybG1X zM1e11KLc2#?SyQb0k#vAV1g1Bm|822Y%_N_;Q~~!-4TCcz%NFq+UK`3m6HGf002ov JPDHLkV1n%(3IYHC literal 0 HcmV?d00001 diff --git a/textures/mobspawnegg.png b/textures/mobspawnegg.png new file mode 100644 index 0000000000000000000000000000000000000000..23fcfac5ce7b756223555fd6b58975ddb6a8008a GIT binary patch literal 1267 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ=c}YY;RCwC#mrHC^WfaGM=eu|AJeUsCB5kFmH35}Jc?fDSf^h*PG%>{J0#KqW z7e*5k7er!wL981W8i`EU*q}sho%B^^*lGyF4R&H`hM9k_P z58*f|44NqLs9(C3q2A;Ce)yCz#>h;Zv1bx45i#5Lzsq3%QL?oeg1{$V2)XC}2WWca zQ5sjCMMQ22F=qe~F7_hEiZ>vV=t!%SkeD?mXY_eVa*$>2J-t3YwqTIAt7V z;nde-fd1}I!a|AAbM>T(s!W~%d#1~@-$QN8Bj0kcredmu< zDaaWBOnPrL4EB79=Z&#=^=`C|P>D3!AElxBDMTrnvNc%Q4811~;y5WpVC}B;h=@5> zQyJ%$5olPs9M5$Lf)d420VkW~%E^PoofHOx@0VzO_(hbHLJw_xtlIGm zZ^>8bTve*TZ2#mVviCM%{D7$J5f#R;((^DO{B!AZlBq1d=Me-&npQjqTGM~A69in> zW!Z+88NPgp@89d7Qdw4wK#+4W3+fm++eQ6~XGpf(hY3Bx;u!TU+YuWEdykU4ah=w5 zoTyl$@xiAtJ}gQkuxy3p#AmMoW5yL-+q?yDV2J+iE?ORYiCB6*%5gA$Nb}kqGy^6K zu~JEtA0yI5tV9fPVi@%70m4$5zq`Ar$<$FS<;lCFgt;6l5yMI(A(0}MsUgVa#(}ja z^gYC}h{_SRvblQZtJwos@i=26E`nk4n&&|Yu}l_hn|L~jMiJz001%Zuv|pmHyOWyq z0>(-%i42z^W#5fqDfqb@x^eT;G}BDcV*O|Os}9+@&e=V>?* zAvts8G_|S65hCo&d{BZ8HT^w@sjF?^uT!64XXY_{=}*3U=lv<;#u&Eb=eUqe+v^O# z`rRAQI%MIJ&E&8BisyUSmc?&}PX1>(owm?aTu7<{Oh1!Cn((ILY?&^&>7LIR;O?K% d{|4aS0RUp>7o&yv_iq3I002ovPDHLkV1l62Mm+!k literal 0 HcmV?d00001 diff --git a/textures/spawnegg.png b/textures/spawnegg.png new file mode 100644 index 0000000000000000000000000000000000000000..c2e875225706b9a6c835ab1f5d9d76ac140dbb1f GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k8}bl&H|6fVg?3oVGw3ym^DWND9B#o z>FdgVhfPFS!u;;lEal|aXmQ!2!LEx2FAG0T2??7gQu&X%Q~loCIFkZAu0d> literal 0 HcmV?d00001 diff --git a/textures/steve.png b/textures/steve.png new file mode 100644 index 0000000000000000000000000000000000000000..6341b183937dfe805685c0ac0e5fbea1e89ebdee GIT binary patch literal 1143 zcmV--1c>{IP)5GnJxfH9s=j)L2b#Qp&Hi3@K8Ia>GO;%@2gdx=2DR$&aAA5)>;40*RuF zzAnNpyYfHzHqV^%p57hi>@kzv)&mbSJM+x!JkQKK=RKiNz*AnZhk(+9yGYi7!kkRH zdoG$3q5u71!O_CK8qxp&B8M8Q=t)l;LZDq9y=sX<-2Gz8MDGmi7in zu{Z&M42KiAJ5Oyb=>}@0XC$K0W4gCPsV@$8jOT92!N<#;Y=;| zTF zcXN3jHI(nyJQ%_pj6oaEBMnHFM{K(RdeH}+U2}vhVPWiahG)drxe;1@7N?&JQ?&Xt zuIl6T{$4lL9?jDna51LBHBXzM=EU4Vc|>ZQfJ5pi7i2rT8g@bf^=L^hy?bz*K2MM8 z^25|9Eyr)r_qjMN-|5f*2V9K7Sky5W=EU!yJR)U6zzKsaI&xq)&0MRa<^EQxi|o_l z*Voqx&zFe-EglcrU%Og_a4!}ZjZ2MZG^m6DDE%l%EK4@O_ zv?zg%)Kr{B^Bt!(T1&F&dCwVo*mX*Cz{MDh#T+^W+;9lWBevZD{(584%LC{2j?Q1N zr}6Vq8f&ej(Ux*;KyyKc77skWQcw3U)@Tm6uLs-p*ri(+oYI|-jWqKJHZJAzf~)Oo zBoT>35)e4S+M0h-r20a=y~z>utgJZm0IH6Vyj*?MD^tP%ztnh33}EptcD4cP1W57j zN7>E_fxkAODiSB4tT?92wz{_okbP!ynm0CirtYl0`97bN+B6fME?NG=QHF>I*W zzZnDk1O^&lTOcnI3&e?#A|)TNiI;QO43?a2Hvq?;7l69_b2dP>`SFu7+Aa%&2?^oBeb(;YTV=+%4w{NKde|!g+2FTr)H?}lD-T{VaX^0eO8i3MffNpm=8-5LL z+5j^KgA6d=0yeIX0p<>y2G~MmOAJWXpY#$k-vFiowoA)^6z69^vO6NsfQE(!0)h-+ z-th2n0z5&Si16;2yYFX!C0GDJ|C26`EzFu+W_ybG1X zM1e11KLc2#?SyQb0k#vAV1g1Bm|822Y%_N_;Q~~!-4TCcz%NFq+UK`3m6HGf002ov JPDHLkV1n%(3IYHC literal 0 HcmV?d00001 diff --git a/textures/zombie.png b/textures/zombie.png new file mode 100644 index 0000000000000000000000000000000000000000..6341b183937dfe805685c0ac0e5fbea1e89ebdee GIT binary patch literal 1143 zcmV--1c>{IP)5GnJxfH9s=j)L2b#Qp&Hi3@K8Ia>GO;%@2gdx=2DR$&aAA5)>;40*RuF zzAnNpyYfHzHqV^%p57hi>@kzv)&mbSJM+x!JkQKK=RKiNz*AnZhk(+9yGYi7!kkRH zdoG$3q5u71!O_CK8qxp&B8M8Q=t)l;LZDq9y=sX<-2Gz8MDGmi7in zu{Z&M42KiAJ5Oyb=>}@0XC$K0W4gCPsV@$8jOT92!N<#;Y=;| zTF zcXN3jHI(nyJQ%_pj6oaEBMnHFM{K(RdeH}+U2}vhVPWiahG)drxe;1@7N?&JQ?&Xt zuIl6T{$4lL9?jDna51LBHBXzM=EU4Vc|>ZQfJ5pi7i2rT8g@bf^=L^hy?bz*K2MM8 z^25|9Eyr)r_qjMN-|5f*2V9K7Sky5W=EU!yJR)U6zzKsaI&xq)&0MRa<^EQxi|o_l z*Voqx&zFe-EglcrU%Og_a4!}ZjZ2MZG^m6DDE%l%EK4@O_ zv?zg%)Kr{B^Bt!(T1&F&dCwVo*mX*Cz{MDh#T+^W+;9lWBevZD{(584%LC{2j?Q1N zr}6Vq8f&ej(Ux*;KyyKc77skWQcw3U)@Tm6uLs-p*ri(+oYI|-jWqKJHZJAzf~)Oo zBoT>35)e4S+M0h-r20a=y~z>utgJZm0IH6Vyj*?MD^tP%ztnh33}EptcD4cP1W57j zN7>E_fxkAODiSB4tT?92wz{_okbP!ynm0CirtYl0`97bN+B6fME?NG=QHF>I*W zzZnDk1O^&lTOcnI3&e?#A|)TNiI;QO43?a2Hvq?;7l69_b2dP>`SFu7+Aa%&2?^oBeb(;YTV=+%4w{NKde|!g+2FTr)H?}lD-T{VaX^0eO8i3MffNpm=8-5LL z+5j^KgA6d=0yeIX0p<>y2G~MmOAJWXpY#$k-vFiowoA)^6z69^vO6NsfQE(!0)h-+ z-th2n0z5&Si16;2yYFX!C0GDJ|C26`EzFu+W_ybG1X zM1e11KLc2#?SyQb0k#vAV1g1Bm|822Y%_N_;Q~~!-4TCcz%NFq+UK`3m6HGf002ov JPDHLkV1n%(3IYHC literal 0 HcmV?d00001