pokecrystal-board/engine/pokemon/move_mon.asm

1822 lines
27 KiB
NASM

RANDY_OT_ID EQU 01001
TryAddMonToParty:
; Check if to copy wild mon or generate a new one
; Whose is it?
ld de, wPartyCount
ld a, [wMonType]
and $f
jr z, .getpartylocation ; PARTYMON
ld de, wOTPartyCount
.getpartylocation
; Do we have room for it?
ld a, [de]
inc a
cp PARTY_LENGTH + 1
ret nc
; Increase the party count
ld [de], a
ld a, [de] ; Why are we doing this?
ldh [hMoveMon], a ; HRAM backup
add e
ld e, a
jr nc, .loadspecies
inc d
.loadspecies
; Load the species of the Pokemon into the party list.
; The terminator is usually here, but it'll be back.
ld a, [wCurPartySpecies]
ld [de], a
; Load the terminator into the next slot.
inc de
ld a, -1
ld [de], a
; Now let's load the OT name.
ld hl, wPartyMonOTs
ld a, [wMonType]
and $f
jr z, .loadOTname
ld hl, wOTPartyMonOTs
.loadOTname
ldh a, [hMoveMon] ; Restore index from backup
dec a
call SkipNames
ld d, h
ld e, l
ld hl, wPlayerName
ld bc, NAME_LENGTH
call CopyBytes
; Only initialize the nickname for party mon
ld a, [wMonType]
and a
jr nz, .skipnickname
ld a, [wCurPartySpecies]
ld [wNamedObjectIndex], a
call GetPokemonName
ld hl, wPartyMonNicknames
ldh a, [hMoveMon]
dec a
call SkipNames
ld d, h
ld e, l
ld hl, wStringBuffer1
ld bc, MON_NAME_LENGTH
call CopyBytes
.skipnickname
ld hl, wPartyMon1Species
ld a, [wMonType]
and $f
jr z, .initializeStats
ld hl, wOTPartyMon1Species
.initializeStats
ldh a, [hMoveMon]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
GeneratePartyMonStats:
; wBattleMode specifies whether it's a wild mon or not.
; wMonType specifies whether it's an opposing mon or not.
; wCurPartySpecies/wCurPartyLevel specify the species and level.
; hl points to the wPartyMon struct to fill.
ld e, l
ld d, h
push hl
; Initialize the species
ld a, [wCurPartySpecies]
ld [wCurSpecies], a
call GetBaseData
ld a, [wBaseDexNo]
ld [de], a
inc de
; Copy the item if it's a wild mon
ld a, [wBattleMode]
and a
ld a, $0
jr z, .skipitem
ld a, [wEnemyMonItem]
.skipitem
ld [de], a
inc de
; Copy the moves if it's a wild mon
push de
ld h, d
ld l, e
ld a, [wBattleMode]
and a
jr z, .randomlygeneratemoves
ld a, [wMonType]
and a
jr nz, .randomlygeneratemoves
ld de, wEnemyMonMoves
rept NUM_MOVES - 1
ld a, [de]
inc de
ld [hli], a
endr
ld a, [de]
ld [hl], a
jr .next
.randomlygeneratemoves
xor a
rept NUM_MOVES - 1
ld [hli], a
endr
ld [hl], a
ld [wSkipMovesBeforeLevelUp], a
predef FillMoves
.next
pop de
rept NUM_MOVES
inc de
endr
; Initialize ID.
ld a, [wPlayerID]
ld [de], a
inc de
ld a, [wPlayerID + 1]
ld [de], a
inc de
; Initialize Exp.
push de
ld a, [wCurPartyLevel]
ld d, a
callfar CalcExpAtLevel
pop de
ldh a, [hProduct + 1]
ld [de], a
inc de
ldh a, [hProduct + 2]
ld [de], a
inc de
ldh a, [hProduct + 3]
ld [de], a
inc de
; Initialize stat experience.
xor a
ld b, MON_DVS - MON_STAT_EXP
.loop
ld [de], a
inc de
dec b
jr nz, .loop
pop hl
push hl
ld a, [wMonType]
and $f
jr z, .registerpokedex
push hl
farcall GetTrainerDVs
pop hl
jr .initializeDVs
.registerpokedex
ld a, [wCurPartySpecies]
ld [wTempSpecies], a
dec a
push de
call CheckCaughtMon
ld a, [wTempSpecies]
dec a
call SetSeenAndCaughtMon
pop de
pop hl
push hl
ld a, [wBattleMode]
and a
jr nz, .copywildmonDVs
call Random
ld b, a
call Random
ld c, a
.initializeDVs
ld a, b
ld [de], a
inc de
ld a, c
ld [de], a
inc de
; Initialize PP.
push hl
push de
inc hl
inc hl
call FillPP
pop de
pop hl
rept NUM_MOVES
inc de
endr
; Initialize happiness.
ld a, BASE_HAPPINESS
ld [de], a
inc de
xor a
; PokerusStatus
ld [de], a
inc de
; CaughtData/CaughtTime/CaughtLevel
ld [de], a
inc de
; CaughtGender/CaughtLocation
ld [de], a
inc de
; Initialize level.
ld a, [wCurPartyLevel]
ld [de], a
inc de
xor a
; Status
ld [de], a
inc de
; Unused
ld [de], a
inc de
; Initialize HP.
ld bc, MON_STAT_EXP - 1
add hl, bc
ld a, 1
ld c, a
ld b, FALSE
call CalcMonStatC
ldh a, [hProduct + 2]
ld [de], a
inc de
ldh a, [hProduct + 3]
ld [de], a
inc de
jr .initstats
.copywildmonDVs
ld a, [wEnemyMonDVs]
ld [de], a
inc de
ld a, [wEnemyMonDVs + 1]
ld [de], a
inc de
push hl
ld hl, wEnemyMonPP
ld b, NUM_MOVES
.wildmonpploop
ld a, [hli]
ld [de], a
inc de
dec b
jr nz, .wildmonpploop
pop hl
; Initialize happiness.
ld a, BASE_HAPPINESS
ld [de], a
inc de
xor a
; PokerusStatus
ld [de], a
inc de
; CaughtData/CaughtTime/CaughtLevel
ld [de], a
inc de
; CaughtGender/CaughtLocation
ld [de], a
inc de
; Initialize level.
ld a, [wCurPartyLevel]
ld [de], a
inc de
ld hl, wEnemyMonStatus
; Copy wEnemyMonStatus
ld a, [hli]
ld [de], a
inc de
; Copy EnemyMonUnused
ld a, [hli]
ld [de], a
inc de
; Copy wEnemyMonHP
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
inc de
.initstats
ld a, [wBattleMode]
dec a
jr nz, .generatestats
ld hl, wEnemyMonMaxHP
ld bc, PARTYMON_STRUCT_LENGTH - MON_MAXHP
call CopyBytes
pop hl
jr .registerunowndex
.generatestats
pop hl
ld bc, MON_STAT_EXP - 1
add hl, bc
ld b, FALSE
call CalcMonStats
.registerunowndex
ld a, [wMonType]
and $f
jr nz, .done
ld a, [wCurPartySpecies]
cp UNOWN
jr nz, .done
ld hl, wPartyMon1DVs
ld a, [wPartyCount]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
predef GetUnownLetter
callfar UpdateUnownDex
.done
scf ; When this function returns, the carry flag indicates success vs failure.
ret
FillPP:
push bc
ld b, NUM_MOVES
.loop
ld a, [hli]
and a
jr z, .next
dec a
push hl
push de
push bc
ld hl, Moves
ld bc, MOVE_LENGTH
call AddNTimes
ld de, wStringBuffer1
ld a, BANK(Moves)
call FarCopyBytes
pop bc
pop de
pop hl
ld a, [wStringBuffer1 + MOVE_PP]
.next
ld [de], a
inc de
dec b
jr nz, .loop
pop bc
ret
AddTempmonToParty:
ld hl, wPartyCount
ld a, [hl]
cp PARTY_LENGTH
scf
ret z
inc a
ld [hl], a
ld c, a
ld b, 0
add hl, bc
ld a, [wCurPartySpecies]
ld [hli], a
ld [hl], $ff
ld hl, wPartyMon1Species
ld a, [wPartyCount]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld e, l
ld d, h
ld hl, wTempMonSpecies
call CopyBytes
ld hl, wPartyMonOTs
ld a, [wPartyCount]
dec a
call SkipNames
ld d, h
ld e, l
ld hl, wOTPartyMonOTs
ld a, [wCurPartyMon]
call SkipNames
ld bc, NAME_LENGTH
call CopyBytes
ld hl, wPartyMonNicknames
ld a, [wPartyCount]
dec a
call SkipNames
ld d, h
ld e, l
ld hl, wOTPartyMonNicknames
ld a, [wCurPartyMon]
call SkipNames
ld bc, MON_NAME_LENGTH
call CopyBytes
ld a, [wCurPartySpecies]
ld [wNamedObjectIndex], a
cp EGG
jr z, .egg
dec a
call SetSeenAndCaughtMon
ld hl, wPartyMon1Happiness
ld a, [wPartyCount]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld [hl], BASE_HAPPINESS
.egg
ld a, [wCurPartySpecies]
cp UNOWN
jr nz, .done
ld hl, wPartyMon1DVs
ld a, [wPartyCount]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
predef GetUnownLetter
callfar UpdateUnownDex
ld a, [wFirstUnownSeen]
and a
jr nz, .done
ld a, [wUnownLetter]
ld [wFirstUnownSeen], a
.done
and a
ret
SendGetMonIntoFromBox:
; Sents/Gets mon into/from Box depending on Parameter
; wPokemonWithdrawDepositParameter == 0: get mon into Party
; wPokemonWithdrawDepositParameter == 1: sent mon into Box
; wPokemonWithdrawDepositParameter == 2: get mon from DayCare
; wPokemonWithdrawDepositParameter == 3: put mon into DayCare
ld a, BANK(sBoxCount)
call OpenSRAM
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .check_IfPartyIsFull
cp DAY_CARE_WITHDRAW
jr z, .check_IfPartyIsFull
cp DAY_CARE_DEPOSIT
ld hl, wBreedMon1Species
jr z, .breedmon
; we want to sent a mon into the Box
; so check if there's enough space
ld hl, sBoxCount
ld a, [hl]
cp MONS_PER_BOX
jr nz, .there_is_room
jp CloseSRAM_And_SetCarryFlag
.check_IfPartyIsFull
ld hl, wPartyCount
ld a, [hl]
cp PARTY_LENGTH
jp z, CloseSRAM_And_SetCarryFlag
.there_is_room
inc a
ld [hl], a
ld c, a
ld b, 0
add hl, bc
ld a, [wPokemonWithdrawDepositParameter]
cp DAY_CARE_WITHDRAW
ld a, [wBreedMon1Species]
jr z, .okay1
ld a, [wCurPartySpecies]
.okay1
ld [hli], a
ld [hl], $ff
ld a, [wPokemonWithdrawDepositParameter]
dec a
ld hl, wPartyMon1Species
ld bc, PARTYMON_STRUCT_LENGTH
ld a, [wPartyCount]
jr nz, .okay2
ld hl, sBoxMon1Species
ld bc, BOXMON_STRUCT_LENGTH
ld a, [sBoxCount]
.okay2
dec a ; wPartyCount - 1
call AddNTimes
.breedmon
push hl
ld e, l
ld d, h
ld a, [wPokemonWithdrawDepositParameter]
and a
ld hl, sBoxMon1Species
ld bc, BOXMON_STRUCT_LENGTH
jr z, .okay3
cp DAY_CARE_WITHDRAW
ld hl, wBreedMon1Species
jr z, .okay4
ld hl, wPartyMon1Species
ld bc, PARTYMON_STRUCT_LENGTH
.okay3
ld a, [wCurPartyMon]
call AddNTimes
.okay4
ld bc, BOXMON_STRUCT_LENGTH
call CopyBytes
ld a, [wPokemonWithdrawDepositParameter]
cp DAY_CARE_DEPOSIT
ld de, wBreedMon1OT
jr z, .okay5
dec a
ld hl, wPartyMonOTs
ld a, [wPartyCount]
jr nz, .okay6
ld hl, sBoxMonOTs
ld a, [sBoxCount]
.okay6
dec a
call SkipNames
ld d, h
ld e, l
.okay5
ld hl, sBoxMonOTs
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .okay7
ld hl, wBreedMon1OT
cp DAY_CARE_WITHDRAW
jr z, .okay8
ld hl, wPartyMonOTs
.okay7
ld a, [wCurPartyMon]
call SkipNames
.okay8
ld bc, NAME_LENGTH
call CopyBytes
ld a, [wPokemonWithdrawDepositParameter]
cp DAY_CARE_DEPOSIT
ld de, wBreedMon1Nickname
jr z, .okay9
dec a
ld hl, wPartyMonNicknames
ld a, [wPartyCount]
jr nz, .okay10
ld hl, sBoxMonNicknames
ld a, [sBoxCount]
.okay10
dec a
call SkipNames
ld d, h
ld e, l
.okay9
ld hl, sBoxMonNicknames
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .okay11
ld hl, wBreedMon1Nickname
cp DAY_CARE_WITHDRAW
jr z, .okay12
ld hl, wPartyMonNicknames
.okay11
ld a, [wCurPartyMon]
call SkipNames
.okay12
ld bc, MON_NAME_LENGTH
call CopyBytes
pop hl
ld a, [wPokemonWithdrawDepositParameter]
cp PC_DEPOSIT
jr z, .took_out_of_box
cp DAY_CARE_DEPOSIT
jp z, .CloseSRAM_And_ClearCarryFlag
push hl
srl a
add $2
ld [wMonType], a
predef CopyMonToTempMon
callfar CalcLevel
ld a, d
ld [wCurPartyLevel], a
pop hl
ld b, h
ld c, l
ld hl, MON_LEVEL
add hl, bc
ld [hl], a
ld hl, MON_MAXHP
add hl, bc
ld d, h
ld e, l
ld hl, MON_STAT_EXP - 1
add hl, bc
push bc
ld b, TRUE
call CalcMonStats
pop bc
ld a, [wPokemonWithdrawDepositParameter]
and a
jr nz, .CloseSRAM_And_ClearCarryFlag
ld hl, MON_STATUS
add hl, bc
xor a
ld [hl], a
ld hl, MON_HP
add hl, bc
ld d, h
ld e, l
ld a, [wCurPartySpecies]
cp EGG
jr z, .egg
inc hl
inc hl
ld a, [hli]
ld [de], a
ld a, [hl]
inc de
ld [de], a
jr .CloseSRAM_And_ClearCarryFlag
.egg
xor a
ld [de], a
inc de
ld [de], a
jr .CloseSRAM_And_ClearCarryFlag
.took_out_of_box
ld a, [sBoxCount]
dec a
ld b, a
call RestorePPOfDepositedPokemon
.CloseSRAM_And_ClearCarryFlag:
call CloseSRAM
and a
ret
CloseSRAM_And_SetCarryFlag:
call CloseSRAM
scf
ret
RestorePPOfDepositedPokemon:
ld a, b
ld hl, sBoxMons
ld bc, BOXMON_STRUCT_LENGTH
call AddNTimes
ld b, h
ld c, l
ld hl, MON_PP
add hl, bc
push hl
push bc
ld de, wTempMonPP
ld bc, NUM_MOVES
call CopyBytes
pop bc
ld hl, MON_MOVES
add hl, bc
push hl
ld de, wTempMonMoves
ld bc, NUM_MOVES
call CopyBytes
pop hl
pop de
ld a, [wMenuCursorY]
push af
ld a, [wMonType]
push af
ld b, 0
.loop
ld a, [hli]
and a
jr z, .done
ld [wTempMonMoves], a
ld a, BOXMON
ld [wMonType], a
ld a, b
ld [wMenuCursorY], a
push bc
push hl
push de
farcall GetMaxPPOfMove
pop de
pop hl
ld a, [wTempPP]
ld b, a
ld a, [de]
and %11000000
add b
ld [de], a
pop bc
inc de
inc b
ld a, b
cp NUM_MOVES
jr c, .loop
.done
pop af
ld [wMonType], a
pop af
ld [wMenuCursorY], a
ret
RetrieveMonFromDayCareMan:
ld a, [wBreedMon1Species]
ld [wCurPartySpecies], a
ld de, SFX_TRANSACTION
call PlaySFX
call WaitSFX
call GetBreedMon1LevelGrowth
ld a, b
ld [wPrevPartyLevel], a
ld a, e
ld [wCurPartyLevel], a
xor a
ld [wPokemonWithdrawDepositParameter], a
jp RetrieveBreedmon
RetrieveMonFromDayCareLady:
ld a, [wBreedMon2Species]
ld [wCurPartySpecies], a
ld de, SFX_TRANSACTION
call PlaySFX
call WaitSFX
call GetBreedMon2LevelGrowth
ld a, b
ld [wPrevPartyLevel], a
ld a, e
ld [wCurPartyLevel], a
ld a, PC_DEPOSIT
ld [wPokemonWithdrawDepositParameter], a
jp RetrieveBreedmon ; pointless
RetrieveBreedmon:
ld hl, wPartyCount
ld a, [hl]
cp PARTY_LENGTH
jr nz, .room_in_party
scf
ret
.room_in_party
inc a
ld [hl], a
ld c, a
ld b, 0
add hl, bc
ld a, [wPokemonWithdrawDepositParameter]
and a
ld a, [wBreedMon1Species]
ld de, wBreedMon1Nickname
jr z, .okay
ld a, [wBreedMon2Species]
ld de, wBreedMon2Nickname
.okay
ld [hli], a
ld [wCurSpecies], a
ld a, $ff
ld [hl], a
ld hl, wPartyMonNicknames
ld a, [wPartyCount]
dec a
call SkipNames
push hl
ld h, d
ld l, e
pop de
call CopyBytes
push hl
ld hl, wPartyMonOTs
ld a, [wPartyCount]
dec a
call SkipNames
ld d, h
ld e, l
pop hl
call CopyBytes
push hl
call GetLastPartyMon
pop hl
ld bc, BOXMON_STRUCT_LENGTH
call CopyBytes
call GetBaseData
call GetLastPartyMon
ld b, d
ld c, e
ld hl, MON_LEVEL
add hl, bc
ld a, [wCurPartyLevel]
ld [hl], a
ld hl, MON_MAXHP
add hl, bc
ld d, h
ld e, l
ld hl, $a
add hl, bc
push bc
ld b, TRUE
call CalcMonStats
ld hl, wPartyMon1Moves
ld a, [wPartyCount]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld d, h
ld e, l
ld a, TRUE
ld [wSkipMovesBeforeLevelUp], a
predef FillMoves
ld a, [wPartyCount]
dec a
ld [wCurPartyMon], a
farcall HealPartyMon
ld a, [wCurPartyLevel]
ld d, a
callfar CalcExpAtLevel
pop bc
ld hl, $8
add hl, bc
ldh a, [hMultiplicand]
ld [hli], a
ldh a, [hMultiplicand + 1]
ld [hli], a
ldh a, [hMultiplicand + 2]
ld [hl], a
and a
ret
GetLastPartyMon:
ld a, [wPartyCount]
dec a
ld hl, wPartyMon1Species
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld d, h
ld e, l
ret
DepositMonWithDayCareMan:
ld de, wBreedMon1Nickname
call DepositBreedmon
xor a ; REMOVE_PARTY
ld [wPokemonWithdrawDepositParameter], a
jp RemoveMonFromPartyOrBox
DepositMonWithDayCareLady:
ld de, wBreedMon2Nickname
call DepositBreedmon
xor a ; REMOVE_PARTY
ld [wPokemonWithdrawDepositParameter], a
jp RemoveMonFromPartyOrBox
DepositBreedmon:
ld a, [wCurPartyMon]
ld hl, wPartyMonNicknames
call SkipNames
call CopyBytes
ld a, [wCurPartyMon]
ld hl, wPartyMonOTs
call SkipNames
call CopyBytes
ld a, [wCurPartyMon]
ld hl, wPartyMon1Species
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld bc, BOXMON_STRUCT_LENGTH
jp CopyBytes
SendMonIntoBox:
; Sends the mon into one of Bills Boxes
; the data comes mainly from 'wEnemyMon:'
ld a, BANK(sBoxCount)
call OpenSRAM
ld de, sBoxCount
ld a, [de]
cp MONS_PER_BOX
jp nc, .full
inc a
ld [de], a
ld a, [wCurPartySpecies]
ld [wCurSpecies], a
ld c, a
.loop
inc de
ld a, [de]
ld b, a
ld a, c
ld c, b
ld [de], a
inc a
jr nz, .loop
call GetBaseData
call ShiftBoxMon
ld hl, wPlayerName
ld de, sBoxMonOTs
ld bc, NAME_LENGTH
call CopyBytes
ld a, [wCurPartySpecies]
ld [wNamedObjectIndex], a
call GetPokemonName
ld de, sBoxMonNicknames
ld hl, wStringBuffer1
ld bc, MON_NAME_LENGTH
call CopyBytes
ld hl, wEnemyMon
ld de, sBoxMon1
ld bc, 1 + 1 + NUM_MOVES ; species + item + moves
call CopyBytes
ld hl, wPlayerID
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
inc de
push de
ld a, [wCurPartyLevel]
ld d, a
callfar CalcExpAtLevel
pop de
ldh a, [hProduct + 1]
ld [de], a
inc de
ldh a, [hProduct + 2]
ld [de], a
inc de
ldh a, [hProduct + 3]
ld [de], a
inc de
; Set all 5 Experience Values to 0
xor a
ld b, 2 * 5
.loop2
ld [de], a
inc de
dec b
jr nz, .loop2
ld hl, wEnemyMonDVs
ld b, 2 + NUM_MOVES ; DVs and PP ; wEnemyMonHappiness - wEnemyMonDVs
.loop3
ld a, [hli]
ld [de], a
inc de
dec b
jr nz, .loop3
ld a, BASE_HAPPINESS
ld [de], a
inc de
xor a
ld [de], a
inc de
ld [de], a
inc de
ld [de], a
inc de
ld a, [wCurPartyLevel]
ld [de], a
ld a, [wCurPartySpecies]
dec a
call SetSeenAndCaughtMon
ld a, [wCurPartySpecies]
cp UNOWN
jr nz, .not_unown
ld hl, sBoxMon1DVs
predef GetUnownLetter
callfar UpdateUnownDex
.not_unown
ld hl, sBoxMon1Moves
ld de, wTempMonMoves
ld bc, NUM_MOVES
call CopyBytes
ld hl, sBoxMon1PP
ld de, wTempMonPP
ld bc, NUM_MOVES
call CopyBytes
ld b, 0
call RestorePPOfDepositedPokemon
call CloseSRAM
scf
ret
.full
call CloseSRAM
and a
ret
ShiftBoxMon:
ld hl, sBoxMonOTs
ld bc, NAME_LENGTH
call .shift
ld hl, sBoxMonNicknames
ld bc, MON_NAME_LENGTH
call .shift
ld hl, sBoxMons
ld bc, BOXMON_STRUCT_LENGTH
.shift
ld a, [sBoxCount]
cp 2
ret c
push hl
call AddNTimes
dec hl
ld e, l
ld d, h
pop hl
ld a, [sBoxCount]
dec a
call AddNTimes
dec hl
push hl
ld a, [sBoxCount]
dec a
ld hl, 0
call AddNTimes
ld c, l
ld b, h
pop hl
.loop
ld a, [hld]
ld [de], a
dec de
dec bc
ld a, c
or b
jr nz, .loop
ret
GiveEgg::
ld a, [wCurPartySpecies]
push af
callfar GetPreEvolution
callfar GetPreEvolution
ld a, [wCurPartySpecies]
dec a
; TryAddMonToParty sets Seen and Caught flags
; when it is successful. This routine will make
; sure that we aren't newly setting flags.
push af
call CheckCaughtMon
pop af
push bc
call CheckSeenMon
push bc
call TryAddMonToParty
; If we haven't caught this Pokemon before receiving
; the Egg, reset the flag that was just set by
; TryAddMonToParty.
pop bc
ld a, c
and a
jr nz, .skip_caught_flag
ld a, [wCurPartySpecies]
dec a
ld c, a
ld d, $0
ld hl, wPokedexCaught
ld b, RESET_FLAG
predef SmallFarFlagAction
.skip_caught_flag
; If we haven't seen this Pokemon before receiving
; the Egg, reset the flag that was just set by
; TryAddMonToParty.
pop bc
ld a, c
and a
jr nz, .skip_seen_flag
ld a, [wCurPartySpecies]
dec a
ld c, a
ld d, $0
ld hl, wPokedexSeen
ld b, RESET_FLAG
predef SmallFarFlagAction
.skip_seen_flag
pop af
ld [wCurPartySpecies], a
ld a, [wPartyCount]
dec a
ld bc, PARTYMON_STRUCT_LENGTH
ld hl, wPartyMon1Species
call AddNTimes
ld a, [wCurPartySpecies]
ld [hl], a
ld hl, wPartyCount
ld a, [hl]
ld b, 0
ld c, a
add hl, bc
ld a, EGG
ld [hl], a
ld a, [wPartyCount]
dec a
ld hl, wPartyMonNicknames
call SkipNames
ld de, String_Egg
call CopyName2
ld a, [wPartyCount]
dec a
ld hl, wPartyMon1Happiness
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [wDebugFlags]
bit DEBUG_FIELD_F, a
ld a, 1
jr nz, .got_init_happiness
ld a, [wBaseEggSteps]
.got_init_happiness
ld [hl], a
ld a, [wPartyCount]
dec a
ld hl, wPartyMon1HP
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
xor a
ld [hli], a
ld [hl], a
and a
ret
String_Egg:
db "EGG@"
RemoveMonFromPartyOrBox:
ld hl, wPartyCount
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .okay
ld a, BANK(sBoxCount)
call OpenSRAM
ld hl, sBoxCount
.okay
ld a, [hl]
dec a
ld [hli], a
ld a, [wCurPartyMon]
ld c, a
ld b, 0
add hl, bc
ld e, l
ld d, h
inc de
.loop
ld a, [de]
inc de
ld [hli], a
inc a
jr nz, .loop
ld hl, wPartyMonOTs
ld d, PARTY_LENGTH - 1
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .party
ld hl, sBoxMonOTs
ld d, MONS_PER_BOX - 1
.party
; If this is the last mon in our party (box),
; shift all the other mons up to close the gap.
ld a, [wCurPartyMon]
call SkipNames
ld a, [wCurPartyMon]
cp d
jr nz, .delete_inside
ld [hl], -1
jp .finish
.delete_inside
; Shift the OT names
ld d, h
ld e, l
ld bc, MON_NAME_LENGTH
add hl, bc
ld bc, wPartyMonNicknames
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .party2
ld bc, sBoxMonNicknames
.party2
call CopyDataUntil
; Shift the struct
ld hl, wPartyMons
ld bc, PARTYMON_STRUCT_LENGTH
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .party4
ld hl, sBoxMons
ld bc, BOXMON_STRUCT_LENGTH
.party4
ld a, [wCurPartyMon]
call AddNTimes
ld d, h
ld e, l
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .party5
ld bc, BOXMON_STRUCT_LENGTH
add hl, bc
ld bc, sBoxMonOTs
jr .copy
.party5
ld bc, PARTYMON_STRUCT_LENGTH
add hl, bc
ld bc, wPartyMonOTs
.copy
call CopyDataUntil
; Shift the nicknames
ld hl, wPartyMonNicknames
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .party6
ld hl, sBoxMonNicknames
.party6
ld bc, MON_NAME_LENGTH
ld a, [wCurPartyMon]
call AddNTimes
ld d, h
ld e, l
ld bc, MON_NAME_LENGTH
add hl, bc
ld bc, wPartyMonNicknamesEnd
ld a, [wPokemonWithdrawDepositParameter]
and a
jr z, .party7
ld bc, sBoxMonNicknamesEnd
.party7
call CopyDataUntil
; Mail time!
.finish
ld a, [wPokemonWithdrawDepositParameter]
and a
jp nz, CloseSRAM
ld a, [wLinkMode]
and a
ret nz
; Shift mail
ld a, BANK(sPartyMail)
call OpenSRAM
; If this is the last mon in our party, no need to shift mail.
ld hl, wPartyCount
ld a, [wCurPartyMon]
cp [hl]
jr z, .close_sram
; Shift our mail messages up.
ld hl, sPartyMail
ld bc, MAIL_STRUCT_LENGTH
call AddNTimes
push hl
add hl, bc
pop de
ld a, [wCurPartyMon]
ld b, a
.loop2
push bc
push hl
ld bc, MAIL_STRUCT_LENGTH
call CopyBytes
pop hl
push hl
ld bc, MAIL_STRUCT_LENGTH
add hl, bc
pop de
pop bc
inc b
ld a, [wPartyCount]
cp b
jr nz, .loop2
.close_sram
jp CloseSRAM
ComputeNPCTrademonStats:
ld a, MON_LEVEL
call GetPartyParamLocation
ld a, [hl]
ld [MON_LEVEL], a ; wow
ld a, MON_SPECIES
call GetPartyParamLocation
ld a, [hl]
ld [wCurSpecies], a
call GetBaseData
ld a, MON_MAXHP
call GetPartyParamLocation
ld d, h
ld e, l
push de
ld a, MON_STAT_EXP - 1
call GetPartyParamLocation
ld b, TRUE
call CalcMonStats
pop de
ld a, MON_HP
call GetPartyParamLocation
ld a, [de]
inc de
ld [hli], a
ld a, [de]
ld [hl], a
ret
CalcMonStats:
; Calculates all 6 Stats of a mon
; b: Take into account stat EXP if TRUE
; 'c' counts from 1-6 and points with 'wBaseStats' to the base value
; hl is the path to the Stat EXP
; de points to where the final stats will be saved
ld c, STAT_HP - 1 ; first stat
.loop
inc c
call CalcMonStatC
ldh a, [hMultiplicand + 1]
ld [de], a
inc de
ldh a, [hMultiplicand + 2]
ld [de], a
inc de
ld a, c
cp STAT_SDEF ; last stat
jr nz, .loop
ret
CalcMonStatC:
; 'c' is 1-6 and points to the BaseStat
; 1: HP
; 2: Attack
; 3: Defense
; 4: Speed
; 5: SpAtk
; 6: SpDef
push hl
push de
push bc
ld a, b
ld d, a
push hl
ld hl, wBaseStats
dec hl ; has to be decreased, because 'c' begins with 1
ld b, 0
add hl, bc
ld a, [hl]
ld e, a
pop hl
push hl
ld a, c
cp STAT_SDEF ; last stat
jr nz, .not_spdef
dec hl
dec hl
.not_spdef
sla c
ld a, d
and a
jr z, .no_stat_exp
add hl, bc
push de
ld a, [hld]
ld e, a
ld d, [hl]
farcall GetSquareRoot
pop de
.no_stat_exp
srl c
pop hl
push bc
ld bc, MON_DVS - MON_HP_EXP + 1
add hl, bc
pop bc
ld a, c
cp STAT_ATK
jr z, .Attack
cp STAT_DEF
jr z, .Defense
cp STAT_SPD
jr z, .Speed
cp STAT_SATK
jr z, .Special
cp STAT_SDEF
jr z, .Special
; DV_HP = (DV_ATK & 1) << 3 | (DV_DEF & 1) << 2 | (DV_SPD & 1) << 1 | (DV_SPC & 1)
push bc
ld a, [hl]
swap a
and 1
add a
add a
add a
ld b, a
ld a, [hli]
and 1
add a
add a
add b
ld b, a
ld a, [hl]
swap a
and 1
add a
add b
ld b, a
ld a, [hl]
and 1
add b
pop bc
jr .GotDV
.Attack:
ld a, [hl]
swap a
and $f
jr .GotDV
.Defense:
ld a, [hl]
and $f
jr .GotDV
.Speed:
inc hl
ld a, [hl]
swap a
and $f
jr .GotDV
.Special:
inc hl
ld a, [hl]
and $f
.GotDV:
ld d, 0
add e
ld e, a
jr nc, .no_overflow_1
inc d
.no_overflow_1
sla e
rl d
srl b
srl b
ld a, b
add e
jr nc, .no_overflow_2
inc d
.no_overflow_2
ldh [hMultiplicand + 2], a
ld a, d
ldh [hMultiplicand + 1], a
xor a
ldh [hMultiplicand + 0], a
ld a, [wCurPartyLevel]
ldh [hMultiplier], a
call Multiply
ldh a, [hProduct + 1]
ldh [hDividend + 0], a
ldh a, [hProduct + 2]
ldh [hDividend + 1], a
ldh a, [hProduct + 3]
ldh [hDividend + 2], a
ld a, 100
ldh [hDivisor], a
ld a, 3
ld b, a
call Divide
ld a, c
cp STAT_HP
ld a, STAT_MIN_NORMAL
jr nz, .not_hp
ld a, [wCurPartyLevel]
ld b, a
ldh a, [hQuotient + 3]
add b
ldh [hMultiplicand + 2], a
jr nc, .no_overflow_3
ldh a, [hQuotient + 2]
inc a
ldh [hMultiplicand + 1], a
.no_overflow_3
ld a, STAT_MIN_HP
.not_hp
ld b, a
ldh a, [hQuotient + 3]
add b
ldh [hMultiplicand + 2], a
jr nc, .no_overflow_4
ldh a, [hQuotient + 2]
inc a
ldh [hMultiplicand + 1], a
.no_overflow_4
ldh a, [hQuotient + 2]
cp HIGH(MAX_STAT_VALUE + 1) + 1
jr nc, .max_stat
cp HIGH(MAX_STAT_VALUE + 1)
jr c, .stat_value_okay
ldh a, [hQuotient + 3]
cp LOW(MAX_STAT_VALUE + 1)
jr c, .stat_value_okay
.max_stat
ld a, HIGH(MAX_STAT_VALUE)
ldh [hMultiplicand + 1], a
ld a, LOW(MAX_STAT_VALUE)
ldh [hMultiplicand + 2], a
.stat_value_okay
pop bc
pop de
pop hl
ret
GivePoke::
push de
push bc
xor a ; PARTYMON
ld [wMonType], a
call TryAddMonToParty
jr nc, .failed
ld hl, wPartyMonNicknames
ld a, [wPartyCount]
dec a
ld [wCurPartyMon], a
call SkipNames
ld d, h
ld e, l
pop bc
ld a, b
ld b, 0
push bc
push de
push af
ld a, [wCurItem]
and a
jr z, .done
ld a, [wCurPartyMon]
ld hl, wPartyMon1Item
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [wCurItem]
ld [hl], a
jr .done
.failed
ld a, [wCurPartySpecies]
ld [wTempEnemyMonSpecies], a
callfar LoadEnemyMon
call SendMonIntoBox
jp nc, .FailedToGiveMon
ld a, BOXMON
ld [wMonType], a
xor a
ld [wCurPartyMon], a
ld de, wMonOrItemNameBuffer
pop bc
ld a, b
ld b, 1
push bc
push de
push af
ld a, [wCurItem]
and a
jr z, .done
ld a, [wCurItem]
ld [sBoxMon1Item], a
.done
ld a, [wCurPartySpecies]
ld [wNamedObjectIndex], a
ld [wTempEnemyMonSpecies], a
call GetPokemonName
ld hl, wStringBuffer1
ld de, wMonOrItemNameBuffer
ld bc, MON_NAME_LENGTH
call CopyBytes
pop af
and a
jp z, .wildmon
pop de
pop bc
pop hl
push bc
push hl
ld a, [wScriptBank]
call GetFarWord
ld bc, MON_NAME_LENGTH
ld a, [wScriptBank]
call FarCopyBytes
pop hl
inc hl
inc hl
ld a, [wScriptBank]
call GetFarWord
pop bc
ld a, b
and a
push de
push bc
jr nz, .send_to_box
push hl
ld a, [wCurPartyMon]
ld hl, wPartyMonOTs
call SkipNames
ld d, h
ld e, l
pop hl
.otnameloop
ld a, [wScriptBank]
call GetFarByte
ld [de], a
inc hl
inc de
cp "@"
jr nz, .otnameloop
ld a, [wScriptBank]
call GetFarByte
ld b, a
push bc
ld a, [wCurPartyMon]
ld hl, wPartyMon1ID
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, HIGH(RANDY_OT_ID)
ld [hli], a
ld [hl], LOW(RANDY_OT_ID)
pop bc
farcall SetGiftPartyMonCaughtData
jr .skip_nickname
.send_to_box
ld a, BANK(sBoxMonOTs)
call OpenSRAM
ld de, sBoxMonOTs
.loop
ld a, [wScriptBank]
call GetFarByte
ld [de], a
inc hl
inc de
cp "@"
jr nz, .loop
ld a, [wScriptBank]
call GetFarByte
ld b, a
ld hl, sBoxMon1ID
call Random
ld [hli], a
call Random
ld [hl], a
call CloseSRAM
farcall SetGiftBoxMonCaughtData
jr .skip_nickname
.wildmon
pop de
pop bc
push bc
push de
ld a, b
and a
jr z, .party
farcall SetBoxMonCaughtData
jr .set_caught_data
.party
farcall SetCaughtData
.set_caught_data
farcall GiveANickname_YesNo
pop de
jr c, .skip_nickname
call InitNickname
.skip_nickname
pop bc
pop de
ld a, b
and a
ret z
ld hl, WasSentToBillsPCText
call PrintText
ld a, BANK(sBoxMonNicknames)
call OpenSRAM
ld hl, wMonOrItemNameBuffer
ld de, sBoxMonNicknames
ld bc, MON_NAME_LENGTH
call CopyBytes
call CloseSRAM
ld b, $1
ret
.FailedToGiveMon:
pop bc
pop de
ld b, $2
ret
WasSentToBillsPCText:
text_far _WasSentToBillsPCText
text_end
InitNickname:
push de
call LoadStandardMenuHeader
call DisableSpriteUpdates
pop de
push de
ld b, NAME_MON
farcall NamingScreen
pop hl
ld de, wStringBuffer1
call InitName
ld a, $4 ; ExitAllMenus is in bank 0; maybe it used to be in bank 4
ld hl, ExitAllMenus
rst FarCall
ret