;;---------------------------------------------------------------------------------------------------------------
;#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"
.include "cpctelera.h.s"


.globl man_entity_destroy
.globl ret_artificial
.globl man_entity_set4destruction
.globl man_entity_forall_matching
.globl player


max_contador_ia=4 ;; 5 iteraciones entre calculo y calculo

newx: .db 0
actualx: .db 0
dirx: .dw 0
ia_contador: .db max_contador_ia


;; Cambia X e Y de la entidad recibida segun su VX y su VY
;; Input: entidad en IX
sys_physics_update_one:: ;;Actualiza la entidad que tenemos en de!

    ld a, e_x(ix)
    ld e_prevx(ix), a
    ld b, e_vx(ix)

    add a, b ;; Sumamos x+vx
    ld e_x(ix), a

    ld a, e_y(ix)
    ld e_prevy(ix), a
    ld b, e_vy(ix)

    add a, b ;; Sumamos y+vy
    ld e_y(ix), a

    ;; Si es un cyborg, le reiniciamos las vx y vy
    ld a, e_e(ix)
    cp #entity_cyborg

    jr nz, salir_physics

    ld e_vx(ix), #0
    ld e_vy(ix), #0

    salir_physics:

    jp ret_artificial ;; Simulamos una funcion

;; Inversion de control, le pasamos la responsabilida de iterar las entidades al manager, porque asi nos despreocupamos y nos indpeendicamos de eso, 
;; nos desacoplamos ya que el que le da la implementacion es el manager, 
;; por lo tanto, de esta forma es como que le decimos, oye, tu apañatelas como quieras para recorrerlas (lista, array, vector...), tu solo ve dandome entidades y yo las actualizo
sys_physics_update:: 

    ld hl, #sys_physics_update_one
    ld a, #(e_type_physics)
    call man_entity_forall_matching
    ret

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

;;Pseudo código IA:

    ;;Personaje=A
    ;;Contrincante=B


    ;;1-Compara posición X del personaje con posición X de la entidad contrincante(Ax-Bx).Si es la misma se va al paso 2(flag zero?).Si es distinta se va al paso 3.
    ;;2-Compara posicion Y del personaje con posicion Y de la entidad contrincante(Ay-By).Si es la misma se va al paso 5(flag zero?).Si es distinta se va al paso 4.

    ;;------------------------La entidad contrincante se tiene que mover----------------------------------------------------------------------------
    ;;3-Si el flag carry esta a 1, entonces significa que el contrincante esta mas a la derecha del personaje.Entonces se resta 1 a la x del contrincante(Movimiento a la izquierda).
      ;;Si el flag carry esta a 0, entonces significa que el contrincante esta mas a la izquierda del personaje.Entonces se suma 1 a la x del contrincante(Movimiento a la derecha).
      ;;Se va al paso 2.
    ;;4-Si el flag carry esta a 1, entonces significa que el contrincante esta mas arriba que el personaje.Entonces se suma 1 a la y del contrincante(Movimiento hacia abajo).
      ;;Si el flag carry esta a 0, entonces significa que el contrincante esta mas abajo que el personaje.Entonces se resta 1 a la y del contrincante(Movimiento hacia arriba).
      ;;Se va al paso 5.
    ;;----------------------------------------------------------------------------------------------------------------------------------------------

    ;;------------------------La entidad contrincante no se tiene que mover-------------------------------------------------------------------------
    ;;5-No se actualiza la posicion de la entidad contrincante.Fin de la rutina.
    ;;----------------------------------------------------------------------------------------------------------------------------------------------

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

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

    ;;Input:    
        ;;Ix-->Entidad personaje
        ;;Iy-->Entidad contrincante
    ;;Function:
        ;;Actualiza las posiciones x,y de la entidad contrincante.Rango operativo [-1,1].Puede darse el caso de que no actualice.
sys_physics_ia_update_one::

    push ix
    pop iy
    ld ix,#player

    _Compare_X:
        ld a,e_x(ix)        ;;Cargamos en el acumulador el valor X del personaje.
        sub e_x(iy)         ;;Le restamos el valor X de la entidad contrincante.
        jr z ,_Compare_Y      ;;Si son iguales las coordenadas x entonces pasamos a comparar las coordenadas Y.
    _Balance_X:
        jr c ,_SUB_X         ;;Si el personaje esta mas a la izquierda del contrincante,entonces se resta 1 a la x del contrincante.
        ld e_vx(iy), #1        ;;Si el personaje esta mas a la derecha del contrincante,entonces se suma 1 a la x del contrincante.

    _Compare_Y:
        ld a,e_y(ix)        ;;Cargamos en el acumulador el valor Y del personaje.
        sub e_y(iy)         ;;Le restamos el valor Y de la entidad contrincante.
        jr z ,_Done_         ;;Si son iguales las coordenadas y entonces finalizamos la subrutina.
    _Balance_Y:
        jr c ,_ADD_Y         ;;Si el personaje esta mas abajo que el contrincante,entonces se suma 1 a la y del contrincante.
        ld e_vy(iy), #2      ;;Si el personaje esta mas arriba que el contrincante,entonces se resta 1 a la y del contrincante.
    _Done_:
        xor a               ;;Se limpia el registro a para evitar futuros errores.
        jp ret_artificial                ;;Ya sea porque no ha sido necesario actualizar la posicion del contrincante o porque ya se ha terminado de actualizar,hemos terminado y retornamos.
    _SUB_X:
        ld e_vx(iy), #-1
        jr _Compare_Y
        
    _ADD_Y:
        ld e_vy(iy), #-2
        jr _Done_

    jp ret_artificial

    
sys_physics_ia_update:: 
    ld a, (ia_contador)
    dec a
    jp nz, no_actualizar_ia

    ;; Si es 0, actualizamos la ia y reiniciamos dicho contador
    ld hl, #sys_physics_ia_update_one
    ld a, #(e_type_ia)
    call man_entity_forall_matching

    ld a, #max_contador_ia


    no_actualizar_ia:
    ld (ia_contador), a
    ret