Difference between revisions of "Spell Customization"
(→Advanced: Water spell) |
m (Link to Element table) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 3: | Line 3: | ||
== Required Tools == | == Required Tools == | ||
− | * a hex editor, e.g. HxD | + | * a hex editor, e.g. [https://mh-nexus.de/en/hxd/ HxD] |
* noisecross's [[Main_Page#Utility|text editor]] | * noisecross's [[Main_Page#Utility|text editor]] | ||
* a backup of your work before any experiments | * a backup of your work before any experiments | ||
− | |||
== Beginner: Multi-target Flare == | == Beginner: Multi-target Flare == | ||
Line 13: | Line 12: | ||
First we need to modify the spell data itself. It is located at | First we need to modify the spell data itself. It is located at | ||
− | $110B80 + 8 * | + | $110B80 + 8 * [[Value:Magic | Spell ID]] |
− | Flare has a | + | Flare has a [[Value:Magic | Spell ID]] of $33 so we find our data at $110D18.<br> |
− | |||
The data is: | The data is: | ||
38 04 00 27 08 00 FE 00 | 38 04 00 27 08 00 FE 00 | ||
− | For now we only care about the first byte, it determines the | + | For now we only care about the first byte, it determines the targeting of the spell: |
80 Multi-target optional | 80 Multi-target optional | ||
40 Hits all targets | 40 Hits all targets | ||
Line 31: | Line 29: | ||
Since we want regular flare to be multi-targetable like Fire1/2/3 we change the 38 to B8. | Since we want regular flare to be multi-targetable like Fire1/2/3 we change the 38 to B8. | ||
− | However the default animation of flare is not compatible with | + | However the default animation of flare is not compatible with multi-targetting; the damage will still be done to all targets but it will not look right - or in case of some spells even fry the graphic engine. |
Animation headers are located at | Animation headers are located at | ||
− | $1838EC + 5 * | + | $1838EC + 5 * [[Value:Magic | Spell ID]] |
so for Flare it is $1839EB with | so for Flare it is $1839EB with | ||
Line 47: | Line 45: | ||
To my knowledge there's little to no use of the !Time spell Drag so let's replace it.<br> | To my knowledge there's little to no use of the !Time spell Drag so let's replace it.<br> | ||
− | It has | + | It has [[Value:Magic | Spell ID]] $36 so the data is located at $110D30. |
The effect of the 8 bytes are as follows: | The effect of the 8 bytes are as follows: | ||
Targeting | Targeting | ||
− | + | Attack Type | |
Misc. | Misc. | ||
Reflectable ($80 not set) + MP cost | Reflectable ($80 not set) + MP cost | ||
Line 61: | Line 59: | ||
Targetting was explained for Flare, so I'll just say we use B8 as well. | Targetting was explained for Flare, so I'll just say we use B8 as well. | ||
− | + | Attack Type determines which group the spell belongs to, e.g. used in "[[Value:Can't_Evade |can't evade]]" checks. | |
+ | 01 Blue | ||
+ | 02 White | ||
+ | 04 Black | ||
+ | 08 Time | ||
+ | 10 Summon | ||
+ | 20 Song | ||
+ | 40 Aerial | ||
+ | 80 Physical | ||
Misc should be 0. The only non-0 values I've seen were for Meteo and Cave In the hit count. If we were to use a non-0 value our spell would behave like Meteo in that it doesn't hit the target(s) once each but that it selects out of the targets a random target up to 4 times and performs a single target attack against it; in that case it would also require us to either use either the Meteo or Cave In spell animation as only those are compatible with that effect.<br> | Misc should be 0. The only non-0 values I've seen were for Meteo and Cave In the hit count. If we were to use a non-0 value our spell would behave like Meteo in that it doesn't hit the target(s) once each but that it selects out of the targets a random target up to 4 times and performs a single target attack against it; in that case it would also require us to either use either the Meteo or Cave In spell animation as only those are compatible with that effect.<br> | ||
Line 89: | Line 95: | ||
2 Duration | 2 Duration | ||
3 [Status 0] added | 3 [Status 0] added | ||
− | We want to deal normal water damage so $06 is fine. The element is built like: | + | We want to deal normal water damage so $06 is fine. The [[Value:Element | element]] is built like: |
01 fire | 01 fire | ||
02 ice | 02 ice | ||
Line 99: | Line 105: | ||
80 water | 80 water | ||
For power 50 should be fine, so the final result is something like | For power 50 should be fine, so the final result is something like | ||
− | B8 | + | B8 08 00 08 06 00 32 80 |
− | Next up we have to change the spell animation. Since the spell is | + | Next up we have to change the spell animation. Since the spell is [[Value:Magic | Spell ID]] $36 we find our animation data at 1839FA. |
The 5 bytes have the following meaning: | The 5 bytes have the following meaning: | ||
Line 183: | Line 189: | ||
custom damage formula<br> | custom damage formula<br> | ||
− | '''Warning: this part requires ASM knowledge''' | + | '''Warning: this part requires ASM knowledge and a bit of free space in the ROM''' |
+ | |||
+ | We'll replace the Void spell this time, $39.<br> | ||
+ | Since Drag was the only spell to use the attack formula $1E we'll edit that in a bit. | ||
+ | |||
+ | First let's modify the spelldata at $110D48: | ||
+ | 48 04 00 9F 1E 00 00 00 | ||
+ | The spell always hits all enemies, costs 31 MP, is not reflectable and will use the spell effect we want to modify. | ||
+ | |||
+ | But we don't have much space at the old Drag spell effect to do anything fancy: | ||
+ | Attack Type 1E (Drag) | ||
+ | C2/6CE4: A2 04 00 LDX #$0004 | ||
+ | C2/6CE7: BF F2 EC D0 LDA $D0ECF2,X | ||
+ | C2/6CEB: 8D D6 3E STA $3ED6 | ||
+ | C2/6CEE: 60 RTS | ||
+ | My free space in the ROM is 285E80, you'll need to look yourself where you have some space. So go to your rom at 26CE4 and write there instead: | ||
+ | 22 80 5E E8 60 (JSL to my address, then the RTS) | ||
+ | |||
+ | For the actual attack animation, we'll just use a simple recolor or the gale cut: | ||
+ | 32 66 33 54 A0 | ||
+ | |||
+ | Name editing should be known at this point, so I won't repeat. For the sake of the tutorial I'd suggest Clash as the spell name; Time spells are limited to 6 characters (magic category icon + 5 letters), !Blue spell names can be a bit longer because of the different spell menu style. | ||
+ | |||
+ | Now let's make it so the spell action $1E starts the best song in the game and deals damage like a 130 power physical magic spell that uses VIT instead of MAG for damage. | ||
+ | |||
+ | Then at 285E80 I have to put: | ||
+ | ---change music to "Big Bridge"--- | ||
+ | AD 05 1D LDA $1D05 - current song | ||
+ | C9 22 CMP #$22 | ||
+ | F0 18 BEQ | ||
+ | A9 22 LDA #$22 song to be played | ||
+ | 8D 01 1D STA $1D01 | ||
+ | A9 01 LDA #$01 | ||
+ | 8D 00 1D STA $1D00 | ||
+ | A9 08 LDA #$08 | ||
+ | 8D 02 1D STA $1D02 | ||
+ | A9 0F LDA #$0F | ||
+ | 8D 03 1D STA $1D03 | ||
+ | 22 04 00 C4 JSL $C40004 start the song | ||
+ | ---custom damage formula--- | ||
+ | AD E3 7B LDA $7BE3 Vitality of attacker with buffs | ||
+ | 8D E4 7B STA $7BE4 overwrite Magic stat (this is calculated fresh for every action) | ||
+ | A9 7F LDA #$7F 127% hit chance | ||
+ | 85 57 STA $57 | ||
+ | A9 82 LDA #$82 130 spell power | ||
+ | 85 58 STA $58 | ||
+ | A9 00 LDA #$00 void element | ||
+ | 85 59 STA $59 | ||
+ | 68 PLA | ||
+ | 68 PLA | ||
+ | 68 PLA | ||
+ | 5C BC 69 C2 JMP attack type 0A (physical spell), but past hit/evade check | ||
+ | |||
+ | That leaves us with the final piece: putting Gilgamesh on the field for our team. | ||
+ | |||
+ | During spell casting, the game checks if the current action is !Release from the tamer, if so $7E:7C4B was set earlier to a non-$FF value; if it is a different value that is the id of the monster that will take the place of your team for the attack - not stat wise, only for animation sake. | ||
+ | |||
+ | The actual check then happens here: | ||
+ | $C1/B536 AD 4B 7C LDA $7C4B | ||
+ | $C1/B539 C9 FF CMP #$FF | ||
+ | Again replace it with a JSL EA to a free spot in your ROM (I have 287FD0) and then put there something like: | ||
+ | AD 4B 7C LDA $7C4B | ||
+ | C9 FF CMP #$FF | ||
+ | F0 01 BEQ | ||
+ | 6B RTL this is a positive return for !Release | ||
+ | ---action was not !Release--- | ||
+ | A0 02 00 LDY #$0002 | ||
+ | B1 E7 LDA ($E7),y[$7E:3853] high byte of "spell id" currently used | ||
+ | C9 00 CMP #$00 $00 means we're still in the regular spell section, not in $01 with !Gaia and !Mix | ||
+ | F0 03 BEQ | ||
+ | A9 00 LDA #$00 nothing to replace with | ||
+ | 6B RTL | ||
+ | A0 03 00 LDY #$0003 | ||
+ | B1 E7 LDA ($E7),y[$7E:3854] actual spell id used | ||
+ | C9 39 CMP #$39 only trigger replacement if it is our Void replacement | ||
+ | 6B RTL | ||
− | + | And the final part is something similar for | |
+ | $C1/B458 AD 4B 7C LDA $7C4B [$7E:7C4B] | ||
+ | $C1/B45B AA TAX | ||
+ | here the full monster id (low + high) is moved to X. So same deal, put a JSL to some free space there - I used 288000 - and then put there something like: | ||
+ | AD 4B 7C LDA $7C4B [$7E:7C4B] | ||
+ | C9 FF CMP #$FF | ||
+ | F0 02 BEQ | ||
+ | AA TAX | ||
+ | 6B RTL | ||
+ | C2 20 REP #$20 | ||
+ | A9 6F 01 LDA #$016F id of the monster to summon, here Gilgamesh | ||
+ | AA TAX | ||
+ | 7B TDC | ||
+ | E2 20 SEP #$20 | ||
+ | 6B RTL |
Latest revision as of 19:51, 9 March 2019
By Praetarius5018
Required Tools
- a hex editor, e.g. HxD
- noisecross's text editor
- a backup of your work before any experiments
Beginner: Multi-target Flare
Goal:
allow Flare to hit all enemies with a working spell animation
First we need to modify the spell data itself. It is located at
$110B80 + 8 * Spell ID
Flare has a Spell ID of $33 so we find our data at $110D18.
The data is:
38 04 00 27 08 00 FE 00
For now we only care about the first byte, it determines the targeting of the spell:
80 Multi-target optional 40 Hits all targets 20 Target selectable 10 Side selectable 08 Target enemy (by default) 04 Roulette 00 caster
Since we want regular flare to be multi-targetable like Fire1/2/3 we change the 38 to B8.
However the default animation of flare is not compatible with multi-targetting; the damage will still be done to all targets but it will not look right - or in case of some spells even fry the graphic engine.
Animation headers are located at
$1838EC + 5 * Spell ID
so for Flare it is $1839EB with
05 10 1D 88 1D
For simplicity's sake we just replace it with L3 Flare's data:
05 10 A8 00 2B
Advanced: Water spell
Goal:
replace !Time/Drag with a water damage spell
To my knowledge there's little to no use of the !Time spell Drag so let's replace it.
It has Spell ID $36 so the data is located at $110D30.
The effect of the 8 bytes are as follows:
Targeting Attack Type Misc. Reflectable ($80 not set) + MP cost Attack formula Parameter 1 Parameter 2 Parameter 3
Targetting was explained for Flare, so I'll just say we use B8 as well.
Attack Type determines which group the spell belongs to, e.g. used in "can't evade" checks.
01 Blue 02 White 04 Black 08 Time 10 Summon 20 Song 40 Aerial 80 Physical
Misc should be 0. The only non-0 values I've seen were for Meteo and Cave In the hit count. If we were to use a non-0 value our spell would behave like Meteo in that it doesn't hit the target(s) once each but that it selects out of the targets a random target up to 4 times and performs a single target attack against it; in that case it would also require us to either use either the Meteo or Cave In spell animation as only those are compatible with that effect.
This byte also holds the learnable flag ($40) for blue magic.
For the next byte, if we want our spell to not be reflectable we would set the $80 bit and then add the MP cost to it. E.g. 20 MP not reflectable would be $94. For this example I went with 8 MP and reflectable, so $08.
Then we need to decide what the spell actually does and fill in the 3 parameter for it.
Notable examples:
$06: Offensive magic
1 00 2 Attack power 3 [Element]
08: Pierce defense
1 00 2 Attack power 3 [Element]
0A: Physical magic
1 Hit % 2 Attack power 3 [element]
0C: Pierce defense + HP leak
1 [Element] 2 Attack power 3 Duration/2
12: Status 0 infliction
1 Hit % 2 Duration 3 [Status 0] added
We want to deal normal water damage so $06 is fine. The element is built like:
01 fire 02 ice 04 lightning 08 poison 10 holy 20 earth 40 wind 80 water
For power 50 should be fine, so the final result is something like
B8 08 00 08 06 00 32 80
Next up we have to change the spell animation. Since the spell is Spell ID $36 we find our animation data at 1839FA.
The 5 bytes have the following meaning:
sprite color palette animation bonus flags + multitarget/multiplication handling type sound
We want something watery, so the bubbles from Aqua Rake ($84) could make a good start for our animation: $46
It also gives as a good starting point for the palette: $38
and the sound effect: $22
To mix it up a bit we use the monster attack animation: $94, this won't always work but some trial and error shows it to work well enough here.
Next comes one of the harder parts, finding a good handling type; the $80 flag most of the time speeds up the animation, the $40 flag does something different for most routines or nothing at all, and the remaing $00 to $3F determines the base routine. The actual effect can vary by the base spell animation. It is mostly down to trial and error. For some $22 was OK, for one other it crashed the game.
00 multitarget able, "one iteration" 01 single target only? multiple parallel 02 single target only? multiple delayed
05 same as 00?
07 same as 00? 08 single target only? multiple delayed, directions may vary
0A single target only? "one iteration"
0C special routine? may crash
0E single target only? multiple parallel, lots 0F multitarget able, multiple parallel
11 single target only? multiple delayed, with red background 12 single target only? multiple delayed, can mirror vs party 13 single target only? multiple delayed 14 single target only? multiple parallel 15 single target only? multiple parallel
1F single target only? multiple parallel, tons, laggy
21 multitarget able, multiple delayed (3?) 22 single target only? multiple parallel, tons, laggy 23 nothing shown?
25 single target only? multiple parallel, tons, laggy 26 single target only? multiple delayed, tons, laggy 27 single target only? multiple parallel 28 shows red X 29 same as 00? 2A multitarget able, moves rows of player characters (if enemy1 was hit, player1 moves back/for) 2B same as 00? 2C multitarget able, multiple parallel (2?) 2D single target only? multiple delayed, tons, laggy
2F same as 00? 30 multitarget able, multiple parallel (2?) 31 same as 00?
33 like flood but with current sprite?, x3 34 like breath wing with current sprite?, x3
37 animation attacks a fixed range 38 same as 00? 39 nothing shown? 3A nothing shown? 3B nothing shown? 3C caster falls infinitely??? 3D nothing shown? 3E nothing shown? 3F caster falls infinitely???
I think that part is much easier to understand when you play around with the !White Heal spell animation. Normally it is just 3 blue lines that rise from the ground but with that multiplication it can become something like a wall of blue lines and other stuff. $21 and $30 are usually my go-to for multitarget spells.
So as a final animation we get something like
46 38 94 30 22
As a final touch we need to change the spellname from Drag to Water.
Open the ROM with noisecross's texteditor, get the template for Skill(M). Open the resulting .csv file with a text editor, NOT with something like Excel, then look for either Drag or Void (the spell names are in the same order as the spells themself) and change it to Water, save the file and inject it via the text editor, done.
Master: Clash
Goal:
summon Gilgamesh
change the battle theme
custom damage formula
Warning: this part requires ASM knowledge and a bit of free space in the ROM
We'll replace the Void spell this time, $39.
Since Drag was the only spell to use the attack formula $1E we'll edit that in a bit.
First let's modify the spelldata at $110D48:
48 04 00 9F 1E 00 00 00
The spell always hits all enemies, costs 31 MP, is not reflectable and will use the spell effect we want to modify.
But we don't have much space at the old Drag spell effect to do anything fancy:
Attack Type 1E (Drag) C2/6CE4: A2 04 00 LDX #$0004 C2/6CE7: BF F2 EC D0 LDA $D0ECF2,X C2/6CEB: 8D D6 3E STA $3ED6 C2/6CEE: 60 RTS
My free space in the ROM is 285E80, you'll need to look yourself where you have some space. So go to your rom at 26CE4 and write there instead:
22 80 5E E8 60 (JSL to my address, then the RTS)
For the actual attack animation, we'll just use a simple recolor or the gale cut:
32 66 33 54 A0
Name editing should be known at this point, so I won't repeat. For the sake of the tutorial I'd suggest Clash as the spell name; Time spells are limited to 6 characters (magic category icon + 5 letters), !Blue spell names can be a bit longer because of the different spell menu style.
Now let's make it so the spell action $1E starts the best song in the game and deals damage like a 130 power physical magic spell that uses VIT instead of MAG for damage.
Then at 285E80 I have to put:
---change music to "Big Bridge"--- AD 05 1D LDA $1D05 - current song C9 22 CMP #$22 F0 18 BEQ A9 22 LDA #$22 song to be played 8D 01 1D STA $1D01 A9 01 LDA #$01 8D 00 1D STA $1D00 A9 08 LDA #$08 8D 02 1D STA $1D02 A9 0F LDA #$0F 8D 03 1D STA $1D03 22 04 00 C4 JSL $C40004 start the song ---custom damage formula--- AD E3 7B LDA $7BE3 Vitality of attacker with buffs 8D E4 7B STA $7BE4 overwrite Magic stat (this is calculated fresh for every action) A9 7F LDA #$7F 127% hit chance 85 57 STA $57 A9 82 LDA #$82 130 spell power 85 58 STA $58 A9 00 LDA #$00 void element 85 59 STA $59 68 PLA 68 PLA 68 PLA 5C BC 69 C2 JMP attack type 0A (physical spell), but past hit/evade check
That leaves us with the final piece: putting Gilgamesh on the field for our team.
During spell casting, the game checks if the current action is !Release from the tamer, if so $7E:7C4B was set earlier to a non-$FF value; if it is a different value that is the id of the monster that will take the place of your team for the attack - not stat wise, only for animation sake.
The actual check then happens here:
$C1/B536 AD 4B 7C LDA $7C4B $C1/B539 C9 FF CMP #$FF
Again replace it with a JSL EA to a free spot in your ROM (I have 287FD0) and then put there something like:
AD 4B 7C LDA $7C4B C9 FF CMP #$FF F0 01 BEQ 6B RTL this is a positive return for !Release ---action was not !Release--- A0 02 00 LDY #$0002 B1 E7 LDA ($E7),y[$7E:3853] high byte of "spell id" currently used C9 00 CMP #$00 $00 means we're still in the regular spell section, not in $01 with !Gaia and !Mix F0 03 BEQ A9 00 LDA #$00 nothing to replace with 6B RTL A0 03 00 LDY #$0003 B1 E7 LDA ($E7),y[$7E:3854] actual spell id used C9 39 CMP #$39 only trigger replacement if it is our Void replacement 6B RTL
And the final part is something similar for
$C1/B458 AD 4B 7C LDA $7C4B [$7E:7C4B] $C1/B45B AA TAX
here the full monster id (low + high) is moved to X. So same deal, put a JSL to some free space there - I used 288000 - and then put there something like:
AD 4B 7C LDA $7C4B [$7E:7C4B] C9 FF CMP #$FF F0 02 BEQ AA TAX 6B RTL C2 20 REP #$20 A9 6F 01 LDA #$016F id of the monster to summon, here Gilgamesh AA TAX 7B TDC E2 20 SEP #$20 6B RTL