diff options
Diffstat (limited to 'engine')
-rw-r--r-- | engine/events/bug_contest/contest_2.asm | 116 | ||||
-rw-r--r-- | engine/events/bug_contest/judging.asm | 373 | ||||
-rw-r--r-- | engine/events/pokerus/apply_pokerus_tick.asm | 26 | ||||
-rwxr-xr-x | engine/specials.asm | 2 |
4 files changed, 516 insertions, 1 deletions
diff --git a/engine/events/bug_contest/contest_2.asm b/engine/events/bug_contest/contest_2.asm new file mode 100644 index 00000000..ddfad864 --- /dev/null +++ b/engine/events/bug_contest/contest_2.asm @@ -0,0 +1,116 @@ +SelectRandomBugContestContestants: +; Select five random people to participate in the current contest. + +; First we have to make sure that any old data is cleared away. + ld c, NUM_BUG_CONTESTANTS + ld hl, BugCatchingContestantEventFlagTable +.loop1 + push bc + push hl + ld e, [hl] + inc hl + ld d, [hl] + ld b, RESET_FLAG + call EventFlagAction + pop hl + inc hl + inc hl + pop bc + dec c + jr nz, .loop1 + +; Now that that's out of the way, we can get on to the good stuff. + ld c, 5 +.loop2 + push bc +.next +; Choose a flag at uniform random to be set. + call Random + cp $ff / NUM_BUG_CONTESTANTS * NUM_BUG_CONTESTANTS + jr nc, .next + ld c, $ff / NUM_BUG_CONTESTANTS + call SimpleDivide + ld e, b + ld d, 0 + ld hl, BugCatchingContestantEventFlagTable + add hl, de + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + push de +; If we've already set it, it doesn't count. + ld b, CHECK_FLAG + call EventFlagAction + pop de + ld a, c + and a + jr nz, .next +; Set the flag. This will cause that sprite to not be visible in the contest. + ld b, SET_FLAG + call EventFlagAction + pop bc +; Check if we're done. If so, return. Otherwise, choose the next victim. + dec c + jr nz, .loop2 + ret + +CheckBugContestContestantFlag: +; Checks the flag of the Bug Catching Contestant whose index is loaded in a. + + ld hl, BugCatchingContestantEventFlagTable + ld e, a + ld d, 0 + add hl, de + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + ld b, CHECK_FLAG + call EventFlagAction + ret + +INCLUDE "data/events/bug_contest_flags.asm" + +ContestDropOffMons: + ld hl, wPartyMon1HP + ld a, [hli] + or [hl] + jr z, .fainted +; Mask the rest of your party by setting the count to 1... + ld hl, wPartyCount + ld a, 1 + ld [hli], a + inc hl +; ... backing up the second mon index somewhere... + ld a, [hl] + ld [wBugContestSecondPartySpecies], a +; ... and replacing it with the terminator byte + ld [hl], -1 + xor a + ld [wScriptVar], a + ret + +.fainted + ld a, $1 + ld [wScriptVar], a + ret + +ContestReturnMons: +; Restore the species of the second mon. + ld hl, wPartySpecies + 1 + ld a, [wBugContestSecondPartySpecies] + ld [hl], a +; Restore the party count, which must be recomputed. + ld b, 1 +.loop + ld a, [hli] + cp -1 + jr z, .done + inc b + jr .loop + +.done + ld a, b + ld [wPartyCount], a + ret diff --git a/engine/events/bug_contest/judging.asm b/engine/events/bug_contest/judging.asm new file mode 100644 index 00000000..fd8015a9 --- /dev/null +++ b/engine/events/bug_contest/judging.asm @@ -0,0 +1,373 @@ +_BugContestJudging: + call ContestScore + call BugContest_JudgeContestants + ld a, [wBugContestThirdPlaceWinnerID] + call LoadContestantName + ld a, [wBugContestThirdPlaceMon] + ld [wNamedObjectIndexBuffer], a + call GetPokemonName + ld hl, ContestJudging_ThirdPlaceText + call PrintText + ld a, [wBugContestSecondPlaceWinnerID] + call LoadContestantName + ld a, [wBugContestSecondPlaceMon] + ld [wNamedObjectIndexBuffer], a + call GetPokemonName + ld hl, ContestJudging_SecondPlaceText + call PrintText + ld a, [wBugContestFirstPlaceWinnerID] + call LoadContestantName + ld a, [wBugContestFirstPlaceMon] + ld [wNamedObjectIndexBuffer], a + call GetPokemonName + ld hl, ContestJudging_FirstPlaceText + call PrintText + jp BugContest_GetPlayersResult + +ContestJudging_FirstPlaceText: + text_far _ContestJudging_FirstPlaceText + text_asm + ld de, SFX_1ST_PLACE + call PlaySFX + call WaitSFX + ld hl, ContestJudging_FirstPlaceScoreText + ret + +ContestJudging_FirstPlaceScoreText: + text_far _ContestJudging_FirstPlaceScoreText + text_end + +ContestJudging_SecondPlaceText: + ; Placing second was @ , who caught a @ !@ @ + text_far _ContestJudging_SecondPlaceText + text_asm + ld de, SFX_2ND_PLACE + call PlaySFX + call WaitSFX + ld hl, ContestJudging_SecondPlaceScoreText + ret + +ContestJudging_SecondPlaceScoreText: + text_far _ContestJudging_SecondPlaceScoreText + text_end + +ContestJudging_ThirdPlaceText: + ; Placing third was @ , who caught a @ !@ @ + text_far _ContestJudging_ThirdPlaceText + text_asm + ld de, SFX_3RD_PLACE + call PlaySFX + call WaitSFX + ld hl, ContestJudging_ThirdPlaceScoreText + ret + +ContestJudging_ThirdPlaceScoreText: + text_far _ContestJudging_ThirdPlaceScoreText + text_end + +LoadContestantName: +; If a = 1, get your name. + dec a ; BUG_CONTEST_PLAYER + jr z, .player +; Find the pointer for the trainer class of the Bug Catching Contestant whose ID is in a. + ld c, a + ld b, 0 + ld hl, BugContestantPointers + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a +; Copy the Trainer Class to c. + ld a, [hli] + ld c, a +; Save hl and bc for later. + push hl + push bc +; Get the Trainer Class name and copy it into wBugContestWinnerName. + callfar GetTrainerClassName + ld hl, wStringBuffer1 + ld de, wBugContestWinnerName + ld bc, TRAINER_CLASS_NAME_LENGTH + call CopyBytes + ld hl, wBugContestWinnerName +; Delete the trailing terminator and replace it with a space. +.next + ld a, [hli] + cp "@" + jr nz, .next + dec hl + ld [hl], " " + inc hl + ld d, h + ld e, l +; Restore the Trainer Class ID and Trainer ID pointer. Save de for later. + pop bc + pop hl + push de +; Get the name of the trainer with class c and ID b. + ld a, [hl] + ld b, a + callfar GetTrainerName +; Append the name to wBugContestWinnerName. + ld hl, wStringBuffer1 + pop de + ld bc, NAME_LENGTH - 1 + jp CopyBytes + +.player + ld hl, wPlayerName + ld de, wBugContestWinnerName + ld bc, NAME_LENGTH + jp CopyBytes + +INCLUDE "data/events/bug_contest_winners.asm" + +BugContest_GetPlayersResult: + ld hl, wBugContestThirdPlaceWinnerID + ld de, - BUG_CONTESTANT_SIZE + ld b, 3 ; 3rd, 2nd, or 1st +.loop + ld a, [hl] + cp BUG_CONTEST_PLAYER + jr z, .done + add hl, de + dec b + jr nz, .loop + +.done + ret + +BugContest_JudgeContestants: + call ClearContestResults + call ComputeAIContestantScores + ld hl, wBugContestTempWinnerID + ld a, BUG_CONTEST_PLAYER + ld [hli], a + ld a, [wContestMon] + ld [hli], a + ldh a, [hProduct] + ld [hli], a + ldh a, [hProduct + 1] + ld [hl], a + call DetermineContestWinners + ret + +ClearContestResults: + ld hl, wBugContestResults + ld b, wBugContestWinnersEnd - wBugContestResults + xor a +.loop + ld [hli], a + dec b + jr nz, .loop + ret + +DetermineContestWinners: + ld de, wBugContestTempScore + ld hl, wBugContestFirstPlaceScore + ld c, 2 + call CompareBytes + jr c, .not_first_place + ld hl, wBugContestSecondPlaceWinnerID + ld de, wBugContestThirdPlaceWinnerID + ld bc, BUG_CONTESTANT_SIZE + call CopyBytes + ld hl, wBugContestFirstPlaceWinnerID + ld de, wBugContestSecondPlaceWinnerID + ld bc, BUG_CONTESTANT_SIZE + call CopyBytes + ld hl, wBugContestFirstPlaceWinnerID + call CopyTempContestant + jr .done + +.not_first_place + ld de, wBugContestTempScore + ld hl, wBugContestSecondPlaceScore + ld c, 2 + call CompareBytes + jr c, .not_second_place + ld hl, wBugContestSecondPlaceWinnerID + ld de, wBugContestThirdPlaceWinnerID + ld bc, BUG_CONTESTANT_SIZE + call CopyBytes + ld hl, wBugContestSecondPlaceWinnerID + call CopyTempContestant + jr .done + +.not_second_place + ld de, wBugContestTempScore + ld hl, wBugContestThirdPlaceScore + ld c, 2 + call CompareBytes + jr c, .done + ld hl, wBugContestThirdPlaceWinnerID + call CopyTempContestant + +.done + ret + +CopyTempContestant: +; Could've just called CopyBytes. + ld de, wBugContestTempWinnerID +rept BUG_CONTESTANT_SIZE + -1 + ld a, [de] + inc de + ld [hli], a +endr + ld a, [de] + inc de + ld [hl], a + ret + +ComputeAIContestantScores: + ld e, 0 +.loop + push de + call CheckBugContestContestantFlag + pop de + jr nz, .done + ld a, e + inc a + inc a + ld [wBugContestTempWinnerID], a + dec a + ld c, a + ld b, 0 + ld hl, BugContestantPointers + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + inc hl +.loop2 + ; 0, 1, or 2 for 1st, 2nd, or 3rd + call Random + and 3 + cp 3 + jr z, .loop2 + ld c, a + ld b, 0 + add hl, bc + add hl, bc + add hl, bc + ld a, [hli] + ld [wBugContestTempMon], a + ld a, [hli] + ld h, [hl] + ld l, a + ; randomly perturb score + call Random + and %111 + ld c, a + ld b, 0 + add hl, bc + ld a, h + ld [wBugContestTempScore], a + ld a, l + ld [wBugContestTempScore + 1], a + push de + call DetermineContestWinners + pop de + +.done + inc e + ld a, e + cp NUM_BUG_CONTESTANTS + jr nz, .loop + ret + +ContestScore: +; Determine the player's score in the Bug Catching Contest. + + xor a + ldh [hProduct], a + ldh [hMultiplicand], a + + ld a, [wContestMonSpecies] ; Species + and a + jr z, .done + + ; Tally the following: + + ; Max HP * 4 + ld a, [wContestMonMaxHP + 1] + call .AddContestStat + ld a, [wContestMonMaxHP + 1] + call .AddContestStat + ld a, [wContestMonMaxHP + 1] + call .AddContestStat + ld a, [wContestMonMaxHP + 1] + call .AddContestStat + + ; Stats + ld a, [wContestMonAttack + 1] + call .AddContestStat + ld a, [wContestMonDefense + 1] + call .AddContestStat + ld a, [wContestMonSpeed + 1] + call .AddContestStat + ld a, [wContestMonSpclAtk + 1] + call .AddContestStat + ld a, [wContestMonSpclDef + 1] + call .AddContestStat + + ; DVs + ld a, [wContestMonDVs + 0] + ld b, a + and %0010 + add a + add a + ld c, a + + swap b + ld a, b + and %0010 + add a + add c + ld d, a + + ld a, [wContestMonDVs + 1] + ld b, a + and %0010 + ld c, a + + swap b + ld a, b + and %0010 + srl a + add c + add c + add d + add d + + call .AddContestStat + + ; Remaining HP / 8 + ld a, [wContestMonHP + 1] + srl a + srl a + srl a + call .AddContestStat + + ; Whether it's holding an item + ld a, [wContestMonItem] + and a + jr z, .done + + ld a, 1 + call .AddContestStat + +.done + ret + +.AddContestStat: + ld hl, hMultiplicand + add [hl] + ld [hl], a + ret nc + dec hl + inc [hl] + ret diff --git a/engine/events/pokerus/apply_pokerus_tick.asm b/engine/events/pokerus/apply_pokerus_tick.asm new file mode 100644 index 00000000..223fe014 --- /dev/null +++ b/engine/events/pokerus/apply_pokerus_tick.asm @@ -0,0 +1,26 @@ +ApplyPokerusTick: +; decreases all pokemon's pokerus counter by b. if the lower nybble reaches zero, the pokerus is cured. + ld hl, wPartyMon1PokerusStatus ; wPartyMon1 + MON_PKRS + ld a, [wPartyCount] + and a + ret z ; make sure it's not wasting time on an empty party + ld c, a +.loop + ld a, [hl] + and $f ; lower nybble is the number of days remaining + jr z, .next ; if already 0, skip + sub b ; subtract the number of days + jr nc, .ok ; max(result, 0) + xor a +.ok + ld d, a ; back up this value because we need to preserve the strain (upper nybble) + ld a, [hl] + and $f0 + add d + ld [hl], a ; this prevents a cured pokemon from recontracting pokerus +.next + ld de, PARTYMON_STRUCT_LENGTH + add hl, de + dec c + jr nz, .loop + ret diff --git a/engine/specials.asm b/engine/specials.asm index bb0086bf..80d32a02 100755 --- a/engine/specials.asm +++ b/engine/specials.asm @@ -298,7 +298,7 @@ ReceivedMysteryGiftText: db "@" BugContestJudging: ; c4a4 (3:44a4) - farcall Function13a5f + farcall _BugContestJudging ld a, b ld [wScriptVar], a ret |