;-----------------------------------------------------------;
;                                                           ;
; Invaded                                                   ;
; Version 1.0                                               ;
; Enemy Routines                                            ;
;                                                           ;
;-----------------------------------------------------------;

;------------------------------------------------
; clearEnemyArray - Clear enemyArray
;
; Input:    None
; Output:   None
;------------------------------------------------
clearEnemyArray:
        ld      hl,enemyArray                   ; HL => Start of enemyArray
        ld      de,enemyArray+1                 ; DE => Start of enemyArray+1
        ld      bc,MAX_ENEMIES*6-1              ; BC = Number of bytes to clear
        ld      (hl),0                          ; Clear first byte
        ldir                                    ; And clear the rest
        ret

;------------------------------------------------
; newEnemy - Create a new enemy
;
; Input:    HL => Entry in enemyIni table
; Output:   HL => Next entry in enemyIni table
;------------------------------------------------
newEnemy:
        push    hl
        ld      hl,enemyArray
        ld      de,6
        ld      b,MAX_ENEMIES
findNewEnemyEntry:
        ld      a,(hl)
        or      a
        jr      z,newEnemyEntryFound
        add     hl,de
        djnz    findNewEnemyEntry
leaveNewEnemy:
        pop     hl
        ld      de,4
        add     hl,de
        ret
newEnemyEntryFound:
        pop     de                              ; DE => enemyIni entry
        push    de                              ; Save it again for after
        inc     de                              ; DE => Type
        ld      a,(de)                          ; A = Type
        ld      (hl),a                          ; Save it to enemyArray entry
        ld      b,a                             ; B = Type
        inc     de                              ; DE => X Coord in enemyIni
        inc     hl                              ; HL => X Coord in enemyArray
        ld      a,(de)
        ld      (hl),a                          ; Copy X Coord to enemyArray entry
        inc     de                              ; DE => Y Coord in enemyIni
        inc     hl                              ; HL => Y Coord in enemyArray
        ld      a,(de)
        ld      (hl),a                          ; Copy Y Coord to enemyArray entry
        inc     hl                              ; HL => Health in enemyArray
        push    hl                              ; Save it
        ld      l,b
        dec     l
        ld      h,ENEMY_DATA_LENGTH
        bcall(_htimesl)                         ; HL = Offset to enemy data
        ld      de,enemyData+18
        add     hl,de                           ; HL => Initial health for enemy
        ld      a,(hl)                          ; A = Health
        pop     hl                              ; HL => Health in enemyArray
        ld      (hl),a                          ; Save it
        xor     a
        inc     hl
        ld      (hl),a                          ; Reset aiCnt1
        inc     hl
        ld      (hl),a                          ; Reset aiCnt2
        jr      leaveNewEnemy                   ; Move to next enemyIni entry and leave

;------------------------------------------------
; drawEnemies - Draw enemies
;
; Input:    None
; Output:   None
;------------------------------------------------
drawEnemies:
        ld      hl,0
        ld      (lastSprite),hl                 ; Clear lastSprite pointer
        ld      ix,enemyArray                   ; IX => Start of enemyArray
        ld      hl,enemyBG                      ; HL => Start of enemy background table
        ld      b,MAX_ENEMIES                   ; B = Number of entries
drawEnemiesLoop:
        push    bc
        ld      a,(ix)
        or      a
        jr      z,endDrawEnemiesLoop
        ld      (lastSprite),hl
        push    hl
        ld      l,a
        dec     l
        ld      h,ENEMY_DATA_LENGTH
        bcall(_htimesl)                         ; HL = Offset to sprite
        ld      de,enemyData
        add     hl,de                           ; HL => Sprite
        pop     de                              ; DE => enemyBG entry
        ex      de,hl                           ; HL => enemyBG entry, DE => Sprite
        ld      b,(ix+1)
        ld      c,(ix+2)
        ld      (hl),b
        inc     hl
        ld      (hl),c
        inc     hl                              ; HL => Where to store background
        ex      de,hl                           ; HL => Sprite, B = X, C = Y, DE => enemyBG entry
        call    PutSprite_MSB
        ld      hl,8
        add     hl,de                           ; HL => Next enemyBG entry
endDrawEnemiesLoop:
        pop     bc
        ld      de,6
        add     ix,de                           ; IX => Next enemyArray entry
        djnz    drawEnemiesLoop
        ret

;------------------------------------------------
; eraseEnemies - Erase enemies from gbuf
;
; Input:    None
; Output:   None
;------------------------------------------------
eraseEnemies:
        ld      hl,(lastSprite)
        ld      a,l
        or      h
        ret     z                               ; Leave if no enemies were drawn
eraseEnemiesLoop:
        ld      b,(hl)                          ; B = X
        inc     hl
        ld      c,(hl)                          ; C = Y
        inc     hl                              ; HL => Background to draw
        call    PutSprite                       ; Draw background
        ld      de,enemyBG+2
        bcall(_cphlde)
        ret     z                               ; If we're done, leave
        ld      de,-12
        add     hl,de                           ; HL => Next background to draw
        jr      eraseEnemiesLoop

;------------------------------------------------
; moveEnemies - Run AI scripts for enemies
;
; Input:    None
; Output:   None
;------------------------------------------------
moveEnemies:
        ld      ix,enemyArray
        ld      b,MAX_ENEMIES
moveEnemiesLoop:
        push    bc
        ld      a,(ix)
        or      a
        jr      z,endMoveEnemiesLoop
        dec     a
        ld      l,a
        ld      h,ENEMY_DATA_LENGTH
        bcall(_htimesl)
        ld      de,16
        add     hl,de
        ld      de,enemyData
        add     hl,de                           ; HL => Number of AI script to run
        push    hl
        inc     hl
        inc     hl
        inc     hl                              ; HL => Speed
        ld      a,(frame)
        and     (hl)
        pop     hl
        jr      nz,endMoveEnemiesLoop
        ld      a,(ix+E_AICNT1)
        ld      (aiCnt),a
        ld      a,(hl)
        inc     hl
        push    hl
        call    runAIScript
        ld      a,(aiCnt)
        ld      (ix+E_AICNT1),a
        pop     hl
        ld      a,(ix+E_AICNT2)
        ld      (aiCnt),a
        ld      a,(hl)
        call    runAIScript
        ld      a,(aiCnt)
        ld      (ix+E_AICNT2),a
endMoveEnemiesLoop:
        pop     bc
        ld      de,6
        add     ix,de
        djnz    moveEnemiesLoop
        ret

;-----------------------------------------------
; runAIScript - Run a specified AI script
;
; Input:    A = AI script to run
;           IX => Entry of enemy in enemyArray
; Output:   None
;-----------------------------------------------
runAIScript:
        add     a,a
        ld      e,a
        ld      d,0
        ld      hl,aiTable
        add     hl,de
        bcall(_ldhlind)
        jp      (hl)

;------------------------------------------------
; checkEnemiesOnScreen - Check all enemies to see if they're still on screen
;
; Input:    None
; Output:   None
;------------------------------------------------
checkEnemiesOnScreen:
        ld      hl,enemyArray
        ld      b,MAX_ENEMIES
enemiesOnScreen:
        ld      a,(hl)
        or      a
        jr      z,endEnemiesOnScreen
        push    bc
        push    hl
        inc     hl
        ld      a,(hl)
        cp      96
        jr      c,ceosXOK
        cp      -7
        jr      c,enemyNotOnScreen
ceosXOK:
        inc     hl
        ld      a,(hl)
        cp      56
        jr      c,ceosYOK
        cp      -7
        jr      nc,ceosYOK
        dec     hl
enemyNotOnScreen:
        dec     hl
        ld      (hl),0
ceosYOK:
        pop     hl
        pop     bc
endEnemiesOnScreen:
        ld      de,6
        add     hl,de
        djnz    enemiesOnScreen
        ret

.end
