ref: a6ac67dea2ea7a1a35fce63a8bd10deb7147c3ed
dir: /engine/phone/phone.asm/
AddPhoneNumber:: call _CheckCellNum jr c, .cant_add call Phone_FindOpenSlot jr nc, .cant_add ld [hl], c xor a ret .cant_add scf ret DelCellNum:: call _CheckCellNum jr nc, .not_in_list xor a ld [hl], a ret .not_in_list scf ret CheckCellNum:: jp _CheckCellNum ; useless _CheckCellNum: ld hl, wPhoneList ld b, CONTACT_LIST_SIZE .loop ld a, [hli] cp c jr z, .got_it dec b jr nz, .loop xor a ret .got_it dec hl scf ret Phone_FindOpenSlot: call GetRemainingSpaceInPhoneList ld b, a ld hl, wPhoneList .loop ld a, [hli] and a jr z, .FoundOpenSpace dec b jr nz, .loop xor a ret .FoundOpenSpace: dec hl scf ret GetRemainingSpaceInPhoneList: xor a ld [wRegisteredPhoneNumbers], a ld hl, PermanentNumbers .loop ld a, [hli] cp -1 jr z, .done cp c jr z, .continue push bc push hl ld c, a call _CheckCellNum jr c, .permanent ld hl, wRegisteredPhoneNumbers inc [hl] .permanent pop hl pop bc .continue jr .loop .done ld a, CONTACT_LIST_SIZE ld hl, wRegisteredPhoneNumbers sub [hl] ret INCLUDE "data/phone/permanent_numbers.asm" BrokenPlaceFarString: ; This routine is not in bank 0 and will fail or crash if called. ldh a, [hROMBank] push af ld a, b rst Bankswitch call PlaceString pop af rst Bankswitch ret CheckPhoneCall:: ; Check if the phone is ringing in the overworld. call CheckStandingOnEntrance jr z, .no_call call .timecheck nop jr nc, .no_call ; 50% chance for a call call Random ld b, a and %01111111 cp b jr nz, .no_call call GetMapPhoneService and a jr nz, .no_call call GetAvailableCallers call ChooseRandomCaller jr nc, .no_call ld e, a call LoadCallerScript ld a, BANK(Script_ReceivePhoneCall) ld hl, Script_ReceivePhoneCall call CallScript scf ret .no_call xor a ret .timecheck farcall CheckReceiveCallTimer ret CheckPhoneContactTimeOfDay: push hl push bc push de push af farcall CheckTime pop af and ANYTIME and c pop de pop bc pop hl ret ChooseRandomCaller: ; If no one is available to call, don't return anything. ld a, [wNumAvailableCallers] and a jr z, .NothingToSample ; Store the number of available callers in c. ld c, a ; Sample a random number between 0 and 31. call Random ldh a, [hRandomAdd] swap a and $1f ; Compute that number modulo the number of available callers. call SimpleDivide ; Return the caller ID you just sampled. ld c, a ld b, 0 ld hl, wAvailableCallers add hl, bc ld a, [hl] scf ret .NothingToSample: xor a ret GetAvailableCallers: farcall CheckTime ld a, c ld [wCheckedTime], a ld hl, wNumAvailableCallers ld bc, CONTACT_LIST_SIZE + 1 xor a call ByteFill ld de, wPhoneList ld a, CONTACT_LIST_SIZE .loop ld [wPhoneListIndex], a ld a, [de] and a jr z, .not_good_for_call ld hl, PhoneContacts + PHONE_CONTACT_SCRIPT2_TIME ld bc, PHONE_CONTACT_SIZE call AddNTimes ld a, [wCheckedTime] and [hl] jr z, .not_good_for_call ld bc, PHONE_CONTACT_MAP_GROUP - PHONE_CONTACT_SCRIPT2_TIME add hl, bc ld a, [wMapGroup] cp [hl] jr nz, .different_map inc hl ld a, [wMapNumber] cp [hl] jr z, .not_good_for_call .different_map ld a, [wNumAvailableCallers] ld c, a ld b, 0 inc a ld [wNumAvailableCallers], a ld hl, wAvailableCallers add hl, bc ld a, [de] ld [hl], a .not_good_for_call inc de ld a, [wPhoneListIndex] dec a jr nz, .loop ret CheckSpecialPhoneCall:: ld a, [wSpecialPhoneCallID] and a jr z, .NoPhoneCall dec a ld c, a ld b, 0 ld hl, SpecialPhoneCallList ld a, SPECIALCALL_SIZE call AddNTimes ld a, [hli] ld h, [hl] ld l, a call _hl_ jr nc, .NoPhoneCall call .DoSpecialPhoneCall inc hl inc hl ld a, [hli] ld e, a push hl call LoadCallerScript pop hl ld de, wCallerContact + PHONE_CONTACT_SCRIPT2_BANK ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a ld a, BANK(.script) ld hl, .script call CallScript scf ret .NoPhoneCall: xor a ret .script pause 30 sjump Script_ReceivePhoneCall .DoSpecialPhoneCall: ld a, [wSpecialPhoneCallID] dec a ld c, a ld b, 0 ld hl, SpecialPhoneCallList ld a, SPECIALCALL_SIZE call AddNTimes ret SpecialCallOnlyWhenOutside: ld a, [wEnvironment] cp TOWN jr z, .outside cp ROUTE jr z, .outside xor a ret .outside scf ret SpecialCallWhereverYouAre: scf ret MakePhoneCallFromPokegear: ; Don't do the call if you're in a link communication ld a, [wLinkMode] and a jr nz, .OutOfArea ; If you're in an area without phone service, don't do the call call GetMapPhoneService and a jr nz, .OutOfArea ; If the person can't take a call at that time, don't do the call ld a, b ld [wCurCaller], a ld hl, PhoneContacts ld bc, PHONE_CONTACT_SIZE call AddNTimes ld d, h ld e, l ld hl, PHONE_CONTACT_SCRIPT1_TIME add hl, de ld a, [hl] call CheckPhoneContactTimeOfDay jr z, .OutOfArea ; If we're in the same map as the person we're calling, ; use the "Just talk to that person" script. ld hl, PHONE_CONTACT_MAP_GROUP add hl, de ld a, [wMapGroup] cp [hl] jr nz, .GetPhoneScript ld hl, PHONE_CONTACT_MAP_NUMBER add hl, de ld a, [wMapNumber] cp [hl] jr nz, .GetPhoneScript ld b, BANK(PhoneScript_JustTalkToThem) ld hl, PhoneScript_JustTalkToThem jr .DoPhoneCall .GetPhoneScript: ld hl, PHONE_CONTACT_SCRIPT1_BANK add hl, de ld b, [hl] ld hl, PHONE_CONTACT_SCRIPT1_ADDR add hl, de ld a, [hli] ld h, [hl] ld l, a jr .DoPhoneCall .OutOfArea: ld b, BANK(LoadOutOfAreaScript) ld de, LoadOutOfAreaScript call ExecuteCallbackScript ret .DoPhoneCall: ld a, b ld [wPhoneScriptBank], a ld a, l ld [wPhoneCaller], a ld a, h ld [wPhoneCaller + 1], a ld b, BANK(LoadPhoneScriptBank) ld de, LoadPhoneScriptBank call ExecuteCallbackScript ret LoadPhoneScriptBank: memcall wPhoneScriptBank endcallback LoadOutOfAreaScript: scall PhoneOutOfAreaScript endcallback LoadCallerScript: nop nop ld a, e ld [wCurCaller], a and a jr nz, .actualcaller ld a, BANK(WrongNumber) ld hl, WrongNumber jr .proceed .actualcaller ld hl, PhoneContacts ld bc, PHONE_CONTACT_SIZE ld a, e call AddNTimes ld a, BANK(PhoneContacts) .proceed ld de, wCallerContact ld bc, PHONE_CONTACT_SIZE call FarCopyBytes ret WrongNumber: db TRAINER_NONE, PHONE_00 dba .script .script writetext .PhoneWrongNumberText end .PhoneWrongNumberText: text_far _PhoneWrongNumberText text_end Script_ReceivePhoneCall: refreshscreen callasm RingTwice_StartCall memcall wCallerContact + PHONE_CONTACT_SCRIPT2_BANK waitbutton callasm HangUp closetext callasm InitCallReceiveDelay end Script_SpecialBillCall:: callasm .LoadBillScript sjump Script_ReceivePhoneCall .LoadBillScript: ld e, PHONE_BILL jp LoadCallerScript Script_SpecialElmCall: ; unreferenced callasm .LoadElmScript pause 30 sjump Script_ReceivePhoneCall .LoadElmScript: ld e, PHONE_ELM jp LoadCallerScript RingTwice_StartCall: call .Ring call .Ring farcall StubbedTrainerRankings_PhoneCalls ret .Ring: call Phone_StartRinging call Phone_Wait20Frames call .CallerTextboxWithName call Phone_Wait20Frames call Phone_CallerTextbox call Phone_Wait20Frames call .CallerTextboxWithName ret .CallerTextboxWithName: ld a, [wCurCaller] ld b, a call Phone_TextboxWithName ret PhoneCall:: ld a, b ld [wPhoneScriptBank], a ld a, e ld [wPhoneCaller], a ld a, d ld [wPhoneCaller + 1], a call .Ring call .Ring farcall StubbedTrainerRankings_PhoneCalls ret .Ring: call Phone_StartRinging call Phone_Wait20Frames call .CallerTextboxWithName call Phone_Wait20Frames call Phone_CallerTextbox call Phone_Wait20Frames call .CallerTextboxWithName ret .CallerTextboxWithName: call Phone_CallerTextbox hlcoord 1, 2 ld [hl], "☎" inc hl inc hl ; BUG: The unused phonecall script command may crash (see docs/bugs_and_glitches.md) ld a, [wPhoneScriptBank] ld b, a ld a, [wPhoneCaller] ld e, a ld a, [wPhoneCaller + 1] ld d, a call BrokenPlaceFarString ret Phone_NoSignal: ld de, SFX_NO_SIGNAL call PlaySFX jr Phone_CallEnd HangUp:: call HangUp_Beep call HangUp_Wait20Frames Phone_CallEnd: call HangUp_BoopOn call HangUp_Wait20Frames call HangUp_BoopOff call HangUp_Wait20Frames call HangUp_BoopOn call HangUp_Wait20Frames call HangUp_BoopOff call HangUp_Wait20Frames call HangUp_BoopOn call HangUp_Wait20Frames call HangUp_BoopOff call HangUp_Wait20Frames ret HangUp_ShutDown: ; unreferenced ld de, SFX_SHUT_DOWN_PC call PlaySFX ret HangUp_Beep: ld hl, PhoneClickText call PrintText ld de, SFX_HANG_UP call PlaySFX ret PhoneClickText: text_far _PhoneClickText text_end HangUp_BoopOn: ld hl, PhoneEllipseText call PrintText ret PhoneEllipseText: text_far _PhoneEllipseText text_end HangUp_BoopOff: call SpeechTextbox ret Phone_StartRinging: call WaitSFX ld de, SFX_CALL call PlaySFX call Phone_CallerTextbox call UpdateSprites farcall PhoneRing_CopyTilemapAtOnce ret HangUp_Wait20Frames: jr Phone_Wait20Frames Phone_Wait20Frames: ld c, 20 call DelayFrames farcall PhoneRing_CopyTilemapAtOnce ret Phone_TextboxWithName: push bc call Phone_CallerTextbox hlcoord 1, 1 ld [hl], "☎" inc hl inc hl ld d, h ld e, l pop bc call GetCallerClassAndName ret Phone_CallerTextbox: hlcoord 0, 0 ld b, 2 ld c, SCREEN_WIDTH - 2 call Textbox ret GetCallerClassAndName: ld h, d ld l, e ld a, b call GetCallerTrainerClass call GetCallerName ret CheckCanDeletePhoneNumber: ld a, c call GetCallerTrainerClass ld a, c ; and a ret nz ld a, b cp PHONECONTACT_MOM ret z cp PHONECONTACT_ELM ret z ld c, $1 ret GetCallerTrainerClass: push hl ld hl, PhoneContacts + PHONE_CONTACT_TRAINER_CLASS ld bc, PHONE_CONTACT_SIZE call AddNTimes ld a, [hli] ld b, [hl] ld c, a pop hl ret GetCallerName: ld a, c and a jr z, .NotTrainer call Phone_GetTrainerName push hl push bc call PlaceString ld a, ":" ld [bc], a pop bc pop hl ld de, SCREEN_WIDTH + 3 add hl, de call Phone_GetTrainerClassName call PlaceString ret .NotTrainer: push hl ld c, b ld b, 0 ld hl, NonTrainerCallerNames add hl, bc add hl, bc ld a, [hli] ld e, a ld d, [hl] pop hl call PlaceString ret INCLUDE "data/phone/non_trainer_names.asm" Phone_GetTrainerName: push hl push bc farcall GetTrainerName pop bc pop hl ret Phone_GetTrainerClassName: push hl push bc farcall GetTrainerClassName pop bc pop hl ret GetCallerLocation: ld a, [wCurCaller] call GetCallerTrainerClass ld d, c ld e, b push de ld a, [wCurCaller] ld hl, PhoneContacts + PHONE_CONTACT_MAP_GROUP ld bc, PHONE_CONTACT_SIZE call AddNTimes ld b, [hl] inc hl ld c, [hl] push bc call GetWorldMapLocation ld e, a farcall GetLandmarkName pop bc pop de ret INCLUDE "data/phone/phone_contacts.asm" INCLUDE "data/phone/special_calls.asm" PhoneOutOfAreaScript: writetext PhoneOutOfAreaText end PhoneOutOfAreaText: text_far _PhoneOutOfAreaText text_end PhoneScript_JustTalkToThem: writetext PhoneJustTalkToThemText end PhoneJustTalkToThemText: text_far _PhoneJustTalkToThemText text_end PhoneThankYouTextScript: ; unreferenced writetext PhoneThankYouText end PhoneThankYouText: text_far _PhoneThankYouText text_end