function imp:_moure( foo, name ) -- name = name or "anonymous" -- if not foo then -- print_dbg(name.." not found") -- else -- print_dbg(name) -- end self.moure = foo end function noop () end ------------------------------- -- ------------------------------- function imp:reduce_timers() if self.mood==self.moods.stop then return end if DEBUG_FN_NAME then print_dbg("reduce_timers") end for key, val in pairs(self.timers) do local is_locked = string.sub(key, -7) == "_locked" if not is_locked then self.timers[key] = val - 1 if (val-1)<0 then self.timers[key] = 0 end end end end ------------------------------- -- ------------------------------- function imp:reset_timer( timer ) if self.mood == self.moods.stop then return end if DEBUG_FN_NAME then print_dbg("reduce_timers") end local time = 0 if timer=="mood" then time = 150 elseif timer=="target" then time = 350 elseif timer=="shot" then time = 100 elseif timer=="super" then time = 200 elseif timer=="super_wait" then time = 200 elseif timer=="flip_wait" then time = 50 end if time > 0 then self.timers[timer] = time end end ------------------------------- -- ------------------------------- function imp:analyze_env() --OK if self.mood==self.moods.stop then return end if DEBUG_FN_NAME then print_dbg("analyze_env") end -- Distancia fins a l'abad local r = distancia(self,abad) self.analisis.can_chase_abad = false if r<=100 then self.analisis.can_chase_abad=true end -- Els dos punts de cintura per a saber si es pot escalar local x1_check = self.x+self.bb.x local x2_check = self.x+self.bb.x+self.bb.w local y_check = self.y+self.bb.h-4 local tile_type1, tile_code1= arc_check_tile(x1_check,y_check) local tile_type2, tile_code2= arc_check_tile(x2_check,y_check) self.analisis.can_climb = false if tile_type1~=tiletype.void or tile_type2~=tiletype.void then self.analisis.can_climb = true end -- Abad a tir self.analisis.can_shot = false if h_collision(self,abad) then self.analisis.can_shot=true end -- Super preparat self.analisis.can_super = false if self.timers.super<=0 then self.analisis.can_super=true end -- Acces a la zona central (només si el super està preparat) x1_check = self.x+self.bb.x x2_check = self.x+self.bb.x+self.bb.w y_check = self.y+self.bb.h+8 self.analisis.can_go_altar = false hab1, tx1, ty1 = coords.world_to_tile(x1_check, y_check) hab2, tx2, ty2 = coords.world_to_tile(x2_check, y_check) if (hab1==44 and tx1==6 and ty1==4) or (hab2==44 and tx2==7 and ty2==4) or (hab1==45 and tx1==7 and ty1==3) or (hab2==45 and tx2==8 and ty2==3)then if self.analisis.can_super then self.analisis.can_go_altar = true end end -- Caiguent self.analisis.falling = false local tile_type1, tile_code1= arc_check_tile(x1_check,y_check) local tile_type2, tile_code2= arc_check_tile(x2_check,y_check) if tile_type1==tiletype.void and tile_type2==tiletype.void then self.analisis.falling = true end -- Cau al següent moviment? self.analisis.going_to_fall = false if not self.analisis.falling then local step_length = self.step_length -- default movent-se cap a la dreta x1_check = self.x+self.bb.x+(self.bb.w/2) x2_check = self.x+self.bb.x+self.bb.w if self.x_old>self.x then -- movent-se cap a l'esquerra step_length = -step_length x1_check = self.x+self.bb.x x2_check = x1_check+(self.bb.w/2) elseif self.x_old==self.x then -- quet step_length = 0 x1_check = self.x+self.bb.x x2_check = self.x+self.bb.x+self.bb.w end local tile_type1, tile_code1= arc_check_tile(x1_check+step_length,y_check) local tile_type2, tile_code2= arc_check_tile(x2_check+step_length,y_check) if tile_type1==tiletype.void and tile_type2==tiletype.void then self.analisis.going_to_fall = true end end -- Ha arribat a destí self.analisis.target_reached = false if not empty_table(self.pattern:target_node()) then -- Target reached if self.pattern:in_target(self) then self.analisis.target_reached=true end end end function imp:update_action_events() if self.analisis.going_to_fall then self:add_action_event("prefall") end if self.analisis.falling then self:add_action_event("falling") end if self.analisis.target_reached then self:add_action_event("target") end if self.analisis.can_go_altar then self:add_action_event("super_ready") end if self.x_old>self.x then self:add_action_event("left") end if self.x_old "..self.action.." / "..k) end -- end if (self.action == self.actions.right or self.action == self.actions.left) then if self.moure == imp.state_normal or self.moure == imp.state_walking then self:_moure(imp.state_walking, "") end elseif (self.action == self.actions.jump) then if self.moure == imp.state_normal or self.moure == imp.state_walking then self:jump() end elseif (self.action == self.actions.jumpfwd) then if self.moure == imp.state_normal or self.moure == imp.state_walking then self:jump(true) end elseif (self.action == self.actions.shot) then self:shot() elseif (self.action == self.actions.super) then self:super() end -- if --(self.moure==imp.state_normal or self.moure==imp.state_walking) and -- (self.action == self.actions.right or self.action == self.actions.left) then -- -- self.moure=imp.state_walking -- self:_moure(imp.state_walking, "state_walking (movement)") -- elseif (self.moure~=imp.state_falling and self.moure~=imp.state_jumping and -- self.moure~=imp.state_super) and self.action == self.actions.jump then -- self:jump() -- elseif (self.moure==imp.state_normal or self.moure==imp.state_walking) and self.action == self.actions.jumpfwd then -- self:jump(true) -- elseif self.action == self.actions.shot then -- self:shot() -- elseif (self.moure~=imp.state_falling and self.moure~=imp.state_jumping and -- self.moure~=imp.state_super) and self.action == self.actions.super then -- self.moure=imp.state_super -- end self.old_action = self.action self.action = self.actions.no_action end ------------------------------- -- ------------------------------- function imp:fight() -- OK if DEBUG_FN_NAME then print_dbg("fight") end self:create_hot_points() self:load_pattern_paths() local node = 6 local path = {target=6, actions={{action="right",event="target"}}} self.pattern:add_manual_target ( node, path ) -- self.pattern.recovery = imp.pattern_recovery self.shot_target = abad self.mood=self.moods.chase self:pattern_movement() self:_moure(imp.state_normal,"") self.stucked = {x=0, y=0, t=0 } end ------------------------------- -- ------------------------------- function imp:shot(actor) if DEBUG_FN_NAME then print("shot") end self:do_flip(abad) -- print_dbg("FIREBALL!!") local flip = false local x_ini = self.x+self.bb.x+self.bb.w+4 if self.x>abad.x then flip=true x_ini = self.x-4 end local hab, tx, ty, off_x, off_y = coords.world_to_tile(x_ini,self.y+(self.h/4)) fireball.init(hab, tx, ty, flip, off_x, off_y) sound.play(audio_hit) self:reset_timer("shot") end ------------------------------- -- ------------------------------- function imp:create_hot_points() --OK self.pattern.node[1] = point.new(44, 6, 3, 0, 0,"P1") self.pattern.node[2] = point.new(45, 7, 3, 0, 0,"P2") self.pattern.node[3] = point.new(44,12, 5, 8, 0,"P3") self.pattern.node[4] = point.new(54, 5, 4, 0, 0,"P4") self.pattern.node[5] = point.new(54,12, 4, 8, 0,"P5") self.pattern.node[6] = point.new(55, 8, 4, 0, 0,"P6") self.pattern.node[7] = point.new(55, 8, 0, 0, 0,"P7") self.pattern.node[8] = point.new(54, 5, 0, 0, 0,"P8") self.pattern.node[9] = point.new(54, 9, 1, 0, 0,"P9") self.pattern.node[10] = point.new(55, 4, 1, 0, 0,"P10") -- self.hot_points[11] = abad -- self.hot_points[11] = point.new(45, 1, 5, 8, 0,"altar-R") -- self.hot_points[12] = point.new(44,11, 5, 0, 0,"altar-L") end ------------------------------- -- ------------------------------- function imp:load_pattern_paths() --OK self.pattern.path[1] = { {target=3, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {target=4, actions= {{action="" , event="land"}, {action="right" , event="land"}, {action="left" , event="target"}}}, {target=4, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {target=10, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {target=6, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {target=5, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="land"}, {action="left" , event="target"}}}, {target=5, actions= {{action="right" , event="target"}}} } self.pattern.path[2] = { {target=3, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {target=6, actions= {{action="" , event="land"}, {action="left" , event="land"}, {action="right" , event="target"}}}, {target=6, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {target=6, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="land"}, {action="right" , event="target"}}}, {target=6, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="land"}, {action="left" , event="land"}, {action="right" , event="target"}}}, {target=9, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {target=4, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {target=5, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="land"}, {action="right" , event="target"}}}, {target=5, actions= {{action="left" , event="target"}}} } self.pattern.path[3] = { {target=1, actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="prefall"}, {action="jump" , event="target"}}}, {target=2, actions={{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="prefall"}, {action="jump" , event="target"}}}, {target=4, actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="land"}, {action="left" , event="target"}}}, {target=5, actions={{action="left" , event="land"}, {action="right" , event="target"}}}, {target=6, actions={{action="left" , event="land"}, {action="right" , event="target"}}} } self.pattern.path[4] = { {target=1, actions={{action="jump" , event="target"}}}, --{target=5, actions={{action="right", event="target"}}}, --{target=6, actions={{action="right", event="target"}}}, --{target=8, actions={{action="jump" , event="target"}}}, } self.pattern.path[5] = { {target=4, actions={{action="left" , event="target"}}}, {target=6, actions={{action="right", event="target"}}} } self.pattern.path[6] = { --{target=2, actions={{action="jump", event="target"}}}, --{target=5, actions={{action="left", event="target"}}}, --{target=7, actions={{action="jump", event="target"}}}, {target=4, actions={{action="left", event="target"}}} } self.pattern.path[7] = { {target=5, actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {target=10,actions={{action="" , event="land"}, {action="left" , event="land"}, {action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {target=2, actions={{action="jump" , event="target"}}}, {target=6, actions={{action="" , event="land"}, {action="left" , event="land"}, {action="left" , event="land"}, {action="right", event="target"}}}, } self.pattern.path[8] = { {target=5, actions={{action="right" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="right" , event="target"}}}, {target=9, actions={{action="" , event="land"}, {action="right" , event="land"}, {action="jumpfwd" , event="land"}, {action="right" , event="target"}}}, {target=1, actions={{action="jump" , event="target"}}} } self.pattern.path[9] = { {target=6, actions={{action="right" , event="target"}}}, {target=5, actions={{action="right" , event="target"}}}, {target=1, actions={{action="left" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="left" , event="prefall"}, {action="jump" , event="target"}}}, {target=4, actions={{action="left" , event="target"}}} } self.pattern.path[10] = { {target=5, actions={{action="left" , event="target"}}}, {target=2, actions={{action="right" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="right" , event="prefall"}, {action="jump" , event="target"}}}, {target=6, actions={{action="right" , event="target"}}}, {target=6, actions={{action="left" , event="land"}, {action="right" , event = "target"}}} } self.pattern.path[11] = { {target=4, actions={{action="left", event="target"}}} } self.pattern.path[12] = { {target=6, actions={{action="right", event="target"}}} } end ------------------------------------------------------------------- -- // PATTERN MOVEMENT function imp:pattern_movement() --OK if DEBUG_FN_NAME then print_dbg("pattern_movement") end self.move_type = self.move_types.pattern -- print("Pattern") end function imp:pattern_recovery() -- OK -- print("Pattern recovery") self:pattern_movement() -- Canviar a moviment per patró -- Situar-se en el mapa respecte als punts de recuperació (els tres punts del pis) local x_after_4 = false local x_after_5 = false local x_after_6 = false local y_upper_4 = false local y_upper_5 = false local y_upper_6 = false if self.pattern.node[4].xself.y+self.h then y_upper_4 = true end if self.pattern.node[5].y>self.y+self.h then y_upper_5 = true end if self.pattern.node[6].y>self.y+self.h then y_upper_6 = true end local node = 0 local path = {} -- Seleccionar les instruccions segons la posicio if not y_upper_5 then -- target 5 node = 5 if not x_after_5 then -- right target path = {target=5, actions={{action="right",event="target"}}} else -- left target path = {target=5, actions={{action="left",event="target"}}} end else if x_after_5 then --target 4 node = 4 -- left target path = {target=4, actions={{action="left",event="target"}}} else --target 6 node = 6 -- right target path = {target=6, actions={{action="right",event="target"}}} end end self.pattern:add_manual_target ( node, path ) -- Tornar l'acció a fer -- return self.actions[self.path.actions[1].action] end ------------------------------------------------------------------- -- // ACTION function imp:next_action() local next_action = self.actions.no_action -- Si el blanc està a tir disparar if self.timers.shot<=0 and h_collision(self, self.shot_target) then next_action = "shot" end if self.timers.super<=0 and self:check_action_event("super_ready") then if self.x=self.timers.stucked_locked then self:pattern_recovery() self:reset_timer("target") end if self.move_type==self.move_types.free then -- FREE -- next_action = self:free_next_action() elseif self.move_type==self.move_types.pattern then -- PATTERN local action_event_done = self:check_action_event(self.pattern:event()) -- local str_aev = "" -- for k,v in pairs(self.action_event) do str_aev=str_aev..", "..v end if action_event_done then next_action=self.pattern:next_action() -- print_dbg("NEXT ACTION "..next_action) else next_action=self.pattern:action() -- print_dbg("HOLD ACTION "..next_action) end elseif self.move_type==self.move_types.super then -- SUPER -- next_action = "no_action" end end self.action_event = {} -- next_action es text, traduir return self.actions[next_action] end function imp:jump ( jumpfwd ) if DEBUG_FN_NAME then print_dbg("") end -- Inicialització de fer el salt jumpfwd = jumpfwd or false self.jump_height = 0 -- self.moure=imp.state_jumping self.step=0 self.jumpfwd=jumpfwd self:_moure(imp.state_jumping,"") -- self.action="" end function imp:state_jumping() if self.mood==self.moods.stop then return self.mood end if DEBUG_FN_NAME then print_dbg("state_jumping") end -- print_dbg(">>>>>>>>>> state_jumping") -- ?? self.wait=self.wait+1 self.wait=0 self.next_frame=imp.jumping_next_frame -- Pujar o caure if self.jump_height0 then self.old_y = self.y self.y=self.y-vspace self.jump_in_half_block = self.jump_in_half_block-1 self.jump_in_half_block_used = true end end end -- Registrar el desplaçament self.jump_height = self.jump_height+vspace end function imp:advance() if DEBUG_FN_NAME then print_dbg("advance") end local limit=tiletype.block if self.moure~=imp.state_walking then limit=tiletype.half end local step_length=self.step_length; --lo que avança el imp cada pas local x_check = 0 local y_check = self.y+self.bb.h-1 if (self.old_action == self.actions.right or self.old_action == self.actions.left) then -- orientació des de control if self.old_action == self.actions.left then step_length = -step_length x_check = self.x+self.bb.x else x_check = self.x+self.bb.x+self.bb.w end x_check = x_check + step_length else -- detectar orientacio des del movimentl if self.x_old>self.x then step_length = -step_length x_check = self.x+self.bb.x else x_check = self.x+self.bb.x+self.bb.w end x_check = x_check + step_length end if arc_check_tile(x_check, y_check)>>>>>>>>> state_falling") -- self.frame=30 self.wait=self.wait+1 self.next_frame=imp.falling_next_frame -- Si toca terra canviar el mode if self:land() then -- self.moure=imp.state_normal self:_moure(imp.state_normal,"state_normal (states)") self.jumpfwd = false return end -- Seguir caiguent self.old_y = self.y self.y=self.y+1 self.jump_height = self.jump_height-1 self.falling=self.falling+1 -- Caiguent cap endavant? if self.jumpfwd then self:advance() end end function imp:land () if DEBUG_FN_NAME then print_dbg("land") end -- Els dos punts de baix de l'abad local x1_check = self.x+self.bb.x local x2_check = self.x+self.bb.x+self.bb.w local y_check = self.y+self.bb.h -- Comprovar on està aterrant local tile1_hit= arc_check_tile(x1_check, y_check ) local tile2_hit= arc_check_tile(x2_check, y_check) local floor_tile = tile1_hit>=tiletype.half or tile2_hit>=tiletype.half -- Encara que siga un tile de piso s'ha de comprovar que -- la y es un múltiple de l'alt dels tiles local over_tile = (y_check & 0xF) == 0 local can_land = floor_tile and over_tile if can_land then self.jump_in_half_block_used = false self.jump_height = 0 self:add_action_event("land") end -- if can_land then print_dbg ("LANDED") end return can_land end function imp:state_walking() if self.mood==self.moods.stop then return end if DEBUG_FN_NAME then print("state_walking") end -- print_dbg(">>>>>>>>>> state_walking") -- Limitar la velocitat de moviment self.wait=self.wait+1 -- Funció de selecció de frame self.next_frame = imp.walking_next_frame -- Comprovar dos punts de contacte del personatge en el piso a vore si cau local x1_check = self.x+self.bb.x local x2_check = x1_check+self.bb.w local y_check = self.y+self.bb.h; -- base del personatge local tile1 = arc_check_tile(x1_check,y_check) local tile2 = arc_check_tile(x2_check,y_check) if tile1==tiletype.void and tile2==tiletype.void then -- si no hi ha piso, caure -- self.moure=imp.state_falling self:_moure(imp.state_falling, "state_falling (states-walking)") return end self:advance() end function imp:state_normal() if DEBUG_FN_NAME then print_dbg("state_normal") end -- print_dbg(">>>>>>>>>> state_normal") self.frame=28 self.wait=0 self.step=0 self.jumpfwd=false self.jump_height = 0 self.next_frame=imp.staying_next_frame end -- imp.next_frame() function imp:walking_next_frame() -- Selecció de frame if self.wait>=6 then self.wait=0 self.step=(self.step+1)%4 self.frame=self.anim[self.step+1] end -- Orientar self:do_flip() -- Aguantar el flip if self.timers.flip_wait<=0 then if self.mood==self.moods.chase then self:do_flip(abad) else self:do_flip(self.pattern:target_node()) end end end function imp:jumping_next_frame() self.frame=30 end function imp:falling_next_frame() self.frame=30 end function imp:staying_next_frame() self.frame=28 end function imp:super_next_frame() self.frame=11 end function imp:do_flip( actor ) actor = actor or self.pattern:target_node() -- enllaçat a actor if actor.x100 then if wait%4==0 then self.zoom=self.zoom+0.1 end elseif not self.super_fired and self.zoom>=1.75 and wait>100 then local x_ini = self.x+self.bb.x+self.bb.w+4 local hab, tx, ty, off_x, off_y = coords.world_to_tile(x_ini,self.y+(self.h/2)) fireball.init(hab, tx, ty, false, off_x, off_y, 2) self.super_fired = true elseif self.zoom>1 and wait<=100 then if wait%4==0 then self.zoom=self.zoom-0.1 end end if wait == 0 then self:_moure(imp.super_end,"") end end function imp:super_end() self.zoom = 1 self.invencible = false self.super_fired = false self:_moure(imp.state_normal,"") self:reset_timer("mood") self:reset_timer("super") self:reset_timer("super_wait") self:pattern_movement() self:pattern_recovery() end function imp:super_movement() if DEBUG_FN_NAME then print("super_movement") end self.move_type = self.move_types.super end