[4.5] Monster Shoot

offparkway

Active member
Following some of Joe's advice, I've made a monster action step to shoot a projectile. I copied the code for the player's projectile as a starting point, and that seems to work. But it shoots in whatever direction the monster is moving. How would I change the code to shoot toward the player?

here's the AI code:

Code:
;;; Create a Projectile.
;;; Assumes that the projectile you want to create is in GameObject Slot 09.

    TXA
    PHA
    TYA
    PHA
    ;;LDX player1_object

        LDA Object_screen,x
   
        STA tempD
        LDA Object_x_hi,x
            CLC
        ADC #$04
        STA tempA
        LDA Object_y_hi,x
        CLC
        ADC #$04
        STA tempB
        LDA Object_direction,x
        AND #%00000111
        STA tempC
        CreateObjectOnScreen tempA, tempB, #$09, #$09, tempD
            ;;; x, y, object, starting action.
            ;;; and now with that object, copy the player's
            ;;; direction and start it moving that way.
            LDA tempC
            STA Object_direction,x
            TAY
            LDA DirectionTableOrdered,y
            STA temp1
            TXA
            STA temp
            StartMoving temp, temp1
    PLA
    TAY
    PLA
    TAX
  
    RTS
 

mouse spirit

Well-known member
I forget what i did to fix this (in 4.1.5 atleast). Try to make the projectile a monster object, not a player object.
Also tick the monster projectile flag in the monsters properties.
 

offparkway

Active member
Monster projectile is ticked, but I’ll try making it a monster object and see if that affects anything. I wonder if the code is telling it to shoot wherever the monster is moving, and is overriding everything


Edit: tried making it a monster object, but no difference
 

mouse spirit

Well-known member
I had this issue and when i "shot" the projectile, it would ofcourse hurt me too!
So in 4.1.5, my monster projectile script has this.
Code:
CreateObject temp1, temp2, #OBJ_MONSTER_PROJECTILE2, #$00, temp

;arg0 x value
	;arg1 y value
	;arg2 object type
	;arg3 action step - great for creating a 'spawning' effect that is non-zero
						;; or even for creating projectiles that may behave differently, where
						;; a single projectile could have 8 action types that are different, and 
						;; could load that particular action step, which could show a unique animation
						;; with specialized behaviors?  Just a thought.
	; arg 4 - Object_scroll (nametable...current, left or right)


Maybe this can help at all like maybe point you in the right direction.
Like where you have your x and y's on your creatobject line, make sure somehow that it is the monsters coordinates stored in those temps,...possibly.
 

mouse spirit

Well-known member
Code:
 LDA Object_x_hi,x
            CLC
ADC #$04
        STA tempA
        LDA Object_y_hi,x
        CLC
        ADC #$04
        STA tempB


This is where it seems to be doing it.Im sorry but im the help that gets here before the real help arrives. :mrgreen:
I wish i was more able to specifically help here.
 

offparkway

Active member
Haha, no you’ve been super helpful and I really appreciate it. I feel bad that you spend all your time answering my issues and not working on your own project!

I’ll check that section of code out. I have no idea what some of it means (like CLC, ADC, “hi”)
 

mouse spirit

Well-known member
LDX player1_object

yeah can you change this or make it monster object?

And no problem, i hang out on here all the time and so many people helped and help me so i'm game for tryin to
help too.
 

mouse spirit

Well-known member
Because when its gettin the position for where the projectile to be, that line says that player is loaded into x.
x is used to get the coodinates and so is used to make the temps which are then used to create the object"projectile"
i.e. , at the player because we loaded it into x(LDX)
 

offparkway

Active member
The LDX I commented out, which allowed my monster to do the shooting. So don’t worry about that line. Joe was hinting that the “move toward player” action would allow the monster to shoot at the player, which is what I’m after (rather than shooting in random directions).

I also noticed that my projectile animation doesn’t animate (it’s a pulsing orb). Not a big deal, but just something I noticed and tried to fix with no luck.
 

mouse spirit

Well-known member
also check this page out to understand CLC LDA and so on a lil bit more.
http://www.6502.org/tutorials/6502opcodes.html
 

mouse spirit

Well-known member
Yes so the monster shoots where it is facing/moving, and if so then moving towards player, it will shoot that way.
 

mouse spirit

Well-known member
when something doesn't animate, first is to check the objects animation speed and to make it not 0. Next would be to check any script
that may be saying "start animation" or "create this object" over and over and over again.Making sure it never even hits frame 2 .
 

offparkway

Active member
It’s not set to zero, so I’ll jump into the scripts and see if somethings up there.

And yes, the shooter is shooting whichever way he’s facing/moving... so I gotta figure out how to get those projectiles headed toward the player. I appreciate all the input, as usual!
 

mouse spirit

Well-known member
Possibly put a move towards player a.i. on the projectile?
Another way may to to say is player x/y less or more than x/y of monster? If less, shoot left, if more, shoot right.
(or up or down too).
 

offparkway

Active member
According to Joe, it has to do with modding the physics script and getting the “aim at player” code to recognize speed and solid objects. Which I have no idea how to do, lol.

Currently my projectile moves toward the player but ignores all object detail properties (like speed, solid tiles, animations, etc).
 

mouse spirit

Well-known member
Maybe try looking at the physics script and copy and paste a bit.
I do know in some script it is sayin stuf like......
Is this a player ? Is this a monster? Colliding? Do stuff.
Is player projectile? Is monster? Colliding?
And so you must do some of that but while identifying
the fact that this is a monster projectile.
 

mouse spirit

Well-known member
Here is my handleobjectcollisions(DC) script from 4.1.5. Studying this may help.Its commented well.


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:
	
	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
	;;
	;; check for monter locks begin:
	CountObjects #%00001000, #$00
	LDA monsterCounter
	CLC
	BEQ +
	JMP ++
	+
		.include SCR_KILLED_LAST_MONSTER
	;; check for monter locks end.
	++	
	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	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;JMP doneWithThisObjectCollision  ;;DC

	
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,x
	SEC 
	SBC Object_top,x
	LSR
	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,x
	SEC 
	SBC Object_top
	LSR
	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


heres 4.1.5 physics if it helps at all also
Code:
CalculateAccAndSpeed:

    LDA update_screen
    BEQ doPhysics
    RTS
doPhysics:
    LDA gameHandler
    AND #%10000000
    BNE doPhysics2
    RTS
doPhysics2:
    CPX player1_object
    BNE noAutoScroll
   ; JSR handleAutoScroll
   ; JSR CheckAutoScrollLeftEdge
noAutoScroll:
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    LDA Object_vulnerability,x
    AND #%00000001
    BNE doAimedPhysics
    JMP doNormalPhysics
doAimedPhysics
    HandleAimedPhysics
    JMP donePhysicsUpdate
doNormalPhysics:

    LDA Object_x_hi,x
    STA xPrev
    LDA Object_y_hi,x
    STA yPrev
    LDY Object_type,x ;; now we can read necessary lut table values for this object.
    
    LDA tempMaxSpeed
    ASL
    ASL
    ASL
    STA temp2 ;; temp2 now equals max speed lo

    LDA tempMaxSpeed
    LSR
    LSR
    LSR
    LSR
    LSR
    STA temp3 ;; temp3 now equals max speed hi

    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    HandleHorizontalInertia
    ;;;;; What we have here is the new potential position.
    ;;;;; If we check this position for collision, we will move precisely outside of the collision, 
    ;;;;; so that the object bumps right up against the solid.
    ;;;;; The same technique could be used for objects tagged as solid (like NPCs), though then we'll
    ;;;;; have to come up with a way to trigger them.
    ;;;;; all of which will happen before the object is actually drawn.
    
    
;;;;;;;;;;;;;;;;;;;;;;;;;=======================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;=======================================================;;
    LDA Object_vulnerability,x
    AND #%00100000
    BNE noGravityPhysics ;; still handle inertia, even if the screen has gravity but this object does not.

    LDA screenFlags
    AND #%00100000
    BEQ noGravityPhysics
    JMP gravityPhysics
noGravityPhysics:

    HandleVerticalInertia
    ;;;;; What we have here is the new potential position.
    ;;;;; If we check this position for collision, we will move precisely outside of the collision, 
    ;;;;; so that the object bumps right up against the solid.
    ;;;;; The same technique could be used for objects tagged as solid (like NPCs), though then we'll
    ;;;;; have to come up with a way to trigger them.
    ;;;;; all of which will happen before the object is actually drawn.

    JMP donePhysicsUpdate
gravityPhysics:   

    
    HandleGravity

    
donePhysicsUpdate:



    RTS
    
    
    
    
    
    
DoLadderStuff:
    CPX player1_object
    BEQ dontSkipLadderStuff
    JMP skipLadderStuff
dontSkipLadderStuff:
    LDA Object_physics_byte,x ;; on ladder
    ORA #%00000010
    STA Object_physics_byte,x
    LDA gamepad
    AND #%00010000 ; if up is pressed
    BEQ notPressingUpOnLadder
    GetCurrentActionType player1_object
    CMP #$04 ;; action state of climbing ladder #OBJ_INDEX_LADDER ;; compare to ladder type
    BEQ dontChangeToLadderState ;; already is in ladder state
    ChangeObjectState #$04, #$04
dontChangeToLadderState:
    LDA Object_y_lo,x
    SEC
    SBC #LADDER_SPEED_LO 
    STA Object_y_lo,x
    LDA Object_y_hi,x
    SBC #LADDER_SPEED_HI
    STA Object_y_hi,x
    STA yHold_hi
    Cmp #BOUNDS_TOP
    BCS hasNotReachedTop
    
    LDA Object_scroll,x
    CMP xScroll_hi
    BEQ + ;; need to reverse
    ;; forward auto scroll
    LDA #%00000000
    JMP ++
+ ;; need to reverse
    LDA #%10000000
++
    ORA #$02
    STA align_screen_flag

    LDA #ALIGN_TIMER
    STA genericTimer
    LDA #$01
    STA prevent_scroll_flag
    ;JSR doTopBounds_player
hasNotReachedTop:
    
    
    JMP skipLadderStuff
notPressingUpOnLadder:
    LDA gamepad
    AND #%00100000 ; if down is pressed
    BEQ notPressingDownOnLadder

    GetCurrentActionType player1_object
    CMP #$04 ; #OBJ_INDEX_LADDER ;; compare to ladder type
    BEQ dontChangeToLadderState2 ;; already is in ladder state
    ChangeObjectState #$04, #$04
dontChangeToLadderState2:
    LDA Object_y_lo,x
    clc
    adc #LADDER_SPEED_LO 
    STA Object_y_lo,x
    LDA Object_y_hi,x
    adc #LADDER_SPEED_HI
    STA Object_y_hi,x
    CMP #BOUNDS_BOTTOM
    CLC
    ADC Object_bottom,x
    BCC skipLadderStuff
    LDA Object_scroll,x
    CMP xScroll_hi
    BEQ + ;; need to reverse
    ;; forward auto scroll
    LDA #%00000000
    JMP ++
+ ;; need to reverse
    LDA #%10000000
++
    ORA #$01
    STA align_screen_flag

    LDA #ALIGN_TIMER
    STA genericTimer
    LDA #$01
    STA prevent_scroll_flag
    
    JMP skipLadderStuff
notPressingDownOnLadder:
skipLadderStuff:
    RTS

I can only imagine this should be a common feature when 4.5 is offical
 

offparkway

Active member
You’re on 4.1? Looking through this, most of this is built into the interface of 4.5. I just check a box to make the item a monster weapon. So I’m all good there.

Nothings triggering any ideas yet, but I’ll keep thinking. The action that is built into 4.5 is called “move toward player”, and it ignores collisions and speed variables by default. So I have to figure out how to tell it to take speed and collisions into account, for this particular game. Setting the items speed and animation (in object details) has no effect... until I do something to the code to make it have an effect.

At least that’s what I took from Joe’s description. It would be hilarious if the update to 4.5 made it super easy.
 
Top Bottom