;-----------------------------------------------------------;
;                                                           ;
; Invaded                                                   ;
; Version 1.0                                               ;
; Damage Checking Routines                                  ;
;                                                           ;
;-----------------------------------------------------------;

;------------------------------------------------
; checkEnemyDamage - Check to see if any enemies are being damaged by bullets or the Orb
;
; Input:    None
; Output:   None
;------------------------------------------------
checkEnemyDamage:
        ld      hl,bulletSizeTable
        ld      (_sbco2Size),hl
        ld      ix,enemyArray
        ld      b,MAX_ENEMIES
enemyDamageLoop:
        push    bc
        ld      a,(ix)
        or      a
        jp      z,endEnemyDamageLoop
        ld      hl,collideObject1
        ld      a,(ix+E_X)
        ld      (hl),a
        inc     hl
        ld      (hl),8
        inc     hl
        ld      a,(ix+E_Y)
        ld      (hl),a
        inc     hl
        ld      (hl),8
;;;; Start Orb collisions
        ld      a,(orb)
        or      a
        jr      z,afterCheckOrbEnemyCollision
        ld      a,(frame)
        and     $01
        jr      nz,afterCheckOrbEnemyCollision
        ld      hl,collideObject2
        call    storeOrbInCollideObject
        call    checkCollision
        jr      nc,afterCheckOrbEnemyCollision
        dec     (ix+E_HEALTH)
        ld      a,(ix+E_HEALTH)
        cp      221
        jr      c,afterCheckOrbEnemyCollision
        call    killEnemy
        jr      endEnemyDamageLoop
afterCheckOrbEnemyCollision:
;;;; End Orb collisions
        ld      hl,bulletArray
        ld      b,MAX_BULLETS
enemyDamageLoop2:
        push    bc
        push    hl
        ld      a,(hl)
        or      a
        jr      z,endEnemyDamageLoop2
        call    storeBulletInCollideObject2
        call    checkCollision
        jr      nc,endEnemyDamageLoop2
        pop     hl
        push    hl
        call    getBulletStrength
        ld      a,(ix+E_HEALTH)
        sub     (hl)
        ld      (ix+E_HEALTH),a
        cp      221
        ex      de,hl
        ld      a,(hl)
        ld      (hl),0
        jp      c,endEnemyDamageLoop2
        cp      1
        jr      z,enemyDamageNoKeepBullet
        ld      (hl),a
enemyDamageNoKeepBullet:
        call    killEnemy
        pop     hl
        pop     bc
        jr      endEnemyDamageLoop
endEnemyDamageLoop2:
        pop     hl
        pop     bc
        ld      de,4
        add     hl,de
        djnz    enemyDamageLoop2
endEnemyDamageLoop:
        pop     bc
        ld      de,6
        add     ix,de
        dec     b
        jp      nz,enemyDamageLoop
        ret

;------------------------------------------------
; checkGuardianDamage - Check to see if end-of-level boss if being damaged by bullets or the Orb
;
; Input:    None
; Output:   CA = 1 if end-of-level boss is dead
;------------------------------------------------
checkGuardianDamage:
        ld      a,(guardian)
        or      a
        ret     z
        ld      hl,bulletSizeTable
        ld      (_sbco2Size),hl
        ld      hl,collideObject1
        ld      a,(gX)
        ld      (hl),a
        inc     hl
        ld      a,(guardianSizeX)
        ld      (hl),a
        inc     hl
        ld      a,(gY)
        ld      (hl),a
        inc     hl
        ld      a,(guardianSizeY)
        ld      (hl),a
;;;; Start Orb collisions
        ld      a,(orb)
        or      a
        jr      z,afterCheckOrbGuardianCollision
        ld      a,(frame)
        and     $01
        jr      nz,afterCheckOrbGuardianCollision
        ld      hl,collideObject2
        call    storeOrbInCollideObject
        call    checkCollision
        jr      nc,afterCheckOrbGuardianCollision
        ld      hl,gHealth
        dec     (hl)
        ld      a,(hl)
        cp      221
        ccf
        ret     c
afterCheckOrbGuardianCollision:
;;;; End Orb collisions
        ld      hl,bulletArray
        ld      b,MAX_BULLETS
guardianDamageLoop:
        push    bc
        push    hl
        ld      a,(hl)
        or      a
        jr      z,endGuardianDamageLoop
        call    storeBulletInCollideObject2
        call    checkCollision
        jr      nc,endGuardianDamageLoop
        pop     hl
        push    hl
        call    getBulletStrength
        xor     a
        ld      (de),a
        ld      a,(gHealth)
        sub     (hl)
        ld      (gHealth),a
        cp      221
        jp      nc,guardianDamageDead
endGuardianDamageLoop:
        pop     hl
        pop     bc
        ld      de,4
        add     hl,de
        djnz    guardianDamageLoop
        or      a
        ret
guardianDamageDead:
        pop     hl
        pop     bc
        scf
        ret

;------------------------------------------------
; getBulletStrength - Get strength of a player bullet
;
; Input:    HL => Entry of bullet in bulletArray
; Output:   DE => Entry of bullet in bulletArray
;           HL => Strength
;           A = Strength
;------------------------------------------------
getBulletStrength:
        ld      a,(hl)
        ex      de,hl
        dec     a
        ld      c,a
        ld      b,0
        ld      hl,bulletStrengthTable
        add     hl,bc
        ld      a,(hl)
        ret

;------------------------------------------------
; killEnemy - Kill an enemy and get points, drop bonuses, etc.
;
; Input:    IX => Entry of enemy in enemyArray
; Output:   IX => Entry of enemy in enemyArray
;------------------------------------------------
killEnemy:
        ld      l,(ix)
        ld      h,0
        dec     l
        add     hl,hl
        ld      de,enemyScoreTable
        add     hl,de
        ld      e,(hl)
        inc     hl
        ld      d,(hl)
        call    updateScore
        call    newAnimation
        ld      l,(ix)
        dec     l
        ld      h,ENEMY_DATA_LENGTH
        bcall(_htimesl)
        ld      de,enemyData+ENEMY_DATA_LENGTH-1
        add     hl,de
        ld      a,(hl)
        or      a
        jr      z,noDropPickup
        ld      c,a
        ld      d,(ix+E_X)
        ld      e,(ix+E_Y)
        call    newPickup
noDropPickup:
        ld      (ix),0
        ret

;------------------------------------------------
; checkOrbEBulletsCollisions - Check for collisions between the Orb and any enemy bullets
;
; Input:    None
; Output:   None
;------------------------------------------------
checkOrbEBulletsCollisions:
        ld      a,(orb)
        or      a
        ret     z
        ld      hl,eBulletSizeTable
        ld      (_sbco2Size),hl
        ld      hl,collideObject1
        call    storeOrbInCollideObject
        ld      hl,eBulletArray
        ld      b,MAX_EBULLETS
orbEBulletCollisionsLoop:
        push    bc
        push    hl
        ld      a,(hl)
        cp      1                               ; Orb only stops type 1 bullets
        jr      nz,endOrbEBulletCollisionsLoop
        call    storeBulletInCollideObject2
        call    checkCollision
        jr      nc,endOrbEBulletCollisionsLoop
        pop     hl
        push    hl
        ld      (hl),0
endOrbEBulletCollisionsLoop:
        pop     hl
        pop     bc
        ld      de,4
        add     hl,de
        djnz    orbEBulletCollisionsLoop
        ret

;------------------------------------------------
; checkPlayerGuardianCollisions - Check for collision between player and end-of-level boss (if fighting one)
;
; Input:    None
; Output:   None
;------------------------------------------------
checkPlayerGuardianCollisions:
        ld      a,(dead)
        or      a
        ret     nz
        ld      a,(guardian)
        or      a
        ret     z
        call    storePlayerInCollideObject1
        ld      hl,collideObject2
        ld      a,(gX)
        ld      (hl),a
        inc     hl
        ld      a,(guardianSizeX)
        ld      (hl),a
        inc     hl
        ld      a,(gY)
        ld      (hl),a
        inc     hl
        ld      a,(guardianSizeY)
        ld      (hl),a
        call    checkCollision
        ret     nc
        ld      a,INI_DEAD
        ld      (dead),a
        ret

;------------------------------------------------
; checkPlayerEnemyCollisions - Check for collisions between player and any enemies
;
; Input:    None
; Output:   None
;------------------------------------------------
checkPlayerEnemyCollisions:
        ld      a,(dead)
        or      a
        ret     nz
        call    storePlayerInCollideObject1
        ld      ix,enemyArray
        ld      b,MAX_ENEMIES
cPlayerEnemyCollisionsLoop:
        push    bc
        ld      a,(ix)
        or      a
        jr      z,eCPlayerEnemyCollisionsLoop
        ld      hl,collideObject2
        ld      a,(ix+E_X)
        ld      (hl),a
        inc     hl
        ld      (hl),8
        inc     hl
        ld      a,(ix+E_Y)
        ld      (hl),a
        inc     hl
        ld      (hl),8
        call    checkCollision
        jr      c,playerHitEnemy
eCPlayerEnemyCollisionsLoop:
        pop     bc
        ld      de,6
        add     ix,de
        djnz    cPlayerEnemyCollisionsLoop
        ret
playerHitEBullet:
        pop     hl
playerHitEnemy:
        ld      a,INI_DEAD
        ld      (dead),a
        pop     bc
        ret

;------------------------------------------------
; checkPlayerEBulletCollisions - Check for collisions between player and enemy bullets
;
; Input:    None
; Output:   None
;------------------------------------------------
checkPlayerEBulletCollisions:
        ld      a,(dead)
        or      a
        ret     nz
        ld      hl,eBulletSizeTable
        ld      (_sbco2Size),hl
        call    storePlayerInCollideObject1
        ld      hl,eBulletArray
        ld      b,MAX_EBULLETS
cPlayerEBulletCollisionsLoop:
        push    bc
        push    hl
        ld      a,(hl)
        or      a
        jr      z,eCPlayerEBulletCollisionsLoop
        call    storeBulletInCollideObject2
        call    checkCollision
        jr      c,playerHitEBullet
eCPlayerEBulletCollisionsLoop:
        pop     hl
        pop     bc
        inc     hl
        inc     hl
        inc     hl
        inc     hl
        djnz    cPlayerEBulletCollisionsLoop
        ret

.end
