1045 lines
36 KiB
Lua
1045 lines
36 KiB
Lua
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=21,
|
|
max_energia=21,
|
|
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_height<self.max_jump_height then
|
|
-- Comprovar que pasa en l'aire
|
|
self:jump()
|
|
else
|
|
-- Canviar a mode caure
|
|
self.update=imp.state_falling
|
|
end
|
|
self.step=self.step+1
|
|
|
|
-- cap endavant?
|
|
if self.jumpfwd then self:advance() end
|
|
|
|
self:actualitzar_comportament()
|
|
end
|
|
|
|
function imp:jump()
|
|
if DEBUG_FN_NAME then print("jump") end
|
|
-- msg_print(0,0,"jump",true)
|
|
local vspace = self.vmove_space
|
|
-- Els dos punts de dalt del personatge
|
|
local x1_check = self.x+self.bb.x
|
|
local x2_check = self.x+self.bb.x+self.bb.w
|
|
local y_check = self.y-vspace; -- posicio de dalt
|
|
|
|
-- Comprovar on està pegant
|
|
local tile1_hit_type= arc_check_tile(x1_check, y_check )
|
|
local tile2_hit_type= arc_check_tile(x2_check, y_check)
|
|
local not_block_tile = tile1_hit_type ~= tiletype.block and tile2_hit_type ~= tiletype.block
|
|
|
|
-- Fer l'acció que correspon
|
|
if not_block_tile then
|
|
-- Ascendir
|
|
self.y=self.y-vspace
|
|
else
|
|
-- Si es un bloc permetre gastar l'espai no pintat
|
|
local tile1_hit = arc_get_tile(x1_check, y_check )
|
|
local tile2_hit = arc_get_tile(x2_check, y_check)
|
|
local half_block1 = mapa_is_half_block_tile(map_to_editor_tile(tile1_hit))
|
|
local half_block2 = mapa_is_half_block_tile(map_to_editor_tile(tile2_hit))
|
|
local full_block1 = tile1_hit_type == tiletype.block and not half_block1
|
|
local full_block2 = tile2_hit_type == tiletype.block and not half_block2
|
|
local full_block = full_block1 and full_block2
|
|
local half_block = half_block1 or half_block2
|
|
-- Si ninguno dels tiles tocats es un block complet
|
|
-- i almenys un dels tiles tocats es mig tile
|
|
-- permetre continuar en el salt
|
|
if not full_block and half_block then
|
|
if self.jump_in_half_block==0 and not self.jump_in_half_block_used then
|
|
self.jump_in_half_block = arcade_config.tiles_height / 2
|
|
end
|
|
if self.jump_in_half_block>0 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)<limit then
|
|
self.x=self.x+step_length
|
|
end
|
|
|
|
local hab,xx, yy = coords.world_to_tile(self.x, self.y)
|
|
self.hab = hab
|
|
-- self.movement = ""
|
|
end
|
|
|
|
-- Controlador principal del personatge
|
|
function imp:state_normal()
|
|
if DEBUG_FN_NAME then print("state_normal") end
|
|
self.frame=28
|
|
self.wait=0
|
|
self.step=0
|
|
self.jumpfwd=false
|
|
self.jump_height = 0
|
|
self:actualitzar_comportament()
|
|
end
|
|
|
|
function imp:state_super()
|
|
if DEBUG_FN_NAME then print("state_super") end
|
|
self.fight_mode = self.fight_modes["super"]
|
|
self:reset_fight_mode_cooldown(1)
|
|
self.super_cooldown=2000
|
|
self.update=imp.state_normal
|
|
end
|
|
|
|
function imp:shot(actor)
|
|
if DEBUG_FN_NAME then print("shot") end
|
|
-- self.fight_mode = self.fight_modes["shot"]
|
|
-- self:reset_fight_mode_cooldown(1)
|
|
self:do_flip(abad)
|
|
self.flip_wait=100
|
|
-- print("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/2))
|
|
fireball.init(hab, tx, ty, flip, off_x, off_y)
|
|
sound.play(audio_hit)
|
|
|
|
self.shot_cooldown = 500
|
|
end
|
|
|
|
function imp:do_flip(actor)
|
|
if DEBUG_FN_NAME then print("do_flip") end
|
|
if actor.x<self.x then self.flip=true else self.flip=false end
|
|
end
|
|
|
|
function imp:reduce_cooldown()
|
|
if DEBUG_FN_NAME then print("reduce_cooldown") end
|
|
if self.fight_mode=="stop" then return end
|
|
|
|
self.fight_mode_cooldown = self.fight_mode_cooldown -1
|
|
self.super_cooldown = self.super_cooldown -1
|
|
self.shot_cooldown = self.shot_cooldown -1
|
|
self.flip_wait = self.flip_wait -1
|
|
end
|
|
|
|
function imp:reset_fight_mode_cooldown( value )
|
|
if DEBUG_FN_NAME then print("reset_fight_mode_cooldown") end
|
|
value = value or 1500
|
|
self.fight_mode_cooldown = value
|
|
return value
|
|
end
|
|
|
|
function imp:path_reset()
|
|
if DEBUG_FN_NAME then print("path_reset") end
|
|
self.path={}
|
|
self.path_curr_action=1;
|
|
end
|
|
|
|
function imp:path_action()
|
|
if DEBUG_FN_NAME then print("path_action") end
|
|
local action = self.path.actions[self.path_curr_action].action
|
|
-- print("PATTERN");
|
|
-- print(" TARGET= "..self.path.next)
|
|
-- print(" ACTION= "..action)
|
|
return action
|
|
end
|
|
|
|
function imp:pattern_movement()
|
|
if DEBUG_FN_NAME then print("pattern_movement") end
|
|
self.movement_type = "pattern"
|
|
|
|
-- print("Pattern")
|
|
end
|
|
|
|
function imp:pattern_next_action()
|
|
if DEBUG_FN_NAME then print("pattern_next_action") end
|
|
local path_event = self.path.actions[self.path_curr_action].event
|
|
-- print(" PATH_EVENT= "..path_event)
|
|
-- print(" ACTION_EV = "..self.action_event)
|
|
-- Si no s'ha donat l'event mantindre el moviment
|
|
if self.action_event~=path_event then
|
|
action = self.path.actions[self.path_curr_action].action
|
|
else
|
|
-- Si s'ha donat l'event avançar el punter del path
|
|
-- print(" #"..self.path_curr_action.." / "..#self.path.actions)
|
|
if self.path_curr_action<#self.path.actions then
|
|
-- En el path
|
|
self.path_curr_action = self.path_curr_action + 1
|
|
-- print(" CURR_ACC= "..self.path_curr_action)
|
|
action = self:path_action()
|
|
-- print(" ACTION 1= "..action)
|
|
else
|
|
-- Path acabat, anar al següent
|
|
action = self:path_next_action()
|
|
-- print(" ACTION 2= "..action)
|
|
end
|
|
end
|
|
self.action_event = ""; -- Action_event processat
|
|
-- print(" ACTION ="..action)
|
|
return action
|
|
end
|
|
|
|
function imp:pattern_next_target(from)
|
|
if DEBUG_FN_NAME then print("pattern_next_target") end
|
|
-- obtindre uno dels possibles camins des del punt "from" (en el que està)
|
|
local next_path_idx = math.random(#self.paths[from])
|
|
|
|
self.path = self.paths[from][next_path_idx]
|
|
self.path_curr_action = 1
|
|
self.target = self.hot_points[self.path.next]
|
|
-- print("Next pattern target => "..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].x<self.x then x_after_4 = true end
|
|
if self.hot_points[5].x<self.x then x_after_5 = true end
|
|
if self.hot_points[6].x<self.x then x_after_6 = true end
|
|
if self.hot_points[4].y>self.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.x<self.x+self.bb.x then
|
|
action="left"
|
|
end
|
|
|
|
-- Els dos punts de baix pero un poc mes alt que el piso
|
|
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
|
|
-- Tiles on esta
|
|
local tile_type1, tile_code1= arc_check_tile(x1_check,y_check)
|
|
local tile_type2, tile_code2= arc_check_tile(x2_check,y_check)
|
|
|
|
-- debug
|
|
local scr_x1, scr_y = viewp:screen_coords( x1_check, y_check )
|
|
local scr_x2, scr_y = viewp:screen_coords( x2_check, y_check )
|
|
draw.rect(scr_x1,scr_y,scr_x2-scr_x1,8,2)
|
|
-- /debug
|
|
|
|
--Comprovar si está en target
|
|
if collision(self, self.target) then
|
|
self:reset_fight_mode_cooldown()
|
|
|
|
-- Buscar quin es el target
|
|
local idx = 1
|
|
for i=1,#self.hot_points do
|
|
if self.target==self.hot_points[i] then
|
|
idx= i
|
|
-- print("TARGET ID= "..self.target.id.." HOT POINT IDX= "..i.." Reached")
|
|
end
|
|
end
|
|
|
|
-- Canviar a moviment per patro
|
|
action = self:path_next_action(idx)
|
|
-- elseif half_collision(self, self.target)
|
|
-- and tile_type1==tiletype.void
|
|
-- and tile_type2==tiletype.void then -- and (self.y>self.target.y or self.y<self.target.y) ) then -- afegir que no hi haja tile per a escalar
|
|
-- -- print("Next Target 2 "..tile_type1.." "..tile_code1)
|
|
-- elseif tile_type1~=tiletype.void
|
|
-- or tile_type2~=tiletype.void then
|
|
-- action="jump"
|
|
end
|
|
|
|
return action
|
|
end
|
|
|
|
function imp:free_next_target()
|
|
if DEBUG_FN_NAME then print("free_next_target") end
|
|
local new_point = math.random(#self.hot_points)
|
|
if self.target == self.hot_points[new_point] then
|
|
new_point = ((new_point+1)%#self.hot_points)+1
|
|
end
|
|
self.old_target = self.target
|
|
self.target=self.hot_points[new_point]
|
|
end
|
|
|
|
function imp:analyze_env()
|
|
if DEBUG_FN_NAME then print("analyze_env") end
|
|
-- Distancia fins els punts
|
|
local scr_x, scr_y = viewp:screen_coords(self.x, self.y)
|
|
-- for _, p in pairs(self.hot_points) do
|
|
-- local scr_x1, scr_y1 = viewp:screen_coords(p.x, p.y)
|
|
-- local color = 2
|
|
-- if self.target == p then color = 4 end
|
|
-- draw.line(scr_x, scr_y, scr_x1, scr_y1, color)
|
|
--
|
|
-- dx = (self.x-p.x)
|
|
-- dy = (self.y-p.y)
|
|
-- d = math.sqrt(dx*dx+dy*dy)
|
|
-- end
|
|
|
|
-- Distancia fins a l'abad
|
|
dx = (self.x-abad.x)
|
|
dy = (self.y-abad.y)
|
|
r = math.sqrt(dx*dx+dy*dy)
|
|
-- msg_print(10,20,r,true)
|
|
self.analisis.can_chase_abad = false
|
|
if r<=100 then
|
|
-- draw.circ(scr_x+self.bb.w/2,scr_y+self.bb.h/2,r,2)
|
|
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.super_cooldown<=0 then self.analisis.can_super=true end
|
|
|
|
-- Acces a la zona central
|
|
x1_check = self.x+self.bb.x
|
|
x2_check = self.x+self.bb.x+self.bb.w
|
|
y_check = self.y+self.bb.h
|
|
self.analisis.can_go_altar = false
|
|
local hab1, tx1, ty1 = coords.world_to_tile(x1_check, y_check)
|
|
local 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
|
|
self.analisis.can_go_altar = true
|
|
end
|
|
|
|
-- Cau al següent moviment
|
|
self.analisis.going_to_fall = false
|
|
if self.movement=="left" then
|
|
x1_check=x1_check-self.step_length
|
|
x2_check=x2_check-self.step_length
|
|
elseif self.movement=="right" then
|
|
x1_check=x1_check+self.step_length
|
|
x2_check=x2_check+self.step_length
|
|
end
|
|
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.going_to_fall = true
|
|
end
|
|
|
|
self.analisis.target_reached = false
|
|
-- local target_aligned = false
|
|
-- self.path= {}
|
|
-- -- print("ANALYZE => "..#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<tx1 then
|
|
-- for i=tx2,tx1 do
|
|
-- tx = i
|
|
-- self.path[#self.path+1] = {hab1, tx, ty1}
|
|
-- end
|
|
-- if ty2<ty1 then
|
|
-- for j=ty2,ty1 do
|
|
-- ty = j
|
|
-- self.path[#self.path+1] = {hab1, tx, ty}
|
|
-- end
|
|
-- else
|
|
-- for j=ty1,ty2 do
|
|
-- ty = j
|
|
-- self.path[#self.path+1] = {hab1, tx, ty}
|
|
-- end
|
|
-- end
|
|
-- elseif tx1<tx2 then
|
|
-- for i=tx1,tx2 do
|
|
-- tx = i
|
|
-- self.path[#self.path+1] = {hab1, tx, ty1}
|
|
-- end
|
|
-- if ty2<ty1 then
|
|
-- for j=ty2,ty1 do
|
|
-- ty = j
|
|
-- self.path[#self.path+1] = {hab1, tx, ty}
|
|
-- end
|
|
-- else
|
|
-- for j=ty1,ty2 do
|
|
-- ty = j
|
|
-- self.path[#self.path+1] = {hab1, tx, ty}
|
|
-- end
|
|
-- end
|
|
-- end
|
|
-- end
|
|
--
|
|
-- self.path[#self.path+1] = {hab1, tx1, ty1}
|
|
-- self.path[#self.path+1] = {hab2, tx2, ty2}
|
|
end
|
|
|
|
-- if can_climb then print("Climb!") end
|
|
-- if can_shot then print("Shot!") end
|
|
-- if can_super then print("Super!") end
|
|
-- if can_go_altar then
|
|
-- -- msg_print(10,20,"Altar READY!", true)
|
|
-- print("Altar!")
|
|
-- end
|
|
-- msg_print(10,40,hab1..", "..tx1..", "..ty1, true)
|
|
-- msg_print(10,60,hab2..", "..tx2..", "..ty2, true)
|
|
end
|
|
|
|
function imp:actualitzar_comportament()
|
|
if DEBUG_FN_NAME then print("actualitzar_comportament") end
|
|
self:reduce_cooldown()
|
|
-- if self.update==imp.state_jumping or self.update==imp.state_falling then
|
|
-- -- self:think()
|
|
-- -- self:move()
|
|
-- end
|
|
self:analyze_env()
|
|
if self.update==imp.state_walking or self.update==imp.state_normal then
|
|
self:move()
|
|
end
|
|
self:controller_input()
|
|
end
|
|
|
|
-------------------------------
|
|
-- imp.controller_input()
|
|
--
|
|
-- Traduir a una entrada de pad
|
|
-------------------------------
|
|
function imp:controller_input()
|
|
if DEBUG_FN_NAME then print("controller_input") end
|
|
|
|
if self.action == "right" or self.action == "left" then
|
|
self.movement = self.action
|
|
self.update=imp.state_walking
|
|
elseif self.action == "jump" then
|
|
self:do_jump()
|
|
elseif self.action == "jumpfwd" then
|
|
self:do_jump(true)
|
|
elseif self.action == "shot" then
|
|
self:shot()
|
|
elseif self.action == "super" then
|
|
self.update=imp.state_super
|
|
end
|
|
self.action = ""
|
|
end
|
|
|
|
function imp:next_action()
|
|
local action = "stay"
|
|
if self.shot_cooldown<=0 then
|
|
if h_collision(self, abad) then
|
|
action = "shot"
|
|
end
|
|
end
|
|
|
|
if action=="stay" then
|
|
if self.movement_type=="free" then
|
|
msg_print(10,20,"FREE",true)
|
|
action = self:free_next_action()
|
|
else
|
|
msg_print(10,20,"PATTERN "..self.action_event,true)
|
|
action=self:pattern_next_action()
|
|
end
|
|
end
|
|
return action
|
|
end
|
|
|
|
function imp:next_target(from)
|
|
if self.movement_type=="free" then
|
|
self:free_next_target()
|
|
else
|
|
self:pattern_next_target( from )
|
|
end
|
|
|
|
-- seleccionar mode d'acció
|
|
--local last_mode=self.fight_mode
|
|
-- self.fight_mode=self.fight_modes["chase"]
|
|
if self.fight_mode_cooldown<=0 then
|
|
self.fight_mode=self.fight_modes[math.random(2)] -- chase o away
|
|
self:reset_fight_mode_cooldown()
|
|
end
|
|
end
|
|
|
|
-------------------------------
|
|
-- imp:move()
|
|
--
|
|
-- Cridar en cada iteració per
|
|
-- a triar l'acció a fer i
|
|
-- traduir a acció de pad
|
|
-------------------------------
|
|
function imp:move( )
|
|
if DEBUG_FN_NAME then print("move "..self.fight_mode) end
|
|
local action = "stay"
|
|
|
|
if self.fight_mode=="stop" then return action end
|
|
|
|
-- S'ha acabat el temps per a arribar a un target
|
|
if self.fight_mode_cooldown <= 0 then
|
|
-- Canviar a moviment lliure
|
|
self:free_movement()
|
|
|
|
-- Reinicialitzar el patró de moviment i el cooldown
|
|
self:reset_fight_mode_cooldown()
|
|
self:path_reset()
|
|
|
|
-- Seleccionar el següent target aleatoriament
|
|
self:next_target()
|
|
|
|
print("Next random target => "..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]
|
|
--end
|
|
end
|