Rancor
New member
I know I said in that previous thread about castlevania jumping that I'd be a good boy and wait for 4.1 but I can't keep away from this program since I activated it.
I've been frankenstein-ing some code together from the threads here about melee in the platform module and I think I found a way to make the weapon stay with the character while in the air.
Basically, I created a new action of the attacking animation, but the second action takes gravity into account while the first does not.
I've been able to get it so at least while idle or while jumping straight up, my character will correctly use the attacking animation as intended.
I've been having some pretty serious issues in other areas though and I'm pretty sure it has to do with this specific code (I've commented out my changes made to jumping/player movement/stopping movement and the problems persist)
Namely, my character stops/staggers their horizontal movement in mid-air when attacking, and the weapon doesn't keep moving with the character horizontally (I end up running into the weapon on the ground or passing through it in air)
Anyway, here's the code for anyone who wants a headache:
shootWeapon.asm:
So, to summarize, I've found a way for the weapon to keep track of vertical movement, essentially by having it fall with the player, which likely creates a number of problems in other situations (as opposed to having it glued to the spot in some way or perhaps that parenting technique I've been hearing about)
I think this could be fixed and working if I understood enough of this code to make a function where the weapon also moves horizontally with the player (maybe if I give it speed+acceleration equal to the player, and link it with movement scripts somehow?)
The one thing I really don't understand though is the staggered horizontal movement in mid-air while attacking. I've tried commenting out various small bits of this trying to narrow down which function does that but I can't make sense of it quite yet.
EDIT: I should also mention I still have the issue of being able to spam the B button and create more instances of the weapon. Still no idea how I would go about fixing that.
EDIT(2): fixed some of my comments so they made a bit more sense
EDIT(3): The whole thing is narrated to the best of my ability now through the comments. Still plenty for me to learn but baby steps are still steps.
I've been frankenstein-ing some code together from the threads here about melee in the platform module and I think I found a way to make the weapon stay with the character while in the air.
Basically, I created a new action of the attacking animation, but the second action takes gravity into account while the first does not.
I've been able to get it so at least while idle or while jumping straight up, my character will correctly use the attacking animation as intended.
I've been having some pretty serious issues in other areas though and I'm pretty sure it has to do with this specific code (I've commented out my changes made to jumping/player movement/stopping movement and the problems persist)
Namely, my character stops/staggers their horizontal movement in mid-air when attacking, and the weapon doesn't keep moving with the character horizontally (I end up running into the weapon on the ground or passing through it in air)
Anyway, here's the code for anyone who wants a headache:
shootWeapon.asm:
Code:
LDA gameHandler ; Load argument "gamehandler" into Accumulator
AND #%00100000 ; Leave accumulator with bits in common with #$00100000 (No idea what this value is, maybe it's explained in 'gamehandler')
BEQ notNPCstate_attack ;; If the bits are in common, jump to label "notNPCstate_attack"
JMP doneAttacking ;; If the bits are not in common, jump to label "done Attacking"
notNPCstate_attack ; Label: "notNPCstate_attack"
LDA weaponsUnlocked ; Load argument "weaponsUnlocked" into Accumulator
AND #%00000001 ; leave accumulator with bits in common with #$00000001 (Again, no clue.)
BNE canAttack ;; If the value is false go to label "canAttack"
JMP doneAttacking ;; If the value is not false jump to label "doneAttacking"
canAttack: ; Label: "canAttack"
LDX player1_object ; Load player1_object into x
GetCurrentActionType player1_object ; Macro "GetCurrentActionType" on player1_object
CMP #$01 ;; if the Player is walking/running ; compare value #$01 to accumulator ("if the Player is walking/running")
CMP #$02 ;; if the Player is jumping ; compare value #$02 to accumulator ("if the Player is jumping")
BEQ isNowAttacking ;; keep it walking/running/jumping ;; If the stored result is true jump to label "isNowAttacking"
CMP #$04 ;; else if is already attacking... ; else compare value #$04 to accumulator ("if player is already attacking")
BNE notAlreadyAttacking ;; If the stored result is true jump to label "notAlreadyAttacking"
JMP doneAttacking ;; If neither stored result is true jump to label "doneAttacking"
notAlreadyAttacking ; Label: "notAlreadyAttacking"
;;; don't attack if already attacking }
;;; do we have to check for hurt here? }>(I have no idea what any of this means in conjunction. Is this a suggestion for the structure of a new function?)
;;;;; Here, we WOULD create melee }
LDA Object_movement,x ; ; Store value of Object_movement at offset x into Accumulator
CMP #$00 ;If player is moving, skip changing the animation ; Compare value #$00 to accumulator (checking if idle?)
BNE + ; ;; If the stored result is false jump to label "+"
LDX player1_object ; ;; If true, Load player1_object into X
ChangeObjectState #$04, #$02 ; ; then macro ChangeObjectState to 04 (attacking) with animation speed 02
+ ; Label: "+"
BEQ isNowAttacking ;; If the stored result is true jump to label "isNowAttacking"
LDA Object_movement,x ;This script seems to keep my weapon in place while I jump ; Store value Object_movement at offset x into Accumulator
AND #%00001111 ; Leave accumulator with bits in common with #$00001111 (some mix of directions?)
STA Object_movement,x ; Store object type Object_movement from object x into Accumulator
LDA #$00 ; Load literal value #$00 into Accumulator
STA Object_h_speed_hi,x ; Store accumulator value into object type Object_h_speed_hi at offset x
STA Object_h_speed_lo,x ; Store accumulator value into object type Object_h_speed_lo at offset x
STA Object_v_speed_hi,x ; Store accumulator value into object type Object_v_speed_hi at offset x
STA Object_v_speed_lo,x ; Store accumulator value into object type Object_v_speed_lo at offset x
; Still can't figure out how this works, need to look at the specific object types
isNowAttacking: ; Label: "isNowAttacking"
;; the script continues from here
; What follows is my franken-script using airborne checks from playerJump.asm
LDX player1_object ; If player1_object is in the air... ; Load player1_object into X
LDA Object_status,x ; Store value Object_status at offset x into Accumulator
AND #%00000100 ; Leave accumulator with bits in common with #$00000100
BEQ isAirborne ;; If the bits are in common, jump to label "isAirborne"
LDA Object_x_hi,x ; Store value of Object_x_hi at offset x into Accumulator
STA temp ; Store value "temp" into Accumulator
LDA Object_y_hi,x ; Store value of Object_y_hi at offset x into Accumulator
STA temp1 ; Store value "temp1" into Accumulator
LDA Object_x_hi,x ; Store value of Object_x_hi at offset x into Accumulator
STA temp ; Store value "temp into Accumulator
LDA Object_y_hi,x ; Store value of Object_y_hi at offset x into Accumulator
STA temp1 ; Store value "temp1" into accumulator
;;; Not sure why this is in here twice. Is it necessary?
LDA Object_movement,x ; Store value of Object_movement at offset x into Accumulator
AND #%00000111 ; Leave accumulator with bits in common with #$00000111 (I get the feeling that isn't "down left")
STA temp2 ; Store value "temp2" into Accumulator
LDA temp2 ; Load value "temp2" into accumulator
TAY ; Transfer value of Accumulator to Y
LDA temp ; Load value "temp" into accumulator
SEC ; Set Carry flag to 1
SBC #$10 ;; width of weapon ; Subtract value #$10 from accumulator (determines x offset of weapon relative to player)
CLC ; Clear the Carry bit
ADC weaponOffsetTableX,y ; Add value of weaponOffsetTableX at offset y into Accumulator
STA temp ; Store value of "temp" into accumulator
LDA temp1 ; Load value "temp1" into accumulator
SEC ; Set Carry flag to 1
SBC #$08 ;; height of weapon ; Subtract value #$08 from accumulator (determines y offset of weapon relative to player)
CLC ; Clear the Carry bit
ADC weaponOffsetTableY,y ; Add value of weaponOffsetTableY at offset y into Accumulator
STA temp1 ; Store value of "temp1" into Accumulator
CreateObject temp, temp1, #$01, #$02 ; ...create weapon with state 02... ; Macro CreateObject with coordinates temp, temp1 using object state 02 with animation speed 01 (???)
JMP meleeCreated ; Jump to label "meleeCreated"
isAirborne ; Label: "isAirborne"
LDA Object_x_hi,x ; Store value Object_x_hi at offset x into Accumulator
STA temp ; Store value "temp" into Accumulator
LDA Object_y_hi,x ; Store value Object_y_hi at offset x into Accumulator
STA temp1 ; Store value "temp1" into Accumulator
; [My assumption so far is that this makes it so value of Object_x_hi,x is given a temp name, correct?]
LDA Object_x_hi,x ; Store value Object_x_hi at offset x into Accumulator
STA temp ; Store value "temp" into Accumulator
LDA Object_y_hi,x ; Store value Object_y_hi at offset x into Accumulator
STA temp1 ; Store value "temp1" into Accumulator
LDA Object_movement,x ; Store value Object_movement at offset x into Accumulator
AND #%00000111 ; Leave Accumulator with bits in common with value #$00000111
STA temp2 ; Store value "temp2" into Accumulator (Leftovers from the AND are put into "temp2"? Unnecessary?)
LDA temp2 ; Load value temp2 into Accumulator
TAY ; Transfer value of Accumulator (i.e temp2) into Y
LDA temp ; Load value temp into Accumulator
SEC ; Set Carry flag to 1
SBC #$10 ;; width of weapon ; Subtract value #$10 from accumulator (determines x offset of weapon relative to player
CLC ; Clear the Carry bit
ADC weaponOffsetTableX,y ; Add value of weaponOffsetTableX at offset y into Accumulator
STA temp ; Store value of "temp" into accumulator
LDA temp1 ; Load value "temp1" into accumulator
SEC ; Set Carry flag to 1
SBC #$08 ;; height of weapon ; Subtract value #$08 from accumulator (determines y offset of weapon relative to player)
CLC ; Clear the Carry bit
ADC weaponOffsetTableY,y
STA temp1
CreateObject temp, temp1, #$01, #$04 ; ...else create weapon with state 04. ; Macro CreateObject with coordinates temp, temp1 using object state 04 with animation speed 01 (???)
meleeCreated:
;;;; x is now the newly created object's x.
LDA Object_movement,x ; Store value of Object_movement at offset x into Accumulator
ORA temp2 ; Leave accumulator with all true bits in temp2 and Accumulator
STA Object_movement,x ; Store value of Object_movement into Accumulator
;PlaySound #sfx_slash ; Macro to play sound "#sfx_slash"
doneAttacking: ; Label: "doneAttacking"
RTS ; Return to subroutine
;;000 down
;010 right
;100 up
;110 left
So, to summarize, I've found a way for the weapon to keep track of vertical movement, essentially by having it fall with the player, which likely creates a number of problems in other situations (as opposed to having it glued to the spot in some way or perhaps that parenting technique I've been hearing about)
I think this could be fixed and working if I understood enough of this code to make a function where the weapon also moves horizontally with the player (maybe if I give it speed+acceleration equal to the player, and link it with movement scripts somehow?)
The one thing I really don't understand though is the staggered horizontal movement in mid-air while attacking. I've tried commenting out various small bits of this trying to narrow down which function does that but I can't make sense of it quite yet.
EDIT: I should also mention I still have the issue of being able to spam the B button and create more instances of the weapon. Still no idea how I would go about fixing that.
EDIT(2): fixed some of my comments so they made a bit more sense
EDIT(3): The whole thing is narrated to the best of my ability now through the comments. Still plenty for me to learn but baby steps are still steps.