Users browsing this thread: 2 Guest(s)
Shock Ability

#21
Posts: 29
Threads: 5
Thanks Received: 0
Thanks Given: 0
Joined: Dec 2017
Reputation: 0
Status
None
(06-02-2018, 09:21 AM)Turbotastic Wrote: It's not a bug in terms of the original game. It's precisely intended to work that way, as blanking out MP is a way to hide the fact that any of your main characters could learn magic under the right circumstances.

I'm aware of that... I said it was "kind of a bug", because it is odd behavior for a character with no magic command to be able to learn a spell they can't use, but they obviously didn't plan on any main character not being able to have the magic command. I've been playing FF3 SNES since the day it came out, so I'm not some noob about the mechanics of the game; I simply haven't done any hex editing before.

Quote:In addition, temporary guest party members like Leo are unable to learn magic due to their actor ID being beyond the bounds for learnable characters. If you didn't change his ID in your hack so you could enforce his "no magic" status, that would also cause a problem with MP-battle related things.

My hack is based on fedorajoe's General Leo edition, and he used the Shadow slot for Leo.
  Find
Quote  

#22
Posts: 106
Threads: 4
Thanks Received: 13
Thanks Given: 1
Joined: Jan 2012
Reputation: 4
Status
None
Characters beyond slot 0B being unable to learn magic is more due to a lack of space than the hardcoded learning check. You'd need to implement b-run's magic hack, but that's intermediate level assembly hacking.
  Find
Quote  

#23
Posts: 72
Threads: 11
Thanks Received: 14
Thanks Given: 34
Joined: Dec 2015
Reputation: 0
Status
Debrave
Lightning, I apologize for the unneeded commentary and butting in.
  Find
Quote  

#24
Posts: 29
Threads: 5
Thanks Received: 0
Thanks Given: 0
Joined: Dec 2017
Reputation: 0
Status
None
(06-02-2018, 07:21 PM)Turbotastic Wrote: Lightning, I apologize for the unneeded vommentary and butting in.

Nah, in hindsight, I retaliated needlessly. Just trying to figure out how to iron out the bugs with Leo's Shock. Wink
  Find
Quote  

#25
Posts: 150
Threads: 10
Thanks Received: 59
Thanks Given: 15
Joined: May 2013
Reputation: 11
Status
Well-Fed
Okay, so characters always have MP, but under certain circumstances, the game ignores it -- if they don't have a relevant ability available, part of the battle initialization sequence zeroes out their MP. In vanilla, it DOESN'T do this if a) they have an esper equipped, b) they have spells learned, or c) they have the Lore skill. (It doesn't check for known lores, because the game starts with Lores already learned -- there's no circumstance outside of hacking in which you'll have zero lores known.)

I'm... not entirely certain why the game zeroes out MP in battle, and this might actually be considered a bug because (I think) it will prevent MP Criticals from proccing if the character doesn't have an esper equipped/spells known. A better solution might actually be to remove that all together, but I want to do a little more research into it first to see if it's just flavour, or if there's some function I'm completely missing that means characters shouldn't have access to MP in battle otherwise. In the meantime, this updated code should solve the problem -- it moves another table and adds Shock to the list of abilities that stop MP from being zeroed out. (I hook it directly into the Lore function, since it does exactly the same thing.)


Code:
hirom
; header

; Defines
!Freespace_1 = $c2A65A          ; 26 bytes, or 77 total
;!Freespace_2 = $c2xxxx         ; 34 bytes (if separate from above)
;!Freespace_3 = $c2xxxx         ; 17 bytes (if separate from above)
!Shock_ID = $1B
!Shock_MP = $32                 ; or 50d


;;; Flagging menu redraw on MP restore
; These were all originally STA $3C08,Y (and one ,X).
; They now jump to new generic functions that update current MP,
; but also flag the attacker/target (as relevant) to have their
; menu updated for Shock's MP cost.
;
; Nothing needed to be done for Mute, as it already flagged the
; function appropriately, and Shock piggybacks on Magic/Lore/X-Magic
; for handling it.
org $C21365
           JSR flagSTAY
           
org $c21375
           JSR flagSTAY
           
org $c2137D
           JSR flagSTAY
           
org $c232E0
           JSR flagSTAX
           
org $c23CB4
           JSR flagSTAY
           
org $c23F47
           JSR flagSTAY

;;; Adding MP Cost to Shock
; Added a jump in the middle of the MP cost code; new code
; replicates the same check for Summon, then checks for Shock
; before jumping back to this codeblock as appropriate.
org $C24F14
           JMP shockMP : NOP

         
;;; Disabling Shock at less than 50MP
; Adjusts some table pointers, and then includes new code includes
; the space opened up by moving the tables to freespace.
;
; New code checks current MP against cost of Shock and disables
; (greys out) the command if MP is too low.
org $c252C6
           LDX #$0008
           CMP.l c2_table1,X   ; Moved table to free space because it's being expanded
           
org $c252D2
           JSR (c2_table2,X)   ; Moved table to free space because it's being expanded
           
org $c252E9                     ; Code fits into the place freed by the moved tables
dis_Shock:  REP #$20            ; Set 16-bit A
           LDA.w #!Shock_MP    ; LDA with $32/50d
           CMP $3C08,Y         ; Compare it to current MP and restore processor flags from stack
           SEP #$20            ; Set 8-bit A
           BCC c25314          ; If MP was over 50, carry is clear, so branch to Magic/Lore/X-Magic code to check for mute
           RTS                 ; Else, return with carry set, which will grey out Shock
           
    warnpc $c25300
           
org $c25314
c25314:                         ; Setting label for branch above

org $c253CB
C253CB:     LDX #$06            ; One more item in the loop
C253CD:     CMP.l c2_table3,X   ; And the table is moved to make space

org $c25445
C25445:                         ; Lore function from jump table below (C2/5468)

org $c25468
C25468:     dw C25445           ; New table entry, in-line due to moved table
                               ; This goes to the Lore function, above, which
                               ; just flags MP as okay to show if the actor has
                               ; the Lore command (and, now, if they have Shock).


;;; New Code!
; This code (jumped to from MP cost function above) sets Shock's MP cost
; and adjusts it as necessary for Gold Hairpin/Economizer.
org !Freespace_1                ; (26 bytes)
shockMP:    CMP #$19            ; Is the command Summon? (Moved check to make space for JMP to new code)
           BNE .notSummon
           JMP $4F24           ; If it is, jump back to where it would have BRA'd in the earlier code
.notSummon CMP #!Shock_ID      ; Is it Shock?
           BEQ .shockMP        ; If it is, branch and set MP to deduct
           JMP $4F18
  .shockMP LDA #!Shock_MP
           XBA                 ; Put Shock's MP cost in the top of A
           LDA $3C45,X         ; Get relic byte 2 (Gold Hairpin/Economizer)
           JSR $5739
           JMP $4F54


; Moved/expanded tables (from the disable CMDs function)
;org !Freespace_2               ; (34 bytes)
c2_table1:  db $03, $0B, $07, $0C, $17, $02, $06, $00, !Shock_ID
c2_table2:  dw $5326, $5322, $531D, $5314, $5314, $5314, $5310, $5310, dis_Shock  

; and a table that handles blanking MP/other commands, so that Shock forces the game to load MP for a character
c2_table3:  db $03, $11, $13, $02, $17, $0C, !Shock_ID


; Generic functions for flagging menu redraw on MP damage/restore (one for STA $3C08,Y, one for STA $3C08,X)
;org !Freespace_3               ; (17 bytes)
flagSTAY:   STA $3C08,Y         ; Stores updated current MP
           PHX : TYX
           INC $2F30,X
           PLX
           RTS
           
flagSTAX:   STA $3C08,X         ; Stores updated current MP
           INC $2F30,X         ; Flags actor/target (as relevant) to have menu updated
           RTS

Let me know if you have any issues with it, but it should be working fine.


Current Project: FF6: Tensei | Discord ID: TristanGrayse
  Find
Quote  
[-] The following 3 users say Thank You to GrayShadows for this post:
  • Gi Nattak (06-05-2018), Turbotastic (06-06-2018), Warrax (06-05-2018)

#26
Posts: 29
Threads: 5
Thanks Received: 0
Thanks Given: 0
Joined: Dec 2017
Reputation: 0
Status
None
(06-05-2018, 09:38 PM)GrayShadows Wrote: Okay, so characters always have MP, but under certain circumstances, the game ignores it -- if they don't have a relevant ability available, part of the battle initialization sequence zeroes out their MP. In vanilla, it DOESN'T do this if a) they have an esper equipped, b) they have spells learned, or c) they have the Lore skill. (It doesn't check for known lores, because the game starts with Lores already learned -- there's no circumstance outside of hacking in which you'll have zero lores known.)

I'm... not entirely certain why the game zeroes out MP in battle, and this might actually be considered a bug because (I think) it will prevent MP Criticals from proccing if the character doesn't have an esper equipped/spells known. A better solution might actually be to remove that all together, but I want to do a little more research into it first to see if it's just flavour, or if there's some function I'm completely missing that means characters shouldn't have access to MP in battle otherwise. In the meantime, this updated code should solve the problem -- it moves another table and adds Shock to the list of abilities that stop MP from being zeroed out. (I hook it directly into the Lore function, since it does exactly the same thing.)


Code:
hirom
; header

; Defines
!Freespace_1 = $c2A65A          ; 26 bytes, or 77 total
;!Freespace_2 = $c2xxxx         ; 34 bytes (if separate from above)
;!Freespace_3 = $c2xxxx         ; 17 bytes (if separate from above)
!Shock_ID = $1B
!Shock_MP = $32                 ; or 50d


;;; Flagging menu redraw on MP restore
; These were all originally STA $3C08,Y (and one ,X).
; They now jump to new generic functions that update current MP,
; but also flag the attacker/target (as relevant) to have their
; menu updated for Shock's MP cost.
;
; Nothing needed to be done for Mute, as it already flagged the
; function appropriately, and Shock piggybacks on Magic/Lore/X-Magic
; for handling it.
org $C21365
           JSR flagSTAY
           
org $c21375
           JSR flagSTAY
           
org $c2137D
           JSR flagSTAY
           
org $c232E0
           JSR flagSTAX
           
org $c23CB4
           JSR flagSTAY
           
org $c23F47
           JSR flagSTAY

;;; Adding MP Cost to Shock
; Added a jump in the middle of the MP cost code; new code
; replicates the same check for Summon, then checks for Shock
; before jumping back to this codeblock as appropriate.
org $C24F14
           JMP shockMP : NOP

         
;;; Disabling Shock at less than 50MP
; Adjusts some table pointers, and then includes new code includes
; the space opened up by moving the tables to freespace.
;
; New code checks current MP against cost of Shock and disables
; (greys out) the command if MP is too low.
org $c252C6
           LDX #$0008
           CMP.l c2_table1,X   ; Moved table to free space because it's being expanded
           
org $c252D2
           JSR (c2_table2,X)   ; Moved table to free space because it's being expanded
           
org $c252E9                     ; Code fits into the place freed by the moved tables
dis_Shock:  REP #$20            ; Set 16-bit A
           LDA.w #!Shock_MP    ; LDA with $32/50d
           CMP $3C08,Y         ; Compare it to current MP and restore processor flags from stack
           SEP #$20            ; Set 8-bit A
           BCC c25314          ; If MP was over 50, carry is clear, so branch to Magic/Lore/X-Magic code to check for mute
           RTS                 ; Else, return with carry set, which will grey out Shock
           
    warnpc $c25300
           
org $c25314
c25314:                         ; Setting label for branch above

org $c253CB
C253CB:     LDX #$06            ; One more item in the loop
C253CD:     CMP.l c2_table3,X   ; And the table is moved to make space

org $c25445
C25445:                         ; Lore function from jump table below (C2/5468)

org $c25468
C25468:     dw C25445           ; New table entry, in-line due to moved table
                               ; This goes to the Lore function, above, which
                               ; just flags MP as okay to show if the actor has
                               ; the Lore command (and, now, if they have Shock).


;;; New Code!
; This code (jumped to from MP cost function above) sets Shock's MP cost
; and adjusts it as necessary for Gold Hairpin/Economizer.
org !Freespace_1                ; (26 bytes)
shockMP:    CMP #$19            ; Is the command Summon? (Moved check to make space for JMP to new code)
           BNE .notSummon
           JMP $4F24           ; If it is, jump back to where it would have BRA'd in the earlier code
.notSummon CMP #!Shock_ID      ; Is it Shock?
           BEQ .shockMP        ; If it is, branch and set MP to deduct
           JMP $4F18
  .shockMP LDA #!Shock_MP
           XBA                 ; Put Shock's MP cost in the top of A
           LDA $3C45,X         ; Get relic byte 2 (Gold Hairpin/Economizer)
           JSR $5739
           JMP $4F54


; Moved/expanded tables (from the disable CMDs function)
;org !Freespace_2               ; (34 bytes)
c2_table1:  db $03, $0B, $07, $0C, $17, $02, $06, $00, !Shock_ID
c2_table2:  dw $5326, $5322, $531D, $5314, $5314, $5314, $5310, $5310, dis_Shock  

; and a table that handles blanking MP/other commands, so that Shock forces the game to load MP for a character
c2_table3:  db $03, $11, $13, $02, $17, $0C, !Shock_ID


; Generic functions for flagging menu redraw on MP damage/restore (one for STA $3C08,Y, one for STA $3C08,X)
;org !Freespace_3               ; (17 bytes)
flagSTAY:   STA $3C08,Y         ; Stores updated current MP
           PHX : TYX
           INC $2F30,X
           PLX
           RTS
           
flagSTAX:   STA $3C08,X         ; Stores updated current MP
           INC $2F30,X         ; Flags actor/target (as relevant) to have menu updated
           RTS

Let me know if you have any issues with it, but it should be working fine.

You rock! I'll test that out when I get a chance.

I actually already used the "zero MP" for non-spell casters as part of my mod. Basically, there are now swords for mages (Illumina, Ragnorok), and swords for non-mages (Excalibur and Scimitar). For example, the best sword for Leo is now Excalibur and a new sword that appears in the General Leo Edition - both of which have been beefed up.
  Find
Quote  



Forum Jump:

Users browsing this thread: 2 Guest(s)


Theme by Madsiur2017Custom Graphics by JamesWhite