.include "../man/man_entity.h.s"
.include "../man/man_game.h.s"
.include "render.h.s"
.include "collision.h.s"
.include "../cpct_globals.h.s"
.include "cpctelera.h.s"

;;[C] >> ACTIVA EL FLAG CARRY SI NO HAY COLISION.
collision_check_collision_ix_iy:

   continue_check_collision_ix_iy:


    ;; SI NO ES LA MISMA ENTIDAD COMPRUEBA COLISION.

    ;; IZQUIERDA

    ld      a, e_posx(iy)   ;; a = iy.x (pos x del colisionable)
    add     e_width(iy)     ;; a = iy.x +iy.w
    dec     a               ;; le restamos 1 al reg. a pq si no, nos estariamos pasando de posicion
    sub     e_posx(ix)      ;;restamos con ix.x
    ret     c               ;; if a < 0, carry --> on; no collision, ret. iy estara a la izq de ix

    ;; ARRIBA

    ld      a, e_posy(iy)   
    add     e_height(iy)     
    dec     a               
    sub     e_posy(ix)      
    ret     c         

    ;; DERECHA

    ld      a, e_posx(ix) 
    add     e_width(ix)   
    dec     a             
    sub     e_posx(iy)    
    ret     c  

    ;; ABAJO

    ld      a, e_posy(ix) 
    add     e_height(ix)   
    dec     a             
    sub     e_posy(iy)    

    ret c

ret 

collision_player::

    ;; SI COLISIONA CON UNA ENTIDAD SOLIDA HACE ESTO:

        ld a, e_type(iy)
        and #e_type_solid

        call nz, collision_player_with_solid

    ;; SI COLISIONA CON LOS PINCHOS HACE ESTO:

        ld a, e_type(iy)
        and #e_type_instakill

        call nz, collision_player_with_instakill

    ;; SI COLISIONA CON LAS MONEDAS AUMENTA LOS PUNTOS.

        ld a, e_type(iy)
        and #e_type_coin

        call nz, collision_player_with_coin
    
    ;; SI COLISIONA EL PLAYER CON LA MONEDA GRANDE:

        ld a, e_type(iy)
        and #e_type_bigcoin

        call nz, collision_player_with_bigcoin

        ;; SI COLISIONA EL PLAYER CON LA MONEDA ARCOIRIRS:

        ld a, e_type(iy)
        and #e_type_rainbow

        call nz, collision_player_with_rainbow

    ;; SI COLISIONA CON LA SALIDA ACABA EL NIVEL:

        ld a, e_type(iy)
        and #e_type_exit

        call nz, collision_player_with_exit
    
ret

collision_enemy::

    ;; SI EL ENEMIGO COLISIONA CON UN SOLIDO HACE ESTO.
    ld a, e_type(iy)
    and #e_type_ewall

    call nz, collision_enemy_with_wall

ret


collision_enemy_with_wall:

    ld a, e_vx(ix)
    neg
    ld e_vx(ix), a

    ld a, e_vy(ix)
    neg
    ld e_vy(ix), a


ret


collision_player_with_solid:

    ld a, e_last_x(ix)
    ld e_posx(ix), a

    ld a, e_last_y(ix)
    ld e_posy(ix), a

    ld  de, #_song_collision
    call cpct_akp_SFXInit_asm

    ld l, #1         ;Numero del instrumento en la cancion SFX (> 0), igual que el nmero dado al instrumento en Arkos Tracker
    ld h, #15        ;Volumen [0-15], 0 = apagado, 15 = volumen max
    ld e, #40        ;Nota para tocar con el instrumento dado [0-143]
    ld d, #0         ;Velocidad (0 = original)
    ld bc, #0        ;Tono invertido (-0xFFFF -> 0xFFFF). 0 es sin tono
    ld a, #0x10      ;Mascara de bits que representa los canales que se utilizaran para reproducir el sonido (Ch.A = 001 (1), Ch.B = 010 (2), Ch.C = 100 (4))
    push ix
    call cpct_akp_SFXPlay_asm
    pop ix
ret

collision_player_with_coin:

    ld  de, #_song_get_coin

    call cpct_akp_SFXInit_asm

    ld l, #1         ;Numero del instrumento en la cancion SFX (> 0), igual que el nmero dado al instrumento en Arkos Tracker
    ld h, #15        ;Volumen [0-15], 0 = apagado, 15 = volumen max
    ld e, #65        ;Nota para tocar con el instrumento dado [0-143]
    ld d, #0         ;Velocidad (0 = original)
    ld bc, #0        ;Tono invertido (-0xFFFF -> 0xFFFF). 0 es sin tono
    ld a, #0x10      ;Mascara de bits que representa los canales que se utilizaran para reproducir el sonido (Ch.A = 001 (1), Ch.B = 010 (2), Ch.C = 100 (4))
    push ix
    call cpct_akp_SFXPlay_asm
    pop ix
    ;; INCREMENTA LOS PUNTOS

        ld bc, #0x100
        call man_game_increasePuntuation

    ;; DESTRUYE LA MONEDA
        call man_entity_setForDestruction_iy

ret

collision_player_with_bigcoin:
    
    ld  de, #_song_get_coin
    call cpct_akp_SFXInit_asm

    ld l, #1         ;Numero del instrumento en la cancion SFX (> 0), igual que el nmero dado al instrumento en Arkos Tracker
    ld h, #15        ;Volumen [0-15], 0 = apagado, 15 = volumen max
    ld e, #65        ;Nota para tocar con el instrumento dado [0-143]
    ld d, #0         ;Velocidad (0 = original)
    ld bc, #0        ;Tono invertido (-0xFFFF -> 0xFFFF). 0 es sin tono
    ld a, #0x10      ;Mascara de bits que representa los canales que se utilizaran para reproducir el sonido (Ch.A = 001 (1), Ch.B = 010 (2), Ch.C = 100 (4))
    push ix
    call cpct_akp_SFXPlay_asm
    pop ix

    ;; INCREMENTA LOS PUNTOS

        ld bc, #0x500
        call man_game_increasePuntuation

    ;; DESTRUYE LA MONEDA
        call man_entity_setForDestruction_iy

ret

collision_player_with_rainbow:
    
    ld  de, #_song_get_coin
    call cpct_akp_SFXInit_asm

    ld l, #1         ;Numero del instrumento en la cancion SFX (> 0), igual que el nmero dado al instrumento en Arkos Tracker
    ld h, #15        ;Volumen [0-15], 0 = apagado, 15 = volumen max
    ld e, #65        ;Nota para tocar con el instrumento dado [0-143]
    ld d, #0         ;Velocidad (0 = original)
    ld bc, #0        ;Tono invertido (-0xFFFF -> 0xFFFF). 0 es sin tono
    ld a, #0x10      ;Mascara de bits que representa los canales que se utilizaran para reproducir el sonido (Ch.A = 001 (1), Ch.B = 010 (2), Ch.C = 100 (4))
    push ix
    call cpct_akp_SFXPlay_asm
    pop ix

    ;; INCREMENTA LOS PUNTOS

        ld bc, #0x1000
        call man_game_increasePuntuation

    ;; DESTRUYE LA MONEDA
        call man_entity_setForDestruction_iy

ret

collision_player_with_instakill:

    call man_entity_setForDestruction

ret

collision_player_with_exit:

    call man_game_incActualLevel

    call man_game_activateEndFlag

ret

;; ix collider - iy collisionable
collision_check:

  call collision_check_collision_ix_iy      ;; SE COMPRUEBA SI HAY COLISION

    ret z
    ret c                                   ;; SI NO HAY COLISION SALE DE LA FUNCION
    
    ;; SI HAY COLISION HACE ESTO.

    ld l, e_col_func_l(ix)      ;; LLAMA A LA FUNCION DE EL COLLIDER
    ld h, e_col_func_h(ix)

    jp (hl)
ret

collision_collider_update:
    ld de, #(e_cmps_collisionable)
    ld hl, #collision_check     
    call man_entity_for_all_matching_iy
ret

collision_update::
    ld de, #(e_cmps_physics | e_cmps_collider)
    ld hl, #collision_collider_update
    call man_entity_for_all_matching
ret