Implement talker events [commit 2] (#30)

This commit is contained in:
xCrystal 2023-11-28 18:02:00 +01:00
parent 88b6810a18
commit 933fca3b4b
12 changed files with 111 additions and 44 deletions

View File

@ -2,6 +2,7 @@
const_def const_def
;; The first eight flags are reset upon reloading the map ;; The first eight flags are reset upon reloading the map
const EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1 const EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1
const EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2 const EVENT_TEMPORARY_UNTIL_MAP_RELOAD_2
@ -17,6 +18,7 @@ const_value = const_value + 8 - (const_value % 8)
endc endc
EVENT_TEMPORARY_UNTIL_MAP_RELOAD_FLAGS_END EQU const_value EVENT_TEMPORARY_UNTIL_MAP_RELOAD_FLAGS_END EQU const_value
;; The next flags are reset upon entering a new level (for e.g. trainers) ;; 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 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 endc
EVENT_LEVEL_SCOPED_FLAGS_END EQU const_value 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 ;; 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 const EVENT_INITIALIZED_EVENTS

View File

@ -47,10 +47,12 @@ DEF CONTEXT_USE EQU 1 << CONTEXT_USE_F
const TRAINERTYPE_ITEM_MOVES const TRAINERTYPE_ITEM_MOVES
; talker events (from talker macro and high bit of wTempTalkerType) ; talker events (from talker macro and high bit of wTempTalkerType)
DEF TALKER_OPTIONAL EQU %0 DEF TALKEREVENTTYPE_MASK EQU %10000000
DEF TALKER_MANDATORY EQU %1 DEF TALKEREVENTTYPE_OPTIONAL EQU %0
DEF TALKEREVENTTYPE_MANDATORY EQU %1
; talker types (from talker macro and low seven bits of wTempTalkerType) ; talker types (from talker macro and low seven bits of wTempTalkerType)
DEF TALKERTYPE_MASK EQU %01111111
const_def const_def
const TALKERTYPE_TEXT const TALKERTYPE_TEXT
const TALKERTYPE_MODAL_TEXT const TALKERTYPE_MODAL_TEXT

View File

@ -342,7 +342,7 @@ If <code><i>item_id</i></code> = `USE_SCRIPT_VAR`, then it uses `[hScriptVar]` i
## `$62`: <code>trainertext <i>text_id</i></code> ## `$62`: <code>trainertext <i>text_id</i></code>
## `$63`: <code>trainerflagaction <i>action</i></code> ## `$63`: <code>trainerortalkerflagaction <i>action</i></code>
## `$64`: <code>winlosstext <i>win_text_pointer</i>, <i>loss_text_pointer</i></code> ## `$64`: <code>winlosstext <i>win_text_pointer</i>, <i>loss_text_pointer</i></code>

View File

@ -20,12 +20,22 @@ BoardMenuScript::
; save after opentext to reanchor map first ; save after opentext to reanchor map first
; save before processing variables like wCurTurn due to BoardMenuScript reentry after game reset ; save before processing variables like wCurTurn due to BoardMenuScript reentry after game reset
farcall AutoSaveGameInOverworld farcall AutoSaveGameInOverworld
; reset turn-scoped variables (wDieRoll, wSpacesLeft) and update wCurTurn
ld hl, wTurnData ld hl, wTurnData
ld bc, wTurnDataEnd - wTurnData ld bc, wTurnDataEnd - wTurnData
xor a xor a
call ByteFill call ByteFill
ld hl, wCurTurn ld hl, wCurTurn
inc [hl] 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 jp LoadCurSpaceData
.Die: .Die:

View File

@ -1,6 +1,6 @@
TalkToTrainerScript:: TalkToTrainerScript::
faceplayer faceplayer
trainerflagaction CHECK_FLAG trainerortalkerflagaction CHECK_FLAG
iftrue AlreadyBeatenTrainerScript iftrue AlreadyBeatenTrainerScript
loadtemptrainer loadtemptrainer
encountermusic encountermusic
@ -25,7 +25,7 @@ StartBattleWithMapTrainerScript:
loadtemptrainer loadtemptrainer
startbattle startbattle
reloadmapafterbattle reloadmapafterbattle
trainerflagaction SET_FLAG trainerortalkerflagaction SET_FLAG
loadmem wRunningTrainerBattleScript, -1 loadmem wRunningTrainerBattleScript, -1
AlreadyBeatenTrainerScript: AlreadyBeatenTrainerScript:
@ -34,8 +34,30 @@ AlreadyBeatenTrainerScript:
SeenByTalkerScript:: SeenByTalkerScript::
waitsfx ; wait for any pending space-related sfx waitsfx ; wait for any pending space-related sfx
showemote EMOTE_TALK, LAST_TALKED, 20 showemote EMOTE_TALK, LAST_TALKED, 20
callasm .TalkOrSkipTalker
iffalse .skipped
callasm TrainerOrTalkerWalkToPlayer callasm TrainerOrTalkerWalkToPlayer
applymovementlasttalked wMovementBuffer applymovementlasttalked wMovementBuffer
writeobjectxy LAST_TALKED writeobjectxy LAST_TALKED
faceobject PLAYER, LAST_TALKED faceobject PLAYER, LAST_TALKED
.skipped
end 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

View File

@ -459,7 +459,7 @@ CheckTrainerOrTalkerEvent:
call CheckTrainerBattleOrTalkerPrompt call CheckTrainerBattleOrTalkerPrompt
jr nc, .nope jr nc, .nope
ld a, [wTrainerOrTalkerIsTalker] ld a, [wSeenTrainerOrTalkerIsTalker]
and a ; cp FALSE and a ; cp FALSE
ld a, PLAYEREVENT_SEENBYTRAINER ld a, PLAYEREVENT_SEENBYTRAINER
jr z, .done jr z, .done

View File

@ -163,7 +163,7 @@ ScriptCommandTable:
dw Script_reloadmapafterbattle ; 60 dw Script_reloadmapafterbattle ; 60
dw Script_catchtutorial ; 61 dw Script_catchtutorial ; 61
dw Script_trainertext ; 62 dw Script_trainertext ; 62
dw Script_trainerflagaction ; 63 dw Script_trainerortalkerflagaction ; 63
dw Script_winlosstext ; 64 dw Script_winlosstext ; 64
dw Script_scripttalkafter ; 65 dw Script_scripttalkafter ; 65
dw Script_endifjustbattled ; 66 dw Script_endifjustbattled ; 66
@ -685,10 +685,10 @@ Script_scripttalkafter:
ld b, a ld b, a
jp ScriptJump jp ScriptJump
Script_trainerflagaction: Script_trainerortalkerflagaction:
xor a xor a
ldh [hScriptVar], a ldh [hScriptVar], a
ld hl, wTempTrainerEventFlag ld hl, wTempTrainerEventFlag ; wTempTalkerEventFlag
ld e, [hl] ld e, [hl]
inc hl inc hl
ld d, [hl] ld d, [hl]

View File

@ -39,14 +39,14 @@ _CheckTrainerBattleOrTalkerPrompt::
jr z, .is_trainer jr z, .is_trainer
cp OBJECTTYPE_TALKER cp OBJECTTYPE_TALKER
jr nz, .next 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 ;.is_talker
ld a, TRUE ld a, TRUE
ld [wTrainerOrTalkerIsTalker], a ld [wSeenTrainerOrTalkerIsTalker], a
jr .go jr .go
.is_trainer .is_trainer
xor a ; FALSE xor a ; FALSE
ld [wTrainerOrTalkerIsTalker], a ld [wSeenTrainerOrTalkerIsTalker], a
.go .go
; Is visible on the map ; Is visible on the map
@ -68,11 +68,31 @@ _CheckTrainerBattleOrTalkerPrompt::
cp b cp b
jr c, .next jr c, .next
ld a, [wTrainerOrTalkerIsTalker] ; And hasn't already been beaten if it's a trainer, or talked to if it's a talker,
and a ; TRUE? ; according to the scope of the flag of the trainer or talker event.
jr z, .trainer_battle 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 de
pop af pop af
ldh [hLastTalked], a ldh [hLastTalked], a
@ -98,26 +118,6 @@ _CheckTrainerBattleOrTalkerPrompt::
scf scf
ret 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 .next
pop de pop de
ld hl, MAPOBJECT_LENGTH ld hl, MAPOBJECT_LENGTH
@ -132,7 +132,7 @@ _CheckTrainerBattleOrTalkerPrompt::
xor a xor a
ret ret
.startbattle .prepare_trainer_battle
pop de pop de
pop af pop af
ldh [hLastTalked], a ldh [hLastTalked], a

View File

@ -206,7 +206,7 @@ DEF battlecheck EQUS "randomwildmon"
DEF loadtrainerdata EQUS "loadtemptrainer" DEF loadtrainerdata EQUS "loadtemptrainer"
DEF loadpokedata EQUS "loadwildmon" DEF loadpokedata EQUS "loadwildmon"
DEF returnafterbattle EQUS "reloadmapafterbattle" DEF returnafterbattle EQUS "reloadmapafterbattle"
DEF trainerstatus EQUS "trainerflagaction" DEF trainerstatus EQUS "trainerortalkerflagaction"
DEF talkaftercancel EQUS "endifjustbattled" DEF talkaftercancel EQUS "endifjustbattled"
DEF talkaftercheck EQUS "checkjustbattled" DEF talkaftercheck EQUS "checkjustbattled"
DEF playrammusic EQUS "encountermusic" DEF playrammusic EQUS "encountermusic"

View File

@ -632,9 +632,9 @@ MACRO trainertext
db \1 ; text_id db \1 ; text_id
ENDM ENDM
const trainerflagaction_command ; $63 const trainerortalkerflagaction_command ; $63
MACRO trainerflagaction MACRO trainerortalkerflagaction
db trainerflagaction_command db trainerortalkerflagaction_command
db \1 ; action db \1 ; action
ENDM ENDM

View File

@ -28,7 +28,7 @@ DebugLevel5_Map1_MapEvents:
.DebugLevel5_Map1TrainerYoungsterMikey2: .DebugLevel5_Map1TrainerYoungsterMikey2:
trainer YOUNGSTER, MIKEY, EVENT_LEVEL_SCOPED_2, .YoungsterMikeySeenText, .YoungsterMikeyBeatenText, 0, .Script 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 ; .Data: ; Text
; db .Text ; db .Text
; .Data: ; Modal text ; .Data: ; Modal text

View File

@ -1551,7 +1551,7 @@ SECTION UNION "Miscellaneous WRAM 1", WRAMX
UNION UNION
; trainer and talker data ; trainer and talker data
wTrainerOrTalkerIsTalker:: db ; TRUE means talker; FALSE means trainer wSeenTrainerOrTalkerIsTalker:: db ; TRUE means talker; FALSE means trainer
wSeenTrainerOrTalkerBank:: db wSeenTrainerOrTalkerBank:: db
wSeenTrainerOrTalkerDistance:: db wSeenTrainerOrTalkerDistance:: db
wSeenTrainerOrTalkerDirection:: db wSeenTrainerOrTalkerDirection:: db