I did the jump-killing tutorial, but could this be done ??

salgue79

New member
364/5000
No, I didn't add anything to the enemy's health. It comes out in the character's health. Without having touched anything.
The enemy's health is 8 hits to be able to eliminate it, a Final Boss. Well, count the health on the character's health meter. Without having touched anything.
I don't want the enemy's health meter. I just want you not to deduct it from the player meter.
 

salgue79

New member
What I want to explain is that the character's health meter and the enemy's health meter are the same. When I take health from the enemy, it counts on the player's meter.
 

dale_coop

Moderator
Staff member
Ok... so, as I told you, you might have made an error in one of the script... I suspect in the "Handle Collision Object" script. (the script where the Jump On Kills code is).
Could you share that script ?
(the one assigned to your Handle Object Collision)

ALSO, share your Handle Monster Hurt script (could be that one too).
 

salgue79

New member
HandleHurtMonster:

;; what should we do with the monster?
;;; monster is loaded in x
LDA Object_vulnerability,x
AND #%00000100 ;; is it weapon immune?
BEQ notWeaponImmune
;PlaySound #SFX_MISS
JMP skipHurtingMonsterAndSound
notWeaponImmune:

LDA Object_status,x
AND #HURT_STATUS_MASK
BEQ dontskipHurtingMonster
JMP skipHurtingMonster
dontskipHurtingMonster:
LDA Object_status,x
ORA #%00000001
STA Object_status,x
LDA #HURT_TIMER
STA Object_timer_0,x
;;; assume idle is in step 0
ChangeObjectState #$00,#$02
;;;; unfortunately this recoil is backwards
LDA Object_status,x
AND #%00000100
BNE skipRecoilBecauseOnEdge
LDA Object_vulnerability,x
AND #%00001000
BNE skipRecoilBecauseOnEdge ;; skip recoil because bit is flipped to ignore recoil

LDA selfCenterX
STA recoil_otherX
LDA selfCenterY
STA recoil_otherY
LDA otherCenterX
STA recoil_selfX
LDA otherCenterY
STA recoil_selfY
JSR DetermineRecoilDirection
skipRecoilBecauseOnEdge:
LDA Object_health,x
SEC
SBC #$01
CMP #$01
BCC +
JMP notMonsterDeath
+

DeactivateCurrentObject
PlaySound #SND_SPLAT
;;;;;;;;;;;;;;;;;; ok, so now we also add points to score
;LDY Object_type,x
;LDA ObjectWorth,y
;STA temp
; AddValue #$03, GLOBAL_Player1_Score, temp
;arg0 = how many places this value has.
;arg1 = home variable
;arg2 = amount to add ... places?
;; and this should trip the update hud flag?

;;;;


TXA
STA tempx

AddValue #$08, myScore, #$01, #$00

;STA hudElementTilesToLoad
; LDA #$00
; STA hudElementTilesMax
; LDA DrawHudBytes
; ora #HUD_myScore
; STA DrawHudBytes
UpdateHud HUD_myScore
LDX tempx

JSR HandleDrops
JSR HandleToggleScrolling

CountObjects #$00001000, #$00
BEQ +
JMP ++
+
.include SCR_KILLED_LAST_MONSTER
++

JMP skipHurtingMonster
notMonsterDeath
STA Object_health,x
skipHurtingMonster:
;PlaySound #SFX_MONSTER_HURT

skipHurtingMonsterAndSound:
LDX tempx
;; what should we do with the projectile?
DeactivateCurrentObject
 

salgue79

New member
HandleObjectCollision:

;; LOAD OBJECT 00
;; OUTER LOOP
;; CHECK IF ACTIVE, IF NOT, SKIP OBJECT
;; LOAD self-collision-box
;; START OBJECT COLLISION LOOP
;; LDA ONE MORE THAN CURRENT OBJECT
;; CHECK IF ACTIVE. IF NOT, SKIP THIS other
;; IF IT IS ACTIVE, then we have to play them against each other.
;; IS self object hurt by monsters? If so, and other object is a monster, respond.
;; IS self object hurt by weapons? If so, and other object is a weapon, respond.
;; at this point, we can still gauge whether or not it's affected by player, like with powerups.
;; ADD one to the object being checked, loop through other objects.
;; increase object, return to outer loop. Repeat thorugh all self objects.

;; ObjectFlags:
;; 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0
; | | | | | | | + -- PERSISTENT (especially good for player!)
; | | | | | | +------- player type
; | | | | | + ---------- player weapon/projectile type
; | | | | +--------------- monster type
; | | | +------------------- monster weapon/projectile type
; | | +----------------------- pickup / power up
; | + -------------------------- target type
; +------------------------------- NPC type

;; player type checks monster, mosnter weapon, and pickup.
;; player weapon checks monster and target.
;; nothing else needs checking, as it would all be handled by those two steps.
;; so if it's a monster, do nothing. if it's a monster projectile, do nothing.
;; if it's a pickup, or a target, or it ignores all collisions, do nothing.
;; only if it's #%00000110, do something.



HandleObjectCollisions:

LDA update_screen
BEQ notChangingScreens
rts
notChangingScreens:

LDA npc_collision
AND #%11111110
STA npc_collision

;LDA currentBank
;STA prevBank
;LDY #BANK_ANIMS
;JSR bankswitchY

LDX #$00
CollisionOuterLoop:
TXA
STA tempx
LDA Object_status,x
AND #%10000000
BNE continueObjectCollisions_objectIsActive
JMP doneWithThisObjectCollision
continueObjectCollisions_objectIsActive:
LDA Object_status,x
AND #%00000100 ;; is ot off screen
BEQ continueObjectCollisions_objectIsOnScreen
JMP doneWithThisObjectCollision
continueObjectCollisions_objectIsOnScreen
LDA Object_status,x
AND #%00000011
BEQ continueObjectCollisions_objectIsNotHurtOrInvincible
JMP doneWithThisObjectCollision
continueObjectCollisions_objectIsNotHurtOrInvincible
;LDY Object_type,x
;LDA ObjectFlags,y
LDA Object_flags,x
AND #%00000110
BNE continueObjectCollisions_onlyPlayerTypesCheck
JMP doneWithThisObjectCollision
continueObjectCollisions_onlyPlayerTypesCheck:
;; this is either a player or player projectile type of object.
;; all other types will be taken care of by iterating through these two types.
;; first, check if it's player type.
;LdA ObjectFlags,y
LDA Object_flags,x
AND #%00000010
BNE isPlayerTypeForCollision
JMP notPlayerType_forObjectCollision
isPlayerTypeForCollision:
LDA player1_object
STA colX
;; is player type for object collision
;; player's index is loaded into tempx
JSR GetSelfCollisionBox
;; now we have the collision box for self object
;; next we loop through objects.

LDX #$00
LoopThroughOtherObjects_player:
CPX tempx
BNE dontSkipThisOtherObject
JMP skipThisOtherObject ;; other object IS the player, the one doing the counting..
dontSkipThisOtherObject:
LDA Object_status,x
AND #%00000100
BEQ dontSkipThisOtherObject_becauseOnScreen
JMP skipThisOtherObject ;; because it was off screen.
dontSkipThisOtherObject_becauseOnScreen:

JSR GetOtherCollisionBox


;; now we can do all the compares
LDA selfNT_R
CMP otherNT_L
BCC + ;; no player object collision
BNE ++ ;; is still possible to see collision.
LDA selfRight
CMP otherLeft
BCC + ;; no player object collision
++ ;; it is still possible there is a collision here.
LDA otherNT_R
CMP selfNT_L
BCC +
BNE +++
LDA otherRight
CMP selfLeft
BCC +

+++ ;; there was a collision here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA otherBottom
CMP selfTop
BCC +
LDA selfBottom
CMP otherTop
BCC +

JMP DoPlayerObjectCollision

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; there is no collision here horizontally.
JMP noPlayerObjectCollision

DoPlayerObjectCollision:



LDA Object_flags,x
AND #%10000000 ;; is it an NPC
BNE isAnNPC
;; is not an NPC
JMP isNotAnNPCcollision
isAnNPC:
;;;; do npc stuff.
LDA npc_collision
ORA #%00000001
STA npc_collision
;;;; enables a button to be used to activate a textbox.
LDA Object_ID,x
STA textVar
;LDA gameHandler
;ORA #%00100000
;STA gameHandler

JMP skipThisOtherObject

isNotAnNPCcollision:
LDA Object_flags,x
;LDA ObjectFlags,y
AND #%00011000 ;; is it a monster type?
BNE otherIsAMonsterTypeCollision
JMP otherIsNotAMonsterTypeCollision
otherIsAMonsterTypeCollision:
LDA Object_status,x
AND #HURT_STATUS_MASK ;; if the monster is hurt, it can't hurt us
BEQ yesPlayerObjectCollision
JMP noPlayerObjectCollision
yesPlayerObjectCollision:

LDA Object_vulnerability,x
AND #%00000010 ;; in this module, this is ignore player collision
BEQ doPlayerHurt
JMP noPlayerObjectCollision
doPlayerHurt:
;;;observe health
TXA
STA tempx ;; object is in tempx.
LDX player1_object
LDA Object_status,x
AND #HURT_STATUS_MASK
BEQ playerWasNotHurtDuringCollision
JMP playerWasHurtDuringCollision
playerWasNotHurtDuringCollision:

;;---- Jump On Kills code begin ----
TYA
STA tempy
LDX tempx
LDA Object_vulnerability,x
AND #%00010000
BNE jumpOnMonster
LDX player1_object
JMP dontJumpOnMonster
jumpOnMonster:
LDX player1_object
;TXA
;STA tempx
;JMP playerWasHurtDuringCollision
;LDX player1_object
LDA selfBottom
CMP otherCenterY
BCC +
JMP dontJumpOnMonster
+
;;; JUMP ON MONSTER
LDX player1_object
LDA #$00
SEC
SBC #$04
STA Object_v_speed_hi,x
LDX tempx
LDA Object_health,x
SEC
SBC #$01
CMP #$01
BCC +
JMP notJumpOnMonsterDeath
+
DeactivateCurrentObject
PlaySound #SND_SPLAT
PlaySound #SND_SPLAT

LDY tempy
;; INCREASE SCORE
AddValue #$08, myScore, #$01, #$00
UpdateHud HUD_myScore
CountObjects #%00001000, #$00
LDA monsterCounter
CLC
BEQ +
JMP ++
+
.include SCR_KILLED_LAST_MONSTER
++
JMP playerWasHurtDuringCollision ;; just skips collision

dontJumpOnMonster:
notJumpOnMonsterDeath:
;;---- Jump On Kills code end ----

LDA Object_vulnerability,x
AND #%01000000 ;; is he lethal invincible?
BNE isLethalInvincible
JMP notLethalInvincible
isLethalInvincible:
LDX tempx
LDA Object_x_hi,x
STA temp
LDA Object_y_hi,x
STA temp1
CreateObject temp, temp1, #OBJ_MONSTER_DEATH, #$00, currentNametable ;; create "splat"
LDX tempx

;;; ordinarily we'll want to destroy the instance.
DeactivateCurrentObject
;; incrase score, you killed a monster
PlaySound #SND_SPLAT
TXA
STA tempx
AddValue #$08, myScore, #$01, #$00

;;; we also need to set up the routine to update the HUD
;; for this to work right, health must be a "blank-then-draw" type element.
;STA hudElementTilesToLoad
; LDA #$00
; STA hudElementTilesMax
; LDA DrawHudBytes
; ora #HUD_myScore
; STA DrawHudBytes
UpdateHud HUD_myScore
LDX tempx
;;

JMP skipThisOtherObject

notLethalInvincible:

;;;;;;;;;;;;;;;;;
;;;;;;;;; WHAT HAPPENS WHEN PLAYER IS HURT
.include SCR_PLAYER_HURT_SCRIPT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


playerWasHurtDuringCollision:
LDX tempx
JMP skipThisOtherObject
otherIsNotAMonsterTypeCollision:
;LDA ObjectFlags,y
LDA Object_flags,x
AND #%00100000 ;; is it a 'collectable'?
BEQ otherIsNotAcollectable
;;;; IS A pickup / power up
DeactivateCurrentObject ;; makes the other object go away
;; since other object is loaded in X

;;=========== WHAT DO YOU WANT TO HAVE HAPPEN WHEN YOU COLLECT THIS ITEM?

JSR HandlePickupPowerup


otherIsNotAcollectable:
noPlayerObjectCollision:
skipThisOtherObject:
INX
CPX #TOTAL_MAX_OBJECTS
BEQ doneLoopThroughOtherObjects_player
JMP LoopThroughOtherObjects_player
doneLoopThroughOtherObjects_player:
;; end of player collision
LDX tempx ;; restore x
JMP doneWithThisObjectCollision



notPlayerType_forObjectCollision:
;; is of player weapon type.
JSR GetSelfCollisionBox
;; now we have the collision box for self object
;; next we loop through objects.
LDX #$00
LoopThroughOtherObjects_weapon:

CPX tempx
BNE dontskipThisOtherObject_weapon
JMP skipThisOtherObject_weapon
dontskipThisOtherObject_weapon
JSR GetOtherCollisionBox
;; now we can do all the compares
LDA selfNT_R
CMP otherNT_L
BCC + ;; no player object collision
BNE ++ ;; is still possible to see collision.
LDA selfRight
CMP otherLeft
BCC + ;; no player object collision
++ ;; it is still possible there is a collision here.
LDA otherNT_R
CMP selfNT_L
BCC +
BNE +++
LDA otherRight
CMP selfLeft
BCC +

+++ ;; there was a collision here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA otherBottom
CMP selfTop
BCC +
LDA selfBottom
CMP otherTop
BCC +

JMP doWeaponObjectCollision

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; there is no collision here horizontally.
JMP noWeaponObjectCollision
doWeaponObjectCollision:
;; go through the different types of collision possible.
;; first, check monster OR monser projectile, as that should lead to hurt/death
;LDY Object_type,x
;LDA ObjectFlags,y
LDA Object_flags,x
AND #%00001000 ;; is it a monster type?
;;; if you'd like the player weapon to ALSO destroy projectiles
;;; use #%00011000 here
BNE otherIsMonsterTypeCollision_weapon
JMP otherIsNotAMonsterTypeCollision_weapon
otherIsMonsterTypeCollision_weapon:
;;;;;;;;;;;;;;;;;;;;;;;;
TXA
PHA
.include SCR_HANDLE_HURT_MONSTER
PLA
TAX
;;; if monster dies, count monsters
;; right now, he always dies, so count the monsters.
JSR countAllMonsters



otherIsNotAMonsterTypeCollision_weapon:

noWeaponObjectCollision:
skipThisOtherObject_weapon:
INX
CPX #TOTAL_MAX_OBJECTS
BEQ doneWithLoopingThroughWeaponObjects
JMP LoopThroughOtherObjects_weapon
doneWithLoopingThroughWeaponObjects:



;; end of player collision
LDX tempx ;; restore x
JMP doneWithThisObjectCollision




doneWithThisObjectCollision:
LDX tempx
INX
CPX #TOTAL_MAX_OBJECTS
BEQ doneWithAllObjects
JMP CollisionOuterLoop
doneWithAllObjects:
;;;;;;;;;;;;;;;;;;;;;;;;;
;; for this module
;; we will check for the melee position.
;; but rather than waste space with an entire object
;; we'll just test it against a single point
.include SCR_CHECK_SPRITE_WEAPON

RTS






GetSelfCollisionBox:
LDA Object_x_hi,x
CLC
ADC Object_left,x
STA selfLeft
LDA Object_scroll,x
ADC #$00
STA selfNT_L

LDA Object_x_hi,x
CLC
ADC Object_right,x
STA selfRight
LDA Object_scroll,x
ADC #$00
STA selfNT_R

LDA Object_vulnerability,x
AND #%10000000
BEQ noDuckingBit
LDA Object_bottom
SEC
SBC Object_top
STA temp
LDA Object_y_hi,x
CLC
ADC temp
JMP gotSelfTop
noDuckingBit:
LDA Object_y_hi,x
CLC
ADC Object_top,x
gotSelfTop:
STA selfTop
LDA Object_y_hi,x
CLC
ADC Object_bottom,x
STA selfBottom
LDA Object_x_hi,x
CLC
ADC Object_origin_x,x
STA selfCenterX
LDA Object_y_hi,x
CLC
ADC Object_origin_y,x
STA selfCenterY


RTS

GetOtherCollisionBox:
LDA Object_x_hi,x
CLC
ADC Object_left,x
STA otherLeft
LDA Object_scroll,x
ADC #$00
STA otherNT_L

LDA Object_x_hi,x
CLC
ADC Object_right,x
STA otherRight
LDA Object_scroll,x
ADC #$00
STA otherNT_R

LDA Object_vulnerability,x
AND #%10000000
BEQ noDuckingBit_other
LDA Object_bottom
SEC
SBC Object_top
STA temp
LDA Object_y_hi,x
CLC
ADC temp
JMP gotSelfTop_other
noDuckingBit_other:
LDA Object_y_hi,x
CLC
ADC Object_top,x
gotSelfTop_other:

STA otherTop
LDA Object_y_hi,x
CLC
ADC Object_bottom,x
STA otherBottom
LDA Object_x_hi,x
CLC
ADC Object_origin_x,x
STA otherCenterX
LDA Object_y_hi,x
CLC
ADC Object_origin_y,x
STA otherCenterY


RTS







DetermineRecoilDirection:

;;;RECOIL
;;First check for the abs x value
LDA recoil_selfX
SEC
SBC recoil_otherX
BCS absCheckDone
EOR #$FF
CLC
ADC #$01
absCheckDone:
STA temp
LDA recoil_selfY
SEC
SBC recoil_otherY
BCS absCheckDone2
EOR #$FF
CLC
ADC #$01
absCheckDone2:
CMP temp
BCS vCol
LDA recoil_selfX
CMP recoil_otherX
BCS recoilRight
;; recoil left
;LDX #$01
LDA #RECOIL_SPEED_LO
STA Object_h_speed_lo,x
LDA #$00
SEC
SBC #RECOIL_SPEED_HI
STA Object_h_speed_hi,x
LDA #$00
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
LDA #%10000000
STA temp1
LDA Object_movement,x
AND #%00000111
ORA temp1
STA Object_movement,x
CPX player1_object
BNE dontChangeScrollDirectionL
LDA #$00
STA scrollDirection
dontChangeScrollDirectionL
RTS

recoilRight:
;LDX #$01
LDA #RECOIL_SPEED_LO
STA Object_h_speed_lo,x
LDA #RECOIL_SPEED_HI
STA Object_h_speed_hi,x
LDA #$00
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
LDA #%11000000
STA temp1
LDA Object_movement,x
AND #%00000111
ORA temp1
STA Object_movement,x
CPX player1_object
BNE dontChangeScrollDirectionR
LDA #$01
STA scrollDirection
dontChangeScrollDirectionR:
RTS

vCol:
LDA recoil_selfY
CMP recoil_otherY
BCS recoilDown
;LDX #$01
LDA #RECOIL_SPEED_LO
STA Object_v_speed_lo,x
LDA #$00
SEC
SBC #RECOIL_SPEED_HI
STA Object_v_speed_hi,x
LDA #%00100000
STA temp1
LDA #$00
STA Object_h_speed_hi,x
STA Object_h_speed_lo,x
LDA Object_movement,x
AND #%00000111
ORA temp1
STA Object_movement,x

RTS

recoilDown:
;LDX #$01
LDA #RECOIL_SPEED_LO
STA Object_v_speed_lo,x
LDA #RECOIL_SPEED_HI
STA Object_v_speed_hi,x
LDA #%00110000
STA temp1
LDA #$00
STA Object_h_speed_hi,x
STA Object_h_speed_lo,x
LDA Object_movement,x
AND #%00000111
ORA temp1
STA Object_movement,x

RTS
 

dale_coop

Moderator
Staff member
Try replacing your Handle MonsterHurt.asm script with that one:

Code:
;;; what should we do with the monster?
        ;;; monster is loaded in x
        LDA Object_vulnerability,x
        AND #%00000100 ;; is it weapon immune?
        BEQ notWeaponImmune
        ;PlaySound #SFX_MISS
        JMP skipHurtingMonsterAndSound
    notWeaponImmune:
        
        LDA Object_status,x
        AND #HURT_STATUS_MASK
        BEQ dontskipHurtingMonster
        JMP skipHurtingMonster
    dontskipHurtingMonster:
        LDA Object_status,x
        ORA #%00000001
        STA Object_status,x
        LDA #HURT_TIMER
        STA Object_timer_0,x
        ;;; assume idle is in step 0
        ChangeObjectState #$00,#$02
        ;;;; unfortunately this recoil is backwards
        LDA Object_status,x
        AND #%00000100
        BNE skipRecoilBecauseOnEdge
        LDA Object_vulnerability,x
        AND #%00001000 
        BNE skipRecoilBecauseOnEdge ;; skip recoil because bit is flipped to ignore recoil
        
        LDA selfCenterX
        STA recoil_otherX
        LDA selfCenterY
        STA recoil_otherY
        LDA otherCenterX
        STA recoil_selfX
        LDA otherCenterY
        STA recoil_selfY
        JSR DetermineRecoilDirection
    skipRecoilBecauseOnEdge:
        LDA Object_health,x
        SEC
        SBC #$01
        CMP #$01
        BCC +
		JMP notMonsterDeath
	+

        DeactivateCurrentObject
        PlaySound #SND_SPLAT
        ;;;;;;;;;;;;;;;;;; ok, so now we also add points to score
        ;LDY Object_type,x
        ;LDA ObjectWorth,y
        ;STA temp
;       AddValue #$03, GLOBAL_Player1_Score, temp
                ;arg0 = how many places this value has.
                ;arg1 = home variable
                ;arg2 = amount to add ... places?
        ;; and this should trip the update hud flag?
        
        ;;;; 
    

	TXA
	STA tempy

	AddValue #$08, myScore, #$01, #$00

	;STA hudElementTilesToLoad
	;	LDA #$00
	;	STA hudElementTilesMax
		; LDA DrawHudBytes
		; ora #HUD_myScore
		; STA DrawHudBytes
	UpdateHud HUD_myScore
	LDX tempy

        JSR HandleDrops
        JSR HandleToggleScrolling
		
		CountObjects #%00001000, #$00
		LDA monsterCounter
		CLC	;;dale_coop
		BEQ +
		JMP ++
	+
		.include SCR_KILLED_LAST_MONSTER
	++
        
        JMP skipHurtingMonster
    notMonsterDeath
        STA Object_health,x
    skipHurtingMonster: 
        ;PlaySound #SFX_MONSTER_HURT
    
    skipHurtingMonsterAndSound:
        LDX tempx
        ;; what should we do with the projectile?
        DeactivateCurrentObject



A quick note, when you share code/script on the forum, use the </ code > tag, in the "full editor & preview".
 

salgue79

New member
The same comes out. When the enemy has 3 health touches left, he discounts it from the player's health counter.
 

dale_coop

Moderator
Staff member
Ok...
Could you now try with that Handle Object Collision, script:

Code:
;; LOAD OBJECT 00
;; OUTER LOOP
;; CHECK IF ACTIVE, IF NOT, SKIP OBJECT
;; LOAD self-collision-box
;; START OBJECT COLLISION LOOP
	;; LDA ONE MORE THAN CURRENT OBJECT
	;; CHECK IF ACTIVE.  IF NOT, SKIP THIS other
	;; IF IT IS ACTIVE, then we have to play them against each other.
		;; IS self object hurt by monsters?  If so, and other object is a monster, respond.
		;; IS self object hurt by weapons?  If so, and other object is a weapon, respond.
		;; at this point, we can still gauge whether or not it's affected by player, like with powerups.
		;; ADD one to the object being checked, loop through other objects.
;; increase object, return to outer loop.  Repeat thorugh all self objects.

;; ObjectFlags:
;; 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0
;  |   |   |   |   |   |   |   + -- PERSISTENT (especially good for player!)
;  |   |   |   |   |   |   +------- player type
;  |   |   |   |   |   + ---------- player weapon/projectile type
;  |   |   |   |   +--------------- monster type
;  |   |   |   +------------------- monster weapon/projectile type
;  |   |   +----------------------- pickup / power up
;  |   + -------------------------- target type 
;  +------------------------------- NPC type

;; player type checks monster, mosnter weapon, and pickup.
;; player weapon checks monster and target.
;; nothing else needs checking, as it would all be handled by those two steps.
;; so if it's a monster, do nothing.  if it's a monster projectile, do nothing. 
;; if it's a pickup, or a target, or it ignores all collisions, do nothing.
;; only if it's #%00000110, do something.



HandleObjectCollisions:

	LDA update_screen
	BEQ notChangingScreens
	rts
notChangingScreens:
	
	LDA npc_collision
	AND #%11111110
	STA npc_collision

	;LDA currentBank
	;STA prevBank
	;LDY #BANK_ANIMS
	;JSR bankswitchY
	
	LDX #$00
CollisionOuterLoop:
	TXA
	STA tempx
	LDA Object_status,x
	AND #%10000000
	BNE continueObjectCollisions_objectIsActive
	JMP doneWithThisObjectCollision
continueObjectCollisions_objectIsActive:
	LDA Object_status,x
	AND #%00000100 ;; is ot off screen
	BEQ continueObjectCollisions_objectIsOnScreen
	JMP doneWithThisObjectCollision
continueObjectCollisions_objectIsOnScreen
	LDA Object_status,x
	AND #%00000011
	BEQ continueObjectCollisions_objectIsNotHurtOrInvincible
	JMP doneWithThisObjectCollision
continueObjectCollisions_objectIsNotHurtOrInvincible
	;LDY Object_type,x
	;LDA ObjectFlags,y
	LDA Object_flags,x
	AND #%00000110
	BNE continueObjectCollisions_onlyPlayerTypesCheck
	JMP doneWithThisObjectCollision
continueObjectCollisions_onlyPlayerTypesCheck:
	;; this is either a player or player projectile type of object.
	;; all other types will be taken care of by iterating through these two types.
	;; first, check if it's player type.
	;LdA ObjectFlags,y
	LDA Object_flags,x
	AND #%00000010
	BNE isPlayerTypeForCollision
	JMP notPlayerType_forObjectCollision
isPlayerTypeForCollision:
	LDA player1_object
	STA colX
	;; is player type for object collision
	;; player's index is loaded into tempx
	JSR GetSelfCollisionBox
	;; now we have the collision box for self object
	;; next we loop through objects.
	
	LDX #$00
LoopThroughOtherObjects_player:
	CPX tempx
	BNE dontSkipThisOtherObject
	JMP skipThisOtherObject ;; other object IS the player, the one doing the counting..
dontSkipThisOtherObject:
	LDA Object_status,x
	AND #%00000100
	BEQ dontSkipThisOtherObject_becauseOnScreen
	JMP skipThisOtherObject ;; because it was off screen.
dontSkipThisOtherObject_becauseOnScreen:

	JSR GetOtherCollisionBox
	

	;; now we can do all the compares
	LDA selfNT_R
	CMP otherNT_L
	BCC + ;; no player object collision
	BNE ++ ;; is still possible to see collision.
	LDA selfRight
	CMP otherLeft
	BCC + ;; no player object collision
++ ;; it is still possible there is a collision here.
	LDA otherNT_R
	CMP selfNT_L
	BCC +
	BNE +++
	LDA otherRight
	CMP selfLeft
	BCC +
	
+++ ;; there was a collision here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDA otherBottom
	CMP selfTop
	BCC +
	LDA selfBottom
	CMP otherTop
	BCC +

	JMP DoPlayerObjectCollision

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
+ ;; there is no collision here horizontally.
	JMP noPlayerObjectCollision

DoPlayerObjectCollision:


	
	LDA Object_flags,x
	AND #%10000000 ;; is it an NPC
	BNE isAnNPC
	;; is not an NPC
	JMP isNotAnNPCcollision
isAnNPC:
	;;;; do npc stuff.
	LDA npc_collision
	ORA #%00000001
	STA npc_collision
	;;;; enables a button to be used to activate a textbox.
	LDA Object_ID,x
	STA textVar
	;LDA gameHandler
	;ORA #%00100000
	;STA gameHandler

	JMP skipThisOtherObject
	
isNotAnNPCcollision:	
	LDA Object_flags,x
	;LDA ObjectFlags,y
	AND #%00011000 ;; is it a monster type?
	BNE otherIsAMonsterTypeCollision
	JMP otherIsNotAMonsterTypeCollision
otherIsAMonsterTypeCollision:
	LDA Object_status,x
	AND #HURT_STATUS_MASK ;; if the monster is hurt, it can't hurt us
	BEQ yesPlayerObjectCollision
	JMP noPlayerObjectCollision
yesPlayerObjectCollision:
	
	LDA Object_vulnerability,x
	AND #%00000010 ;; in this module, this is ignore player collision
	BEQ doPlayerHurt
	JMP	noPlayerObjectCollision
doPlayerHurt:
	;;;observe health
	TXA
	STA tempx ;; object is in tempx.
	LDX player1_object
	LDA Object_status,x
	AND #HURT_STATUS_MASK
	BEQ playerWasNotHurtDuringCollision
	JMP playerWasHurtDuringCollision
playerWasNotHurtDuringCollision:
;;---- Jump On Kills code begin ----
	TYA
	STA tempy
	LDX tempx
	LDA Object_vulnerability,x
	AND #%00010000
	BNE jumpOnMonster
	LDX player1_object
	JMP dontJumpOnMonster
jumpOnMonster:
	LDX player1_object
	LDA selfBottom
	CMP otherCenterY
	BCC +
	JMP dontJumpOnMonster
	+
	;;; JUMP ON MONSTER
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDA #$00
	SEC
	SBC #$04
	STA Object_v_speed_hi,x
	
	LDX tempx

        LDA Object_status,x
        AND #HURT_STATUS_MASK
        BEQ dontskipHurtingMonsterJumpOnMonster
        JMP skipHurtingMonsterJumpOnMonster
    dontskipHurtingMonsterJumpOnMonster:
        LDA Object_status,x
        ORA #%00000001
        STA Object_status,x
        LDA #HURT_TIMER
        STA Object_timer_0,x
        ;;; assume idle is in step 0
        ChangeObjectState #$00,#$02
        ;;;; unfortunately this recoil is backwards
        LDA Object_status,x
        AND #%00000100
        BNE skipRecoilBecauseOnEdgeJumpOnMonster
        LDA Object_vulnerability,x
        AND #%00001000 
        BNE skipRecoilBecauseOnEdgeJumpOnMonster ;; skip recoil because bit is flipped to ignore recoil
        
        LDA selfCenterX
        STA recoil_otherX
        LDA selfCenterY
        STA recoil_otherY
        LDA otherCenterX
        STA recoil_selfX
        LDA otherCenterY
        STA recoil_selfY
        JSR DetermineRecoilDirection
    skipRecoilBecauseOnEdgeJumpOnMonster:
        LDA Object_health,x
        SEC
        SBC #$01
        CMP #$01
        BCC +
		JMP notMonsterDeathJumpOnMonster
	+

		LDA Object_x_hi,x
		STA temp
		LDA Object_y_hi,x
		STA temp1
		LDA Object_scroll,x
		STA temp2

        DeactivateCurrentObject
        PlaySound #SND_SPLAT
    
		STX tempy	;;dale_coop
		AddValue #$08, myScore, #$01, #$00
		UpdateHud HUD_myScore
		LDX tempy	;;dale_coop

        JSR HandleDrops
        JSR HandleToggleScrolling
		
		CountObjects #%00001000, #$00
		LDA monsterCounter
		CLC	;;dale_coop
		BEQ +
		JMP ++
	+
		.include SCR_KILLED_LAST_MONSTER
	++
        JMP skipHurtingMonsterJumpOnMonster
    notMonsterDeathJumpOnMonster:
        STA Object_health,x
    skipHurtingMonsterJumpOnMonster: 	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	JMP playerWasHurtDuringCollision
dontJumpOnMonster:
;;---- Jump On Kills code end ----

	
	LDA Object_vulnerability,x
	AND #%01000000 ;; is he lethal invincible?
	BNE isLethalInvincible
	JMP notLethalInvincible
isLethalInvincible:
	LDX tempx
	LDA Object_x_hi,x
	STA temp
	LDA Object_y_hi,x
	STA temp1
	CreateObject temp, temp1, #OBJ_MONSTER_DEATH, #$00, currentNametable ;; create "splat"
	LDX tempx
	
	;;; ordinarily we'll want to destroy the instance.
	 DeactivateCurrentObject
	;; incrase score, you killed a monster
	PlaySound #SND_SPLAT
	TXA
	STA tempx
	AddValue #$08, myScore, #$01, #$00

	;;; we also need to set up the routine to update the HUD
	;; for this to work right, health must be a "blank-then-draw" type element.
	;STA hudElementTilesToLoad
	;	LDA #$00
	;	STA hudElementTilesMax
		; LDA DrawHudBytes
		; ora #HUD_myScore
		; STA DrawHudBytes
	UpdateHud HUD_myScore
	LDX tempx
	;;
	
	JMP skipThisOtherObject
	
notLethalInvincible:
	
	;;;;;;;;;;;;;;;;;
	;;;;;;;;; WHAT HAPPENS WHEN PLAYER IS HURT
	.include SCR_PLAYER_HURT_SCRIPT
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	
playerWasHurtDuringCollision:	
	LDX tempx
	JMP skipThisOtherObject
otherIsNotAMonsterTypeCollision:
	;LDA ObjectFlags,y
	LDA Object_flags,x
	AND #%00100000 ;; is it a 'collectable'?
	BEQ otherIsNotAcollectable
	;;;; IS A pickup / power up
	DeactivateCurrentObject ;; makes the other object go away
							;; since other object is loaded in X
							
;;=========== WHAT DO YOU WANT TO HAVE HAPPEN WHEN YOU COLLECT THIS ITEM?

	JSR HandlePickupPowerup

	
otherIsNotAcollectable:
noPlayerObjectCollision:	
skipThisOtherObject:
	INX
	CPX #TOTAL_MAX_OBJECTS
	BEQ doneLoopThroughOtherObjects_player
	JMP LoopThroughOtherObjects_player
doneLoopThroughOtherObjects_player:
	;; end of player collision
	LDX tempx ;; restore x
	JMP doneWithThisObjectCollision
	
	
	
notPlayerType_forObjectCollision:
	;; is of player weapon type.
	JSR GetSelfCollisionBox
	;; now we have the collision box for self object
	;; next we loop through objects.
	LDX #$00
LoopThroughOtherObjects_weapon:

	CPX tempx
	BNE dontskipThisOtherObject_weapon
	JMP skipThisOtherObject_weapon
dontskipThisOtherObject_weapon
	JSR GetOtherCollisionBox
	;; now we can do all the compares
	LDA selfNT_R
	CMP otherNT_L
	BCC + ;; no player object collision
	BNE ++ ;; is still possible to see collision.
	LDA selfRight
	CMP otherLeft
	BCC + ;; no player object collision
++ ;; it is still possible there is a collision here.
	LDA otherNT_R
	CMP selfNT_L
	BCC +
	BNE +++
	LDA otherRight
	CMP selfLeft
	BCC +
	
+++ ;; there was a collision here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDA otherBottom
	CMP selfTop
	BCC +
	LDA selfBottom
	CMP otherTop
	BCC +

	JMP doWeaponObjectCollision

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
+ ;; there is no collision here horizontally.
	JMP noWeaponObjectCollision
doWeaponObjectCollision:
	;; go through the different types of collision possible.
	;; first, check monster OR monser projectile, as that should lead to hurt/death
	;LDY Object_type,x
	;LDA ObjectFlags,y
	LDA Object_flags,x
	AND #%00001000 ;; is it a monster type?
	;;; if you'd like the player weapon to ALSO destroy projectiles
	;;; use #%00011000 here
	BNE otherIsMonsterTypeCollision_weapon
	JMP otherIsNotAMonsterTypeCollision_weapon
otherIsMonsterTypeCollision_weapon:
;;;;;;;;;;;;;;;;;;;;;;;;
	TXA
	PHA
	.include SCR_HANDLE_HURT_MONSTER
	PLA
	TAX
	;;; if monster dies, count monsters
	;; right now, he always dies, so count the monsters.
	JSR countAllMonsters	
	

	
otherIsNotAMonsterTypeCollision_weapon:
	
noWeaponObjectCollision:	
skipThisOtherObject_weapon:
	INX
	CPX #TOTAL_MAX_OBJECTS
	BEQ doneWithLoopingThroughWeaponObjects
	JMP LoopThroughOtherObjects_weapon
doneWithLoopingThroughWeaponObjects:
	
	
	
	;; end of player collision
	LDX tempx ;; restore x
	JMP doneWithThisObjectCollision
	
	
	
	
doneWithThisObjectCollision:
	LDX tempx
	INX
	CPX #TOTAL_MAX_OBJECTS
	BEQ doneWithAllObjects
	JMP CollisionOuterLoop
doneWithAllObjects:
	;;;;;;;;;;;;;;;;;;;;;;;;;
	;; for this module
	;; we will check for the melee position.
	;; but rather than waste space with an entire object
	;; we'll just test it against a single point
	.include SCR_CHECK_SPRITE_WEAPON

	RTS
	
	
	
	
	
	
GetSelfCollisionBox:	
	LDA Object_x_hi,x
	CLC
	ADC Object_left,x
	STA selfLeft
	LDA Object_scroll,x
	ADC #$00
	STA selfNT_L
	
	LDA Object_x_hi,x
	CLC
	ADC Object_right,x
	STA selfRight
	LDA Object_scroll,x
	ADC #$00
	STA selfNT_R
	
	LDA Object_vulnerability,x
	AND #%10000000
	BEQ noDuckingBit
	LDA Object_bottom
	SEC 
	SBC Object_top
	STA temp
	LDA Object_y_hi,x
	CLC
	ADC temp
	JMP gotSelfTop
noDuckingBit:
	LDA Object_y_hi,x
	CLC
	ADC Object_top,x
gotSelfTop:
	STA selfTop
	LDA Object_y_hi,x
	CLC
	ADC Object_bottom,x
	STA selfBottom
	LDA Object_x_hi,x
	CLC
	ADC Object_origin_x,x
	STA selfCenterX
	LDA Object_y_hi,x
	CLC
	ADC Object_origin_y,x
	STA selfCenterY
	

	RTS
	
GetOtherCollisionBox:
	LDA Object_x_hi,x
	CLC
	ADC Object_left,x
	STA otherLeft
	LDA Object_scroll,x
	ADC #$00
	STA otherNT_L
	
	LDA Object_x_hi,x
	CLC
	ADC Object_right,x
	STA otherRight
	LDA Object_scroll,x
	ADC #$00
	STA otherNT_R
	
	LDA Object_vulnerability,x
	AND #%10000000
	BEQ noDuckingBit_other
	LDA Object_bottom
	SEC 
	SBC Object_top
	STA temp
	LDA Object_y_hi,x
	CLC
	ADC temp
	JMP gotSelfTop_other
noDuckingBit_other:
	LDA Object_y_hi,x
	CLC
	ADC Object_top,x
gotSelfTop_other:	
	
	STA otherTop
	LDA Object_y_hi,x
	CLC
	ADC Object_bottom,x
	STA otherBottom
	LDA Object_x_hi,x
	CLC
	ADC Object_origin_x,x
	STA otherCenterX
	LDA Object_y_hi,x
	CLC
	ADC Object_origin_y,x
	STA otherCenterY
	

	RTS
	
	
	
	
	
	
	
DetermineRecoilDirection:

	;;;RECOIL
	;;First check for the abs x value
	LDA recoil_selfX
	SEC
	SBC recoil_otherX
	BCS absCheckDone
	EOR #$FF
	CLC
	ADC #$01
absCheckDone:
	STA temp
	LDA recoil_selfY
	SEC
	SBC recoil_otherY
	BCS absCheckDone2
	EOR #$FF
	CLC
	ADC #$01
absCheckDone2:
	CMP temp
	BCS vCol
	LDA recoil_selfX
	CMP recoil_otherX
	BCS recoilRight
	;; recoil left
	;LDX #$01
	LDA #RECOIL_SPEED_LO
	STA Object_h_speed_lo,x
	LDA #$00
	SEC
	SBC	#RECOIL_SPEED_HI
	STA Object_h_speed_hi,x
	LDA #$00
	STA Object_v_speed_hi,x
	STA Object_v_speed_lo,x
	LDA #%10000000
	STA temp1
	LDA Object_movement,x
	AND #%00000111
	ORA temp1
	STA Object_movement,x
	CPX player1_object
	BNE dontChangeScrollDirectionL
	LDA #$00
	STA scrollDirection
dontChangeScrollDirectionL
	RTS
	
recoilRight:
	;LDX #$01
	LDA #RECOIL_SPEED_LO
	STA Object_h_speed_lo,x
	LDA	#RECOIL_SPEED_HI
	STA Object_h_speed_hi,x
	LDA #$00
	STA Object_v_speed_hi,x
	STA Object_v_speed_lo,x
	LDA #%11000000
	STA temp1
	LDA Object_movement,x
	AND #%00000111
	ORA temp1
	STA Object_movement,x
	CPX player1_object
	BNE dontChangeScrollDirectionR
	LDA #$01
	STA scrollDirection
dontChangeScrollDirectionR:
	RTS
	
vCol:
	LDA recoil_selfY
	CMP recoil_otherY
	BCS recoilDown
	;LDX #$01
	LDA #RECOIL_SPEED_LO
	STA Object_v_speed_lo,x
	LDA #$00
	SEC
	SBC	#RECOIL_SPEED_HI
	STA Object_v_speed_hi,x
	LDA #%00100000
	STA temp1
	LDA #$00
	STA Object_h_speed_hi,x
	STA Object_h_speed_lo,x
	LDA Object_movement,x
	AND #%00000111
	ORA temp1
	STA Object_movement,x

	RTS
	
recoilDown:
	;LDX #$01
	LDA #RECOIL_SPEED_LO
	STA Object_v_speed_lo,x
	LDA #RECOIL_SPEED_HI
	STA Object_v_speed_hi,x
	LDA #%00110000
	STA temp1
	LDA #$00
	STA Object_h_speed_hi,x
	STA Object_h_speed_lo,x
	LDA Object_movement,x
	AND #%00000111
	ORA temp1
	STA Object_movement,x
	
	RTS
 

salgue79

New member
YEEEEEEEEEEEEEEEES!!!!
Now if it goes !! What was wrong with him? Why didn't it work well before?
Thank you!! You are so big!!
 

dale_coop

Moderator
Staff member
Don't know, but your code (the jump on kills part) was not correct... So, I gave you my script ;)
 

salgue79

New member
Thank you very much for your help, friend !!
Now it's going great !! Now, I'm going to see if I can get an enemy to fire, so that the Bosses fire something. Another question I have ... is the size of the ROM, how much should it be? To be able to save it later in a physical cartridge, I mean.
 

dale_coop

Moderator
Staff member
The rom is always the same size (512Kb)
It's a special type of rom (Mapper30 - UNROM512), you can find NES cartriges that support that mapper at INL
http://www.infiniteneslives.com
(official NESmaker carts and also the flasher)
 

salgue79

New member
Okay. It is that when compiling, the ROM already occupies me. Or is it that when compiling it always gives the same size of ROM ?? I'm going to buy the Infinite NES Lives Flasher for testing. Where can I find a tutorial to shoot the enemy? Thanks in advance!!
 

dale_coop

Moderator
Staff member
512kb is the size of every mapper30 games (made with NESmaker or not)
Shoot at enemy, I am not sure there is a dedicated tutorial about that... take a look at that topic: http://nesmakers.com/viewtopic.php?f=60&t=2037&p=12208
 
Top Bottom