07-01-2018, 06:33 PM
(This post was last modified: 08-17-2018, 04:34 AM by NPCnextdoor.)
Hello,
I started to learn ASM and I'm having lots of fun. I have an idea to expand the treasure chest subroutine. Currently, it offers the following possibilities:
I want to change it so it would also be possible to:
While the first two are technically already possible (as a small test, I changed the JSR branching of getting an item to the one that gives a summon and it worked. The message box was wrong, but I got the summon.), the other ones require an additional byte in the chest information. The Treasure Chest data is composed of 5 bytes starting at $ED/8634.
Here is the beginning of the subroutine:
The thing is that the X register contains the relative value of the first byte of the current treasure chest. It is 5 times larger than the chest "ID". So, it gave me an idea. There is absolutely no need the keep the encoding byte/bit as hard-coded information if it can be found by a simple division (I know it costs many cycles, so it is not that simple!
). In that way, you ensure that every chest has its own encoding bit.
Personally, I never liked the whole "not opening treasure chests so they offer more powerful items in the future" thing. I want to open ALL the chests. Additionally, it frees a whole byte.
Please note this is only a proof-of-concept. I know the code is really not optimized. I just wanted to move as less stuff as possible around. Now, this works. The chest is obtainable once and no longer available after that. But when the map is reloaded (after opening/closing the menu, finishing a battle or leaving the map and coming back), the chest is closed once more (its content can't be retaken though). My first question would be: Where in the map generation code the subroutine that decides if a chest is open or closed? Thanks in advance!
I started to learn ASM and I'm having lots of fun. I have an idea to expand the treasure chest subroutine. Currently, it offers the following possibilities:
- Granting an item.
- Granting a multiple of 100 gold, up to 25500 gold.
- Starting a Monster-in-a-box encounter with a monster pack between #256 and #511.
- Being empty.
I want to change it so it would also be possible to:
- Grant a rare item. [DONE]
- Grant a summon. [DONE]
- Grant between 1 and 99 items of one type. [DONE]
- Grant a multiple of 10 gold, up to 655350 gold (the value of 10 is arbitrary, of course). [DONE]
- Start a Monster-in-a-box encounter with any encounter pack.
- Start a MiaB encounter with a monster pack between #256 and #511 then grant an item, some gold, a rare item or a summon upon winning the battle.
While the first two are technically already possible (as a small test, I changed the JSR branching of getting an item to the one that gives a summon and it worked. The message box was wrong, but I got the summon.), the other ones require an additional byte in the chest information. The Treasure Chest data is composed of 5 bytes starting at $ED/8634.
- Coordinates of the chest (X, Y)
- Encoding byte and bit (byte is added to $1E40)
- Treasure type (0x08: empty, 0x20: Monster-in-a-box, 0x40: Item, 0x80: Gold)
- Treasure value (MiaB encounter pack, item type or gold quantity)
Here is the beginning of the subroutine:
Code:
C0/4C06: C220 REP #$20 (16 bit accum./memory)
C0/4C08: BF3886ED LDA $ED8638,X (Load chest item index / gold / encounter # in A)
C0/4C0C: 851A STA $1A (Store A in $1A)
C0/4C0E: BF3686ED LDA $ED8636,X (Load relative encoding byte/bit and treasure type in A)
C0/4C12: 851E STA $1E (Store A in $1E)
C0/4C14: 290700 AND #$0007 (A = A AND #$0007 => Load encoding bit in A)
C0/4C17: AA TAX (Transfer A to X)
C0/4C18: A51E LDA $1E (Load relative encoding byte/bit and treasure type in A from $1E)
C0/4C1A: 29FF01 AND #$01FF (A = A AND #$01FF => Load encoding byte/bit in A)
C0/4C1D: 4A LSR A
C0/4C1E: 4A LSR A
C0/4C1F: 4A LSR A (Getting rid of encoding bit, keeping relative encoding byte in A)
C0/4C20: A8 TAY (Transfer A to Y)
The thing is that the X register contains the relative value of the first byte of the current treasure chest. It is 5 times larger than the chest "ID". So, it gave me an idea. There is absolutely no need the keep the encoding byte/bit as hard-coded information if it can be found by a simple division (I know it costs many cycles, so it is not that simple!

Personally, I never liked the whole "not opening treasure chests so they offer more powerful items in the future" thing. I want to open ALL the chests. Additionally, it frees a whole byte.
Code:
C0/4C06 C2 20 -- -- REP #$20
C0/4C08 20 13 D6 -- JSR $D613 (Jumping to subroutine at $D613)
C0/4C0B BF 36 86 ED LDA $ED8636,X (Loading encoding byte/bit and treasure chest in A)
C0/4C0F 85 1E -- -- STA $1E (Storing A in $1E, item type / gold quantity / encounter number is in $1F, just as before)
C0/4C11 AD 16 42 -- LDA $4216 (Loading quotient in A)
C0/4C14 29 07 00 -- AND #$0007 (A = A AND 0x0007, keeping encoding bit)
C0/4C17 AA -- -- -- TAX (Transfer A to X)
C0/4C18 AD 16 42 -- LDA $4216 (Reloading quotient in A)
C0/4C1B 4A -- -- -- LSR A
C0/4C1C 4A -- -- -- LSR A
C0/4C1D 4A -- -- -- LSR A (Shifting data three bits to the right, keeping only encoding byte in A)
C0/4C1E A8 -- -- -- TAY (Transfer A to Y)
C0/4C1F EA -- -- -- NOP
C0/4C20 EA -- -- -- NOP (Chilling for 4 cycles, then resuming original subroutine)
C0/D613 8E 04 42 -- STX $4204 (Storing X as dividend)
C0/D616 A9 00 05 -- LDA #$0500 (Loading 0x0500 in A)
C0/D619 8D 06 42 -- STA $4206 (Storing 0x05 as divisor)
C0/D61C BF 38 86 ED LDA $ED8638,X (Putting item type / gold quantity / encounter number in A)
C0/D620 85 1A -- -- STA $1A (Storing A in $1A)
C0/D622 60 -- -- -- RTS
Please note this is only a proof-of-concept. I know the code is really not optimized. I just wanted to move as less stuff as possible around. Now, this works. The chest is obtainable once and no longer available after that. But when the map is reloaded (after opening/closing the menu, finishing a battle or leaving the map and coming back), the chest is closed once more (its content can't be retaken though). My first question would be: Where in the map generation code the subroutine that decides if a chest is open or closed? Thanks in advance!