622 lines
18 KiB
Lua
622 lines
18 KiB
Lua
cxr2 = arcade_config.character_per_row_base2
|
|
|
|
-- 4, 3
|
|
|
|
-- imp={hab=75,
|
|
-- x=24,
|
|
-- y=24,
|
|
-- w=32,
|
|
-- h=32,
|
|
-- flip=true,
|
|
-- enabled=false,
|
|
-- counter=500,
|
|
-- frame=28,
|
|
-- wait=0,
|
|
-- step=0,
|
|
-- anim={28,29,28,30},
|
|
-- bb={x=4,y=0,w=16,h=32},
|
|
-- scene_intro=false,
|
|
-- scene_object=false,
|
|
-- fight_modes={"chase","away","super","shot"},
|
|
-- mode="stop",
|
|
-- mode_cooldown=100}
|
|
|
|
imp = {}
|
|
|
|
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,
|
|
fight_modes=_fight_modes,
|
|
mode="stop",
|
|
mode_cooldown=1000,
|
|
super_cooldown=2000,
|
|
shot_cooldown=500,
|
|
action="",
|
|
movement="",
|
|
enabled=true,
|
|
disable_reason="",
|
|
can_warp=false,
|
|
fight=imp.fight,
|
|
draw=imp.draw,
|
|
hit=imp.hit,
|
|
hot_points={},
|
|
target={},
|
|
old_target={},
|
|
invencible=false,
|
|
-- direccio=imp.direccio,
|
|
do_jump=imp.do_jump,
|
|
jump=imp.jump,
|
|
state_jumping=imp.state_jumping,
|
|
chase=imp.chase,
|
|
away=imp.away,
|
|
move=imp.move,
|
|
super=imp.super,
|
|
shot=imp.shot,
|
|
do_flip=imp.do_flip,
|
|
update=imp.state_normal,
|
|
land=imp.land,
|
|
mode_controller=imp.mode_controller,
|
|
movement=imp.movement,
|
|
advance=imp.advance,
|
|
reduce_cooldown=imp.reduce_cooldown,
|
|
set_fight_mode=imp.set_fight_mode,
|
|
think=imp.think,
|
|
controller_input=imp.controller_input,
|
|
-- imp.enabled=false
|
|
-- imp.counter=500
|
|
}
|
|
end
|
|
|
|
function imp:fight()
|
|
print("FIGHTING MODE")
|
|
table.insert(self.hot_points, point.new(54,5,4,12,8,"P1"))
|
|
table.insert(self.hot_points, point.new(44,5,3,12,8,"P2"))
|
|
table.insert(self.hot_points, point.new(55,7,4,12,8,"P3"))
|
|
table.insert(self.hot_points, point.new(45,7,3,12,8,"P4"))
|
|
table.insert(self.hot_points, point.new(44,12,5,12,8,"P5"))
|
|
table.insert(self.hot_points, point.new(54,12,4,12,8,"P6"))
|
|
table.insert(self.hot_points, abad);
|
|
self.mode="chase"
|
|
self.target = self.hot_points[3]
|
|
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
|
|
end
|
|
|
|
function imp:hit()
|
|
print("HIT!")
|
|
end
|
|
|
|
function imp:do_jump ( jumpfwd )
|
|
-- 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()
|
|
-- msg_print(0,0,"state_jumping",true)
|
|
self:reduce_cooldown()
|
|
-- ??
|
|
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:set_fight_mode()
|
|
-- self:think()
|
|
self:controller_input()
|
|
end
|
|
|
|
function imp:jump()
|
|
-- 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()
|
|
msg_print(16,48,"state_walking",true)
|
|
self:reduce_cooldown()
|
|
|
|
-- 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:set_fight_mode()
|
|
self:think()
|
|
self:controller_input()
|
|
end
|
|
|
|
function imp:state_falling()
|
|
msg_print(16,16,"state_falling",true)
|
|
self:reduce_cooldown()
|
|
|
|
self.frame=30
|
|
self.wait=self.wait+1
|
|
|
|
-- Si toca terra canviar el mode
|
|
if self:land() then
|
|
print("landing")
|
|
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:set_fight_mode()
|
|
-- self:think()
|
|
self:controller_input()
|
|
end
|
|
|
|
function imp:land ()
|
|
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
|
|
end
|
|
|
|
return can_land
|
|
end
|
|
|
|
function imp:advance()
|
|
-- 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
|
|
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()
|
|
-- msg_print(0,0,"state_normal",true)
|
|
self:reduce_cooldown()
|
|
|
|
self.frame=28
|
|
self.wait=0
|
|
self.step=0
|
|
self.jumpfwd=false
|
|
self.jump_height = 0
|
|
self:set_fight_mode()
|
|
self:think()
|
|
self:controller_input()
|
|
end
|
|
|
|
function imp:chase()
|
|
self.mode = self.fight_modes["chase"]
|
|
self.mode_cooldown = 150+math.random(50)-1
|
|
end
|
|
|
|
function imp:away()
|
|
self.mode = self.fight_modes["away"]
|
|
self.mode_cooldown = 150+math.random(50)-1
|
|
end
|
|
|
|
function imp:state_super()
|
|
self.mode = self.fight_modes["super"]
|
|
self.mode_cooldown=1
|
|
print("SUPER POWER")
|
|
self.super_cooldown=2000
|
|
self.update=imp.state_normal
|
|
end
|
|
|
|
function imp:shot(actor)
|
|
self.mode = self.fight_modes["shot"]
|
|
self.mode_cooldown=1
|
|
print("FIREBALL!!")
|
|
self.shot_cooldown = 500
|
|
end
|
|
|
|
function imp:do_flip(actor)
|
|
if actor.x<self.x then self.flip=true else self.flip=false end
|
|
end
|
|
|
|
-------------------------------
|
|
-- imp.controller_input()
|
|
--
|
|
-- Traduir a una entrada de pad
|
|
-------------------------------
|
|
function imp:controller_input()
|
|
-- msg_print(0,0,"move",true)
|
|
-- self.action = self:movement(abad)
|
|
|
|
if self.action == "right" or self.action == "left" then
|
|
self.movement = self.action
|
|
self.update=imp.state_walking
|
|
-- abad.flip=false
|
|
elseif self.action == "jump" then
|
|
self:do_jump()
|
|
elseif self.action == "jumpfwd" then
|
|
self:do_jump(true)
|
|
elseif self.action == "shot" then
|
|
-- abad_shot_cacau()
|
|
self:shot()
|
|
elseif self.action == "super" then
|
|
self.update=imp.state_super
|
|
end
|
|
self.action = ""
|
|
end
|
|
|
|
-------------------------------
|
|
-- imp.think()
|
|
--
|
|
-- Cridar en cada iteració per
|
|
-- a triar l'acció a fer i
|
|
-- traduir a acció de pad
|
|
-------------------------------
|
|
function imp:think( )
|
|
local scr_x, scr_y = viewp:screen_coords( self.x+self.bb.x, self.y )
|
|
-- local check_x =
|
|
-- local check_y =
|
|
local action = "stay"
|
|
|
|
if self.mode=="stop" then return action end
|
|
|
|
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 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-2
|
|
local tile_type1, tile_code1= arc_check_tile(x1_check,y_check)
|
|
local tile_type2, tile_code2= arc_check_tile(x2_check,y_check)
|
|
draw.rect(scr_x+self.bb.x,scr_y+self.bb.h-1,16,16,2)
|
|
if collision(self, self.target) then
|
|
print("Next target "..tile_type1.." "..tile_code1)
|
|
self.mode_cooldown = 0
|
|
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)
|
|
self.mode_cooldown = 0
|
|
-- self:set_fight_mode()
|
|
elseif tile_type1~=tiletype.void or tile_type2~=tiletype.void then
|
|
print("jump "..tile_type1..", "..tile_type2)
|
|
action="jump"
|
|
end
|
|
-- local scr_x, scr_y = viewp:screen_coords( self.x, self.y )
|
|
-- draw.line(0,scr_y,256,scr_y,2)
|
|
-- draw.line(scr_x,0,scr_x,192,2)
|
|
-- if self.y+self.bb.y>=self.target.y+self.target.bb.y then
|
|
-- local tile_type, tile_code = arc_check_tile(self.x+self.bb.x,self.y+self.bb.h, true)
|
|
-- local tile_type2, tile_code2 = arc_check_tile(self.x+self.bb.x+self.bb.w,self.y+self.bb.h, true)
|
|
-- msg_print(50, 50, tile_type..", "..tile_code, true )
|
|
-- if tile_type ~=tiletype.void or tile_type2 ~=tiletype.void then
|
|
-- print("JUMP")
|
|
-- action = "jump"
|
|
-- else
|
|
-- if self.target.x+self.target.bb.x>=self.x+self.bb.x then
|
|
-- print("sense eixida")
|
|
-- -- self.mode_cooldown = 0
|
|
-- -- self:set_fight_mode()
|
|
-- end
|
|
-- end
|
|
-- -- elseif self.y==self.target.y and math.abs(self.x-self.target.x)<=8 then
|
|
-- -- action = "jumpfwd"
|
|
-- end
|
|
-- local ix, iy = viewp:screen_coords( self.x, self.y )
|
|
-- draw.rect(ix+(self.bb.x+(self.bb.w/2)), iy+(self.h/2), 2,2, 2)
|
|
-- if self.fight_modes[self.mode]=="away" or self.fight_modes[self.mode]=="chase" then
|
|
-- if self.y>=self.target.y
|
|
-- and arc_check_tile(self.x+(self.bb.x+(self.bb.w/2)),(self.y+(self.h/2)))~=tiletype.void then
|
|
-- action = "jump"
|
|
-- elseif self.y==self.target.y and math.abs(self.x-self.target.x)<=8 then
|
|
-- action = "jumpfwd"
|
|
-- else
|
|
-- if self.fight_modes[self.mode]=="away" then
|
|
-- if self.target.x<=self.x then
|
|
-- action="right"
|
|
-- else
|
|
-- action="left"
|
|
-- end
|
|
-- elseif self.fight_modes[self.mode]=="chase" then
|
|
-- if self.target.x>=self.x then
|
|
-- action="right"
|
|
-- else
|
|
-- action="left"
|
|
-- end
|
|
-- end
|
|
-- end
|
|
-- elseif self.fight_modes[self.mode]=="super" then
|
|
-- action="super"
|
|
-- elseif self.fight_modes[self.mode]=="shot" then
|
|
-- action="shot"
|
|
-- end
|
|
|
|
self.action = action
|
|
print(self.action)
|
|
return action
|
|
end
|
|
|
|
function imp:reduce_cooldown()
|
|
if self.mode=="stop" then return end
|
|
|
|
self.mode_cooldown = self.mode_cooldown -1
|
|
self.super_cooldown = self.super_cooldown -1
|
|
self.shoot_cooldown = self.shoot_cooldown -1
|
|
end
|
|
|
|
-------------------------------
|
|
-- imp.set_fight_mode()
|
|
--
|
|
-- Cridar en cada iteració per
|
|
-- a canviar el mode de lluita
|
|
-------------------------------
|
|
function imp:set_fight_mode()
|
|
if self.mode=="stop" then return end
|
|
|
|
if self.mode_cooldown <= 0 then
|
|
-- seleccionar mode d'acció
|
|
local last_mode=self.mode
|
|
-- self.mode_cooldown = 150+math.random(50)-1
|
|
self.mode_cooldown = 1000
|
|
-- self.mode=math.random(#self.fight_modes)
|
|
--
|
|
-- if self.mode==self.fight_modes["super"] and self.super_cooldown>0 then self.mode=self.fight_modes["shot"] end
|
|
-- if self.mode==self.fight_modes["shot"] and self.shot_cooldown>0 then self.mode=self.fight_modes["chase"] end
|
|
|
|
self.mode=self.fight_modes["chase"]
|
|
|
|
-- print("cambiar modo => "..self.fight_modes[self.mode])
|
|
|
|
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]
|
|
print("target => "..self.target.id)
|
|
end
|
|
-- -- if self.mode==last_mode then self.mode=((last_mode+1)%#self.fight_modes)+1 end
|
|
-- elseif self.mode_cooldown == 0 then
|
|
-- if self.shot_cooldown<=0 then self.mode=self.fight_modes["shot"] end;
|
|
-- end
|
|
|
|
self:do_flip(abad)
|
|
-- self:movement(abad)
|
|
|
|
--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
|
|
|
|
function imp:collision()
|
|
-- comprovar colisio en l'abad
|
|
if viewp:inside(self.x, self.y, self.w, self.h) then
|
|
if collision(abad,self) then
|
|
abad_hurt(1)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- function imp:direccio( actor )
|
|
-- -- msg_print(0,0,"direccio",true)
|
|
-- local check_side = "L"
|
|
-- -- definir el punts per a comprobar en el mapa
|
|
-- if self.fight_modes[self.mode]=="away" then
|
|
-- if actor.x>self.x then
|
|
-- -- caminar cap "enrere", check costat esq
|
|
-- check_side = "L"
|
|
-- else
|
|
-- -- caminar cap "endavant", check costat dret
|
|
-- check_side = "R"
|
|
-- end
|
|
-- elseif self.fight_modes[self.mode]=="chase" then
|
|
-- if actor.x>self.x then
|
|
-- -- caminar cap "endavant", check costat dret
|
|
-- check_side = "R"
|
|
-- else
|
|
-- -- caminar cap "enrere", check costat esq
|
|
-- check_side = "L"
|
|
-- end
|
|
-- end
|
|
--
|
|
-- local step = 1
|
|
-- if check_side=="L" then step = -step end
|
|
--
|
|
-- return step
|
|
-- end |