diff options
Diffstat (limited to 'engine/pokemon/move_mon.asm')
-rw-r--r-- | engine/pokemon/move_mon.asm | 1820 |
1 files changed, 1820 insertions, 0 deletions
diff --git a/engine/pokemon/move_mon.asm b/engine/pokemon/move_mon.asm new file mode 100644 index 000000000..128bbf200 --- /dev/null +++ b/engine/pokemon/move_mon.asm @@ -0,0 +1,1820 @@ +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? + ld [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, wPartyMonOT + ld a, [wMonType] + and $f + jr z, .loadOTname + ld hl, wOTPartyMonOT + +.loadOTname + ld 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 [wd265], a + call GetPokemonName + ld hl, wPartyMonNicknames + ld 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 + ld 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 [wBuffer1], 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 + ld a, [hProduct + 1] + ld [de], a + inc de + ld a, [hProduct + 2] + ld [de], a + inc de + ld 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 [wd265], a + dec a + push de + call CheckCaughtMon + ld a, [wd265] + 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 + ld a, [hProduct + 2] + ld [de], a + inc de + ld 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, wPartyMonOT + ld a, [wPartyCount] + dec a + call SkipNames + ld d, h + ld e, l + ld hl, wOTPartyMonOT + 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 [wNamedObjectIndexBuffer], 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 GetSRAMBank + 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, wPartyMonOT + ld a, [wPartyCount] + jr nz, .okay6 + ld hl, sBoxMonOT + ld a, [sBoxCount] + +.okay6 + dec a + call SkipNames + ld d, h + ld e, l + +.okay5 + ld hl, sBoxMonOT + ld a, [wPokemonWithdrawDepositParameter] + and a + jr z, .okay7 + ld hl, wBreedMon1OT + cp DAY_CARE_WITHDRAW + jr z, .okay8 + ld hl, wPartyMonOT + +.okay7 + ld a, [wCurPartyMon] + call SkipNames + +.okay8 + ld bc, NAME_LENGTH + call CopyBytes + ld a, [wPokemonWithdrawDepositParameter] + cp DAY_CARE_DEPOSIT + ld de, wBreedMon1Nick + 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, wBreedMon1Nick + 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, [wd265] + 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 [wd002], 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 [wd002], a + ld a, e + ld [wCurPartyLevel], a + ld a, PC_DEPOSIT + ld [wPokemonWithdrawDepositParameter], a + jp RetrieveBreedmon + +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, wBreedMon1Nick + jr z, .okay + ld a, [wBreedMon2Species] + ld de, wBreedMon2Nick + +.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, wPartyMonOT + 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, $1 + ld [wBuffer1], 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 + ld a, [hMultiplicand] + ld [hli], a + ld a, [hMultiplicand + 1] + ld [hli], a + ld 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, wBreedMon1Nick + call DepositBreedmon + xor a ; REMOVE_PARTY + ld [wPokemonWithdrawDepositParameter], a + jp RemoveMonFromPartyOrBox + +DepositMonWithDayCareLady: + ld de, wBreedMon2Nick + 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, wPartyMonOT + 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 GetSRAMBank + 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, sBoxMonOT + ld bc, NAME_LENGTH + call CopyBytes + + ld a, [wCurPartySpecies] + ld [wd265], 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 + ld a, [hProduct + 1] + ld [de], a + inc de + ld a, [hProduct + 2] + ld [de], a + inc de + ld 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, sBoxMonOT + 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, [wMonStatusFlags] + bit 1, 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 GetSRAMBank + 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, wPartyMonOT + ld d, PARTY_LENGTH - 1 + ld a, [wPokemonWithdrawDepositParameter] + and a + jr z, .party + ld hl, sBoxMonOT + 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, sBoxMonOT + jr .copy + +.party5 + ld bc, PARTYMON_STRUCT_LENGTH + add hl, bc + ld bc, wPartyMonOT +.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 GetSRAMBank + ; 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 + ld a, [hMultiplicand + 1] + ld [de], a + inc de + ld 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 + ld [hMultiplicand + 2], a + ld a, d + ld [hMultiplicand + 1], a + xor a + ld [hMultiplicand + 0], a + ld a, [wCurPartyLevel] + ld [hMultiplier], a + call Multiply + ld a, [hProduct + 1] + ld [hDividend + 0], a + ld a, [hProduct + 2] + ld [hDividend + 1], a + ld a, [hProduct + 3] + ld [hDividend + 2], a + ld a, 100 + ld [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 + ld a, [hQuotient + 2] + add b + ld [hMultiplicand + 2], a + jr nc, .no_overflow_3 + ld a, [hQuotient + 1] + inc a + ld [hMultiplicand + 1], a + +.no_overflow_3 + ld a, STAT_MIN_HP + +.not_hp + ld b, a + ld a, [hQuotient + 2] + add b + ld [hMultiplicand + 2], a + jr nc, .no_overflow_4 + ld a, [hQuotient + 1] + inc a + ld [hMultiplicand + 1], a + +.no_overflow_4 + ld a, [hQuotient + 1] + cp HIGH(MAX_STAT_VALUE + 1) + 1 + jr nc, .max_stat + cp HIGH(MAX_STAT_VALUE + 1) + jr c, .stat_value_okay + ld a, [hQuotient + 2] + cp LOW(MAX_STAT_VALUE + 1) + jr c, .stat_value_okay + +.max_stat + ld a, HIGH(MAX_STAT_VALUE) + ld [hMultiplicand + 1], a + ld a, LOW(MAX_STAT_VALUE) + ld [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 [wd265], 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 GetFarHalfword + ld bc, MON_NAME_LENGTH + ld a, [wScriptBank] + call FarCopyBytes + pop hl + inc hl + inc hl + ld a, [wScriptBank] + call GetFarHalfword + pop bc + ld a, b + and a + push de + push bc + jr nz, .send_to_box + + push hl + ld a, [wCurPartyMon] + ld hl, wPartyMonOT + 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(01001) + ld [hli], a + ld [hl], LOW(01001) + pop bc + farcall SetGiftPartyMonCaughtData + jr .skip_nickname + +.send_to_box + ld a, BANK(sBoxMonOT) + call GetSRAMBank + ld de, sBoxMonOT +.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, TextJump_WasSentToBillsPC + call PrintText + ld a, BANK(sBoxMonNicknames) + call GetSRAMBank + 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 + +TextJump_WasSentToBillsPC: + ; was sent to BILL's PC. + text_jump Text_WasSentToBillsPC + db "@" + +InitNickname: + push de + call LoadStandardMenuHeader + call DisableSpriteUpdates + pop de + push de + ld b, $0 + farcall NamingScreen + pop hl + ld de, wStringBuffer1 + call InitName + ld a, $4 ; ExitAllMenus is in bank 0, XXX could this be in bank 4 in pokered? + ld hl, ExitAllMenus + rst FarCall + ret |