cxr2 = arcade_config.character_per_row_base2 imp = {} local DEBUG_FN_NAME = false function imp.reset() imp.hit=imp.hit imp.update=imp.update imp.draw=imp.draw imp.hab=abad.hab imp.enabled=false imp.counter=500 end function imp.new(_hab, _x, _y) local world_x, world_y = coords.room_to_world(_hab,_x,_y) _fight_modes={"chase","away","super","shot"} for i,v in ipairs(_fight_modes) do _fight_modes[v] = i end return { name="imp", hab=_hab, x=world_x, y=world_y, w=32, h=32, flip=true, frame=28, wait=0, vides=1, energia=6, max_energia=6, falling=0, step=0, hurting=0, jumpfwd=false, step_length=1, vmove_space=1, max_jump_height=24, jump_height=0, jump_in_half_block=0, jump_in_half_block_used = false, -- max_shoot_cooldown=24, shot_power=1, shot_num_shots=1, shoot_cooldown=25, anim={28,29,28,30}, bb={x=8,y=0,w=16,h=32}, -- scene_intro=false, -- scene_object=false, enabled=true, disable_reason="", can_warp=false, -- Atributs de jefe movement_type="", -- Mode de moviment {pattern, free} action="", -- Acció a realitzar en el "pad" movement="", -- Cap on es mou independentment de si està "flipat" fight_modes=_fight_modes, -- mode de lluita (Llevar?) fight_mode="stop", -- mode de lluita actiu fight_mode_cooldown=1500, -- cicles fins al canvi de mode super_cooldown=2000, -- cicles fins a Super actiu shot_cooldown=500, -- cicles fina a poder disparar hot_points={}, -- llista de punts del mapa on anar target={}, -- següent punt on anar old_target={}, -- target anterior paths={}, -- Llista de "camins" a fer des d'un hot_point path={}, -- Cami actiu path_curr_action=1, -- Index d'acció dins del cami actiu action_event="", -- Event d'acció que ha passat analisis={}, -- Resultat de la informació extreta de l'entorn old_action="-", invencible=false, flip_wait=100, -- Temps per a forçar un flip -- direccio=imp.direccio, draw=imp.draw, hit=imp.hit, do_jump=imp.do_jump, jump=imp.jump, state_jumping=imp.state_jumping, update=imp.state_normal, land=imp.land, advance=imp.advance, -- Funcions de jefe fight=imp.fight, -- Inicialització per al combat. Crea el punts, carrega els paths, etc. -- chase=imp.chase, -- away=imp.away, move=imp.move, -- Determina el següent moviment a fer (dreta, esq, bot, etc...) super=imp.state_super, -- Entra en mode super poder shot=imp.shot, -- Dispara do_flip=imp.do_flip, -- Orienta a l'imp cap a l'actor -- mode_controller=imp.mode_controller, reduce_cooldown=imp.reduce_cooldown, -- Decrementa els cooldown reset_fight_mode_cooldown=imp.reset_fight_mode_cooldown, -- Asignar un valor a fight_mode_cooldown (per a mantindre una coherència cada volta que es crida) controller_input=imp.controller_input, -- Traduir l'accio en moviment actualitzar_comportament=imp.actualitzar_comportament, -- "Pensar" que fer analyze_env=imp.analyze_env, -- Analitza l'entorn a vore que està pasant path_reset=imp.path_reset, -- Elimina el path actiu path_next_action=imp.path_next_action, -- Següent acció del path actiu path_action=imp.path_action, -- Acció actual del path actiu pattern_movement=imp.pattern_movement, -- Pasar a mode de moviment per patró pattern_next_action=imp.pattern_next_action, -- Següent acció en mode pattern pattern_next_target=imp.pattern_next_target, -- Següent target en mode pattern pattern_recovery=imp.pattern_recovery, -- Si per algun motiu perd el mode pattern recuperar-lo -- Al afegir pattern_recovery el moviment lliure no te sentit (ni es gasta en este moment), se queda ara per si de cas free_movement=imp.free_movement, -- Pasar a mode de moviment lliure free_next_action=imp.free_next_action, -- Següent acció en mode lliure free_next_target=imp.free_next_target, -- Següent target en mode free next_action=imp.next_action, -- Següent acció en qualsevol mode de moviment next_target=imp.next_target, -- Següent target en qualsevol mode de moviment -- imp.enabled=false -- imp.counter=500 } end function imp:fight() if DEBUG_FN_NAME then print("fight") end self.hot_points[1] = point.new(44, 5, 1, 0, 8,"P1") self.hot_points[2] = point.new(45, 8, 1, 0, 8,"P2") self.hot_points[3] = point.new(44,12, 5, 8, 0,"P3") self.hot_points[4] = point.new(54, 5, 4, -8, 0,"P4") self.hot_points[5] = point.new(54,12, 4, 8, 0,"P5") self.hot_points[6] = point.new(55, 8, 4, 8, 0,"P6") self.hot_points[7] = point.new(55, 8, 0, 0, 0,"P7") self.hot_points[8] = point.new(54, 5, 0, 0, 0,"P8") self.hot_points[9] = point.new(54, 9, 1, 0, 0,"P9") self.hot_points[10] = point.new(55,4, 1, 0, 0,"P10") self.hot_points[11] = abad self.target = self.hot_points[6] self.path = {next=6, actions={{action="right",event="target"}}} self.paths[1] = { {next=3, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {next=4, actions= {{action="right" , event="land"}, {action="left" , event="target"}}}, {next=4, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {next=10, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {next=6, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {next=5, actions= {{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="land"}, {action="left" , event="target"}}}, {next=5, actions= {{action="right" , event="target"}}} } self.paths[2] = { {next=3, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {next=6, actions= {{action="left" , event="land"}, {action="right" , event="target"}}}, {next=6, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="target"}}}, {next=9, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {next=4, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {next=5, actions= {{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="land"}, {action="right" , event="target"}}}, {next=5, actions= {{action="left" , event="target"}}} } self.paths[3] = { {next=1, actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="prefall"}, {action="jump" , event="target"}}}, {next=2, actions={{action="right" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="prefall"}, {action="jump" , event="target"}}}, {next=4, actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="right" , event="land"}, {action="left" , event="target"}}}, {next=5, actions={{action="left" , event="land"}, {action="right" , event="target"}}}, {next=6, actions={{action="left" , event="land"}, {action="right" , event="target"}}} } self.paths[4] = { {next=1, actions={{action="jump" , event="target"}}}, {next=5, actions={{action="right", event="target"}}}, {next=6, actions={{action="right", event="target"}}}, {next=8, actions={{action="jump" , event="target"}}}, } self.paths[5] = { {next=4, actions={{action="left" , event="target"}}}, {next=6, actions={{action="right", event="target"}}} } self.paths[6] = { {next=2, actions={{action="jump", event="target"}}}, --{next=5, actions={{action="left", event="target"}}}, --{next=7, actions={{action="jump", event="target"}}}, --{next=4, actions={{action="left", event="target"}}} } self.paths[7] = { {next=5, actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {next=10,actions={{action="left" , event="prefall"}, {action="jumpfwd", event="land"}, {action="left" , event="target"}}}, {next=2, actions={{action="jump" , event="target"}}} } self.paths[8] = { {next=5, actions={{action="right" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="right" , event="target"}}}, {next=9, actions={{action="right" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="right" , event="target"}}}, {next=1, actions={{action="jump" , event="target"}}} } self.paths[9] = { {next=5, actions={{action="right" , event="target"}}}, {next=1, actions={{action="left" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="left" , event="prefall"}, {action="jump" , event="target"}}}, {next=4, actions={{action="left" , event="target"}}} } self.paths[10] = { {next=5, actions={{action="left" , event="target"}}}, {next=2, actions={{action="right" , event="prefall"}, {action="jumpfwd" , event="land"}, {action="right" , event="prefall"}, {action="jump" , event="target"}}}, {next=6, actions={{action="right" , event="target"}}} } -- self.paths[11] = {} self.fight_mode="chase" self:pattern_movement() end function imp:draw() local scr_x, scr_y = viewp:screen_coords( self.x, self.y ) draw.surf((self.frame&7)*self.w, (self.frame>>cxr2)*self.h, self.w, self.h, scr_x, scr_y, self.w, self.h, self.flip) draw.rect(scr_x+self.bb.x,scr_y+self.bb.y,self.bb.w,self.bb.h,3) if #self.hot_points>0 then for _, p in pairs(self.hot_points) do if self.target==p then p:draw(true) else p:draw() end end end -- print("DRAW path= "..#self.path) if #self.path>0 then for i=1,#self.path do local world_x, world_y = coords.room_to_world(self.path[i][1], self.path[i][2], self.path[i][3]) local scr_x, scr_y = viewp:screen_coords( world_x, world_y ) draw.rect(scr_x, scr_y, 16, 16, 14) end end end function imp:hit() if DEBUG_FN_NAME then print("hit") end end function imp:do_jump ( jumpfwd ) if DEBUG_FN_NAME then print("do_jump") end -- msg_print(0,0,"do_jump",true) -- Inicialització de fer el salt jumpfwd = jumpfwd or false self.jump_height = 0 self.update=imp.state_jumping self.step=0 self.jumpfwd=jumpfwd self.action="" end function imp:state_jumping() if DEBUG_FN_NAME then print("state_jumping") end -- msg_print(0,0,"state_jumping",true) -- ?? self.wait=self.wait+1 self.wait=0 -- Pujar o caure if self.jump_height0 then 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+1 end function imp:state_walking() if DEBUG_FN_NAME then print("state_walking") end -- msg_print(16,48,"state_walking",true) -- Limitar la velocitat de moviment self.wait=self.wait+1 -- representació del moviment -- 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 -- 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.update=imp.state_falling return end self:advance() self:actualitzar_comportament() end function imp:state_falling() if DEBUG_FN_NAME then print("state_falling") end -- msg_print(16,16,"state_falling",true) self.frame=30 self.wait=self.wait+1 -- Si toca terra canviar el mode if self:land() then self.update=imp.state_normal return end -- Seguir caiguent 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 self:actualitzar_comportament() end function imp:land () if DEBUG_FN_NAME then print("land") end -- msg_print(16,32,"land",true) -- 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.action_event = "land" end return can_land end function imp:advance() if DEBUG_FN_NAME then print("advance") end -- msg_print(0,0,"advance",true) local step_length=self.step_length; --lo que avança el imp cada pas local limit=tiletype.block if self.update~=imp.state_walking then limit=tiletype.half end local x_check = self.x+self.bb.x+self.bb.w+step_length -- if self.flip then -- step_length = -step_length -- x_check = self.x+self.bb.x+step_length -- end -- self.action=="right" -- if self.action=="left" then -- print("ADVANCE => "..self.movement) if self.movement=="left" then step_length = -step_length x_check = self.x+self.bb.x+step_length end local y_check = self.y+self.bb.h-4 if arc_check_tile(x_check, y_check) "..self.path.next) end function imp:path_next_action( from ) from = from or self.path.next if DEBUG_FN_NAME then print("path_next_action "..from) end if #self.paths[from]>0 then self:pattern_movement() self:reset_fight_mode_cooldown() -- Activar següent target self:next_target(from) action = self:path_action() -- self.action_event="" else -- self:free_movement() -- action = self:next_action() action = self:pattern_recovery() end return action end function imp:free_movement() if DEBUG_FN_NAME then print("free_movement") end self.movement_type = "free" print("Free") end function imp:pattern_recovery() self:pattern_movement() self:path_reset() 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.hot_points[4].xself.y+self.h then y_upper_4 = true end if self.hot_points[5].y>self.y+self.h then y_upper_5 = true end if self.hot_points[6].y>self.y+self.h then y_upper_6 = true end if not y_upper_5 then -- target 5 self.target = self.hot_points[5] if not x_after_5 then -- right target self.path = {next=5, actions={{action="right",event="target"}}} else -- left target self.path = {next=5, actions={{action="left",event="target"}}} end else if x_after_5 then --target 4 self.target = self.hot_points[4] -- left target self.path = {next=4, actions={{action="left",event="target"}}} else --target 6 self.target = self.hot_points[6] -- right target self.path = {next=6, actions={{action="right",event="target"}}} end end return self.path.actions[1].action end function imp:free_next_action() if DEBUG_FN_NAME then print("free_next_action") end -- Moviment horitzontal if self.target.x+self.target.bb.x>=self.x+self.bb.x then action="right" elseif self.target.x+self.target.bb.xself.target.y or self.y "..#self.target) if not empty_table(self.target) then -- Target reached if collision(self, self.target) then self.analisis.target_reached=true end -- -- -- Target aligned -- if half_collision(self, self.target) then target_aligned=true end -- -- local hab1, tx1, ty1 = coords.world_to_tile(self.x+self.bb.x, self.y+self.bb.y+self.h/2) -- local hab2, tx2, ty2 = coords.world_to_tile(self.target.x, self.target.y) -- -- print(hab1..", "..tx1..", "..ty1) -- -- print(hab2..", "..tx2..", "..ty2) -- local floorImp = math.floor(hab1 / 10) -- local floorTarget = math.floor(hab2 / 10) -- local roomImp = hab1 % 10 -- local roomTarget = hab2 % 10 -- -- local sentit_y = 1 -- if floorImp>floorTarget then -- sentit_y = -1 -- elseif floorImp==floorTarget then -- sentit_y = 1 -- if ty1>ty2 then -- sentit_y= -1 -- elseif ty1==ty2 then -- sentit_y = 0 -- end -- end -- -- local sentit_x = 1 -- if roomImp>roomTarget then -- sentit_x = -1 -- elseif roomImp==roomTarget then -- sentit_x = 1 -- if tx1>tx2 then -- sentit_x = -1 -- elseif tx1==tx2 then -- sentit_x = 0 -- end -- end -- -- local max_steps = 50 -- local found = false -- while not found and max_steps>0 do -- max_steps = max_steps -1 -- end -- -- if hab1==hab2 then -- local tx = 0 -- local ty = 0 -- if tx2 "..self.target.id) -- Intentar recuperar el mode per patró self:pattern_recovery() end if self.flip_wait<=0 then if self.fight_mode==self.fight_modes["chase"] then self:do_flip(abad) else self:do_flip(self.target) end end if self.analisis.going_to_fall then self.action_event="prefall" end if self.analisis.target_reached then self.action_event="target" end action = self:next_action() if self.old_action~=action then self.old_action=action -- print(self.old_action) end self.action = action return action --if imp.wait==6 then -- imp.wait=0 -- if not imp.enabled then -- imp.counter=imp.counter-1 -- local r = math.random(0,imp.counter-1) -- --print(r) -- if imp.counter==1 or r==1 then -- imp.init() -- end -- return -- end -- -- imp.step=(imp.step+1)%4 -- imp.frame=imp.anim[imp.step+1] -- -- if imp.flip then -- imp.x=imp.x-2 -- if imp.x==78 then -- fireball.init(imp.hab,imp.x+8,imp.y+4,imp.flip) -- sound.play(audio_hit) -- imp.flip=not imp.flip -- elseif imp.x==-12 then -- imp.reset() -- end -- else -- imp.x=imp.x+2 -- if imp.x==4 then -- fireball.init(imp.hab,imp.x+8,imp.y+4,imp.flip) -- sound.play(audio_hit) -- imp.flip=not imp.flip -- elseif imp.x==92 then -- imp.reset() -- end -- end -- --end end