;;---------------------------------------------------------------------------------------------------------------
;#MIT License                                                                                                   #
;#Copyright (c) 2021 Cyb3rApes                                                                                  #
;#                                                                                                              #
;#Permission is hereby granted, free of charge, to any person obtaining a copy 					                #
;#of this software and associated documentation files (the "Software"), 					                    #
;#to deal in the Software without restriction, including without limitation the rights to use, copy, 		    #
;#modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 				            #
;#and to permit persons to whom the Software is furnished to do so, subject to the following conditions:	    #
;#														                                                        #
;#The above copyright notice and this permission notice shall be included in all copies or substantial 		    #
;#portions of the Software.											                                            #
;#														                                                        #
;#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 		    #
;#NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.	    #
;#IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,	    #
;#WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 		    #
;#SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.							                            #
;################################################################################################################

;#GPL License
;#This file is part of "The Capeture".
;#
;#"The Capeture" is free software: you can redistribute it and/or modify
;#it under the terms of the GNU General Public License as published by
;#the Free Software Foundation, either version 3 of the License, or
;#(at your option) any later version.
;#
;#"The Capeture"  is distributed in the hope that it will be useful,
;#but WITHOUT ANY WARRANTY; without even the implied warranty of
;#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;#GNU General Public License for more details.
;#
;#You should have received a copy of the GNU General Public License
;#along with "The Capeture".  If not, see https://www.gnu.org/licenses/.
;;----------------------------------------------------------------------------------------------------------------

.include "man/entity.h.s"
.globl man_entity_forall_pairing 
.globl ret_collision
.globl ret_artificial
.globl man_entity_forall_matching
.globl man_entity_set4destruction
.globl man_level_map
.globl level_output
.globl is_switch_on




;;
;; Esta funcion permitira detectar si las dos entidades que se han pasado por parametro son del Tipo
;; Que le hemos indicado en los registros B y C! 
;;
;; Input:
;; B: Tipo entidad 1
;; C: Tipo entidad 2
;; IX: Entidad 1
;; IY: Entidad 2
;;
;; Output:
;; A: 0 if false, 1 if B-C is true, 2 if C-B is true
;;
;; Se puede cumplir el patron de dos formas, que sea B-C o C-B. Jugamos con esto:
checkCase::
    ld a, e_e(ix) ;; Pasamos el tipo de la primera entidad
    cp b          ;; Comparamos con el tipo 1

    jr nz, casoC_B ;; Si no se cumple (B-C), comprobamos C-B

    ld a, e_e(iy)  ;; Pasamos el tipo de la segunda entidad
    cp c

    jp nz, check_not_true ;; Si no se cumple (B-C) teniendo B==True, no se podra dar C==B, por lo que devolvemos 0

    jp check_true_B_C

    casoC_B:
    ld a, e_e(ix)
    cp c

    jr nz, check_not_true

    ld a, e_e(iy)
    cp b

    jr nz, check_not_true

    check_true_C_B:
        ld a, #2
        ret
    
    check_true_B_C:
        ld a, #1
        ret

    check_not_true:
        ld a, #0 ;; Devolvemos 0 (false) ya que si estamos aqui significa que no se cumple!
        ret
    

;;------------------
    ;;INPUT:
        ;;IX->ENTIDAD1
        ;;IY->ENTIDAD2

sys_collision_check:

    ;;axis_x:

        ;;Comprobamos que A<B (A=e_x1+e_w1 y B=e_x2) para descartar colision.
        ld a,e_x(ix) ;;Guarda en el acumulador la posicion x de la entidad1.
        add e_w(ix)  ;;Suma al acumulador el ancho de la entidad1.Ya tenemos A.
        dec a        ;;Offset de ajuste.
        sub e_x(iy)  ;;Resta al acumulador la posicion x de la entidad2.A-B

        jp c,no_collision ;;Si al restar B a A nos da menor que cero,es que A<B.

        ;;Comprobamos que C<D (C=e_x2+e_w2 y D=e_x1) para descartar colision.
        ld a,e_x(iy) ;;Guarda en el acumulador la posicion x de la entidad2.
        add e_w(iy)  ;;Suma al acumulador el ancho de la entidad2.Ya tenemos C.
        dec a        ;;Offset de ajuste.
        sub e_x(ix)  ;;Resta al acumulador la posicion x de la entidad1.C-D

        jp c,no_collision ;;Si al restar D a C nos da menor que cero,es que C<D.

    ;;axis_y:

        ;;Comprobamos que A<B (A=e_y1+e_h1 y B=e_y2) para descartar colision.
        ld a,e_y(ix) ;;Guarda en el acumulador la posicion y de la entidad1.
        add e_h(ix)  ;;Suma al acumulador el alto de la entidad1.Ya tenemos A.
        dec a        ;;Offset de ajuste.
        sub e_y(iy)  ;;Resta al acumulador la posicion y de la entidad2.A-B

        jp c,no_collision ;;Si al restar B a A nos da menor que cero,es que A<B.

        ;;Comprobamos que C<D (C=e_y2+e_h2 y D=e_y1) para descartar colision.
        ld a,e_y(iy) ;;Guarda en el acumulador la posicion y de la entidad2.
        add e_h(iy)  ;;Suma al acumulador el alto de la entidad2.Ya tenemos C.
        dec a        ;;Offset de ajuste.
        sub e_y(ix)  ;;Resta al acumulador la posicion y de la entidad1.C-D

        jp c,no_collision ;;Si al restar D a C nos da menor que cero,es que C<D

        ;; Si llegamos hasta aqui, significa que ha habido una colision, por lo que activamos el bit de que han colisionado a ambas entidades

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        ;; A partir de aqui, pasamos a implementar la logica de colision. Dependiendo de que entidades esten colisionando, querre que haga una cosa u otra:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
        ;; Caso 2: valla-jugador
        ld b, #entity_valla
        ld c, #entity_player
        call checkCase
        cp #1
        jp z, valla_jugador
        cp #2
        jp z, jugador_valla

        ;;; Caso torreta-jugador/jugador-torreta
        ld b, #entity_torreta
        ld c, #entity_player
        call checkCase
        cp #1
        jp z, valla_jugador ;; Reusamos etiquetas porque es la misma logica de reposicionamiento
        cp #2
        jp z, jugador_valla ;; Reusamos etiquetas porque es la misma logica de reposicionamiento

        ;;; Caso chica-jugador/jugador-chica
        ld b, #entity_chica
        ld c, #entity_player
        call checkCase
        cp #1
        jp z, fin_del_juego_XD ;; Reusamos etiquetas porque es la misma logica de reposicionamiento
        cp #2
        jp z, fin_del_juego_XD ;; Reusamos etiquetas porque es la misma logica de reposicionamiento

        ;; Caso switch-jugador/jugador-switch
        ld b, #entity_switch
        ld c, #entity_player
        call checkCase
        cp #1
        jp z, switch_jugador
        cp #2
        jp z, jugador_switch
        
        ;; Caso puerta-jugador/jugador-puerta
        ld b, #entity_puerta
        ld c, #entity_player
        call checkCase
        cp #1
        jp z, valla_jugador ;; Reusamos etiquetas porque es la misma logica de reposicionamiento
        cp #2
        jp z, jugador_valla ;; Reusamos etiquetas porque es la misma logica de reposicionamiento

        ;; Caso cchamber-jugador/jugador-cchamber
        ld b, #entity_cchamber
        ld c, #entity_player
        call checkCase
        cp #1
        jp z, valla_jugador ;; Reusamos etiquetas porque es la misma logica de reposicionamiento
        cp #2
        jp z, jugador_valla ;; Reusamos etiquetas porque es la misma logica de reposicionamiento

        ;; Caso cyborg-cchamber
        ld b, #entity_cyborg
        ld c, #entity_cchamber
        call checkCase
        cp #1
        jp z, jugador_valla ;; Reusamos etiquetas porque es la misma logica de reposicionamiento
        cp #2
        jp z, valla_jugador ;; Reusamos etiquetas porque es la misma logica de reposicionamiento

       ; ;; Caso cyborg-cyborg
        siguiente_caso_cyborg:
        ld b, #entity_cyborg
        ld c, #entity_cyborg
        call checkCase
        cp #0
        jp nz, reposicionar_ambos_cyborg
  
        ;; Caso else (logica para el resto de colisiones)
        caso_else:

            ;; Entidad IX
            ld a, e_type(ix) ;; Cargamos el type actual
            ld b, #e_type_collided
            or b ;; Activamos el bit que indica que la queremos destruir!
            ld e_type(ix), a ;; Ponemos el nuevo valor!

            ;; Entidad IY
            ld a, e_type(iy) ;; Cargamos el type actual
            ld b, #e_type_collided
            or b ;; Activamos el bit que indica que la queremos destruir!
            ld e_type(iy), a ;; Ponemos el nuevo valor!

            jp ret_collision 


        reposicionar_cyborg:
            ;; Tenemos que reposicionar el cyborg, pero tenemos que ver en que registro esta:
            ld a, e_e(ix)
            cp #entity_cyborg
            jr z, cyborg_en_ix

            ;; Si no esta en IY, reposicionamos:
            ld a, e_prevx(iy)
            ld e_x(iy), a
            ld a, e_prevy(iy)
            ld e_y(iy), a
            jp ret_collision

            cyborg_en_ix:
            ld a, e_prevx(ix)
            ld e_x(ix), a
            ld a, e_prevy(ix)
            ld e_y(ix), a
            jp ret_collision

        valla_jugador:
            ld a, e_prevx(iy)
            ld e_x(iy), a
            ld a, e_prevy(iy)
            ld e_y(iy), a
            jp ret_collision

        reposicionar_ambos_cyborg:
            ld a, e_prevx(iy)
            ld e_x(iy), a
            ld a, e_prevy(iy)
            ld e_y(iy), a

            ld a, e_prevx(ix)
            ld e_x(ix), a
            ld a, e_prevy(ix)
            ld e_y(ix), a
            jp ret_collision

        jugador_valla:
            ld a, e_prevx(ix)
            ld e_x(ix), a
            ld a, e_prevy(ix)
            ld e_y(ix), a
            jp ret_collision
        
        switch_jugador:
            ld hl, #_spr_switch_1
            ld e_spriteupperbyte(ix), h
            ld e_spritelowerbyte(ix), l

            ;; Ponemos a on el switch:
            ld a, #1
            ld (is_switch_on), a
            jp ret_collision

        jugador_switch:
            ld hl, #_spr_switch_1
            ld e_spriteupperbyte(iy), h
            ld e_spritelowerbyte(iy), l

            ;; Ponemos a on el switch:
            ld a, #1
            ld (is_switch_on), a
            jp ret_collision
        
        fin_del_juego_XD:
            ld a, #1
            ld (level_output), a

        no_collision:
        ;; Si no hay colision no hacemos nada

        jp ret_collision

sys_collision_update::

    ld hl,#sys_collision_check
    ld a,#(e_type_collision)
    call man_entity_forall_pairing 

    ret


;; Esta funcion recibira entidades que han sido colisionadas, y dependiendo del tipo que entidad que sea, hara una cosa u otra. 
;; Por ejemplo, si recibimos un jugador, le quitamos vida, si recibimos una bala, la borramos (en el pulido sera que explote) y asi...
;; Input: Entity in IX
sys_collision_aftermatch_one::

    ld a, e_e(ix)

    cp #entity_mina
    jr z, mina

    cp #entity_valla
    jr z, mina

    cp #entity_cyborg
    jr z, mina

    cp #entity_bala
    jr z, bala

    cp #entity_player
    jr z, player_collision

    cp #entity_cchamber
    jp z, cchamber_collision

    ;;De  momemento si no es nada, nos vamos
    jp ret_artificial

    ;; Aqui entrara cuadno el jugador ha colisionado con algo que le ha hecho daño, aqui iria la logica de la cantidad de vidas.
    ;; Como de momento solo tenemos 1, terminamos la partida
    player_collision:
        ld a, #0
        ld (level_output), a
        jp ret_artificial

    mina: ;; Si es una mina, la marcamos para destruir
        call man_entity_set4destruction
        jp ret_artificial

    valla: ;; Si es una mina, la marcamos para destruir
        call man_entity_set4destruction
        jp ret_artificial

    bala: ;; Si es una bala, la marcamos para destruir
        call man_entity_set4destruction
        jp ret_artificial ;; Simulamos una funcion

    cchamber_collision:
        ld a, e_vx(ix) ;; Cchamber life
        dec a

        jp nz, cchamber_still_alive

        ;; Si llegamos aqui, es que se han acabado las vidas de la camara de cyborg. Cambiamos de estado:
        ld a, e_vy(ix) ;; Cchamber state

        cp #3
        jp z, cchamber_change_to_2

        cp #2
        jp z, cchamber_change_to_1

        ;; Si llega aqui tenia el estado 1, por lo que nos toca destruirla
        call man_entity_set4destruction
        jp ret_artificial ;; Simulamos una funcion

        cchamber_change_to_2:
            ld a, #2
            ld e_vy(ix), a

            ;; Reiniciamos las vidas:
            ld a, #cchamber_life
            jp cchamber_still_alive

        cchamber_change_to_1:
            ld a, #1
            ld e_vy(ix), a

            ;; Reiniciamos las vidas:
            ld a, #cchamber_life
            jp cchamber_still_alive

        cchamber_still_alive:
        ld e_vx(ix), a

        apagar_bit_colision:
        ;; Apagamos bit de coliison!
        ld b, #e_type_collided
        ld a, e_type(ix)
        xor b
        ld e_type(ix), a
        jp ret_artificial



;;; Esta funcion procesara el aftermatch despues de colisionar. Que haremos con esas entidades basicamente:
sys_collision_aftermatch::

    ld hl,#sys_collision_aftermatch_one
    ld a,#(e_type_collided)
    call man_entity_forall_matching
    ret

;;comprobara si una entidad ha colsionado con un tile y ajustara tanto la posicion como la velocidad
sys_collision_tiles_one::

    ;;cargamos tx, ty, tw iniciales esquina_sup_izq

    ;;A=y 
    ld a, e_y(ix);;posicion del personaje en el eje y
    srl a;; |
    srl a;; | y/8=ty 
    srl a;; |
    ;;Cargamos ty en hl
    ld h, #0
    ld l, a
    ;;Proceso para obtener 20·ty
    add hl, hl;;ty·2
    add hl, hl;;ty·4
    ld d, h;; |de=4·ty
    ld e, l;; |
    add hl, hl;;ty·8
    add hl, hl;;16·ty
    add hl, de;;(16+4)·ty=20·ty ->tw·ty

    ;;B=x
    ld a, e_x(ix)
    srl a;; |
    srl a;; | x/4=tx 
    ld d, #0
    ld e, a ;;b=1 tx
    add hl, de ;;tw·ty + tx
    ;;puntero de inicio del tilemap (mirar como pasarlo como variable)
    ld de, #man_level_map
    add hl, de;;tilemap+tw·ty+tx posicion del tile en el tilemap

    ;;Conocer el tipo de tile que hay en la posicion relevante
    ld a, (hl)
    ld b, a;;guarda el valor del tile
    and #0xE0 ;;1110 0000 Tiles colisionables son 0...31 => 000x xxxx
    jp z, colision;;detecta colision

    
    ld a, b
    cp #32
    jp z, objetivo
    cp #33
    jp z, objetivo
    cp #34
    jp z, objetivo
    cp #35
    jp z, objetivo
    cp #38
    jp z, objetivo
    cp #39
    jp z, objetivo
    cp #36
    jp z, objetivo_arco
    cp #37
    jp z, objetivo_arco
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;;A=y
    ld a, e_y(ix);;posicion de la entidad en el eje y
    srl a;; |
    srl a;; | y/8=ty 
    srl a;; |
    ;;Cargamos ty en hl
    ld h, #0
    ld l, a
    ;;Proceso para obtener 20·ty
    add hl, hl;;ty·2
    add hl, hl;;ty·4
    ld d, h;; |de=4·ty
    ld e, l;; |
    add hl, hl;;ty·8
    add hl, hl;;16·ty
    add hl, de;;(16+4)·ty=20·ty ->tw·ty

    ;;B=x+e_w-1
    ld a, e_x(ix)
    ld b, e_w(ix);;ancho de la entidad 
    add a, b ;; x+e_w
    dec a;;x+e_w-1, compensa por pixel 0
    srl a;; |
    srl a;; | x/4=tx 
    ld d, #0
    ld e, a ;;b=1 tx
    add hl, de ;;tw·ty + tx
    ;;puntero de inicio del tilemap (mirar como pasarlo como variable)
    ld de, #man_level_map
    add hl, de;;tilemap+tw·ty+tx posicion del tile en el tilemap

    ;;Conocer el tipo de tile que hay en la posicion relevante
    ld a, (hl)
    ld b, a
    and #0xE0 ;;1110 0000 Tiles colisionables son 0...31 => 000x xxxx
    jp z, colision

    
    ld a, b
    cp #32
    jp z, objetivo
    cp #33
    jp z, objetivo
    cp #34
    jp z, objetivo
    cp #35
    jp z, objetivo
    cp #38
    jp z, objetivo
    cp #39
    jp z, objetivo
    cp #36
    jp z, objetivo_arco
    cp #37
    jp z, objetivo_arco
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;A=y+e_h-1 
    ld a, e_y(ix);;posicion de la entidad en el eje y
    ld b, e_h(ix);;altura de la entidad 
    add a, b ;; y+e_h
    dec a;;y+e_h-1, compensa por pixel 0
    srl a;; |
    srl a;; | y/8=ty 
    srl a;; |
    ;;Cargamos ty en hl
    ld h, #0
    ld l, a
    ;;Proceso para obtener 20·ty
    add hl, hl;;ty·2
    add hl, hl;;ty·4
    ld d, h;; |de=4·ty
    ld e, l;; |
    add hl, hl;;ty·8
    add hl, hl;;16·ty
    add hl, de;;(16+4)·ty=20·ty ->tw·ty

    ;;B=x+e_w-1 
    ld a, e_x(ix)
    ld b, e_w(ix);;ancho de la entidad 
    add a, b ;; x+e_w
    dec a;;x+e_w-1, compensa por pixel 0
    srl a;; |
    srl a;; | x/4=tx 
    ld d, #0
    ld e, a ;;b=1 tx
    add hl, de ;;tw·ty + tx
    ;;puntero de inicio del tilemap (mirar como pasarlo como variable)
    ld de, #man_level_map
    add hl, de;;tilemap+tw·ty+tx posicion del tile en el tilemap

    ;;Conocer el tipo de tile que hay en la posicion relevante
    ld a, (hl)
    ld b, a
    and #0xE0 ;;1110 0000 Tiles colisionables son 0...31 => 000x xxxx
    jp z, colision;;

    ld a, b
    cp #32
    jp z, objetivo
    cp #33
    jp z, objetivo
    cp #34
    jp z, objetivo
    cp #35
    jp z, objetivo
    cp #38
    jp z, objetivo
    cp #39
    jp z, objetivo
    cp #36
    jp z, objetivo_arco
    cp #37
    jp z, objetivo_arco
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;A=y+e_h-1 
    ld a, e_y(ix);;posicion de la entidad en el eje y
    ld b, e_h(ix);;altura de la entidad 
    add a, b ;; y+e_h
    dec a;;y+e_h-1, compensa por pixel 0
    srl a;; |
    srl a;; | y/8=ty 
    srl a;; |
    ;;Cargamos ty en hl
    ld h, #0
    ld l, a
    ;;Proceso para obtener 20·ty
    add hl, hl;;ty·2
    add hl, hl;;ty·4
    ld d, h;; |de=4·ty
    ld e, l;; |
    add hl, hl;;ty·8
    add hl, hl;;16·ty
    add hl, de;;(16+4)·ty=20·ty ->tw·ty

    ;;B=x
    ld a, e_x(ix)
    srl a;; |
    srl a;; | x/4=tx 
    ld d, #0
    ld e, a ;;b=1 tx
    add hl, de ;;tw·ty + tx
    ;;puntero de inicio del tilemap (mirar como pasarlo como variable)
    ld de, #man_level_map
    add hl, de;;tilemap+tw·ty+tx posicion del tile en el tilemap

    ;;Conocer el tipo de tile que hay en la posicion relevante
    ld a, (hl)
    ld b, a
    and #0xE0 ;;1110 0000 Tiles colisionables son 0...31 => 000x xxxx
    jp z, colision;;

    
    ld a, b
    cp #32
    jp z, objetivo
    cp #33
    jp z, objetivo
    cp #34
    jp z, objetivo
    cp #35
    jp z, objetivo
    cp #38
    jp z, objetivo
    cp #39
    jp z, objetivo
    cp #36
    jp z, objetivo_arco
    cp #37
    jp z, objetivo_arco
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    jp ret_artificial

    objetivo:
    ;;logica de finalizar
    ;;ejemplo usando reposicionado

        ld a, e_e(ix)
        cp #entity_player

        jr nz, no_ha_entrado
        ld a, e_prevx(ix)
        ld e_x(ix), a
        ld a, e_prevy(ix)
        ld e_y(ix), a

        ld a, #1
        ld (level_output), a
        jp ret_artificial

    objetivo_arco:

    ;;logica finalizar con salto al nivel arcoiris
    ;ld a, e_e(ix)
    ;cp #entity_player
;
    ;jr nz, no_ha_entrado
    ;ld a, e_prevx(ix)
    ;ld e_x(ix), a
    ;ld a, e_prevy(ix)
    ;ld e_y(ix), a

    ld a, #3
    ld (level_output), a
    jp ret_artificial

    no_ha_entrado:
    
    cp #entity_bala 
    jr z, bala_dest

    jp ret_artificial

    colision:

    ld a, e_e(ix)

    cp #entity_fuego 
    jp z, fuego_cambiar ;; Si es un fuego, no queremos que se reposicione

    cp #entity_switch 
    jp z, fuego_cambiar ;; Si es un switch, no queremos que se reposicione

    ;;basico, reposicion a tile hueco previo
    ld a, e_prevx(ix)
    ld e_x(ix), a

    ld a, e_prevy(ix)
    ld e_y(ix), a
    ;;colision especifica de entidad
    ld a, e_e(ix)

    cp #entity_bala 
    jr z, bala_dest

    ;;Si a es #entity_rotatorio, cambiar la vx
    cp #entity_rotatorio
    jr z, rotatorio_cambiar

    ;; Si es #entity_arachnoid, cambiar la vy
    cp #entity_arachnoid
    jr z, arachnoid_cambiar

    jp ret_artificial
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   

    bala_dest:
        call man_entity_set4destruction
        jp ret_artificial

    rotatorio_cambiar:
        ;; Invertimos la velocidad!
        ld a, e_vx(ix)
        neg
        ld e_vx(ix),a

        ;; Cambiamos la orientacion!
        ld a, e_o(ix)
        cp #orientation_left
        jp z, rotatorio_left

        ;; Aqui significa que estaba en right
        ;; Cambiamos a left y su sprite
        ld e_o(ix), #orientation_left
        ld hl, #_spr_rotatorioL_0
        ld e_spriteupperbyte(ix), h
        ld e_spritelowerbyte(ix), l
        jp ret_artificial
        
        rotatorio_left:
        ;; Cambiamos a right y su sprite
        ld e_o(ix), #orientation_right
        ld hl, #_spr_rotatorioR_0
        ld e_spriteupperbyte(ix), h
        ld e_spritelowerbyte(ix), l
        jp ret_artificial
    
    arachnoid_cambiar:
        ;; Gestionamos la accion del arachnoid en caso de colisionar con un tile:
        ;; Invertimos la velocidad!
        ld a, e_vy(ix)
        neg
        ld e_vy(ix),a

        ;; Cambiamos la orientacion!
        ld a, e_o(ix)
        cp #orientation_down
        jp z, arachnoid_o_down

        ;; Aqui significa que estaba en up
        ;; Cambiamos a down y su sprite
        ld e_o(ix), #orientation_down
        ld hl, #_spr_arachnoid_down_0
        ld e_spriteupperbyte(ix), h
        ld e_spritelowerbyte(ix), l
        jp ret_artificial
        
        arachnoid_o_down:
        ;; Cambiamos a up y su sprite
        ld e_o(ix), #orientation_up
        ld hl, #_spr_arachnoid_up_0
        ld e_spriteupperbyte(ix), h
        ld e_spritelowerbyte(ix), l
    
    fuego_cambiar:

    jp ret_artificial
    
;;todas las entidades que esten vivas o puedan colisionar se comprobara si han colisionado con un tile
sys_collision_tiles::

    ld hl,#sys_collision_tiles_one
    ld a,#(e_type_collision) ;;preguntar si el bit correcto seria el de collision y no collided
    call man_entity_forall_matching
    ret


