Skeetendo

’Cause all games were better on the GBC

You are not logged in.

  • Index
  • → Help/Question
  • → [SOLVED] Attempting to recreate "Foresight" in Red; game locks up.

#1 2017-03-10 02:21:42

KeiTaRo
Member
Registered: 2015-12-05
Post 34/56
Website

[SOLVED] Attempting to recreate "Foresight" in Red; game locks up.

UPDATE: it works!

I hope you aren't all sick of me yet :P I'm just really eager to learn how these games work, and I've been learning quite a lot from here! Anyways, as the title implies, I am trying to add Foresight to Red version. I'm pretty sure I have converted the code correctly, but whenever I use the attack, the game just freezes. Let me walk you through my process. I'm sorry for how verbose this is, I just wanted to make this as detailed as possible.

First, I went in to wram.asm and added a W_PLAYERBATTSTATUS4 and W_ENEMYBATTSTATUS4 to d06e and d073 respectively. This bytes seemed not to be used, so I thought it might be okay. Anyways, after that, I added in some variables in to the end of status_constants:

;volatile statuses 4
HasNightmare    EQU 0
UsingCurse      EQU 1
UsingProtect    EQU 2
BeenIdentified  EQU 3
UsingPerishSong EQU 4
UsingEndure     EQU 5
HasAnEncore        EQU 6
UsedDefenseCurl   EQU 7 ;unused

....these are just placeholders for eventual other moves of course, but what we care about is BeenIdentified, $3. I also replaced the type matchup table with the exact one pokecrystal used.

anyways, I went and looked at the original code for Foresight in pokecrystal's code, and it LOOKS like there are only two critical components to it. They look like the following:

BattleCommand_Foresight: ; 376a0
; foresight

    ld a, [AttackMissed]
    and a
    jr nz, .failed

    call CheckHiddenOpponent
    jr nz, .failed

    ld a, BATTLE_VARS_SUBSTATUS1_OPP
    call GetBattleVarAddr
    bit SUBSTATUS_IDENTIFIED, [hl]
    jr nz, .failed

    set SUBSTATUS_IDENTIFIED, [hl]
    call AnimateCurrentMove
    ld hl, IdentifiedText
    jp StdBattleTextBox

.failed
    jp FailForesight
; 376c2

which was inside foresight.asm, and:

.TypesLoop:
    ld a, [hli]

    cp $ff
    jr z, .end

    ; foresight
    cp $fe
    jr nz, .SkipForesightCheck
    ld a, BATTLE_VARS_SUBSTATUS1_OPP
    call GetBattleVar
    bit SUBSTATUS_IDENTIFIED, a
    jr nz, .end

    jr .TypesLoop

.SkipForesightCheck:
    cp b
    jr nz, .SkipType
    ld a, [hl]
    cp d
    jr z, .GotMatchup
    cp e
    jr z, .GotMatchup
    jr .SkipType

.GotMatchup:
etc....

which is part of the code that determines the type of a move for effectiveness. ANYWAY! I rewrote both of those, inserting the latter in to the type loop in pokered's Core.asm:

.loop
    ld a,[hli] ; a = "attacking type" of the current type pair
    cp a,$ff
    jr z,.done
    
    ; foresight
    cp $fe
    jr nz, .SkipForesightCheck
    ;jp nz, PrintDidntAffectText
    ;ld bc, W_ENEMYBATTSTATUS4
    ld a,[W_ENEMYBATTSTATUS4]
    bit BeenIdentified, a
    jr nz, .done

    jr .loop
    
.SkipForesightCheck:
    cp b ; does move type match "attacking type"?
    jr nz,.nextTypePair
        etc......

and then the actual effect code, in e_2.asm .....why there? I dunno. Do you have a better idea? Please advise.

ForesightEffect_: ; 376a0
; foresight
    callab MoveHitTest
    ld a, [W_MOVEMISSED] ; W_MOVEMISSED
    and a
    jr nz, .failed
    
    ld a, [W_ENEMYBATTSTATUS1]
    bit Invulnerable, a
    jr nz, .failed
 
    ld a,[W_ENEMYBATTSTATUS4]
    bit BeenIdentified, [hl]
    jr nz, .failed

    set BeenIdentified, [hl]
    call PlayMoveAnimation
    ld hl, IdentifiedText
    jp PrintText
.failed
    jp PrintButItFailedText_
    
IdentifiedText: ; 3fb49 (f:7b49)
    TX_FAR _IdentifiedText
    db "@"
; 376c2

....now just from a glance it LOOKS like I rewrote these correctly, but.........the game freezes whenever I use the attack. In addition to obviously adding the text for the command, I also added ForesightEffect to the effect pointer table (as well as made an effect constant for it) but then also defined this in core.asm:

ForesightEffect:
    ld hl, ForesightEffect_
    ld b, BANK(ForesightEffect_)
    jp Bankswitch

the same way stuff like transform does it, etc.

Now, I'm pretty sure I'm understanding how the original code works, and functionally, it LOOKS like I rewrote it to work in red version correctly. But like I said, the game freezes. I'm sure there'a glaringly obvious error in what I've done and I'm hoping someone will point that out for me. Particularly, I'm pretty confused by what BATTLE_VARS_SUBSTATUS1_OPP and GetBattleVar are supposed to be, so I tried to aproximate their functionality? I SUSPECT that the issue is NOT in the routine from core.asm, as the game functions perfectly when the move is not used, but then again I could be wrong. Sorry for how verbose this post is, like I said, I just wanted to be as detailed as possible.

Last edited by KeiTaRo (2017-03-12 03:02:36)

Offline

#2 2017-03-10 18:59:08

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 3,457/3,578

Re: [SOLVED] Attempting to recreate "Foresight" in Red; game locks up.

Well you're trying to call PlayMoveAnimation as if it was in the same bank as your code, but it isn't. So that's making it call unrelated data from the bank it is in, and that's probably at least part of what's causing the crash.

Also, I see your code only cares about the opponent having been foresighted, with no checks whatsoever to allow the opponent to use Foresight on you. Might want to fix that. Also, you are trying to set a bit in hl as if you had loaded hl with W_ENEMYBATTSTATUS4, but you haven't, you loaded register a with whatever value was there. So that means you are trying to set a bit in whatever hl currently holds.

Offline

#3 2017-03-11 02:15:54

KeiTaRo
Member
Registered: 2015-12-05
Post 36/56
Website

Re: [SOLVED] Attempting to recreate "Foresight" in Red; game locks up.

EDIT: here it is in action, if anyone is curious, heh.

AUGH! I swear, every time I feel like I'm making progress, really basic things like this trip me up. Indeed, fixing those things made this code work flawlessly. Adding the enemy/player check code broke it, but then I realized a simple mistake there as well (the failed text was being called from a different bank, and broke the game if you used Foresight twice) Thanks for looking at the code for me. For those who are wondering, here is the final finished routine for that effect, if you want to use Foresight in your own hack (maybe this will help someone else learn too!):

ForesightEffect_:
; foresight
    ld a, [H_WHOSETURN]
    and a
    ld a, [W_PLAYERBATTSTATUS1]
    jr nz, .hitTest
    ld a, [W_ENEMYBATTSTATUS1]
.hitTest
    callab MoveHitTest
    bit Invulnerable, a
    jr nz, .failed
    ld a, [W_MOVEMISSED] ; W_MOVEMISSED
    and a
    jr nz, .failed
    ld hl, W_PLAYERBATTSTATUS4
    ld a, [H_WHOSETURN]
    and a
    jr z, .foresightEffect
    ld hl, W_ENEMYBATTSTATUS4
.foresightEffect]
    bit BeenIdentified, [hl]
    jr nz, .failed
    set BeenIdentified, [hl]
    callab PlayCurrentMoveAnimation
    ld hl, IdentifiedText
        jp PrintText
.failed
    ld c, $32
    call DelayFrames
    ld hl, PrintButItFailedText_
    ld b, BANK(PrintButItFailedText_)
    jp Bankswitch
    
IdentifiedText: ; 3fb49 (f:7b49)
    TX_FAR _IdentifiedText
    db "@"

and the modified loop, which goes in AdjustDamageForMoveType in core.asm:

.loop
    ld a,[hli] ; a = "attacking type" of the current type pair
    cp a,$ff
    jr z,.done
    
    ; foresight
    cp $fe
    jr nz, .SkipForesightCheck
    ld a, [H_WHOSETURN]
    and a
    ld a, [W_ENEMYBATTSTATUS4]
    jr nz, .beenIdentified
    ld a, [W_PLAYERBATTSTATUS4]
.beenIdentified
    bit BeenIdentified, a
    jr nz, .done

    jr .loop
    
.SkipForesightCheck:
    cp b ; does move type match "attacking type"?
    jr nz,.nextTypePair
    ld a,[hl] ; a = "defending type" of the current type pair
    cp d ; does type 1 of defender match "defending type"?
    jr z,.matchingPairFound
    cp e ; does type 2 of defender match "defending type"?
    jr z,.matchingPairFound
    jr .nextTypePair

if anyone uses this in their own hack, let me know if you encounter any issues with it. I noticed Crystal also did some stuff with foresight in the accuracy check code, but it doesn't seem necessary? I'm pretty happy that I could get this working at least...! Thanks again for your help.

One minor thing I am not completely sure about is [H_WHOSETURN] ... aware that it returns the value of who's turn it is, and based on existing code in the game it seemed like the Enemy's would come before the player in the routine....this is not always the case though, as you can see in the difference between my two code chunks. I guess what I'm saying is, how do I know what order to check the parameters in, other than trial and error?

Last edited by KeiTaRo (2017-03-11 04:03:32)

Offline

  • Index
  • → Help/Question
  • → [SOLVED] Attempting to recreate "Foresight" in Red; game locks up.

Board footer

Powered by FluxBB