Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/engine/overworld/trainer_sight.asm
1271 views
1
_GetSpritePosition1::
2
ld hl, wSpriteStateData1
3
ld de, SPRITESTATEDATA1_YPIXELS
4
ld a, [wSpriteIndex]
5
ldh [hSpriteIndex], a
6
call GetSpriteDataPointer
7
ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
8
ldh [hSpriteScreenYCoord], a
9
inc hl
10
ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
11
ldh [hSpriteScreenXCoord], a
12
ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
13
add hl, de
14
ld a, [hli] ; x#SPRITESTATEDATA2_MAPY
15
ldh [hSpriteMapYCoord], a
16
ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
17
ldh [hSpriteMapXCoord], a
18
ret
19
20
_GetSpritePosition2::
21
ld hl, wSpriteStateData1
22
ld de, SPRITESTATEDATA1_YPIXELS
23
ld a, [wSpriteIndex]
24
ldh [hSpriteIndex], a
25
call GetSpriteDataPointer
26
ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
27
ld [wSavedSpriteScreenY], a
28
inc hl
29
ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
30
ld [wSavedSpriteScreenX], a
31
ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
32
add hl, de
33
ld a, [hli] ; x#SPRITESTATEDATA2_MAPY
34
ld [wSavedSpriteMapY], a
35
ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
36
ld [wSavedSpriteMapX], a
37
ret
38
39
_SetSpritePosition1::
40
ld hl, wSpriteStateData1
41
ld de, SPRITESTATEDATA1_YPIXELS
42
ld a, [wSpriteIndex]
43
ldh [hSpriteIndex], a
44
call GetSpriteDataPointer
45
ldh a, [hSpriteScreenYCoord] ; x#SPRITESTATEDATA1_YPIXELS
46
ld [hli], a
47
inc hl
48
ldh a, [hSpriteScreenXCoord] ; x#SPRITESTATEDATA1_XPIXELS
49
ld [hl], a
50
ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
51
add hl, de
52
ldh a, [hSpriteMapYCoord] ; x#SPRITESTATEDATA2_MAPY
53
ld [hli], a
54
ldh a, [hSpriteMapXCoord] ; x#SPRITESTATEDATA2_MAPX
55
ld [hl], a
56
ret
57
58
_SetSpritePosition2::
59
ld hl, wSpriteStateData1
60
ld de, SPRITESTATEDATA1_YPIXELS
61
ld a, [wSpriteIndex]
62
ldh [hSpriteIndex], a
63
call GetSpriteDataPointer
64
ld a, [wSavedSpriteScreenY]
65
ld [hli], a ; x#SPRITESTATEDATA1_YPIXELS
66
inc hl
67
ld a, [wSavedSpriteScreenX]
68
ld [hl], a ; x#SPRITESTATEDATA1_XPIXELS
69
ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
70
add hl, de
71
ld a, [wSavedSpriteMapY]
72
ld [hli], a ; x#SPRITESTATEDATA2_MAPY
73
ld a, [wSavedSpriteMapX]
74
ld [hl], a ; x#SPRITESTATEDATA2_MAPX
75
ret
76
77
TrainerWalkUpToPlayer::
78
ld a, [wSpriteIndex]
79
swap a
80
ld [wTrainerSpriteOffset], a
81
call ReadTrainerScreenPosition
82
ld a, [wTrainerFacingDirection]
83
and a ; SPRITE_FACING_DOWN
84
jr z, .facingDown
85
cp SPRITE_FACING_UP
86
jr z, .facingUp
87
cp SPRITE_FACING_LEFT
88
jr z, .facingLeft
89
jr .facingRight
90
.facingDown
91
ld a, [wTrainerScreenY]
92
ld b, a
93
ld a, $3c ; (fixed) player screen Y pos
94
call CalcDifference
95
cp $10 ; trainer is right above player
96
ret z
97
swap a
98
dec a
99
ld c, a ; bc = steps yet to go to reach player
100
xor a ; NPC_MOVEMENT_DOWN
101
ld b, a
102
jr .writeWalkScript
103
.facingUp
104
ld a, [wTrainerScreenY]
105
ld b, a
106
ld a, $3c ; (fixed) player screen Y pos
107
call CalcDifference
108
cp $10 ; trainer is right below player
109
ret z
110
swap a
111
dec a
112
ld c, a ; bc = steps yet to go to reach player
113
ld b, $0
114
ld a, NPC_MOVEMENT_UP
115
jr .writeWalkScript
116
.facingRight
117
ld a, [wTrainerScreenX]
118
ld b, a
119
ld a, $40 ; (fixed) player screen X pos
120
call CalcDifference
121
cp $10 ; trainer is directly left of player
122
ret z
123
swap a
124
dec a
125
ld c, a ; bc = steps yet to go to reach player
126
ld b, $0
127
ld a, NPC_MOVEMENT_RIGHT
128
jr .writeWalkScript
129
.facingLeft
130
ld a, [wTrainerScreenX]
131
ld b, a
132
ld a, $40 ; (fixed) player screen X pos
133
call CalcDifference
134
cp $10 ; trainer is directly right of player
135
ret z
136
swap a
137
dec a
138
ld c, a ; bc = steps yet to go to reach player
139
ld b, $0
140
ld a, NPC_MOVEMENT_LEFT
141
.writeWalkScript
142
ld hl, wNPCMovementDirections2
143
ld de, wNPCMovementDirections2
144
call FillMemory ; write the necessary steps to reach player
145
ld [hl], $ff ; write end of list sentinel
146
ld a, [wSpriteIndex]
147
ldh [hSpriteIndex], a
148
jp MoveSprite_
149
150
; input: de = offset within sprite entry
151
; output: hl = pointer to sprite data
152
GetSpriteDataPointer:
153
push de
154
add hl, de
155
ldh a, [hSpriteIndex]
156
swap a
157
ld d, $0
158
ld e, a
159
add hl, de
160
pop de
161
ret
162
163
; tests if this trainer is in the right position to engage the player and do so if she is.
164
TrainerEngage:
165
push hl
166
push de
167
ld a, [wTrainerSpriteOffset]
168
add SPRITESTATEDATA1_IMAGEINDEX
169
ld d, $0
170
ld e, a
171
ld hl, wSpriteStateData1
172
add hl, de
173
ld a, [hl] ; x#SPRITESTATEDATA1_IMAGEINDEX
174
sub $ff
175
jr nz, .spriteOnScreen ; test if sprite is on screen
176
jp .noEngage
177
.spriteOnScreen
178
ld a, [wTrainerSpriteOffset]
179
add SPRITESTATEDATA1_FACINGDIRECTION
180
ld d, $0
181
ld e, a
182
ld hl, wSpriteStateData1
183
add hl, de
184
ld a, [hl] ; x#SPRITESTATEDATA1_FACINGDIRECTION
185
ld [wTrainerFacingDirection], a
186
call ReadTrainerScreenPosition
187
ld a, [wTrainerScreenY] ; sprite screen Y pos
188
ld b, a
189
ld a, $3c
190
cp b
191
jr z, .linedUpY
192
ld a, [wTrainerScreenX] ; sprite screen X pos
193
ld b, a
194
ld a, $40
195
cp b
196
jr z, .linedUpX
197
xor a
198
jp .noEngage
199
.linedUpY
200
ld a, [wTrainerScreenX] ; sprite screen X pos
201
ld b, a
202
ld a, $40 ; (fixed) player X position
203
call CalcDifference ; calc distance
204
jr z, .noEngage ; exact same position as player
205
call CheckSpriteCanSeePlayer
206
jr c, .engage
207
xor a
208
jr .noEngage
209
.linedUpX
210
ld a, [wTrainerScreenY] ; sprite screen Y pos
211
ld b, a
212
ld a, $3c ; (fixed) player Y position
213
call CalcDifference ; calc distance
214
jr z, .noEngage ; exact same position as player
215
call CheckSpriteCanSeePlayer
216
jr c, .engage
217
xor a
218
jp .noEngage
219
.engage
220
call CheckPlayerIsInFrontOfSprite
221
ld a, [wTrainerSpriteOffset]
222
and a
223
jr z, .noEngage
224
ld hl, wMiscFlags
225
set BIT_SEEN_BY_TRAINER, [hl]
226
call EngageMapTrainer
227
ld a, $ff
228
.noEngage
229
ld [wTrainerSpriteOffset], a
230
pop de
231
pop hl
232
ret
233
234
; reads trainer's Y position to wTrainerScreenY and X position to wTrainerScreenX
235
ReadTrainerScreenPosition:
236
ld a, [wTrainerSpriteOffset]
237
add SPRITESTATEDATA1_YPIXELS
238
ld d, $0
239
ld e, a
240
ld hl, wSpriteStateData1
241
add hl, de
242
ld a, [hl] ; x#SPRITESTATEDATA1_YPIXELS
243
ld [wTrainerScreenY], a
244
ld a, [wTrainerSpriteOffset]
245
add SPRITESTATEDATA1_XPIXELS
246
ld d, $0
247
ld e, a
248
ld hl, wSpriteStateData1
249
add hl, de
250
ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
251
ld [wTrainerScreenX], a
252
ret
253
254
; checks if the sprite is properly lined up with the player with respect to the direction it's looking. Also checks the distance between player and sprite
255
; note that this does not necessarily mean the sprite is seeing the player, he could be behind it's back
256
; a: distance player to sprite
257
CheckSpriteCanSeePlayer:
258
ld b, a
259
ld a, [wTrainerEngageDistance] ; how far the trainer can see
260
cp b
261
jr nc, .checkIfLinedUp
262
jr .notInLine ; player too far away
263
.checkIfLinedUp
264
ld a, [wTrainerFacingDirection] ; sprite facing direction
265
cp SPRITE_FACING_DOWN
266
jr z, .checkXCoord
267
cp SPRITE_FACING_UP
268
jr z, .checkXCoord
269
cp SPRITE_FACING_LEFT
270
jr z, .checkYCoord
271
cp SPRITE_FACING_RIGHT
272
jr z, .checkYCoord
273
jr .notInLine
274
.checkXCoord
275
ld a, [wTrainerScreenX] ; sprite screen X position
276
ld b, a
277
cp $40
278
jr z, .inLine
279
jr .notInLine
280
.checkYCoord
281
ld a, [wTrainerScreenY] ; sprite screen Y position
282
ld b, a
283
cp $3c
284
jr nz, .notInLine
285
.inLine
286
scf
287
ret
288
.notInLine
289
and a
290
ret
291
292
; tests if the player is in front of the sprite (rather than behind it)
293
CheckPlayerIsInFrontOfSprite:
294
ld a, [wCurMap]
295
cp POWER_PLANT
296
jp z, .engage ; bypass this for power plant to get voltorb fake items to work
297
ld a, [wTrainerSpriteOffset]
298
add SPRITESTATEDATA1_YPIXELS
299
ld d, $0
300
ld e, a
301
ld hl, wSpriteStateData1
302
add hl, de
303
ld a, [hl] ; x#SPRITESTATEDATA1_YPIXELS
304
cp $fc
305
jr nz, .notOnTopmostTile ; special case if sprite is on topmost tile (Y = $fc (-4)), make it come down a block
306
ld a, $c
307
.notOnTopmostTile
308
ld [wTrainerScreenY], a
309
ld a, [wTrainerSpriteOffset]
310
add SPRITESTATEDATA1_XPIXELS
311
ld d, $0
312
ld e, a
313
ld hl, wSpriteStateData1
314
add hl, de
315
ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
316
ld [wTrainerScreenX], a
317
ld a, [wTrainerFacingDirection] ; facing direction
318
cp SPRITE_FACING_DOWN
319
jr nz, .notFacingDown
320
ld a, [wTrainerScreenY] ; sprite screen Y pos
321
cp $3c
322
jr c, .engage ; sprite above player
323
jr .noEngage ; sprite below player
324
.notFacingDown
325
cp SPRITE_FACING_UP
326
jr nz, .notFacingUp
327
ld a, [wTrainerScreenY] ; sprite screen Y pos
328
cp $3c
329
jr nc, .engage ; sprite below player
330
jr .noEngage ; sprite above player
331
.notFacingUp
332
cp SPRITE_FACING_LEFT
333
jr nz, .notFacingLeft
334
ld a, [wTrainerScreenX] ; sprite screen X pos
335
cp $40
336
jr nc, .engage ; sprite right of player
337
jr .noEngage ; sprite left of player
338
.notFacingLeft
339
ld a, [wTrainerScreenX] ; sprite screen X pos
340
cp $40
341
jr nc, .noEngage ; sprite right of player
342
.engage
343
ld a, $ff
344
jr .done
345
.noEngage
346
xor a
347
.done
348
ld [wTrainerSpriteOffset], a
349
ret
350
351