forked from pret/pokered
-
Notifications
You must be signed in to change notification settings - Fork 65
Expand file tree
/
Copy pathtrainers.asm
More file actions
365 lines (342 loc) · 9.19 KB
/
trainers.asm
File metadata and controls
365 lines (342 loc) · 9.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
; PureRGBnote: MOVED: a bunch of code was moved from this file to other banks or commented out since it was unused.
; stores hl in [wTrainerHeaderPtr]
StoreTrainerHeaderPointer::
ld a, h
ld [wTrainerHeaderPtr], a
ld a, l
ld [wTrainerHeaderPtr+1], a
ret
; executes the current map script from the function pointer array provided in de.
; a: map script index to execute (unless overridden by [wStatusFlags7] BIT_USE_CUR_MAP_SCRIPT)
; hl: trainer header pointer
ExecuteCurMapScriptInTable::
push af
push de
call StoreTrainerHeaderPointer
pop hl
pop af
push hl
ld hl, wStatusFlags7
bit BIT_USE_CUR_MAP_SCRIPT, [hl]
res BIT_USE_CUR_MAP_SCRIPT, [hl]
jr z, .useProvidedIndex ; test if map script index was overridden manually
ld a, [wCurMapScript]
.useProvidedIndex
pop hl
ld [wCurMapScript], a
call CallFunctionInTable
ld a, [wCurMapScript]
ret
; reads specific information from trainer header (pointed to at wTrainerHeaderPtr)
; a: offset in header data
; 0 -> flag's bit (into wTrainerHeaderFlagBit)
; 2 -> flag's byte ptr (into hl)
; 4 -> before battle text (into hl)
; 6 -> after battle text (into hl)
; 8 -> end battle text (into hl)
ReadTrainerHeaderInfo::
push de
push af
ld d, $0
ld e, a
ld hl, wTrainerHeaderPtr
ld a, [hli]
ld l, [hl]
ld h, a
add hl, de
pop af
and a
jr nz, .nonZeroOffset
ld a, [hl]
ld [wTrainerHeaderFlagBit], a ; store flag's bit
jr .done
.nonZeroOffset
cp $2
jr z, .readPointer ; read flag's byte ptr
cp $4
jr z, .readPointer ; read before battle text
cp $6
jr z, .readPointer ; read after battle text
cp $8
jr nz, .done
; jr z, .readPointer
; cp $a
; jr nz, .done
; ld a, [hli] ; read end battle text (2) but override the result afterwards (XXX why, bug?)
; ld d, [hl]
; ld e, a
; jr .done
.readPointer ; read end battle text
call GetAddressFromPointer
.done
pop de
ret
; PureRGBnote: CHANGED: this function was optimized a bit.
TalkToTrainer::
call StoreTrainerHeaderPointer
xor a
call ReadTrainerHeaderInfo ; read flag's bit
call TrainerFlagActionTest ; read trainer's flag
ld a, c
and a
jr z, .trainerNotYetFought ; test trainer's flag
ld a, $6
call ReadTrainerHeaderInfo ; print after battle text
rst _PrintText
ret
.trainerNotYetFought
ld a, $4
call ReadTrainerHeaderInfo ; print before battle text
rst _PrintText
;ld a, $a
;call ReadTrainerHeaderInfo ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo)
push de
ld a, $8
call ReadTrainerHeaderInfo ; read end battle text
pop de
call SaveEndBattleTextPointers
ld hl, wStatusFlags7
set BIT_USE_CUR_MAP_SCRIPT, [hl] ; activate map script index override (index is set below)
ld hl, wMiscFlags
bit BIT_SEEN_BY_TRAINER, [hl] ; test if player is already engaging the trainer (because the trainer saw the player)
ret nz
; if the player talked to the trainer of his own volition
call EngageMapTrainer
ld hl, wCurMapScript
inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle)
jp StartTrainerBattle
; checks if any trainers are seeing the player and wanting to fight
CheckFightingMapTrainers::
IF DEF(_DEBUG)
call DebugPressedOrHeldB
jr nz, .trainerNotEngaging
ENDC
call CheckForEngagingTrainers
ld a, [wSpriteIndex]
cp $ff
jr nz, .trainerEngaging
IF DEF(_DEBUG)
.trainerNotEngaging
ENDC
xor a
ld [wSpriteIndex], a
ld [wTrainerHeaderFlagBit], a
ret
.trainerEngaging
ld hl, wStatusFlags7
set BIT_TRAINER_BATTLE, [hl]
ld [wEmotionBubbleSpriteIndex], a
xor a ; EXCLAMATION_BUBBLE
ld [wWhichEmotionBubble], a
predef EmotionBubble
call DisableDpad
xor a
ldh [hJoyHeld], a
call TrainerWalkUpToPlayer_Bank0
ld hl, wCurMapScript
inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle)
ret
; display the before battle text after the enemy trainer has walked up to the player's sprite
DisplayEnemyTrainerTextAndStartBattle::
ld a, [wStatusFlags5]
and 1 << BIT_SCRIPTED_NPC_MOVEMENT
ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite
call EnableAllJoypad
ld a, [wSpriteIndex]
ldh [hSpriteIndex], a
call DisplayTextID
; fall through
StartTrainerBattle::
call EnableAllJoypad
call InitBattleEnemyParameters
ld hl, wStatusFlags3
set BIT_TALKED_TO_TRAINER, [hl]
set BIT_PRINT_END_BATTLE_TEXT, [hl]
ld hl, wStatusFlags4
set BIT_UNKNOWN_4_1, [hl]
ld hl, wCurMapScript
inc [hl] ; increment map script index (next script function is usually EndTrainerBattle)
ret
EndTrainerBattle::
ld hl, wCurrentMapScriptFlags
set BIT_CUR_MAP_LOADED_1, [hl]
set BIT_CUR_MAP_LOADED_2, [hl]
ld hl, wStatusFlags3
res BIT_PRINT_END_BATTLE_TEXT, [hl]
ld hl, wMiscFlags
res BIT_SEEN_BY_TRAINER, [hl] ; player is no longer engaged by any trainer
ld a, [wIsInBattle]
cp $ff
jr z, ResetButtonPressedAndMapScript
ld b, FLAG_SET
call TrainerFlagAction ; flag trainer as fought
ld a, [wEnemyMonOrTrainerClass]
cp OPP_ID_OFFSET
jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite)
; code that removes overworld pokemon like articuno, mewtwo, snorlax, etc. when defeated
; TODO: hide extra object if in extra map???
ld hl, wToggleableObjectList
ld de, 2
ld a, [wSpriteIndex]
call IsInArray ; search for sprite ID
inc hl
ld a, [hl]
ld [wToggleableObjectIndex], a ; load corresponding toggleable object index and remove it
predef HideObject
.skipRemoveSprite
ld hl, wStatusFlags5
bit BIT_UNKNOWN_5_4, [hl]
res BIT_UNKNOWN_5_4, [hl]
ret nz
ResetButtonPressedAndMapScript::
call EnableAllJoypad
; a = 0 from EnableAllJoypad
ldh [hJoyHeld], a
ldh [hJoyPressed], a
ldh [hJoyReleased], a
ld [wCurMapScript], a ; reset battle status
ret
; calls TrainerWalkUpToPlayer
TrainerWalkUpToPlayer_Bank0::
farjp TrainerWalkUpToPlayer
; sets opponent type and mon set/lvl based on the engaging trainer data
InitBattleEnemyParameters::
ld a, [wEngagedTrainerClass]
ld [wCurOpponent], a
ld [wEnemyMonOrTrainerClass], a
cp OPP_ID_OFFSET
ld a, [wEngagedTrainerSet]
jr c, .noTrainer
ld [wTrainerNo], a
ret
.noTrainer
ld [wCurEnemyLevel], a
ret
GetSpritePosition1::
ld hl, _GetSpritePosition1
jr SpritePositionBankswitch
GetSpritePosition2::
ld hl, _GetSpritePosition2
jr SpritePositionBankswitch
SetSpritePosition1::
ld hl, _SetSpritePosition1
jr SpritePositionBankswitch
SetSpritePosition2::
ld hl, _SetSpritePosition2
SpritePositionBankswitch::
ld b, BANK("Trainer Sight")
rst _Bankswitch
ret
CheckForEngagingTrainers::
xor a
call ReadTrainerHeaderInfo ; read trainer flag's bit (unused)
ld d, h ; store trainer header address in de
ld e, l
.trainerLoop
call StoreTrainerHeaderPointer ; set trainer header pointer to current trainer
ld a, [de]
ld [wSpriteIndex], a ; store trainer flag's bit
ld [wTrainerHeaderFlagBit], a
cp -1
ret z
call TrainerFlagActionTest ; read trainer flag
ld a, c
and a ; has the trainer already been defeated?
jr nz, .continue
push hl
push de
push hl
xor a
call ReadTrainerHeaderInfo ; get trainer header pointer
inc hl
ld a, [hl] ; read trainer engage distance
pop hl
ld [wTrainerEngageDistance], a
ld a, [wSpriteIndex]
swap a
ld [wTrainerSpriteOffset], a
predef TrainerEngage
pop de
pop hl
ld a, [wTrainerSpriteOffset]
and a
ret nz ; break if the trainer is engaging
.continue
ld hl, $c
add hl, de
ld d, h
ld e, l
jr .trainerLoop
; hl = text if the player wins
; de = text if the player loses
SaveEndBattleTextPointers::
ldh a, [hLoadedROMBank]
ld [wEndBattleTextRomBank], a
ld a, h
ld [wEndBattleWinTextPointer], a
ld a, l
ld [wEndBattleWinTextPointer + 1], a
ld a, d
ld [wEndBattleLoseTextPointer], a
ld a, e
ld [wEndBattleLoseTextPointer + 1], a
ret
; loads data of some trainer on the current map and plays pre-battle music
; [wSpriteIndex]: sprite ID of trainer who is engaged
EngageMapTrainer::
ld hl, wMapSpriteExtraData
ld d, $0
ld a, [wSpriteIndex]
dec a
add a
ld e, a
add hl, de ; seek to engaged trainer data
ld a, [hli] ; load trainer class
ld [wEngagedTrainerClass], a
ld a, [hl] ; load trainer mon set
ld [wEngagedTrainerSet], a
jpfar PlayTrainerMusic ; PureRGBnote: MOVED: playtrainermusic was moved to another bank
PrintEndBattleText::
push hl
ld hl, wStatusFlags3
bit BIT_PRINT_END_BATTLE_TEXT, [hl]
res BIT_PRINT_END_BATTLE_TEXT, [hl]
pop hl
ret z
ldh a, [hLoadedROMBank]
push af
ld a, [wEndBattleTextRomBank]
call SetCurBank
push hl
farcall SaveTrainerName
ld hl, TrainerEndBattleText
rst _PrintText
pop hl
pop af
call SetCurBank
farcall SetEnemyTrainerToStayAndFaceAnyDirection
jp WaitForSoundToFinish
GetSavedEndBattleTextPointer::
ld a, [wBattleResult]
and a
jr nz, .lostBattle
hl_deref_reverse wEndBattleWinTextPointer
ret
.lostBattle
hl_deref_reverse wEndBattleLoseTextPointer
ret
TrainerEndBattleText::
text_far _TrainerNameText
text_asm
call GetSavedEndBattleTextPointer
call TextCommandProcessor
rst TextScriptEnd
TrainerFlagActionTest::
ld b, FLAG_TEST
; fall through
TrainerFlagAction::
ld a, $2
call ReadTrainerHeaderInfo ; read flag's byte ptr (does not change b register)
ld a, [wTrainerHeaderFlagBit]
ld c, a
predef_jump FlagActionPredef