Wall Grab

Mugi

Member
so might aswell try and write a proper forum thread for this since i already shared it out on the thread i made earlier.

so here's a wall grab tile:

Code:
    CPX player1_object
    BNE dontMessWithGravity

    LDA gamepad
    AND #%00010000              ; is up pressed ?
    BEQ dontMessWithGravity
    
    LDA Object_v_speed_hi,x     ; are we falling downwards ?
    BMI dontMessWithGravity
    CLC
    ADC Object_y_hi,x           ; are we in map bounds ?
    CMP #$10
    BCC dontMessWithGravity
    CMP #$D6
    BCS dontMessWithGravity
    
    LDX player1_object          ; fetch facing direction of player 
    LDA Object_movement,x
    AND #%00001111
    CMP #%00000110
    BEQ doLeftCollisionCheck

    LDA collisionPoint1         ; compare top right collision point
    CMP #$03                    ; compare against "wallgrab tile"
    BNE dontMessWithGravity
    JMP doGrab
    
doLeftCollisionCheck:
    LDA collisionPoint0         ; compare top left collision point
    CMP #$03                    ; compare against "wallgrab tile"
    BNE dontMessWithGravity

doGrab:                         ; enable grabbing the wall
    ChangeObjectState #$07, #$03

dontMessWithGravity:

just save it as wallgrabtile.asm and assign it to an unused tiletype. (the script assumes that wall grab tiletype is 03, change in the tile code if necessary.)

This tile assumes that your wall grab action state is #$07
and requires action state 07 to have "ignore gravity" set

this tile requires modifications to be made to the players jump script, to bypass gravity based jumping, since gravity is turned off when you hang on the wall.
to do so, the following will have to be added and adapted to your jump script.

Code:
   GetCurrentActionType player1_object
   CMP #$07
   BEQ doWallClimbJumpThing
   JMP dontDoWallClimbJumpThing

doWallClimbJumpThing:
    ChangeObjectState #$02, #$03
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    RTS
dontDoWallClimbJumpThing:

in addition, extracontrollscript will need the following piece of code in order to disable L/R from the dpad during wall climb.

Code:
    LDX player1_object
    GetCurrentActionType player1_object
    STA temp
    CMP #$07
    BNE +
    LDA gamepad
    AND #%00111111
    STA gamepad
    RTS  
+
 

dale_coop

Moderator
Staff member
Thanks, Mugi, for that tutorial (I love this feature in your game).
Will be very useful for some of us!
 

rimoJO

Member
This didn't work for me... of course, i don't know asm at all, so i don't know what's wrong. the character just jumps through the wall. action step 7 is set to ignore gravity, tiletype is 3. jump script:
Code:
; a jumps
 
   LDX player1_object
   ;;; let's check for if we are standing on a jumpthrough platform,
   ;;; for which "down and jump" will jump downwards through
   ;;; comment this out if you do not want that functionality
    LDA screenFlags
    AND #%00100000 ;; does it use gravity?
    BEQ dontJump
    
   LDA Object_physics_byte,x
   AND #%00001000
   BEQ notStandingOnJumpThroughPlatform
   LDA gamepad
   AND #%00100000
   BEQ notStandingOnJumpThroughPlatform
   LDA Object_y_hi,x
   CLC
   ADC #$09
   STA Object_y_hi,x
   JMP dontJump
notStandingOnJumpThroughPlatform:
   
   LDA Object_physics_byte,x
   AND #%00000001
   BNE canJump
   LDA Object_physics_byte,x
   AND #%00000100
   BEQ dontJump
    
canJump:
    ;;; TURN OFF "STANDING ON JUMPTHROUGH PLATFORM" if it is on
    LDA Object_physics_byte,x
    AND #%11110111
    STA Object_physics_byte,x
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    GetCurrentActionType player1_object
    CMP #$03 ;; attack
    BEQ +
    ChangeObjectState #$02, #$04
   +
   PlaySound #sfx_shoot
dontJump:
    RTS 
    GetCurrentActionType player1_object
    CMP #$07
    BEQ doWallClimbJumpThing
    JMP dontDoWallClimbJumpThing

doWallClimbJumpThing:
    ChangeObjectState #$02, #$03
    LDA #$00
    SEC
    SBC #JUMP_SPEED_LO
    STA Object_v_speed_lo,x
    LDA #$00
    SEC
    SBC #JUMP_SPEED_HI
    STA Object_v_speed_hi,x
    RTS
dontDoWallClimbJumpThing:
 

Mugi

Member
you need to place the jump code to the beginning of your jumpscript.
the way you placed it now is after the last RTS on the file, meaning it will never run.

also, make sure you add the little code i posted to the extracontrollscript, the grab wont work without it (pressing/holding any button will just make you not grab or instantly fall off.)
 

Mugi

Member
it's an assembly file that's assigned to run after controller input assemblies, you should see it assigned to Extra Controll Script
on your game's script settings.
 

rimoJO

Member
Tiles are still walkable. there might be something wrong with the extra cs, maybe i could have put the extra code in the wrong place, idk. anyways, here's the ecs:
Code:
ExtraInputControl:
    LDX player1_object
    GetCurrentActionType player1_object
    STA temp
    CMP #$07
    BNE +
    LDA gamepad
    AND #%00111111
    STA gamepad
    RTS  
+   

    ;;; occasionally, there is input code that may be very specific, and it may be 
    ;;; difficult to implement via the visual interface and accompanying scripts.
    ;;; this is a code that runs after all input checks, and allows for custom ASM.
    LDA gameState
    CMP #GS_MainGame
    BEQ doMainGameUpdates
    JMP skipMainGameExtraInputControl
doMainGameUpdates:  
    LDX player1_object

	GetCurrentActionType player1_object
	STA temp
	LDA Object_physics_byte,x
	AND #%00000010
	BEQ isNotClimbing
    LDA temp
    CMP #$04
    BNE isNotClimbing
	LDA gamepad
	AND #%11000000
	BEQ noDirWhileClimbing
	ChangeObjectState #$02, #$04
noDirWhileClimbing:
    ;;; is climbing.
    ;;; which means don't check to change to idle.
   JMP skipMainGameExtraInputControl
isNotClimbing:
    LDA temp
    CMP #$03 ;; is it shooting (shooting is same anim in air and on ground)
    BNE isNotAttackingAction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    JMP skipMainGameExtraInputControl
isNotAttackingAction:   

    
    LDA gamepad
    AND #%11000000 ;;; left and right
    BEQ dontskipMainGameExtraInputControl
	JMP skipMainGameExtraInputControl
dontskipMainGameExtraInputControl:
    ;;; if left and right are not pressed
	
	LDA screenFlags
	AND #%00100000 ;; does it use gravity?
					;; if it does not, it would not have jumping or ducking, so
					;; skip state updates for jumping and ducking.
	BEQ notDucking ;; just will change to idle.

    LDA Object_physics_byte,x
    AND #%00000001 ;; if is in air
    BNE notInAir
    GetCurrentActionType player1_object
    CMP #$02 ;; is it already state 2?
    BEQ skipMainGameExtraInputControl

    ChangeObjectState #$02, #$04
    JMP skipMainGameExtraInputControl
notInAir:
    LDA Object_h_speed_lo,x
    ORA Object_h_speed_hi,x
    BNE skipMainGameExtraInputControl
    ;;;; controller is not pressed
    ;;;; horizontal speed is zero.
    ;; check to see if in air, shooting, etc.
	 LDA gamepad
	AND #%00100000 ; if down is pressed
	BEQ notDucking
	 ChangeObjectState #$5, #$04
	 JMP skipMainGameExtraInputControl
notDucking:
    LDA gamepad
	AND #%11110000
	BNE skipMainGameExtraInputControl
    ChangeObjectState #$00, #$04
skipMainGameExtraInputControl:  
    
    RTS
 

Jonny

Well-known member
Damn it. I wish I'd have seen this a while ago before I did my own, not as good, grab tile.

I'm going to see what I can learn from this and maybe re-hash my hook grab. I'll probably still need to add player pos. offset.
 

Levty87

New member
I can't seem to find the extracontrollscript in 4.5.9. Does the wallgrab-thing also work for this version?
 

dale_coop

Moderator
Staff member
The 4.5.9 is quite different than the previous version.
That guide won't work as it. You will have a lot of code to change/adapt.
 

Levty87

New member
Thanks dale for the explanation. I already messed around with this code and went nowhere. How than can I make the wallgrab work in 4.5.9?
 
Top Bottom