The current URL is datacrystal.tcrf.net.
Yu-Gi-Oh! Duel Monsters 4: Kaiba Deck/Tutorials
The following article is a Tutorial for Yu-Gi-Oh! Duel Monsters 4: Kaiba Deck.
Create new Magic/Trap/Ritual Effects
In progress
You can either:
- Replace an existing Magic/Trap/Ritual Effect, by using its effect_id then replacing its associated subroutine, and optionally the associated subroutine used by the CPU as well;
- Add your new Spell/Trap/Ritual by either:
- Extending the array of pointers at 3:799E (as well as the CPU one; both will need some re-pointing in Banks 0x03 and 0x14) and finding space in the current Bank for your new subroutine (there are a lot of ways to do this, for example you can keep only one Trap setting subroutine and remove all the others, then point every Trap to that subroutine);
- Or add your new effect subroutine in another Bank (and probably use some rst 08 magic). Effect IDs 0x7E to 0xFE are free, so there's 128 slots available if you don't modify or get around the game engine.
How to do your new subroutines:
- In the subroutine executing your new card effect:
- Start by pushing the register couples which will be used to the stack
- Make the checks you have to do if your Spell/Trap/Ritual has specific requirements, and jump accordingly. You can look at the existing Ritual spells for example, they define a value specific to the effect and rst 08 to another routine which does the checks before using the card.
- Remove the card you activated from the hand by calling 3:5FB0 or doing a rst 08 to it (the original card effects do this at the end rather than at the beginning of the card effect logic, it causes an issue with Pot of Greed which only lets your draw 2 cards if you already have 2 empty slots in your hand before activating it)
- If the new card effect has a non-targeting effect on Monsters on the field:
- Loop over each Monster Zone. To do so, set register b which contains the Column to 0 and loop/increment on it 5 times, and register c to 0 for Player's Row, 1 for CPU's Row, or set it at 0 and increment it once all 5 columns have been checked for current row and set Column back to 0 before looping 5 more times on it if applying the card effect on both the Player and CPU.
- In your loop, call 0:199D to update the current card Column and Row, and call 0:19E0 to update the card_id and card_status of the card of the current Monster Zone; WRAM wC7DD-C7DE for current_card_id and wC7DF for current_card_status
- Call existing subroutines or put your custom asm instructions to apply whatever transformations to the card_id in wC7DD-wC7DE and card_status in wC7DF; card_status flags can be found in the RAM map under the WRAM address C7DD, and there are a handful of subroutines updating and setting certain card_status flags from 0:1E99 to 0:1F8C, which are followed by two subroutines doing everything needed to destroy a card at 0:1F96 (Player's card) and 0:1FAF (CPU's card)
- todo : add a section here explaining how to retrieve the card's data and its current card stats, if checks or transformations need to be applied to the current card
- Call 0:19C8 with the current card Column and Row in register bc as a parameter to copy the updated card_id and card_status to the WRAM address for the current Monster Zone
- After the end of your loop, call 3:7BED to update the Field display
- Then rst 08 to the pointer located at 6:400B, with the textbox ID you wish to use in accumulator as a parameter
- To edit the displayed textbox, check the section "Text boxes in battle - Magic/Trap/Ritual"
- And finally pop from the stack all the register couples you pushed to the stack at the start of the new subroutine, then ret
- If the new card_effect draws cards from the Player's deck, call 3:4528 for each card drawn
(To be continued)
Notable Breakpoints for Magic/Trap/Ritual Effects
0:199D - Update card column and row 0:19A8 - Retrieve card column and row 0:19B3 - 00s card_id and set card_status to 0x10 in current_card_zone 0:19C8 - Copy current_card_id and current_card_status in [bc] 0:19E0 - Update current_card_id and current_card_status 0:1A03 - Retrieves card zone pointer 0:1A3F - Checks if bc ≠ 0 0:1E99 - Card status subroutines (Read and Update) 0:1F96 - Destroy Player's card 0:1FAF - Destroy CPU's card 3:412C - Field change (in order: Arena, Forest, Wasteland, Mountain, Sogen, Umi, Yami) 3:4528 - Draw a card 3:4EF5 - Check if current_card_id is non-zero 3:51D2 - Check highest ATK enemy Monster; a bit glitched, needs fixing 3:5FB0 - Removes card 3:6215 - Summon Monster card from hand
(In progress)
Text boxes in battle - Magic/Trap/Ritual
Usually you'll be outside of Bank 06, since you'll be mostly calling these for card effects and lingering effects such as Swords of Revealing Light.
So do a rst 08 to Bank 06, grabbing the pointer at 6:400B, with the textbox ID in accumulator as the parameter.
3E 13 ld a,13 ;0x13 is Stop Defense textbox CF rst 08 => 0B 06 ;Display text box
The parameter you send in accumulator is also used to retrieve up to 3 card_ids stored in three arrays at 6:41F3, used by func_display_textbox at 6:41B4.
These card_ids are 2 bytes long, and are stored in wC8F6, wC8F8, and wC8FA.
You can display these card_id names in your textboxes using the special character codes (in DM3, these are 0xB5 to 0xB8, but it might be different in DM4, I will check).
todo : Explain how to retrieve card's data if the new effect needs to check these, and card's current stats if the new effect modifies these.
There is also a Sound Effect ID associated to the textbox, which you can change (I will document it, it works the same as in Dark Duel Stories)
Internal Data for Yu-Gi-Oh! Duel Monsters 4: Kaiba Deck
| |
---|---|