MISSLE_TR	EQU 2	;missile thresold for ->0>+

	ld A,(missleTimer)
	or A
	jr z,MISSLE_UpdateTimerOut
	dec A
	ld (missleTimer),A
.MISSLE_UpdateTimerOut

;new missile code , update missiles start here
	ld IX,missleA	;point on both to avoid tracking on same target
	ld IY,missleB
	call MISSLE_Update
	ld IX,missleB
	ld IY,missleA
.MISSLE_Update
;is still active ?
	ld A,(IX)
	or A
	ret z

;check for targeting and tracking
	call MISSLE_DoTargeting	
	call MISSLE_DoTracking

	
;get current direction
	ld L,(IX+3)
	ld H,0
	add HL,HL	;*2
	add HL,HL	;*4	
	add HL,HL	;*8 8 bytes per direction
	ld DE,MISSLE_Table
	add HL,DE	;get address in table
	
	ld C,(IX+1)
	ld B,(IX+2)
	
;save old pos for flammes
	ld (IX+8),C
	ld (IX+9),B
;save table address
	ld (MISSLE_DirAdress),HL

;compute new pos and check if on screen	
;X
	ld A,(HL)
	add C
	cp 32
	jp nc,MISSLE_Kill
	ld C,A
;Y	
	inc HL
	ld A,(HL)
	add B
	cp 20
	jp nc,MISSLE_Kill
	ld B,A
;get sprite address
	inc HL
	ld E,(HL)
	inc HL
	ld D,(HL)
	push DE		;save sprite address

;save new pos	
	ld (IX+1),C
	ld (IX+2),B
	
;now , compute address in array
	add A
	add ATTR_Addr_low
	ld L,A
	ld H,ATTR_Addr_High
	;get it !
	ld E,(HL)
	inc L
	ld D,(HL)
	;add X
	ld A,C
	add E
	ld E,A
	;so we are , now check if we owns something here
	ld A,(DE)
	bit 6,A
	jr nz,MISSLE_OnEgg
	and %10000001
	jr z,MISSLE_Draw
	inc D	;bank
	inc D	;low addr
	inc D	;high addr
	inc D	;master !
	ld A,(DE)
	or A
	jr z,MISSLE_Destroy
	cp 32
	jr nc,MISSLE_End
;do damage here
	ld B,1
	call THEM_MakeDamage
	jr MISSLE_Destroy
.MISSLE_End
	pop HL ;get sprite address
	ret
	
.MISSLE_Draw
	ex DE,HL
	ld (HL),1	;normal sprite
	inc H
	ld (HL),#C0	;bank
	inc H
	pop DE		;sprite address
	ld (HL),E
	inc H
	ld (HL),D
	inc H
	ld (HL),NeutralMaster	;neutral master
;draw flammes
	ld A,(IX+9)
	add A
	add ATTR_Addr_low
	ld L,A
	ld H,ATTR_Addr_High
	;get it !
	ld E,(HL)
	inc L
	ld D,(HL)
	;add X
	ld A,(IX+8)
	add E
	ld E,A
	ld A,(DE)	;is address empty ?
	and %10000001
	ret nz
;if yes , draw flamme
MISSLE_DirAdress	EQU $+1	
	ld HL,0
	ld A,(FRAME)
	and 1
	add A
	add 4
	ld C,A
	ld B,0
	add HL,BC
	
	ld A,(HL)
	inc HL
	ld H,(HL)
	ld L,A
	
	ex DE,HL
	ld (HL),1	;normal sprite
	inc H
	ld (HL),#C0	;bank
	inc H		;sprite address
	ld (HL),E
	inc H
	ld (HL),D
	inc H
	ld (HL),NeutralMaster	;neutral master
	
	ret	
	
.MISSLE_OnEgg
	ex DE,HL
	ld (HL),4	;auto erase
	inc H
	inc H
	inc H
	inc H
	ld (HL),64	;neutral
.MISSLE_Destroy
	pop HL	;remove sprite address from stack
.MISSLE_Kill
	ld (IX),0
	ret
	
;missile table
;dir X , dir Y , dw missle spr address , dw flamme 1 , dw flamme 2
;clockwise
.MISSLE_Table
	db 1,0:dw 0,0,0
	db 1,1:dw 0,0,0
	db 0,1:dw 0,0,0
	db -1,1:dw 0,0,0
	db -1,0:dw 0,0,0
	db -1,-1:dw 0,0,0
	db 0,-1:dw 0,0,0
	db 1,-1:dw 0,0,0                                                                            
	
.MISSLE_Spawn
;check timer
	ld A,(missleTimer)
	or A
	ret nz
	
	ld A,32
	ld (missleTimer),A

;spawn only if 2 slots are free
	ld A,(missleA)
	ld B,A
	ld A,(missleB)
	or B
	ret nz
	
;
	;#38 jr c
	;#30 jr nc
	
	ld BC,(SHIPX)
	ld DE,#3000
	ld HL,missleA
	dec B
	call MISSLE_SpawnOne
	
	inc B
	inc B
	inc B
	ld HL,missleB
	ld DE,#3800
	call MISSLE_SpawnOne

;play sound	
	ld A,sfx_missile
	call SND_SfxPlay
	
	ret
;spawn a missile
.MISSLE_SpawnOne
;valid pos on screen ?
	ld A,B
	cp 20
	ret nc
	
	ld A,C
	cp 32
	ret nc
	
	ld (HL),1
	inc HL
	ld (HL),C
	inc HL
	ld (HL),B
	inc HL
	ld (HL),E	;direction
	inc HL
	ld (HL),#FF	;no target !
	inc HL
	ld (HL),3	;max change count
	inc HL
	ld (HL),D	;opcode for up/down
	inc HL
	ld (HL),4	;time before start targeting
	ret
	
.MISSLE_Init
	xor A
	ld (missleA),A
	ld (missleB),A
	
	inc A
	ld (missleTimer),A
	
	ld IX,MISSLE_Table+2
	ld A,202	;first sprite = 201
	ld B,8		; 8 directions

;get sprites	
.MISSLE_InitLoop

	push BC
	ld B,3	;3 sprites per direction

.MISSLE_initLoop2
	push BC 
	push AF
	call USPGADD
	
	;get first tile
	inc HL	;global flag
	inc HL	;tile flags
	ld A,(HL)	;low addr
	ld (IX),A
	inc IX
	inc HL	
	ld A,(HL)	;high addr
	ld (IX),A
	inc IX

	pop AF
	inc A
	pop BC
	djnz MISSLE_InitLoop2
	
	inc IX
	inc IX
	pop BC
	djnz MISSLE_InitLoop
	
	ret
	
;track a target
.MISSLE_DoTracking
	;ld A,(FRAME)
	;and 3
	;ret nz

	ld A,(IX+4)	;do we have a target ?
	cp #FF
	ret z
	
;point on slot
	ld L,A
	LD H,SEQBUFF_high
	
;is target alive ?	
	ld A,(HL)
	and 63
	jr nz,MISSLE_DoTrackingTargetAlive	
	
	ld (IX+5),0
	ret
	
.MISSLE_DoTrackingTargetAlive	
	call MISSLE_DoTrackingComputeDirection
	
	ld A,(IX+3)
	cp E
	ret Z
	
	ld A,(IX+5)
	or A
	ret z
	
	dec A
	ld (IX+5),A	

;do tracking , wanted direction in E	
	;ld (IX+3),E

	ld A,E	
	sub (IX+3)
	and 7

	cp 4
	jr nc,MISSLE_DoTrackingRight
;goto left
	ld A,(IX+3)
	inc A
	and 7
	ld (IX+3),A	
	ret
;goto right
.MISSLE_DoTrackingRight
	ld A,(IX+3)
	dec A
	and 7
	ld (IX+3),A
	ret

.MISSLE_DoTrackingComputeDirection
;the worst part	, get direction from coords , return in E
	ld A,(IX+1)	;get missle x pos
	dec A
	inc L
	inc L
	inc L
	sub (HL)	;substract target x pos
	ld C,A
	ex AF,AF'	;keep flag
	
;same thing for Y
	inc L
	ld A,(HL)
	add 5
	ld B,A
	ld A,(IX+2)
	;dec A
	;inc L
	;sub (HL)
	;ld B,A
	add 4
	sub B
	ld B,A

	jr z,MISSLE_DoTrackingNullY
	jr nc,MISSLE_DoTrackingUp
.MISSLE_DoTrackingDown	
	ld A,B
	neg
	cp MISSLE_TR
	jr c,MISSLE_DoTrackingNullY
	
	ex AF,AF' 		;examine X diffence
	ld E,2
	jr c,MISSLE_DoTrackingDownRight
	jr nc,MISSLE_DoTrackingDownLeft
	ret
.MISSLE_DoTrackingDownRight
	ld A,C
	neg
	cp MISSLE_TR
	ret C
	dec E
	ret
.MISSLE_DoTrackingDownLeft
	ld A,C
	cp MISSLE_TR
	ret C
	inc E
	ret
;targety<missley
.MISSLE_DoTrackingUp
	ld A,B
	neg
	cp MISSLE_TR
	jr c,MISSLE_DoTrackingNullY
	
	ex AF,AF'		;examine X difference now
	ld E,6			;directly up
	jr c,MISSLE_DoTrackingUpRight
	jr nc,MISSLE_DoTrackingUpLeft	
	ret
.MISSLE_DoTrackingUpRight
	ld A,C
	neg
	cp MISSLE_TR
	ret C
	inc E
	ret
.MISSLE_DoTrackingUpLeft
	ld A,C
	cp MISSLE_TR
	ret C
	dec E
	ret
;Y - Y =0
.MISSLE_DoTrackingNullY
	ld E,0
	ex AF,AF'
	ret c		;if targetX>missX direction = 0 = 1,0
	ld E,4		;else direction = 4 = -1,0
	ret
	
;search for a target
;set low byte of address in (IX+4) if found one
.MISSLE_DoTargeting
	ld A,(IX+4)
	cp #FF			;still own no target ?	
	ret nz
	
	ld A,(IX+7)
	or A
	jr z,MISSLE_DoTargetingCan
	dec A
	ld (IX+7),A
	ret
.MISSLE_DoTargetingCan
	
	;opcode for Y targeting jr c/jr nc
	ld A,(IX+6)
	ld (MISSLE_DoTargetingOpcode),A
	
	ld A,(IX+1)
	add 2			;a bit far from missile
	cp 32
	ret nc			;still on screen ?
	
	ld C,A			;keep x on C
	ld B,28			;28 slots
	ld HL,SEQBUFF
	
.MISSLE_DoTargetingLoop
	ld E,L		;current object
	ld A,(HL)	;get target state
	inc L		;pattern low
	inc L		;pattern hi
	inc L		;x
	
	and 63		;is target alive ?
	jr z,MISSLE_DoTargetingNext
	cp 63		;is target indestuctible ?
	jr z,MISSLE_DoTargetingNext
	
	ld A,(HL)
	cp C
	jr nz,MISSLE_DoTargetingNext
;check if Y up/down
	inc L
	ld A,(HL)
	dec L
	cp (IX+2)
.MISSLE_DoTargetingOpcode
	jr z,MISSLE_DoTargetingNext
;is already targeted ?	
	ld A,(IY+0)
	or A
	jr z,MISSLE_DoTargetingNotAlready
	ld A,(IY+4)
	cp E		;already targeted ?
	jr z,MISSLE_DoTargetingNext
	;else write it !
.MISSLE_DoTargetingNotAlready	
	ld (IX+4),E
	ret
	
.MISSLE_DoTargetingNext
	ld A,6	;still 6 bytes to next object
	add L
	ld L,A
	djnz MISSLE_DoTargetingLoop

	ret
	
	