diff --git a/constants/event_flags.asm b/constants/event_flags.asm index e150e4903..89d945450 100644 --- a/constants/event_flags.asm +++ b/constants/event_flags.asm @@ -2,6 +2,7 @@ const_def + ;; The first eight flags are reset upon reloading the map const EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1 const EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2 @@ -17,6 +18,7 @@ const_value = const_value + 8 - (const_value % 8) endc EVENT_TEMPORARY_UNTIL_MAP_RELOAD_FLAGS_END EQU const_value + ;; The next flags are reset upon entering a new level (for e.g. trainers) EVENT_LEVEL_SCOPED_FLAGS_START EQU EVENT_TEMPORARY_UNTIL_MAP_RELOAD_FLAGS_END @@ -46,8 +48,39 @@ const_value = const_value + 8 - (const_value % 8) endc EVENT_LEVEL_SCOPED_FLAGS_END EQU const_value + +;; The next flags are reset upon taking a step (for e.g. talker) +EVENT_TURN_SCOPED_FLAGS_START EQU EVENT_LEVEL_SCOPED_FLAGS_END + + const EVENT_TURN_SCOPED_1 + const EVENT_TURN_SCOPED_2 + const EVENT_TURN_SCOPED_3 + const EVENT_TURN_SCOPED_4 + const EVENT_TURN_SCOPED_5 + const EVENT_TURN_SCOPED_6 + const EVENT_TURN_SCOPED_7 + const EVENT_TURN_SCOPED_8 + const EVENT_TURN_SCOPED_9 + const EVENT_TURN_SCOPED_10 + const EVENT_TURN_SCOPED_11 + const EVENT_TURN_SCOPED_12 + const EVENT_TURN_SCOPED_13 + const EVENT_TURN_SCOPED_14 + const EVENT_TURN_SCOPED_15 + const EVENT_TURN_SCOPED_16 + const EVENT_TURN_SCOPED_17 + const EVENT_TURN_SCOPED_18 + const EVENT_TURN_SCOPED_19 + const EVENT_TURN_SCOPED_20 + +if (const_value % 8) != 0 +const_value = const_value + 8 - (const_value % 8) +endc +EVENT_TURN_SCOPED_FLAGS_END EQU const_value + + ;; The remaining flags are only reset explicitly -EVENT_REGULAR_FLAGS_START EQU EVENT_LEVEL_SCOPED_FLAGS_END +EVENT_REGULAR_FLAGS_START EQU EVENT_TURN_SCOPED_FLAGS_END const EVENT_INITIALIZED_EVENTS diff --git a/constants/trainer_data_constants.asm b/constants/trainer_data_constants.asm index dda4fd451..639b2d61a 100644 --- a/constants/trainer_data_constants.asm +++ b/constants/trainer_data_constants.asm @@ -47,10 +47,12 @@ DEF CONTEXT_USE EQU 1 << CONTEXT_USE_F const TRAINERTYPE_ITEM_MOVES ; talker events (from talker macro and high bit of wTempTalkerType) -DEF TALKER_OPTIONAL EQU %0 -DEF TALKER_MANDATORY EQU %1 +DEF TALKEREVENTTYPE_MASK EQU %10000000 +DEF TALKEREVENTTYPE_OPTIONAL EQU %0 +DEF TALKEREVENTTYPE_MANDATORY EQU %1 ; talker types (from talker macro and low seven bits of wTempTalkerType) +DEF TALKERTYPE_MASK EQU %01111111 const_def const TALKERTYPE_TEXT const TALKERTYPE_MODAL_TEXT diff --git a/docs/event_commands.md b/docs/event_commands.md index e6aa4c229..29cc2520f 100644 --- a/docs/event_commands.md +++ b/docs/event_commands.md @@ -342,7 +342,7 @@ If item_id = `USE_SCRIPT_VAR`, then it uses `[hScriptVar]` i ## `$62`: trainertext text_id -## `$63`: trainerflagaction action +## `$63`: trainerortalkerflagaction action ## `$64`: winlosstext win_text_pointer, loss_text_pointer diff --git a/engine/board/menu.asm b/engine/board/menu.asm index 411c4c9c0..e20a88b5a 100755 --- a/engine/board/menu.asm +++ b/engine/board/menu.asm @@ -20,12 +20,22 @@ BoardMenuScript:: ; save after opentext to reanchor map first ; save before processing variables like wCurTurn due to BoardMenuScript reentry after game reset farcall AutoSaveGameInOverworld +; reset turn-scoped variables (wDieRoll, wSpacesLeft) and update wCurTurn ld hl, wTurnData ld bc, wTurnDataEnd - wTurnData xor a call ByteFill ld hl, wCurTurn inc [hl] +; reset turn-scoped event flags + ld hl, wEventFlags + EVENT_LEVEL_SCOPED_FLAGS_START / 8 + ld c, (EVENT_LEVEL_SCOPED_FLAGS_END / 8) - (EVENT_LEVEL_SCOPED_FLAGS_START / 8) + xor a +.loop + ld [hli], a + dec c + jr nz, .loop +; load the data for the current space to wCurSpaceStruct jp LoadCurSpaceData .Die: diff --git a/engine/events/trainer_scripts.asm b/engine/events/trainer_scripts.asm index 030130fc5..9f2b16248 100644 --- a/engine/events/trainer_scripts.asm +++ b/engine/events/trainer_scripts.asm @@ -1,6 +1,6 @@ TalkToTrainerScript:: faceplayer - trainerflagaction CHECK_FLAG + trainerortalkerflagaction CHECK_FLAG iftrue AlreadyBeatenTrainerScript loadtemptrainer encountermusic @@ -25,7 +25,7 @@ StartBattleWithMapTrainerScript: loadtemptrainer startbattle reloadmapafterbattle - trainerflagaction SET_FLAG + trainerortalkerflagaction SET_FLAG loadmem wRunningTrainerBattleScript, -1 AlreadyBeatenTrainerScript: @@ -34,8 +34,30 @@ AlreadyBeatenTrainerScript: SeenByTalkerScript:: waitsfx ; wait for any pending space-related sfx showemote EMOTE_TALK, LAST_TALKED, 20 + callasm .TalkOrSkipTalker + iffalse .skipped callasm TrainerOrTalkerWalkToPlayer applymovementlasttalked wMovementBuffer writeobjectxy LAST_TALKED faceobject PLAYER, LAST_TALKED +.skipped end + +.TalkOrSkipTalker: + ld a, [wTempTalkerType] + and %1 + cp TALKEREVENTTYPE_MANDATORY + jr z, .skip + call WaitButton + call PlayClickSFX + call WaitSFX + ldh a, [hJoyPressed] + bit A_BUTTON_F, a + jr z, .skip ; jump if b was pressed + ld a, TRUE + jr .done +.skip + xor a ; FALSE +.done + ld [hScriptVar], a + ret diff --git a/engine/overworld/events.asm b/engine/overworld/events.asm index b047f326c..c854b1078 100644 --- a/engine/overworld/events.asm +++ b/engine/overworld/events.asm @@ -459,7 +459,7 @@ CheckTrainerOrTalkerEvent: call CheckTrainerBattleOrTalkerPrompt jr nc, .nope - ld a, [wTrainerOrTalkerIsTalker] + ld a, [wSeenTrainerOrTalkerIsTalker] and a ; cp FALSE ld a, PLAYEREVENT_SEENBYTRAINER jr z, .done diff --git a/engine/overworld/scripting.asm b/engine/overworld/scripting.asm index bada8759e..18cc56d10 100644 --- a/engine/overworld/scripting.asm +++ b/engine/overworld/scripting.asm @@ -163,7 +163,7 @@ ScriptCommandTable: dw Script_reloadmapafterbattle ; 60 dw Script_catchtutorial ; 61 dw Script_trainertext ; 62 - dw Script_trainerflagaction ; 63 + dw Script_trainerortalkerflagaction ; 63 dw Script_winlosstext ; 64 dw Script_scripttalkafter ; 65 dw Script_endifjustbattled ; 66 @@ -685,10 +685,10 @@ Script_scripttalkafter: ld b, a jp ScriptJump -Script_trainerflagaction: +Script_trainerortalkerflagaction: xor a ldh [hScriptVar], a - ld hl, wTempTrainerEventFlag + ld hl, wTempTrainerEventFlag ; wTempTalkerEventFlag ld e, [hl] inc hl ld d, [hl] diff --git a/home/trainers.asm b/home/trainers.asm index bbfe25ed9..536444cdc 100644 --- a/home/trainers.asm +++ b/home/trainers.asm @@ -39,14 +39,14 @@ _CheckTrainerBattleOrTalkerPrompt:: jr z, .is_trainer cp OBJECTTYPE_TALKER jr nz, .next -; also set wTrainerOrTalkerIsTalker accordingly (flag is only relevant if there's actually an event) +; also set wSeenTrainerOrTalkerIsTalker accordingly (flag is only relevant if there's actually an event) ;.is_talker ld a, TRUE - ld [wTrainerOrTalkerIsTalker], a + ld [wSeenTrainerOrTalkerIsTalker], a jr .go .is_trainer xor a ; FALSE - ld [wTrainerOrTalkerIsTalker], a + ld [wSeenTrainerOrTalkerIsTalker], a .go ; Is visible on the map @@ -68,11 +68,31 @@ _CheckTrainerBattleOrTalkerPrompt:: cp b jr c, .next - ld a, [wTrainerOrTalkerIsTalker] - and a ; TRUE? - jr z, .trainer_battle +; And hasn't already been beaten if it's a trainer, or talked to if it's a talker, +; according to the scope of the flag of the trainer or talker event. + push bc + push de + ld hl, MAPOBJECT_SCRIPT_POINTER + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld e, [hl] + inc hl + ld d, [hl] ; de = wTempTrainerEventFlag = wTempTalkerEventFlag + ld b, CHECK_FLAG + call EventFlagAction + ld a, c + pop de + pop bc + and a + jr nz, .next -;.talker_prompt + ld a, [wSeenTrainerOrTalkerIsTalker] + and a ; cp FALSE + jr z, .prepare_trainer_battle + +;.prepare_talker_prompt pop de pop af ldh [hLastTalked], a @@ -98,26 +118,6 @@ _CheckTrainerBattleOrTalkerPrompt:: scf ret -.trainer_battle -; And hasn't already been beaten if it's a trainer - push bc - push de - ld hl, MAPOBJECT_SCRIPT_POINTER - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a - ld e, [hl] - inc hl - ld d, [hl] - ld b, CHECK_FLAG - call EventFlagAction - ld a, c - pop de - pop bc - and a - jr z, .startbattle - .next pop de ld hl, MAPOBJECT_LENGTH @@ -132,7 +132,7 @@ _CheckTrainerBattleOrTalkerPrompt:: xor a ret -.startbattle +.prepare_trainer_battle pop de pop af ldh [hLastTalked], a diff --git a/macros/legacy.asm b/macros/legacy.asm index 696cfece3..49abe93d9 100644 --- a/macros/legacy.asm +++ b/macros/legacy.asm @@ -206,7 +206,7 @@ DEF battlecheck EQUS "randomwildmon" DEF loadtrainerdata EQUS "loadtemptrainer" DEF loadpokedata EQUS "loadwildmon" DEF returnafterbattle EQUS "reloadmapafterbattle" -DEF trainerstatus EQUS "trainerflagaction" +DEF trainerstatus EQUS "trainerortalkerflagaction" DEF talkaftercancel EQUS "endifjustbattled" DEF talkaftercheck EQUS "checkjustbattled" DEF playrammusic EQUS "encountermusic" diff --git a/macros/scripts/events.asm b/macros/scripts/events.asm index 71f52e94f..adf4e8442 100644 --- a/macros/scripts/events.asm +++ b/macros/scripts/events.asm @@ -632,9 +632,9 @@ MACRO trainertext db \1 ; text_id ENDM - const trainerflagaction_command ; $63 -MACRO trainerflagaction - db trainerflagaction_command + const trainerortalkerflagaction_command ; $63 +MACRO trainerortalkerflagaction + db trainerortalkerflagaction_command db \1 ; action ENDM diff --git a/maps/DebugLevel5_Map1.asm b/maps/DebugLevel5_Map1.asm index f50a1ee47..196623344 100755 --- a/maps/DebugLevel5_Map1.asm +++ b/maps/DebugLevel5_Map1.asm @@ -28,7 +28,7 @@ DebugLevel5_Map1_MapEvents: .DebugLevel5_Map1TrainerYoungsterMikey2: trainer YOUNGSTER, MIKEY, EVENT_LEVEL_SCOPED_2, .YoungsterMikeySeenText, .YoungsterMikeyBeatenText, 0, .Script -; talker EVENT_STEP_SCOPED_*, OPTIONAL/MANDATORY | TEXT/MODAL_TEXT/SCRIPT, .Data +; talker EVENT_TURN_SCOPED_*, OPTIONAL/MANDATORY | TEXT/MODAL_TEXT/SCRIPT, .Data ; .Data: ; Text ; db .Text ; .Data: ; Modal text diff --git a/ram/wram.asm b/ram/wram.asm index 619423540..fb1f6b28f 100644 --- a/ram/wram.asm +++ b/ram/wram.asm @@ -1551,7 +1551,7 @@ SECTION UNION "Miscellaneous WRAM 1", WRAMX UNION ; trainer and talker data -wTrainerOrTalkerIsTalker:: db ; TRUE means talker; FALSE means trainer +wSeenTrainerOrTalkerIsTalker:: db ; TRUE means talker; FALSE means trainer wSeenTrainerOrTalkerBank:: db wSeenTrainerOrTalkerDistance:: db wSeenTrainerOrTalkerDirection:: db