
;;-----------------------------LICENSE NOTICE------------------------------------
;;  This file is part of Nightmare Fortress: An Amstrad CPC Game 
;;  Copyright (C) 2017 Natalia Bernal Pérez / Álvaro Esteve Bernabeu / Plácido Antonio López Ávila
;;
;;  Nightmare Fortress is free software: you can redistribute it and/or modify
;;  it under the terms of the GNU Lesser General Public License as published by
;;  the Free Software Foundation, either version 3 of the License, or
;;  (at your option) any later version.
;;
;;  Nightmare Fortress 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 Lesser General Public License for more details.
;;
;;  You should have received a copy of the GNU Lesser General Public License
;;  along with Nightmare Fortress.  If not, see <http://www.gnu.org/licenses/>.
;;-------------------------------------------------------------------------------

.area _DATA
.area _CODE


;;-----------------------------------------------------------------------
;;PRIVATE DATA 
;;-----------------------------------------------------------------------
.include "cpctelera.h.s"
.include "utils.h.s"
.include "macros.h.s"
.include "sprites/sprites.h.s"
.include "gameController.h.s"
.include "stage.h.s"
.include "interface.h.s"



shoot_width: .db #2
shoot_height: .db #8
shoot_size_in_bytes::  .db #12					;; Valor necesario para iterar sobre el array de disparos


;;-----------------------------------------------------------------------
;; PUBLIC FUNCTIONS
;;-----------------------------------------------------------------------

;;-----------------------------------------------------------------------
;; Rutina para dibujar el disparo. 
;; -> IX debe apuntar al disparo que se quiere pintar
;;-----------------------------------------------------------------------
shoot_draw::
	call  entity_draw
	ret


;;-----------------------------------------------------------------------
;; Rutina para borrar el disparo y dejar lo de detras como estaba
;; -> IX debe apuntar al disparo que se quiere borrar
;;-----------------------------------------------------------------------
shoot_erase::
	call entity_erase
	ret

;;-----------------------------------------------------------------------
;; Rutina para mover el disparo hacia la direccion en la que se mueve
;; -> IX debe apuntar al disparo que se quiere mover
;;-----------------------------------------------------------------------
shoot_update::

	ld a, x(ix)
	cp #0xFE
	jr z, not_update

	ld a, state(ix)
	dec a
	dec a
	jp z, disparo_derecha
	dec a
	jp z, disparo_abajo
	dec a
	jp z, disparo_izquierda
	jp disparo_arriba


	disparo_derecha:
		ld a, x(ix)
		inc a
		inc a
		ld x(ix), a
		cp #76
		call nc, shoot_destroy
		ret nc

		jp check_shoot_tile_collision

	disparo_abajo:
		ld a, y(ix)
		add #6
		ld y(ix), a
		cp #172
		
		call nc, shoot_destroy
		ret nc

		jp check_shoot_tile_collision


	disparo_izquierda:
		ld a, x(ix)

		cp #3
		call c, shoot_destroy
		ret c


		sub #2
		ld x(ix), a 

		jp check_shoot_tile_collision


	disparo_arriba::
		ld a, y(ix)	
		cp #9
		call c, shoot_destroy
		ret c
		ld a, y(ix)
		sub #6
		ld y(ix), a
		
		jp check_shoot_tile_collision


	not_update:
		call shoot_destroy
		ret

	check_shoot_tile_collision:
		call tile_collision
		cp #1
		call z, shoot_destroy

		push ix
		push ix
		pop de

		ld ix, (currentStage)
    		ld h, enemies_h(ix)
    		ld l, enemies_l(ix)
    		push hl 
    		pop ix
		call check_enemy_collision
		push ix	;; ENEMIGO
		pop ix	;; ENEMIGO
		cp #0
		jp nz, actualizar_enemigo_vida
		pop ix	;; disparo
		ret 

		actualizar_enemigo_vida:

		ld a, vivo_muerto(ix)
		cp #0
		jp z, no_borrar

		ld a, life(ix)
		cp #0
		jp z, muerto

		sub #10
		ld life(ix), a

		cp #0
		jp z, muerto

		pop ix
		call shoot_destroy
		ret

		muerto:

		ld a, #0
		ld vivo_muerto(ix), a

		pop ix
		call shoot_destroy

		ld hl, (score_number)
		ld bc, #0010
		add hl, bc
		ld (score_number), hl

		ret

		no_borrar:
		pop ix
		ret



;;-----------------------------------------------------------------------
;; Rutina para crear un disparo y meterlo en una direccion de memoria dada, SIN COMPRABAR NADA
;;
;; LAS COMPROBACIONES DE SI SE HA ALCANZADO EL NUMERO MAXIMO DE DISPAROS O DE SI LA POSICION DEL ARRAY 
;; ESTA LIBRE SE HARAN EN UNA RUTINA SUPERIOR, NO AQUI.
;;
;; -> IY es el puntero a la posicion del array donde se quiere meter el disparo
;; -> IX es el puntero a la entidad que ha efectuado el disparo
;;-----------------------------------------------------------------------
shoot_spawn::
	ld a, x(ix)						;Shoot_x = entity_x
	ld x(iy), a
	;;ld last_x(iy), a
	;;ld previousLast_x(iy), a

	ld a, y(ix)						;Shoot_y = entity_y
	add #4
	ld y(iy), a
	;;ld last_y(iy), a
	;;ld previousLast_Y(iy), a


	ld a, (shoot_width)
	ld width(iy), a					;Shoot_width = 2 (Anchura del disparo CUIDADO!!!!!!!)

	ld a, (shoot_height)
	ld height(iy), a				;Shoot_height = 8 (Altura del disparo CUIDADO!!!!!!!)


	ld hl, #_g_fireball				;Shoot_sprite = _g_fireball
	ld sprite_l(iy), l
	ld sprite_h(iy), h

	ld a, state(ix)					;Shoot_state = entity_state
	ld state(iy), a
	ret


;;-----------------------------------------------------------------------
;; Rutina para eliminar del juego un disparo
;; -> IX debe apuntar al disparo que se quiere borrar
;;-----------------------------------------------------------------------
shoot_destroy::
	call entity_destroy
	ret

;;------------------------------------------------
;; Llama a la funcion generica que modifica las x y las y para el doble buffer
;;
;;  -> IX es el puntero a la entidad que se quiere modificar
;;------------------------------------------------
shoot_update_xy::
	ld ix, #shootsArray ;; Puntero en ix al array de disparos
	ld bc, (shoot_size_in_bytes) ;; Hay que sumarle al puntero del array el numero de elementos que tiene el array
	call array_update_xy
	ret
