voltopt
Member
A lot of this is covered in the tutorials, but I saw some questions come up so I thought I'd share what I've done.
First, in the Adventure Module, I took the standard ChangeToAttack input script and rewrote it to allow the first selectable weapon to be a projectile. The default in the script is a melee attack (a sword), but the melee is the default weapon assigned to A button in my demo. My second selectable weapon is a boomerang. I love the boomerang, although it's a bit buggy!
The projectile weapon is playerobject 03, or #$03 (shell). The boomerang is playerobject 10, or #$0A (coral) You would change these to match whatever object you have used for your player weapon.
There is a variable myAmmo, which is a default uservariable, that counts down ammo. It also should be a variable in your HUD.
To get the game to do weapon specific stuff I added the following at about line 40, after the sword creation constants.
The code loads the selected weapon and checks it, and skips ahead if it isn't. If it is, say, weapon one, it will check ammo, which is a standard varcheck for projectiles w/ ammo. In this case, on the weapon 2 boomerang, it checks the myBoomerang variable to see if it is 0 or 1. If it is 0, it can be used, if it is 1, it skips. If it is used, it will save #$01 to myBoomerang so you can't fire more than one at a time. This is a little buggy, but works for the most part.
An issue here is that the weapon location constants are the same for each weapon. If you need to change these for different types of weapons, you could build a much more robust code, say for a whip, throwing axe, etc. Also the weapon states are consistent, so if you want something unique for an upward facing weapon, you would need to update this.
At the very end of ChangetoAttack is the WeaponObjectTable - update the arguments here in order to match your weapon objects, in order.
My full ChangeToAttack script, which is very specific to my game:
You also need to make sure you have SelectWeapon input script assigned to the select button in MainGame state.
To get the weapons, they are bestowed w/ text from an NPC, as described in the official Adventure Tutorial. I think this could also be bestowed as a power up the first time you collect it, but I haven't tested that yet (will relate to the pickup script)
As far as the boomerang goes, there are a few other things I had to, such as create an action state for the weapon that makes it constantly follow the player, edit the collision scripts to check for the returning boomerang, and add a little variable at screen load to make sure the boomerang is always reset on a new screen.
The only thing I really figured out here was the boomerang, but I thought I'd share the selectable weapon branching code to help people looking for a way to add more.
First, in the Adventure Module, I took the standard ChangeToAttack input script and rewrote it to allow the first selectable weapon to be a projectile. The default in the script is a melee attack (a sword), but the melee is the default weapon assigned to A button in my demo. My second selectable weapon is a boomerang. I love the boomerang, although it's a bit buggy!
The projectile weapon is playerobject 03, or #$03 (shell). The boomerang is playerobject 10, or #$0A (coral) You would change these to match whatever object you have used for your player weapon.
There is a variable myAmmo, which is a default uservariable, that counts down ammo. It also should be a variable in your HUD.
To get the game to do weapon specific stuff I added the following at about line 40, after the sword creation constants.
The code loads the selected weapon and checks it, and skips ahead if it isn't. If it is, say, weapon one, it will check ammo, which is a standard varcheck for projectiles w/ ammo. In this case, on the weapon 2 boomerang, it checks the myBoomerang variable to see if it is 0 or 1. If it is 0, it can be used, if it is 1, it skips. If it is used, it will save #$01 to myBoomerang so you can't fire more than one at a time. This is a little buggy, but works for the most part.
Code:
LDY weaponChoice
LDA weaponObjectTable,y ;;; load weapon choice
STA tempC ;;; CHANGE TO CHECK WEAPON
CMP #$03 ;;; CHECK WEAPON ONE OBJECT 03
BNE notWeaponOne ;;; if not got check next weapon
LDA myAmmo ;;; standard ammo stuff
BNE +canShootWeaponOne
JMP canNotUseWeapon
+canShootWeaponOne ;;; there is ammo here.
DEC myAmmo
UpdateHudElement #$03 ;;; change this to which element shows myAmmo.
JMP canUseWeapon ;;; jump to main change to attack script
notWeaponOne: ;;; next weapon
LDA tempC ;;; reload weapon choice, not sure if this necessary
CMP #$0A ;;; CHECK WEAPONTWO OBJECT 10
BNE notWeaponTwo ;;; if not go to next weapon
LDA myBoomerang ;;; this is a new variable set to 0
BEQ +canUseWeaponTwo ;;; if zero, means weapon has not been fired
JMP +canNotUseWeapon
+canUseWeaponTwo
LDA #$01
STA myBoomerang
JMP canUseWeapon
notWeaponTwo:
JMP canNotUseWeapon
;;;;WOULD ADD WEAPON THREE HERE, SAME BASIC PREMISE
canUseWeapon:
;;;;;;END MY CODE;;;;;
An issue here is that the weapon location constants are the same for each weapon. If you need to change these for different types of weapons, you could build a much more robust code, say for a whip, throwing axe, etc. Also the weapon states are consistent, so if you want something unique for an upward facing weapon, you would need to update this.
At the very end of ChangetoAttack is the WeaponObjectTable - update the arguments here in order to match your weapon objects, in order.
My full ChangeToAttack script, which is very specific to my game:
Code:
;; if you would like unlockable weapons,
;; that will be created with the b button
;; use this code.
LDA weaponsUnlocked
BNE +canCreateWeapon
LDY weaponChoice
LDA weaponChoiceTable,y
AND weaponsUnlocked
BNE +canCreateWeapon
RTS
+canCreateWeapon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;END UNLOCKABLE WEAPONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TXA
STA temp ;; assumes the object that we want is in x.
ChangeActionStep temp, #$02 ;; assumes that "attack" is in action 2
;arg0 = what object?
;arg1 = what behavior?
StopMoving temp, #$FF, #$00
;;; some constants for where to create the sword.
;;; Constants do not take up any memory.
WEAPON_POSITION_RIGHT_X = #$10
WEAPON_POSITION_RIGHT_Y = #$0A
WEAPON_POSITION_UP_X = #$00
WEAPON_POSITION_UP_Y = #$F0
WEAPON_POSITION_DOWN_X = #$00
WEAPON_POSITION_DOWN_Y = #$20
WEAPON_POSITION_LEFT_X = #$F0
WEAPON_POSITION_LEFT_Y = #$0A
WEAPON_OBJECT = #$06
WEAPON_RIGHT_STATE = #$00
WEAPON_LEFT_STATE = #$00
WEAPON_UP_STATE = #$00
WEAPON_DOWN_STATE = #$00
;;;;;; VOLTOPT - TO ASSIGN UNIQUE ATTRIBUTES TO SELECTED WEAPON ;;;;
LDY weaponChoice
LDA weaponObjectTable,y ;;; load weapon choice
STA tempC ;;; CHANGE TO CHECK WEAPON
CMP #$03 ;;; CHECK WEAPON ONE OBJECT 03
BNE notWeaponOne ;;; if not got check next weapon
LDA myAmmo ;;; standard ammo stuff
BNE +canShootWeaponOne
JMP canNotUseWeapon
+canShootWeaponOne ;;; there is ammo here.
DEC myAmmo
UpdateHudElement #$03 ;;; change this to which element shows myAmmo.
JMP canUseWeapon ;;; jump to main change to attack script
notWeaponOne: ;;; next weapon
LDA tempC ;;; reload weapon choice, not sure if this necessary
CMP #$0A ;;; CHECK WEAPONTWO OBJECT 10
BNE notWeaponTwo ;;; if not go to next weapon
LDA myBoomerang ;;; this is a new variable set to 0
BEQ +canUseWeaponTwo ;;; if zero, means weapon has not been fired
JMP +canNotUseWeapon
+canUseWeaponTwo
LDA #$01
STA myBoomerang
JMP canUseWeapon
notWeaponTwo:
JMP canNotUseWeapon
;;;;WOULD ADD WEAPON THREE HERE, SAME BASIC PREMISE
canUseWeapon:
;;;;;;END MY CODE;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Now, we have to create the object.
;; We will need to determine the direction
;; of the player.
LDX player1_object
TXA
STA temp
GetObjectDirection temp ;; temp still observed from above.
;;; this object's direction is now loaded into the
;;; accumulator for comparison after the macro.
;; 0 = down
;; 1 = downright
;; 2 = right
;; 3 = upright
;; 4 = up
;; 5 = upleft
;; 6 = left
;; 7 = downleft
BNE +notDown ;; jump if not equal to zero.
;;; CREATE DOWN WEAPON
;;; create an object for the weapon.
;;; create it at the down positions.
;;; create it with the down state
LDX player1_object
LDA Object_x_hi,x
CLC
ADC #WEAPON_POSITION_DOWN_X
STA tempA
LDA Object_y_hi,x
CLC
ADC #WEAPON_POSITION_DOWN_Y
STA tempB
LDY weaponChoice
LDA weaponObjectTable,y
STA tempC
;; use this is you want to always create a single object, based on
;; the constant above.
; CreateObject tempA, tempB, #WEAPON_OBJECT, #WEAPON_DOWN_STATE, currentNametable
;;; use this if you want to create a variable object based on
;;; the weaponChoice varaible.
CreateObject tempA, tempB, tempC, #WEAPON_DOWN_STATE, currentNametable
LDA #%00110000
STA Object_direction,x
JMP +doneWithCreatingWeapon
+notDown
CMP #$02
BNE +notRight
;;; CREATE RIGHT WEAPON
LDX player1_object
LDA Object_x_hi,x
CLC
ADC #WEAPON_POSITION_RIGHT_X
STA tempA
LDA Object_y_hi,x
CLC
ADC #WEAPON_POSITION_RIGHT_Y
STA tempB
LDY weaponChoice
LDA weaponObjectTable,y
STA tempC
;; use this is you want to always create a single object, based on
;; the constant above.
; CreateObject tempA, tempB, #WEAPON_OBJECT, #WEAPON_RIGHT_STATE, currentNametable
;;; use this if you want to create a variable object based on
;;; the weaponChoice varaible.
CreateObject tempA, tempB, tempC, #WEAPON_RIGHT_STATE, currentNametable
LDA #%11000000
STA Object_direction,x
JMP +doneWithCreatingWeapon
+notRight
CMP #$04
BNE +notUp
;;; CREATE UP WEAPON
LDX player1_object
LDA Object_x_hi,x
CLC
ADC #WEAPON_POSITION_UP_X
STA tempA
LDA Object_y_hi,x
CLC
ADC #WEAPON_POSITION_UP_Y
STA tempB
LDY weaponChoice
LDA weaponObjectTable,y
STA tempC
;; use this is you want to always create a single object, based on
;; the constant above.
; CreateObject tempA, tempB, #WEAPON_OBJECT, #WEAPON_DOWN_STATE, currentNametable
;;; use this if you want to create a variable object based on
;;; the weaponChoice varaible.
CreateObject tempA, tempB, tempC, #WEAPON_UP_STATE, currentNametable
LDA #%00100000
STA Object_direction,x
JMP +doneWithCreatingWeapon
+notUp
CMP #$06
BNE +notLeft
;;; CREATE LEFT WEAPON
LDX player1_object
LDA Object_x_hi,x
CLC
ADC #WEAPON_POSITION_LEFT_X
STA tempA
LDA Object_y_hi,x
CLC
ADC #WEAPON_POSITION_LEFT_Y
STA tempB
LDY weaponChoice
LDA weaponObjectTable,y
STA tempC
;; use this is you want to always create a single object, based on
;; the constant above.
; CreateObject tempA, tempB, #WEAPON_OBJECT, #WEAPON_DOWN_STATE, currentNametable
;;; use this if you want to create a variable object based on
;;; the weaponChoice varaible.
CreateObject tempA, tempB, tempC, #WEAPON_LEFT_STATE, currentNametable
LDA #%10000000
STA Object_direction,x
JMP +doneWithCreatingWeapon
+notLeft
+doneWithCreatingWeapon
:canNotUseWeapon;;;;;;;;;;;;;
RTS
;;;;;;;;;;;;;;;;;END OF MY CODE;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RTS
weaponChoiceTable:
.db #%00000001, #%00000010, #%00000100, #%00001000
.db #%00010000, #%00100000, #%01000000, #%10000000
weaponObjectTable:
.db #$03, #$0A, #$03, #$03, #$03, #$03, #$03, #$03
You also need to make sure you have SelectWeapon input script assigned to the select button in MainGame state.
To get the weapons, they are bestowed w/ text from an NPC, as described in the official Adventure Tutorial. I think this could also be bestowed as a power up the first time you collect it, but I haven't tested that yet (will relate to the pickup script)
As far as the boomerang goes, there are a few other things I had to, such as create an action state for the weapon that makes it constantly follow the player, edit the collision scripts to check for the returning boomerang, and add a little variable at screen load to make sure the boomerang is always reset on a new screen.
The only thing I really figured out here was the boomerang, but I thought I'd share the selectable weapon branching code to help people looking for a way to add more.