Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Scene/Legacy/v3/CollisionLegacyv3.cpp
1177 views
1
2
int32 RSDK::Legacy::v3::collisionLeft = 0;
3
int32 RSDK::Legacy::v3::collisionTop = 0;
4
int32 RSDK::Legacy::v3::collisionRight = 0;
5
int32 RSDK::Legacy::v3::collisionBottom = 0;
6
7
RSDK::Legacy::v3::CollisionSensor RSDK::Legacy::v3::sensors[6];
8
RSDK::Legacy::v3::CollisionStore RSDK::Legacy::v3::collisionStorage[2];
9
10
const int32 hammerJumpHitbox[] = {
11
-25, -25, 25, 25,
12
-25, -25, 25, 25,
13
-25, -25, 25, 25,
14
-25, -25, 25, 25
15
};
16
17
const int32 hammerDashHitbox[] = {
18
-10, -17, 23, 17,
19
-23, -17, 10, 17,
20
-18, -24, 10, 17,
21
-10, -26, 25, 17,
22
-10, -17, 23, 17,
23
-23, -17, 10, 17,
24
-18, -24, 10, 17,
25
-10, -26, 25, 17
26
};
27
28
const int32 chibiHammerJumpHitbox[] = {
29
-15, -11, 15, 20,
30
-15, -11, 15, 20,
31
};
32
33
const int32 chibiHammerDashHitbox[] = {
34
-14, -12, 8, 12,
35
-10, -12, 8, 12,
36
-8, -12,16, 12
37
};
38
39
#if !RETRO_USE_ORIGINAL_CODE
40
int32 RSDK::Legacy::v3::AddDebugHitbox(uint8 type, Entity *entity, int32 left, int32 top, int32 right, int32 bottom)
41
{
42
int32 XPos = 0, YPos = 0;
43
if (entity) {
44
XPos = entity->XPos;
45
YPos = entity->YPos;
46
}
47
else {
48
Player *player = &playerList[activePlayer];
49
XPos = player->XPos;
50
YPos = player->YPos;
51
}
52
53
int32 i = 0;
54
for (; i < debugHitboxCount; ++i) {
55
if (debugHitboxList[i].hitbox.left == left && debugHitboxList[i].hitbox.top == top && debugHitboxList[i].hitbox.right == right
56
&& debugHitboxList[i].hitbox.bottom == bottom && debugHitboxList[i].pos.x == XPos && debugHitboxList[i].pos.y == YPos
57
&& debugHitboxList[i].entity == entity) {
58
return i;
59
}
60
}
61
62
if (i < DEBUG_HITBOX_COUNT) {
63
debugHitboxList[i].type = type;
64
debugHitboxList[i].entity = entity;
65
debugHitboxList[i].collision = 0;
66
debugHitboxList[i].hitbox.left = left;
67
debugHitboxList[i].hitbox.top = top;
68
debugHitboxList[i].hitbox.right = right;
69
debugHitboxList[i].hitbox.bottom = bottom;
70
debugHitboxList[i].pos.x = XPos;
71
debugHitboxList[i].pos.y = YPos;
72
73
int32 id = debugHitboxCount;
74
debugHitboxCount++;
75
return id;
76
}
77
78
return -1;
79
}
80
#endif
81
82
RSDK::Legacy::Hitbox *RSDK::Legacy::v3::GetPlayerHitbox(Player *player)
83
{
84
AnimationFile *animFile = player->animationFile;
85
return &hitboxList
86
[animFrames[animationList[animFile->aniListOffset + player->boundEntity->animation].frameListOffset + player->boundEntity->frame].hitboxID
87
+ animFile->hitboxListOffset];
88
}
89
90
void RSDK::Legacy::v3::FindFloorPosition(Player *player, CollisionSensor *sensor, int32 startY)
91
{
92
int32 c = 0;
93
int32 angle = sensor->angle;
94
int32 tsm1 = (TILE_SIZE - 1);
95
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
96
if (!sensor->collided) {
97
int32 XPos = sensor->XPos >> 16;
98
int32 chunkX = XPos >> 7;
99
int32 tileX = (XPos & 0x7F) >> 4;
100
int32 YPos = (sensor->YPos >> 16) + i - TILE_SIZE;
101
int32 chunkY = YPos >> 7;
102
int32 tileY = (YPos & 0x7F) >> 4;
103
if (XPos > -1 && YPos > -1) {
104
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
105
tile += tileX + (tileY << 3);
106
int32 tileIndex = tiles128x128.tileIndex[tile];
107
if (tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_LRB
108
&& tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_NONE) {
109
switch (tiles128x128.direction[tile]) {
110
case FLIP_NONE: {
111
c = (XPos & tsm1) + (tileIndex << 4);
112
if (collisionMasks[player->collisionPlane].floorMasks[c] >= 0x40)
113
break;
114
115
sensor->YPos = collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
116
sensor->collided = true;
117
sensor->angle = collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF;
118
break;
119
}
120
case FLIP_X: {
121
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
122
if (collisionMasks[player->collisionPlane].floorMasks[c] >= 0x40)
123
break;
124
125
sensor->YPos = collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
126
sensor->collided = true;
127
sensor->angle = 0x100 - (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF);
128
break;
129
}
130
case FLIP_Y: {
131
c = (XPos & 15) + (tileIndex << 4);
132
if (collisionMasks[player->collisionPlane].roofMasks[c] <= -0x40)
133
break;
134
135
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
136
sensor->collided = true;
137
uint8 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24;
138
sensor->angle = (uint8)(-0x80 - cAngle);
139
break;
140
}
141
case FLIP_XY: {
142
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
143
if (collisionMasks[player->collisionPlane].roofMasks[c] <= -0x40)
144
break;
145
146
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
147
sensor->collided = true;
148
uint8 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24;
149
sensor->angle = 0x100 - (uint8)(-0x80 - cAngle);
150
break;
151
}
152
}
153
}
154
155
if (sensor->collided) {
156
if (sensor->angle < 0)
157
sensor->angle += 0x100;
158
159
if (sensor->angle > 0xFF)
160
sensor->angle -= 0x100;
161
162
if ((abs(sensor->angle - angle) > 0x20) && (abs(sensor->angle - 0x100 - angle) > 0x20)
163
&& (abs(sensor->angle + 0x100 - angle) > 0x20)) {
164
sensor->YPos = startY << 16;
165
sensor->collided = false;
166
sensor->angle = angle;
167
i = TILE_SIZE * 3;
168
}
169
else if (sensor->YPos - startY > (TILE_SIZE - 2)) {
170
sensor->YPos = startY << 16;
171
sensor->collided = false;
172
}
173
else if (sensor->YPos - startY < -(TILE_SIZE - 2)) {
174
sensor->YPos = startY << 16;
175
sensor->collided = false;
176
}
177
}
178
}
179
}
180
}
181
}
182
void RSDK::Legacy::v3::FindLWallPosition(Player *player, CollisionSensor *sensor, int32 startX)
183
{
184
int32 c = 0;
185
int32 angle = sensor->angle;
186
int32 tsm1 = (TILE_SIZE - 1);
187
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
188
if (!sensor->collided) {
189
int32 XPos = (sensor->XPos >> 16) + i - TILE_SIZE;
190
int32 chunkX = XPos >> 7;
191
int32 tileX = (XPos & 0x7F) >> 4;
192
int32 YPos = sensor->YPos >> 16;
193
int32 chunkY = YPos >> 7;
194
int32 tileY = (YPos & 0x7F) >> 4;
195
if (XPos > -1 && YPos > -1) {
196
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
197
tile = tile + tileX + (tileY << 3);
198
int32 tileIndex = tiles128x128.tileIndex[tile];
199
if (tiles128x128.collisionFlags[player->collisionPlane][tile] < SOLID_NONE) {
200
switch (tiles128x128.direction[tile]) {
201
case FLIP_NONE: {
202
c = (YPos & tsm1) + (tileIndex << 4);
203
if (collisionMasks[player->collisionPlane].lWallMasks[c] >= 0x40)
204
break;
205
206
sensor->XPos = collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
207
sensor->collided = true;
208
sensor->angle = ((collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF00) >> 8);
209
break;
210
}
211
case FLIP_X: {
212
c = (YPos & tsm1) + (tileIndex << 4);
213
if (collisionMasks[player->collisionPlane].rWallMasks[c] <= -0x40)
214
break;
215
216
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
217
sensor->collided = true;
218
sensor->angle = 0x100 - ((collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF0000) >> 16);
219
break;
220
}
221
case FLIP_Y: {
222
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
223
if (collisionMasks[player->collisionPlane].lWallMasks[c] >= 0x40)
224
break;
225
226
sensor->XPos = collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
227
sensor->collided = true;
228
int32 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF00) >> 8;
229
sensor->angle = (uint8)(-0x80 - cAngle);
230
break;
231
}
232
case FLIP_XY: {
233
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
234
if (collisionMasks[player->collisionPlane].rWallMasks[c] <= -0x40)
235
break;
236
237
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
238
sensor->collided = true;
239
int32 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF0000) >> 16;
240
sensor->angle = 0x100 - (uint8)(-0x80 - cAngle);
241
break;
242
}
243
}
244
}
245
if (sensor->collided) {
246
if (sensor->angle < 0)
247
sensor->angle += 0x100;
248
249
if (sensor->angle > 0xFF)
250
sensor->angle -= 0x100;
251
252
if (abs(angle - sensor->angle) > 0x20) {
253
sensor->XPos = startX << 16;
254
sensor->collided = false;
255
sensor->angle = angle;
256
i = TILE_SIZE * 3;
257
}
258
else if (sensor->XPos - startX > TILE_SIZE - 2) {
259
sensor->XPos = startX << 16;
260
sensor->collided = false;
261
}
262
else if (sensor->XPos - startX < -(TILE_SIZE - 2)) {
263
sensor->XPos = startX << 16;
264
sensor->collided = false;
265
}
266
}
267
}
268
}
269
}
270
}
271
void RSDK::Legacy::v3::FindRoofPosition(Player *player, CollisionSensor *sensor, int32 startY)
272
{
273
int32 c = 0;
274
int32 angle = sensor->angle;
275
int32 tsm1 = (TILE_SIZE - 1);
276
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
277
if (!sensor->collided) {
278
int32 XPos = sensor->XPos >> 16;
279
int32 chunkX = XPos >> 7;
280
int32 tileX = (XPos & 0x7F) >> 4;
281
int32 YPos = (sensor->YPos >> 16) + TILE_SIZE - i;
282
int32 chunkY = YPos >> 7;
283
int32 tileY = (YPos & 0x7F) >> 4;
284
if (XPos > -1 && YPos > -1) {
285
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
286
tile = tile + tileX + (tileY << 3);
287
int32 tileIndex = tiles128x128.tileIndex[tile];
288
if (tiles128x128.collisionFlags[player->collisionPlane][tile] < SOLID_NONE) {
289
switch (tiles128x128.direction[tile]) {
290
case FLIP_NONE: {
291
c = (XPos & tsm1) + (tileIndex << 4);
292
if (collisionMasks[player->collisionPlane].roofMasks[c] <= -0x40)
293
break;
294
295
sensor->YPos = collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
296
sensor->collided = true;
297
sensor->angle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24;
298
break;
299
}
300
case FLIP_X: {
301
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
302
if (collisionMasks[player->collisionPlane].roofMasks[c] <= -0x40)
303
break;
304
305
sensor->YPos = collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
306
sensor->collided = true;
307
sensor->angle = 0x100 - ((collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24);
308
break;
309
}
310
case FLIP_Y: {
311
c = (XPos & tsm1) + (tileIndex << 4);
312
if (collisionMasks[player->collisionPlane].floorMasks[c] >= 0x40)
313
break;
314
315
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
316
sensor->collided = true;
317
uint8 cAngle = collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF;
318
sensor->angle = (uint8)(-0x80 - cAngle);
319
break;
320
}
321
case FLIP_XY: {
322
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
323
if (collisionMasks[player->collisionPlane].floorMasks[c] >= 0x40)
324
break;
325
326
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
327
sensor->collided = true;
328
uint8 cAngle = collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF;
329
sensor->angle = 0x100 - (uint8)(-0x80 - cAngle);
330
break;
331
}
332
}
333
}
334
335
if (sensor->collided) {
336
if (sensor->angle < 0)
337
sensor->angle += 0x100;
338
339
if (sensor->angle > 0xFF)
340
sensor->angle -= 0x100;
341
342
if (abs(sensor->angle - angle) <= 0x20) {
343
if (sensor->YPos - startY > tsm1) {
344
sensor->YPos = startY << 16;
345
sensor->collided = false;
346
}
347
if (sensor->YPos - startY < -tsm1) {
348
sensor->YPos = startY << 16;
349
sensor->collided = false;
350
}
351
}
352
else {
353
sensor->YPos = startY << 16;
354
sensor->collided = false;
355
sensor->angle = angle;
356
i = TILE_SIZE * 3;
357
}
358
}
359
}
360
}
361
}
362
}
363
void RSDK::Legacy::v3::FindRWallPosition(Player *player, CollisionSensor *sensor, int32 startX)
364
{
365
int32 c;
366
int32 angle = sensor->angle;
367
int32 tsm1 = (TILE_SIZE - 1);
368
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
369
if (!sensor->collided) {
370
int32 XPos = (sensor->XPos >> 16) + TILE_SIZE - i;
371
int32 chunkX = XPos >> 7;
372
int32 tileX = (XPos & 0x7F) >> 4;
373
int32 YPos = sensor->YPos >> 16;
374
int32 chunkY = YPos >> 7;
375
int32 tileY = (YPos & 0x7F) >> 4;
376
if (XPos > -1 && YPos > -1) {
377
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
378
tile = tile + tileX + (tileY << 3);
379
int32 tileIndex = tiles128x128.tileIndex[tile];
380
if (tiles128x128.collisionFlags[player->collisionPlane][tile] < SOLID_NONE) {
381
switch (tiles128x128.direction[tile]) {
382
case FLIP_NONE: {
383
c = (YPos & tsm1) + (tileIndex << 4);
384
if (collisionMasks[player->collisionPlane].rWallMasks[c] <= -0x40)
385
break;
386
387
sensor->XPos = collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
388
sensor->collided = true;
389
sensor->angle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF0000) >> 16;
390
break;
391
}
392
case FLIP_X: {
393
c = (YPos & tsm1) + (tileIndex << 4);
394
if (collisionMasks[player->collisionPlane].lWallMasks[c] >= 0x40)
395
break;
396
397
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
398
sensor->collided = true;
399
sensor->angle = 0x100 - ((collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF00) >> 8);
400
break;
401
}
402
case FLIP_Y: {
403
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
404
if (collisionMasks[player->collisionPlane].rWallMasks[c] <= -0x40)
405
break;
406
407
sensor->XPos = collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
408
sensor->collided = true;
409
int32 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF0000) >> 16;
410
sensor->angle = (uint8)(-0x80 - cAngle);
411
break;
412
}
413
case FLIP_XY: {
414
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
415
if (collisionMasks[player->collisionPlane].lWallMasks[c] >= 0x40)
416
break;
417
418
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
419
sensor->collided = true;
420
int32 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF00) >> 8;
421
sensor->angle = 0x100 - (uint8)(-0x80 - cAngle);
422
break;
423
}
424
}
425
}
426
if (sensor->collided) {
427
if (sensor->angle < 0)
428
sensor->angle += 0x100;
429
430
if (sensor->angle > 0xFF)
431
sensor->angle -= 0x100;
432
433
if (abs(sensor->angle - angle) > 0x20) {
434
sensor->XPos = startX << 16;
435
sensor->collided = false;
436
sensor->angle = angle;
437
i = TILE_SIZE * 3;
438
}
439
else if (sensor->XPos - startX > (TILE_SIZE - 2)) {
440
sensor->XPos = startX >> 16;
441
sensor->collided = false;
442
}
443
else if (sensor->XPos - startX < -(TILE_SIZE - 2)) {
444
sensor->XPos = startX << 16;
445
sensor->collided = false;
446
}
447
}
448
}
449
}
450
}
451
}
452
453
void RSDK::Legacy::v3::FloorCollision(Player *player, CollisionSensor *sensor)
454
{
455
int32 c;
456
int32 startY = sensor->YPos >> 16;
457
int32 tsm1 = (TILE_SIZE - 1);
458
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
459
if (!sensor->collided) {
460
int32 XPos = sensor->XPos >> 16;
461
int32 chunkX = XPos >> 7;
462
int32 tileX = (XPos & 0x7F) >> 4;
463
int32 YPos = (sensor->YPos >> 16) + i - TILE_SIZE;
464
int32 chunkY = YPos >> 7;
465
int32 tileY = (YPos & 0x7F) >> 4;
466
if (XPos > -1 && YPos > -1) {
467
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
468
tile += tileX + (tileY << 3);
469
int32 tileIndex = tiles128x128.tileIndex[tile];
470
if (tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_LRB
471
&& tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_NONE) {
472
switch (tiles128x128.direction[tile]) {
473
case FLIP_NONE: {
474
c = (XPos & tsm1) + (tileIndex << 4);
475
if ((YPos & tsm1) <= collisionMasks[player->collisionPlane].floorMasks[c] + i - TILE_SIZE
476
|| collisionMasks[player->collisionPlane].floorMasks[c] >= tsm1)
477
break;
478
479
sensor->YPos = collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
480
sensor->collided = true;
481
sensor->angle = collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF;
482
break;
483
}
484
case FLIP_X: {
485
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
486
if ((YPos & tsm1) <= collisionMasks[player->collisionPlane].floorMasks[c] + i - TILE_SIZE
487
|| collisionMasks[player->collisionPlane].floorMasks[c] >= tsm1)
488
break;
489
490
sensor->YPos = collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
491
sensor->collided = true;
492
sensor->angle = 0x100 - (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF);
493
break;
494
}
495
case FLIP_Y: {
496
c = (XPos & tsm1) + (tileIndex << 4);
497
if ((YPos & tsm1) <= tsm1 - collisionMasks[player->collisionPlane].roofMasks[c] + i - TILE_SIZE)
498
break;
499
500
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
501
sensor->collided = true;
502
int32 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24;
503
sensor->angle = (uint8)(-0x80 - cAngle);
504
break;
505
}
506
case FLIP_XY: {
507
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
508
if ((YPos & tsm1) <= tsm1 - collisionMasks[player->collisionPlane].roofMasks[c] + i - TILE_SIZE)
509
break;
510
511
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
512
sensor->collided = true;
513
int32 cAngle = (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24;
514
sensor->angle = 0x100 - (uint8)(-0x80 - cAngle);
515
break;
516
}
517
}
518
}
519
520
if (sensor->collided) {
521
if (sensor->angle < 0)
522
sensor->angle += 0x100;
523
524
if (sensor->angle > 0xFF)
525
sensor->angle -= 0x100;
526
527
if (sensor->YPos - startY > (TILE_SIZE - 2)) {
528
sensor->YPos = startY << 16;
529
sensor->collided = false;
530
}
531
else if (sensor->YPos - startY < -(TILE_SIZE + 1)) {
532
sensor->YPos = startY << 16;
533
sensor->collided = false;
534
}
535
}
536
}
537
}
538
}
539
}
540
void RSDK::Legacy::v3::LWallCollision(Player *player, CollisionSensor *sensor)
541
{
542
int32 c;
543
int32 startX = sensor->XPos >> 16;
544
int32 tsm1 = (TILE_SIZE - 1);
545
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
546
if (!sensor->collided) {
547
int32 XPos = (sensor->XPos >> 16) + i - TILE_SIZE;
548
int32 chunkX = XPos >> 7;
549
int32 tileX = (XPos & 0x7F) >> 4;
550
int32 YPos = sensor->YPos >> 16;
551
int32 chunkY = YPos >> 7;
552
int32 tileY = (YPos & 0x7F) >> 4;
553
if (XPos > -1 && YPos > -1) {
554
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
555
tile += tileX + (tileY << 3);
556
int32 tileIndex = tiles128x128.tileIndex[tile];
557
if (tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_TOP
558
&& tiles128x128.collisionFlags[player->collisionPlane][tile] < SOLID_NONE) {
559
switch (tiles128x128.direction[tile]) {
560
case FLIP_NONE: {
561
c = (YPos & tsm1) + (tileIndex << 4);
562
if ((XPos & tsm1) <= collisionMasks[player->collisionPlane].lWallMasks[c] + i - TILE_SIZE)
563
break;
564
565
sensor->XPos = collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
566
sensor->collided = true;
567
break;
568
}
569
case FLIP_X: {
570
c = (YPos & tsm1) + (tileIndex << 4);
571
if ((XPos & tsm1) <= tsm1 - collisionMasks[player->collisionPlane].rWallMasks[c] + i - TILE_SIZE)
572
break;
573
574
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
575
sensor->collided = true;
576
break;
577
}
578
case FLIP_Y: {
579
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
580
if ((XPos & tsm1) <= collisionMasks[player->collisionPlane].lWallMasks[c] + i - TILE_SIZE)
581
break;
582
583
sensor->XPos = collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
584
sensor->collided = true;
585
break;
586
}
587
case FLIP_XY: {
588
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
589
if ((XPos & tsm1) <= tsm1 - collisionMasks[player->collisionPlane].rWallMasks[c] + i - TILE_SIZE)
590
break;
591
592
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
593
sensor->collided = true;
594
break;
595
}
596
}
597
}
598
599
if (sensor->collided) {
600
if (sensor->XPos - startX > tsm1) {
601
sensor->XPos = startX << 16;
602
sensor->collided = false;
603
}
604
else if (sensor->XPos - startX < -tsm1) {
605
sensor->XPos = startX << 16;
606
sensor->collided = false;
607
}
608
}
609
}
610
}
611
}
612
}
613
void RSDK::Legacy::v3::RoofCollision(Player *player, CollisionSensor *sensor)
614
{
615
int32 c;
616
int32 startY = sensor->YPos >> 16;
617
int32 tsm1 = (TILE_SIZE - 1);
618
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
619
if (!sensor->collided) {
620
int32 XPos = sensor->XPos >> 16;
621
int32 chunkX = XPos >> 7;
622
int32 tileX = (XPos & 0x7F) >> 4;
623
int32 YPos = (sensor->YPos >> 16) + TILE_SIZE - i;
624
int32 chunkY = YPos >> 7;
625
int32 tileY = (YPos & 0x7F) >> 4;
626
if (XPos > -1 && YPos > -1) {
627
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
628
tile += tileX + (tileY << 3);
629
int32 tileIndex = tiles128x128.tileIndex[tile];
630
if (tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_TOP
631
&& tiles128x128.collisionFlags[player->collisionPlane][tile] < SOLID_NONE) {
632
switch (tiles128x128.direction[tile]) {
633
case FLIP_NONE: {
634
c = (XPos & tsm1) + (tileIndex << 4);
635
if ((YPos & tsm1) >= collisionMasks[player->collisionPlane].roofMasks[c] + TILE_SIZE - i)
636
break;
637
638
sensor->YPos = collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
639
sensor->collided = true;
640
sensor->angle = ((collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24);
641
break;
642
}
643
case FLIP_X: {
644
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
645
if ((YPos & tsm1) >= collisionMasks[player->collisionPlane].roofMasks[c] + TILE_SIZE - i)
646
break;
647
648
sensor->YPos = collisionMasks[player->collisionPlane].roofMasks[c] + (chunkY << 7) + (tileY << 4);
649
sensor->collided = true;
650
sensor->angle = 0x100 - ((collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF000000) >> 24);
651
break;
652
}
653
case FLIP_Y: {
654
c = (XPos & tsm1) + (tileIndex << 4);
655
if ((YPos & tsm1) >= tsm1 - collisionMasks[player->collisionPlane].floorMasks[c] + TILE_SIZE - i)
656
break;
657
658
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
659
sensor->collided = true;
660
sensor->angle = (uint8)(-0x80 - (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF));
661
break;
662
}
663
case FLIP_XY: {
664
c = tsm1 - (XPos & tsm1) + (tileIndex << 4);
665
if ((YPos & tsm1) >= tsm1 - collisionMasks[player->collisionPlane].floorMasks[c] + TILE_SIZE - i)
666
break;
667
668
sensor->YPos = tsm1 - collisionMasks[player->collisionPlane].floorMasks[c] + (chunkY << 7) + (tileY << 4);
669
sensor->collided = true;
670
sensor->angle = 0x100 - (uint8)(-0x80 - (collisionMasks[player->collisionPlane].angles[tileIndex] & 0xFF));
671
break;
672
}
673
}
674
}
675
676
if (sensor->collided) {
677
if (sensor->angle < 0)
678
sensor->angle += 0x100;
679
680
if (sensor->angle > 0xFF)
681
sensor->angle -= 0x100;
682
683
if (sensor->YPos - startY > (TILE_SIZE - 2)) {
684
sensor->YPos = startY << 16;
685
sensor->collided = false;
686
}
687
else if (sensor->YPos - startY < -(TILE_SIZE - 2)) {
688
sensor->YPos = startY << 16;
689
sensor->collided = false;
690
}
691
}
692
}
693
}
694
}
695
}
696
void RSDK::Legacy::v3::RWallCollision(Player *player, CollisionSensor *sensor)
697
{
698
int32 c;
699
int32 startX = sensor->XPos >> 16;
700
int32 tsm1 = (TILE_SIZE - 1);
701
for (int32 i = 0; i < TILE_SIZE * 3; i += TILE_SIZE) {
702
if (!sensor->collided) {
703
int32 XPos = (sensor->XPos >> 16) + TILE_SIZE - i;
704
int32 chunkX = XPos >> 7;
705
int32 tileX = (XPos & 0x7F) >> 4;
706
int32 YPos = sensor->YPos >> 16;
707
int32 chunkY = YPos >> 7;
708
int32 tileY = (YPos & 0x7F) >> 4;
709
if (XPos > -1 && YPos > -1) {
710
int32 tile = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
711
tile += tileX + (tileY << 3);
712
int32 tileIndex = tiles128x128.tileIndex[tile];
713
if (tiles128x128.collisionFlags[player->collisionPlane][tile] != SOLID_TOP
714
&& tiles128x128.collisionFlags[player->collisionPlane][tile] < SOLID_NONE) {
715
switch (tiles128x128.direction[tile]) {
716
case FLIP_NONE: {
717
c = (YPos & tsm1) + (tileIndex << 4);
718
if ((XPos & tsm1) >= collisionMasks[player->collisionPlane].rWallMasks[c] + TILE_SIZE - i)
719
break;
720
721
sensor->XPos = collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
722
sensor->collided = true;
723
break;
724
}
725
case FLIP_X: {
726
c = (YPos & tsm1) + (tileIndex << 4);
727
if ((XPos & tsm1) >= tsm1 - collisionMasks[player->collisionPlane].lWallMasks[c] + TILE_SIZE - i)
728
break;
729
730
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
731
sensor->collided = true;
732
break;
733
}
734
case FLIP_Y: {
735
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
736
if ((XPos & tsm1) >= collisionMasks[player->collisionPlane].rWallMasks[c] + TILE_SIZE - i)
737
break;
738
739
sensor->XPos = collisionMasks[player->collisionPlane].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
740
sensor->collided = true;
741
break;
742
}
743
case FLIP_XY: {
744
c = tsm1 - (YPos & tsm1) + (tileIndex << 4);
745
if ((XPos & tsm1) >= tsm1 - collisionMasks[player->collisionPlane].lWallMasks[c] + TILE_SIZE - i)
746
break;
747
748
sensor->XPos = tsm1 - collisionMasks[player->collisionPlane].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
749
sensor->collided = true;
750
break;
751
}
752
}
753
}
754
755
if (sensor->collided) {
756
if (sensor->XPos - startX > tsm1) {
757
sensor->XPos = startX << 16;
758
sensor->collided = false;
759
}
760
else if (sensor->XPos - startX < -tsm1) {
761
sensor->XPos = startX << 16;
762
sensor->collided = false;
763
}
764
}
765
}
766
}
767
}
768
}
769
770
void RSDK::Legacy::v3::ProcessAirCollision(Player *player)
771
{
772
Hitbox *playerHitbox = GetPlayerHitbox(player);
773
collisionLeft = playerHitbox->left[0];
774
collisionTop = playerHitbox->top[0];
775
collisionRight = playerHitbox->right[0];
776
collisionBottom = playerHitbox->bottom[0];
777
778
uint8 movingDown = 0;
779
uint8 movingUp = 1;
780
uint8 movingLeft = 0;
781
uint8 movingRight = 0;
782
783
if (player->XVelocity < 0) {
784
movingRight = 0;
785
}
786
else {
787
movingRight = 1;
788
sensors[0].YPos = player->YPos + 0x20000;
789
sensors[0].collided = false;
790
sensors[0].XPos = player->XPos + (collisionRight << 16);
791
}
792
if (player->XVelocity > 0) {
793
movingLeft = 0;
794
}
795
else {
796
movingLeft = 1;
797
sensors[1].YPos = player->YPos + 0x20000;
798
sensors[1].collided = false;
799
sensors[1].XPos = player->XPos + ((collisionLeft - 1) << 16);
800
}
801
sensors[2].XPos = player->XPos + (playerHitbox->left[1] << 16);
802
sensors[3].XPos = player->XPos + (playerHitbox->right[1] << 16);
803
sensors[2].collided = false;
804
sensors[3].collided = false;
805
sensors[4].XPos = sensors[2].XPos;
806
sensors[5].XPos = sensors[3].XPos;
807
sensors[4].collided = false;
808
sensors[5].collided = false;
809
if (player->YVelocity < 0) {
810
movingDown = 0;
811
}
812
else {
813
movingDown = 1;
814
sensors[2].YPos = player->YPos + (collisionBottom << 16);
815
sensors[3].YPos = player->YPos + (collisionBottom << 16);
816
}
817
sensors[4].YPos = player->YPos + ((collisionTop - 1) << 16);
818
sensors[5].YPos = player->YPos + ((collisionTop - 1) << 16);
819
int32 cnt = (abs(player->XVelocity) <= abs(player->YVelocity) ? (abs(player->YVelocity) >> 19) + 1 : (abs(player->XVelocity) >> 19) + 1);
820
int32 XVel = player->XVelocity / cnt;
821
int32 YVel = player->YVelocity / cnt;
822
int32 XVel2 = player->XVelocity - XVel * (cnt - 1);
823
int32 YVel2 = player->YVelocity - YVel * (cnt - 1);
824
while (cnt > 0) {
825
if (cnt < 2) {
826
XVel = XVel2;
827
YVel = YVel2;
828
}
829
cnt--;
830
831
if (movingRight == 1) {
832
sensors[0].XPos += XVel + 0x10000;
833
sensors[0].YPos += YVel;
834
LWallCollision(player, &sensors[0]);
835
if (sensors[0].collided)
836
movingRight = 2;
837
}
838
839
if (movingLeft == 1) {
840
sensors[1].XPos += XVel - 0x10000;
841
sensors[1].YPos += YVel;
842
RWallCollision(player, &sensors[1]);
843
if (sensors[1].collided)
844
movingLeft = 2;
845
}
846
847
if (movingRight == 2) {
848
player->XVelocity = 0;
849
player->speed = 0;
850
player->XPos = (sensors[0].XPos - collisionRight) << 16;
851
sensors[2].XPos = player->XPos + ((collisionLeft + 1) << 16);
852
sensors[3].XPos = player->XPos + ((collisionRight - 2) << 16);
853
sensors[4].XPos = sensors[2].XPos;
854
sensors[5].XPos = sensors[3].XPos;
855
XVel = 0;
856
XVel2 = 0;
857
movingRight = 3;
858
}
859
860
if (movingLeft == 2) {
861
player->XVelocity = 0;
862
player->speed = 0;
863
player->XPos = (sensors[1].XPos - collisionLeft + 1) << 16;
864
sensors[2].XPos = player->XPos + ((collisionLeft + 1) << 16);
865
sensors[3].XPos = player->XPos + ((collisionRight - 2) << 16);
866
sensors[4].XPos = sensors[2].XPos;
867
sensors[5].XPos = sensors[3].XPos;
868
XVel = 0;
869
XVel2 = 0;
870
movingLeft = 3;
871
}
872
873
if (movingDown == 1) {
874
for (int32 i = 2; i < 4; i++) {
875
if (!sensors[i].collided) {
876
sensors[i].XPos += XVel;
877
sensors[i].YPos += YVel;
878
FloorCollision(player, &sensors[i]);
879
}
880
}
881
if (sensors[2].collided || sensors[3].collided) {
882
movingDown = 2;
883
cnt = 0;
884
}
885
}
886
887
if (movingUp == 1) {
888
for (int32 i = 4; i < 6; i++) {
889
if (!sensors[i].collided) {
890
sensors[i].XPos += XVel;
891
sensors[i].YPos += YVel;
892
RoofCollision(player, &sensors[i]);
893
}
894
}
895
if (sensors[4].collided || sensors[5].collided) {
896
movingUp = 2;
897
cnt = 0;
898
}
899
}
900
}
901
902
if (movingRight < 2 && movingLeft < 2)
903
player->XPos = player->XPos + player->XVelocity;
904
905
if (movingUp < 2 && movingDown < 2) {
906
player->YPos = player->YPos + player->YVelocity;
907
return;
908
}
909
910
if (movingDown == 2) {
911
player->gravity = 0;
912
if (sensors[2].collided && sensors[3].collided) {
913
if (sensors[2].YPos >= sensors[3].YPos) {
914
player->YPos = (sensors[3].YPos - collisionBottom) << 16;
915
player->angle = sensors[3].angle;
916
}
917
else {
918
player->YPos = (sensors[2].YPos - collisionBottom) << 16;
919
player->angle = sensors[2].angle;
920
}
921
}
922
else if (sensors[2].collided == 1) {
923
player->YPos = (sensors[2].YPos - collisionBottom) << 16;
924
player->angle = sensors[2].angle;
925
}
926
else if (sensors[3].collided == 1) {
927
player->YPos = (sensors[3].YPos - collisionBottom) << 16;
928
player->angle = sensors[3].angle;
929
}
930
if (player->angle > 0xA0 && player->angle < 0xE0 && player->collisionMode != CMODE_LWALL) {
931
player->collisionMode = CMODE_LWALL;
932
player->XPos = player->XPos - 0x40000;
933
}
934
if (player->angle > 0x20 && player->angle < 0x60 && player->collisionMode != CMODE_RWALL) {
935
player->collisionMode = CMODE_RWALL;
936
player->XPos = player->XPos + 0x40000;
937
}
938
if (player->angle < 0x20 || player->angle > 0xE0) {
939
player->controlLock = 0;
940
}
941
player->boundEntity->rotation = player->angle << 1;
942
943
int32 speed = 0;
944
if (player->down) {
945
if (player->angle < 128) {
946
if (player->angle < 16) {
947
speed = player->XVelocity;
948
}
949
else if (player->angle >= 32) {
950
speed = (abs(player->XVelocity) <= abs(player->YVelocity) ? player->YVelocity + player->YVelocity / 12 : player->XVelocity);
951
}
952
else {
953
speed = (abs(player->XVelocity) <= abs(player->YVelocity >> 1) ? (player->YVelocity + player->YVelocity / 12) >> 1
954
: player->XVelocity);
955
}
956
}
957
else if (player->angle > 240) {
958
speed = player->XVelocity;
959
}
960
else if (player->angle <= 224) {
961
speed = (abs(player->XVelocity) <= abs(player->YVelocity) ? -(player->YVelocity + player->YVelocity / 12) : player->XVelocity);
962
}
963
else {
964
speed = (abs(player->XVelocity) <= abs(player->YVelocity >> 1) ? -((player->YVelocity + player->YVelocity / 12) >> 1)
965
: player->XVelocity);
966
}
967
}
968
else if (player->angle < 0x80) {
969
if (player->angle < 0x10) {
970
speed = player->XVelocity;
971
}
972
else if (player->angle >= 0x20) {
973
speed = (abs(player->XVelocity) <= abs(player->YVelocity) ? player->YVelocity : player->XVelocity);
974
}
975
else {
976
speed = (abs(player->XVelocity) <= abs(player->YVelocity >> 1) ? player->YVelocity >> 1 : player->XVelocity);
977
}
978
}
979
else if (player->angle > 0xF0) {
980
speed = player->XVelocity;
981
}
982
else if (player->angle <= 0xE0) {
983
speed = (abs(player->XVelocity) <= abs(player->YVelocity) ? -player->YVelocity : player->XVelocity);
984
}
985
else {
986
speed = (abs(player->XVelocity) <= abs(player->YVelocity >> 1) ? -(player->YVelocity >> 1) : player->XVelocity);
987
}
988
989
if (speed < -0x180000)
990
speed = -0x180000;
991
if (speed > 0x180000)
992
speed = 0x180000;
993
player->speed = speed;
994
player->YVelocity = 0;
995
scriptEng.checkResult = 1;
996
}
997
998
if (movingUp == 2) {
999
int32 sensorAngle = 0;
1000
if (sensors[4].collided && sensors[5].collided) {
1001
if (sensors[4].YPos <= sensors[5].YPos) {
1002
player->YPos = (sensors[5].YPos - collisionTop + 1) << 16;
1003
sensorAngle = sensors[5].angle;
1004
}
1005
else {
1006
player->YPos = (sensors[4].YPos - collisionTop + 1) << 16;
1007
sensorAngle = sensors[4].angle;
1008
}
1009
}
1010
else if (sensors[4].collided) {
1011
player->YPos = (sensors[4].YPos - collisionTop + 1) << 16;
1012
sensorAngle = sensors[4].angle;
1013
}
1014
else if (sensors[5].collided) {
1015
player->YPos = (sensors[5].YPos - collisionTop + 1) << 16;
1016
sensorAngle = sensors[5].angle;
1017
}
1018
sensorAngle &= 0xFF;
1019
1020
int32 angle = ArcTanLookup(player->XVelocity, player->YVelocity);
1021
if (sensorAngle > 0x40 && sensorAngle < 0x62 && angle > 0xA0 && angle < 0xC2) {
1022
player->gravity = 0;
1023
player->angle = sensorAngle;
1024
player->boundEntity->rotation = player->angle << 1;
1025
player->collisionMode = CMODE_RWALL;
1026
player->XPos = player->XPos + 0x40000;
1027
player->YPos = player->YPos - 0x20000;
1028
if (player->angle <= 0x60)
1029
player->speed = player->YVelocity;
1030
else
1031
player->speed = player->YVelocity >> 1;
1032
}
1033
if (sensorAngle > 0x9E && sensorAngle < 0xC0 && angle > 0xBE && angle < 0xE0) {
1034
player->gravity = 0;
1035
player->angle = sensorAngle;
1036
player->boundEntity->rotation = player->angle << 1;
1037
player->collisionMode = CMODE_LWALL;
1038
player->XPos = player->XPos - 0x40000;
1039
player->YPos = player->YPos - 0x20000;
1040
if (player->angle >= 0xA0)
1041
player->speed = -player->YVelocity;
1042
else
1043
player->speed = -player->YVelocity >> 1;
1044
}
1045
if (player->YVelocity < 0)
1046
player->YVelocity = 0;
1047
scriptEng.checkResult = 2;
1048
}
1049
}
1050
void RSDK::Legacy::v3::ProcessPathGrip(Player *player)
1051
{
1052
int32 cosValue256;
1053
int32 sinValue256;
1054
sensors[4].XPos = player->XPos;
1055
sensors[4].YPos = player->YPos;
1056
for (int32 i = 0; i < 6; ++i) {
1057
sensors[i].angle = player->angle;
1058
sensors[i].collided = false;
1059
}
1060
SetPathGripSensors(player);
1061
int32 absSpeed = abs(player->speed);
1062
int32 checkDist = absSpeed >> 18;
1063
absSpeed &= 0x3FFFF;
1064
uint8 cMode = player->collisionMode;
1065
1066
while (checkDist > -1) {
1067
if (checkDist >= 1) {
1068
cosValue256 = cos256LookupTable[player->angle] << 10;
1069
sinValue256 = sin256LookupTable[player->angle] << 10;
1070
checkDist--;
1071
}
1072
else {
1073
cosValue256 = absSpeed * cos256LookupTable[player->angle] >> 8;
1074
sinValue256 = absSpeed * sin256LookupTable[player->angle] >> 8;
1075
checkDist = -1;
1076
}
1077
1078
if (player->speed < 0) {
1079
cosValue256 = -cosValue256;
1080
sinValue256 = -sinValue256;
1081
}
1082
1083
sensors[0].collided = false;
1084
sensors[1].collided = false;
1085
sensors[2].collided = false;
1086
sensors[4].XPos += cosValue256;
1087
sensors[4].YPos += sinValue256;
1088
int32 tileDistance = -1;
1089
switch (player->collisionMode) {
1090
case CMODE_FLOOR: {
1091
sensors[3].XPos += cosValue256;
1092
sensors[3].YPos += sinValue256;
1093
1094
if (player->speed > 0)
1095
LWallCollision(player, &sensors[3]);
1096
1097
if (player->speed < 0)
1098
RWallCollision(player, &sensors[3]);
1099
1100
if (sensors[3].collided) {
1101
cosValue256 = 0;
1102
checkDist = -1;
1103
}
1104
1105
for (int32 i = 0; i < 3; i++) {
1106
sensors[i].XPos += cosValue256;
1107
sensors[i].YPos += sinValue256;
1108
FindFloorPosition(player, &sensors[i], sensors[i].YPos >> 16);
1109
}
1110
1111
tileDistance = -1;
1112
for (int32 i = 0; i < 3; i++) {
1113
if (tileDistance > -1) {
1114
if (sensors[i].collided) {
1115
if (sensors[i].YPos < sensors[tileDistance].YPos)
1116
tileDistance = i;
1117
1118
if (sensors[i].YPos == sensors[tileDistance].YPos && (sensors[i].angle < 0x08 || sensors[i].angle > 0xF8))
1119
tileDistance = i;
1120
}
1121
}
1122
else if (sensors[i].collided)
1123
tileDistance = i;
1124
}
1125
1126
if (tileDistance <= -1) {
1127
checkDist = -1;
1128
}
1129
else {
1130
sensors[0].YPos = sensors[tileDistance].YPos << 16;
1131
sensors[0].angle = sensors[tileDistance].angle;
1132
sensors[1].YPos = sensors[0].YPos;
1133
sensors[1].angle = sensors[0].angle;
1134
sensors[2].YPos = sensors[0].YPos;
1135
sensors[2].angle = sensors[0].angle;
1136
sensors[3].YPos = sensors[0].YPos - 0x40000;
1137
sensors[3].angle = sensors[0].angle;
1138
sensors[4].XPos = sensors[1].XPos;
1139
sensors[4].YPos = sensors[0].YPos - (collisionBottom << 16);
1140
}
1141
1142
if (sensors[0].angle < 0xDE && sensors[0].angle > 0x80)
1143
player->collisionMode = CMODE_LWALL;
1144
if (sensors[0].angle > 0x22 && sensors[0].angle < 0x80)
1145
player->collisionMode = CMODE_RWALL;
1146
break;
1147
}
1148
case CMODE_LWALL: {
1149
sensors[3].XPos += cosValue256;
1150
sensors[3].YPos += sinValue256;
1151
1152
if (player->speed > 0)
1153
RoofCollision(player, &sensors[3]);
1154
1155
if (player->speed < 0)
1156
FloorCollision(player, &sensors[3]);
1157
1158
if (sensors[3].collided) {
1159
sinValue256 = 0;
1160
checkDist = -1;
1161
}
1162
for (int32 i = 0; i < 3; i++) {
1163
sensors[i].XPos += cosValue256;
1164
sensors[i].YPos += sinValue256;
1165
FindLWallPosition(player, &sensors[i], sensors[i].XPos >> 16);
1166
}
1167
1168
tileDistance = -1;
1169
for (int32 i = 0; i < 3; i++) {
1170
if (tileDistance > -1) {
1171
if (sensors[i].XPos < sensors[tileDistance].XPos && sensors[i].collided) {
1172
tileDistance = i;
1173
}
1174
}
1175
else if (sensors[i].collided) {
1176
tileDistance = i;
1177
}
1178
}
1179
1180
if (tileDistance <= -1) {
1181
checkDist = -1;
1182
}
1183
else {
1184
sensors[0].XPos = sensors[tileDistance].XPos << 16;
1185
sensors[0].angle = sensors[tileDistance].angle;
1186
sensors[1].XPos = sensors[0].XPos;
1187
sensors[1].angle = sensors[0].angle;
1188
sensors[2].XPos = sensors[0].XPos;
1189
sensors[2].angle = sensors[0].angle;
1190
sensors[4].YPos = sensors[1].YPos;
1191
sensors[4].XPos = sensors[1].XPos - (collisionRight << 16);
1192
}
1193
1194
if (sensors[0].angle > 0xE2)
1195
player->collisionMode = CMODE_FLOOR;
1196
if (sensors[0].angle < 0x9E)
1197
player->collisionMode = CMODE_ROOF;
1198
break;
1199
break;
1200
}
1201
case CMODE_ROOF: {
1202
sensors[3].XPos += cosValue256;
1203
sensors[3].YPos += sinValue256;
1204
1205
if (player->speed > 0)
1206
RWallCollision(player, &sensors[3]);
1207
1208
if (player->speed < 0)
1209
LWallCollision(player, &sensors[3]);
1210
1211
if (sensors[3].collided) {
1212
cosValue256 = 0;
1213
checkDist = -1;
1214
}
1215
for (int32 i = 0; i < 3; i++) {
1216
sensors[i].XPos += cosValue256;
1217
sensors[i].YPos += sinValue256;
1218
FindRoofPosition(player, &sensors[i], sensors[i].YPos >> 16);
1219
}
1220
1221
tileDistance = -1;
1222
for (int32 i = 0; i < 3; i++) {
1223
if (tileDistance > -1) {
1224
if (sensors[i].YPos > sensors[tileDistance].YPos && sensors[i].collided) {
1225
tileDistance = i;
1226
}
1227
}
1228
else if (sensors[i].collided) {
1229
tileDistance = i;
1230
}
1231
}
1232
1233
if (tileDistance <= -1) {
1234
checkDist = -1;
1235
}
1236
else {
1237
sensors[0].YPos = sensors[tileDistance].YPos << 16;
1238
sensors[0].angle = sensors[tileDistance].angle;
1239
sensors[1].YPos = sensors[0].YPos;
1240
sensors[1].angle = sensors[0].angle;
1241
sensors[2].YPos = sensors[0].YPos;
1242
sensors[2].angle = sensors[0].angle;
1243
sensors[3].YPos = sensors[0].YPos + 0x40000;
1244
sensors[3].angle = sensors[0].angle;
1245
sensors[4].XPos = sensors[1].XPos;
1246
sensors[4].YPos = sensors[0].YPos - ((collisionTop - 1) << 16);
1247
}
1248
1249
if (sensors[0].angle > 0xA2)
1250
player->collisionMode = CMODE_LWALL;
1251
if (sensors[0].angle < 0x5E)
1252
player->collisionMode = CMODE_RWALL;
1253
break;
1254
}
1255
case CMODE_RWALL: {
1256
sensors[3].XPos += cosValue256;
1257
sensors[3].YPos += sinValue256;
1258
1259
if (player->speed > 0)
1260
FloorCollision(player, &sensors[3]);
1261
1262
if (player->speed < 0)
1263
RoofCollision(player, &sensors[3]);
1264
1265
if (sensors[3].collided) {
1266
sinValue256 = 0;
1267
checkDist = -1;
1268
}
1269
for (int32 i = 0; i < 3; i++) {
1270
sensors[i].XPos += cosValue256;
1271
sensors[i].YPos += sinValue256;
1272
FindRWallPosition(player, &sensors[i], sensors[i].XPos >> 16);
1273
}
1274
1275
tileDistance = -1;
1276
for (int32 i = 0; i < 3; i++) {
1277
if (tileDistance > -1) {
1278
if (sensors[i].XPos > sensors[tileDistance].XPos && sensors[i].collided) {
1279
tileDistance = i;
1280
}
1281
}
1282
else if (sensors[i].collided) {
1283
tileDistance = i;
1284
}
1285
}
1286
1287
if (tileDistance <= -1) {
1288
checkDist = -1;
1289
}
1290
else {
1291
sensors[0].XPos = sensors[tileDistance].XPos << 16;
1292
sensors[0].angle = sensors[tileDistance].angle;
1293
sensors[1].XPos = sensors[0].XPos;
1294
sensors[1].angle = sensors[0].angle;
1295
sensors[2].XPos = sensors[0].XPos;
1296
sensors[2].angle = sensors[0].angle;
1297
sensors[4].YPos = sensors[1].YPos;
1298
sensors[4].XPos = sensors[1].XPos - ((collisionLeft - 1) << 16);
1299
}
1300
1301
if (sensors[0].angle < 0x1E)
1302
player->collisionMode = CMODE_FLOOR;
1303
if (sensors[0].angle > 0x62)
1304
player->collisionMode = CMODE_ROOF;
1305
break;
1306
}
1307
}
1308
if (tileDistance > -1)
1309
player->angle = sensors[0].angle;
1310
1311
if (!sensors[3].collided)
1312
SetPathGripSensors(player);
1313
else
1314
checkDist = -2;
1315
}
1316
1317
switch (cMode) {
1318
case CMODE_FLOOR: {
1319
if (sensors[0].collided || sensors[1].collided || sensors[2].collided) {
1320
player->angle = sensors[0].angle;
1321
player->boundEntity->rotation = player->angle << 1;
1322
player->flailing[0] = sensors[0].collided;
1323
player->flailing[1] = sensors[1].collided;
1324
player->flailing[2] = sensors[2].collided;
1325
if (!sensors[3].collided) {
1326
player->pushing = 0;
1327
player->XPos = sensors[4].XPos;
1328
}
1329
else {
1330
if (player->speed > 0)
1331
player->XPos = (sensors[3].XPos - collisionRight) << 16;
1332
1333
if (player->speed < 0)
1334
player->XPos = (sensors[3].XPos - collisionLeft + 1) << 16;
1335
1336
player->speed = 0;
1337
if ((player->left || player->right) && player->pushing < 2)
1338
player->pushing++;
1339
}
1340
player->YPos = sensors[4].YPos;
1341
return;
1342
}
1343
player->gravity = 1;
1344
player->collisionMode = CMODE_FLOOR;
1345
player->XVelocity = cos256LookupTable[player->angle] * player->speed >> 8;
1346
player->YVelocity = sin256LookupTable[player->angle] * player->speed >> 8;
1347
if (player->YVelocity < -0x100000)
1348
player->YVelocity = -0x100000;
1349
1350
if (player->YVelocity > 0x100000)
1351
player->YVelocity = 0x100000;
1352
1353
player->speed = player->XVelocity;
1354
player->angle = 0;
1355
if (!sensors[3].collided) {
1356
player->pushing = 0;
1357
player->XPos = player->XPos + player->XVelocity;
1358
}
1359
else {
1360
if (player->speed > 0)
1361
player->XPos = (sensors[3].XPos - collisionRight) << 16;
1362
if (player->speed < 0)
1363
player->XPos = (sensors[3].XPos - collisionLeft + 1) << 16;
1364
1365
player->speed = 0;
1366
if ((player->left || player->right) && player->pushing < 2)
1367
player->pushing++;
1368
}
1369
player->YPos = player->YPos + player->YVelocity;
1370
return;
1371
}
1372
case CMODE_LWALL: {
1373
if (!sensors[0].collided && !sensors[1].collided && !sensors[2].collided) {
1374
player->gravity = 1;
1375
player->collisionMode = CMODE_FLOOR;
1376
player->XVelocity = cos256LookupTable[player->angle] * player->speed >> 8;
1377
player->YVelocity = sin256LookupTable[player->angle] * player->speed >> 8;
1378
if (player->YVelocity < -1048576) {
1379
player->YVelocity = -1048576;
1380
}
1381
if (player->YVelocity > 0x100000) {
1382
player->YVelocity = 0x100000;
1383
}
1384
player->speed = player->XVelocity;
1385
player->angle = 0;
1386
}
1387
else if (player->speed >= 0x28000 || player->speed <= -0x28000 || player->controlLock != 0) {
1388
player->angle = sensors[0].angle;
1389
player->boundEntity->rotation = player->angle << 1;
1390
}
1391
else {
1392
player->gravity = 1;
1393
player->angle = 0;
1394
player->collisionMode = CMODE_FLOOR;
1395
player->speed = player->XVelocity;
1396
player->controlLock = 30;
1397
}
1398
if (!sensors[3].collided) {
1399
player->YPos = sensors[4].YPos;
1400
}
1401
else {
1402
if (player->speed > 0)
1403
player->YPos = (sensors[3].YPos - collisionTop) << 16;
1404
1405
if (player->speed < 0)
1406
player->YPos = (sensors[3].YPos - collisionBottom) << 16;
1407
1408
player->speed = 0;
1409
}
1410
player->XPos = sensors[4].XPos;
1411
return;
1412
}
1413
case CMODE_ROOF: {
1414
if (!sensors[0].collided && !sensors[1].collided && !sensors[2].collided) {
1415
player->gravity = 1;
1416
player->collisionMode = CMODE_FLOOR;
1417
player->XVelocity = cos256LookupTable[player->angle] * player->speed >> 8;
1418
player->YVelocity = sin256LookupTable[player->angle] * player->speed >> 8;
1419
player->flailing[0] = 0;
1420
player->flailing[1] = 0;
1421
player->flailing[2] = 0;
1422
if (player->YVelocity < -0x100000)
1423
player->YVelocity = -0x100000;
1424
1425
if (player->YVelocity > 0x100000)
1426
player->YVelocity = 0x100000;
1427
1428
player->angle = 0;
1429
player->speed = player->XVelocity;
1430
if (!sensors[3].collided) {
1431
player->XPos = player->XPos + player->XVelocity;
1432
}
1433
else {
1434
if (player->speed > 0)
1435
player->XPos = (sensors[3].XPos - collisionRight) << 16;
1436
1437
if (player->speed < 0)
1438
player->XPos = (sensors[3].XPos - collisionLeft + 1) << 16;
1439
1440
player->speed = 0;
1441
}
1442
}
1443
else if (player->speed <= -0x28000 || player->speed >= 0x28000) {
1444
player->angle = sensors[0].angle;
1445
player->boundEntity->rotation = player->angle << 1;
1446
if (!sensors[3].collided) {
1447
player->XPos = sensors[4].XPos;
1448
}
1449
else {
1450
if (player->speed < 0)
1451
player->XPos = (sensors[3].XPos - collisionRight) << 16;
1452
1453
if (player->speed > 0)
1454
player->XPos = (sensors[3].XPos - collisionLeft + 1) << 16;
1455
player->speed = 0;
1456
}
1457
}
1458
else {
1459
player->gravity = 1;
1460
player->angle = 0;
1461
player->collisionMode = CMODE_FLOOR;
1462
player->speed = player->XVelocity;
1463
player->flailing[0] = 0;
1464
player->flailing[1] = 0;
1465
player->flailing[2] = 0;
1466
if (!sensors[3].collided) {
1467
player->XPos = player->XPos + player->XVelocity;
1468
}
1469
else {
1470
if (player->speed > 0)
1471
player->XPos = (sensors[3].XPos - collisionRight) << 16;
1472
1473
if (player->speed < 0)
1474
player->XPos = (sensors[3].XPos - collisionLeft + 1) << 16;
1475
player->speed = 0;
1476
}
1477
}
1478
player->YPos = sensors[4].YPos;
1479
return;
1480
}
1481
case CMODE_RWALL: {
1482
if (!sensors[0].collided && !sensors[1].collided && !sensors[2].collided) {
1483
player->gravity = 1;
1484
player->collisionMode = CMODE_FLOOR;
1485
player->XVelocity = cos256LookupTable[player->angle] * player->speed >> 8;
1486
player->YVelocity = sin256LookupTable[player->angle] * player->speed >> 8;
1487
if (player->YVelocity < -0x100000)
1488
player->YVelocity = -0x100000;
1489
1490
if (player->YVelocity > 0x100000)
1491
player->YVelocity = 0x100000;
1492
1493
player->speed = player->XVelocity;
1494
player->angle = 0;
1495
}
1496
else if (player->speed <= -0x28000 || player->speed >= 0x28000 || player->controlLock != 0) {
1497
player->angle = sensors[0].angle;
1498
player->boundEntity->rotation = player->angle << 1;
1499
}
1500
else {
1501
player->gravity = 1;
1502
player->angle = 0;
1503
player->collisionMode = CMODE_FLOOR;
1504
player->speed = player->XVelocity;
1505
player->controlLock = 30;
1506
}
1507
if (!sensors[3].collided) {
1508
player->YPos = sensors[4].YPos;
1509
}
1510
else {
1511
if (player->speed > 0)
1512
player->YPos = (sensors[3].YPos - collisionBottom) << 16;
1513
1514
if (player->speed < 0)
1515
player->YPos = (sensors[3].YPos - collisionTop + 1) << 16;
1516
1517
player->speed = 0;
1518
}
1519
player->XPos = sensors[4].XPos;
1520
return;
1521
}
1522
default: return;
1523
}
1524
}
1525
1526
void RSDK::Legacy::v3::SetPathGripSensors(Player *player)
1527
{
1528
Hitbox *playerHitbox = GetPlayerHitbox(player);
1529
switch (player->collisionMode) {
1530
case CMODE_FLOOR: {
1531
collisionLeft = playerHitbox->left[0];
1532
collisionTop = playerHitbox->top[0];
1533
collisionRight = playerHitbox->right[0];
1534
collisionBottom = playerHitbox->bottom[0];
1535
sensors[0].YPos = sensors[4].YPos + (collisionBottom << 16);
1536
sensors[1].YPos = sensors[0].YPos;
1537
sensors[2].YPos = sensors[0].YPos;
1538
sensors[3].YPos = sensors[4].YPos + 0x40000;
1539
sensors[0].XPos = sensors[4].XPos + ((playerHitbox->left[1] - 1) << 16);
1540
sensors[1].XPos = sensors[4].XPos;
1541
sensors[2].XPos = sensors[4].XPos + (playerHitbox->right[1] << 16);
1542
if (player->speed > 0) {
1543
sensors[3].XPos = sensors[4].XPos + ((collisionRight + 1) << 16);
1544
return;
1545
}
1546
sensors[3].XPos = sensors[4].XPos + ((collisionLeft - 1) << 16);
1547
return;
1548
}
1549
case CMODE_LWALL: {
1550
collisionLeft = playerHitbox->left[2];
1551
collisionTop = playerHitbox->top[2];
1552
collisionRight = playerHitbox->right[2];
1553
collisionBottom = playerHitbox->bottom[2];
1554
sensors[0].XPos = sensors[4].XPos + (collisionRight << 16);
1555
sensors[1].XPos = sensors[0].XPos;
1556
sensors[2].XPos = sensors[0].XPos;
1557
sensors[3].XPos = sensors[4].XPos + 0x40000;
1558
sensors[0].YPos = sensors[4].YPos + ((playerHitbox->top[3] - 1) << 16);
1559
sensors[1].YPos = sensors[4].YPos;
1560
sensors[2].YPos = sensors[4].YPos + (playerHitbox->bottom[3] << 16);
1561
if (player->speed > 0) {
1562
sensors[3].YPos = sensors[4].YPos + (collisionTop << 16);
1563
return;
1564
}
1565
sensors[3].YPos = sensors[4].YPos + ((collisionBottom - 1) << 16);
1566
return;
1567
}
1568
case CMODE_ROOF: {
1569
collisionLeft = playerHitbox->left[4];
1570
collisionTop = playerHitbox->top[4];
1571
collisionRight = playerHitbox->right[4];
1572
collisionBottom = playerHitbox->bottom[4];
1573
sensors[0].YPos = sensors[4].YPos + ((collisionTop - 1) << 16);
1574
sensors[1].YPos = sensors[0].YPos;
1575
sensors[2].YPos = sensors[0].YPos;
1576
sensors[3].YPos = sensors[4].YPos - 0x40000;
1577
sensors[0].XPos = sensors[4].XPos + ((playerHitbox->left[5] - 1) << 16);
1578
sensors[1].XPos = sensors[4].XPos;
1579
sensors[2].XPos = sensors[4].XPos + (playerHitbox->right[5] << 16);
1580
if (player->speed < 0) {
1581
sensors[3].XPos = sensors[4].XPos + ((collisionRight + 1) << 16);
1582
return;
1583
}
1584
sensors[3].XPos = sensors[4].XPos + ((collisionLeft - 1) << 16);
1585
return;
1586
}
1587
case CMODE_RWALL: {
1588
collisionLeft = playerHitbox->left[6];
1589
collisionTop = playerHitbox->top[6];
1590
collisionRight = playerHitbox->right[6];
1591
collisionBottom = playerHitbox->bottom[6];
1592
sensors[0].XPos = sensors[4].XPos + ((collisionLeft - 1) << 16);
1593
sensors[1].XPos = sensors[0].XPos;
1594
sensors[2].XPos = sensors[0].XPos;
1595
sensors[3].XPos = sensors[4].XPos - 0x40000;
1596
sensors[0].YPos = sensors[4].YPos + ((playerHitbox->top[7] - 1) << 16);
1597
sensors[1].YPos = sensors[4].YPos;
1598
sensors[2].YPos = sensors[4].YPos + (playerHitbox->bottom[7] << 16);
1599
if (player->speed > 0) {
1600
sensors[3].YPos = sensors[4].YPos + (collisionBottom << 16);
1601
return;
1602
}
1603
sensors[3].YPos = sensors[4].YPos + ((collisionTop - 1) << 16);
1604
return;
1605
}
1606
default: return;
1607
}
1608
}
1609
1610
void RSDK::Legacy::v3::ProcessPlayerTileCollisions(Player *player)
1611
{
1612
player->flailing[0] = 0;
1613
player->flailing[1] = 0;
1614
player->flailing[2] = 0;
1615
1616
scriptEng.checkResult = false;
1617
1618
if (player->gravity == 1)
1619
ProcessAirCollision(player);
1620
else
1621
ProcessPathGrip(player);
1622
}
1623
1624
void RSDK::Legacy::v3::ObjectFloorCollision(int32 xOffset, int32 yOffset, int32 cPath)
1625
{
1626
scriptEng.checkResult = false;
1627
Entity *entity = &objectEntityList[objectLoop];
1628
int32 c = 0;
1629
int32 XPos = (entity->XPos >> 16) + xOffset;
1630
int32 YPos = (entity->YPos >> 16) + yOffset;
1631
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7) {
1632
int32 chunkX = XPos >> 7;
1633
int32 tileX = (XPos & 0x7F) >> 4;
1634
int32 chunkY = YPos >> 7;
1635
int32 tileY = (YPos & 0x7F) >> 4;
1636
int32 chunk = (stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6) + tileX + (tileY << 3);
1637
int32 tileIndex = tiles128x128.tileIndex[chunk];
1638
if (tiles128x128.collisionFlags[cPath][chunk] != SOLID_LRB && tiles128x128.collisionFlags[cPath][chunk] != SOLID_NONE) {
1639
switch (tiles128x128.direction[chunk]) {
1640
case 0: {
1641
c = (XPos & 15) + (tileIndex << 4);
1642
if ((YPos & 15) <= collisionMasks[cPath].floorMasks[c]) {
1643
break;
1644
}
1645
YPos = collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
1646
scriptEng.checkResult = true;
1647
break;
1648
}
1649
case 1: {
1650
c = 15 - (XPos & 15) + (tileIndex << 4);
1651
if ((YPos & 15) <= collisionMasks[cPath].floorMasks[c]) {
1652
break;
1653
}
1654
YPos = collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
1655
scriptEng.checkResult = true;
1656
break;
1657
}
1658
case 2: {
1659
c = (XPos & 15) + (tileIndex << 4);
1660
if ((YPos & 15) <= 15 - collisionMasks[cPath].roofMasks[c]) {
1661
break;
1662
}
1663
YPos = 15 - collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
1664
scriptEng.checkResult = true;
1665
break;
1666
}
1667
case 3: {
1668
c = 15 - (XPos & 15) + (tileIndex << 4);
1669
if ((YPos & 15) <= 15 - collisionMasks[cPath].roofMasks[c]) {
1670
break;
1671
}
1672
YPos = 15 - collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
1673
scriptEng.checkResult = true;
1674
break;
1675
}
1676
}
1677
}
1678
if (scriptEng.checkResult) {
1679
entity->YPos = (YPos - yOffset) << 16;
1680
}
1681
}
1682
}
1683
void RSDK::Legacy::v3::ObjectLWallCollision(int32 xOffset, int32 yOffset, int32 cPath)
1684
{
1685
int32 c;
1686
scriptEng.checkResult = false;
1687
Entity *entity = &objectEntityList[objectLoop];
1688
int32 XPos = (entity->XPos >> 16) + xOffset;
1689
int32 YPos = (entity->YPos >> 16) + yOffset;
1690
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7) {
1691
int32 chunkX = XPos >> 7;
1692
int32 tileX = (XPos & 0x7F) >> 4;
1693
int32 chunkY = YPos >> 7;
1694
int32 tileY = (YPos & 0x7F) >> 4;
1695
int32 chunk = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
1696
chunk = chunk + tileX + (tileY << 3);
1697
int32 tileIndex = tiles128x128.tileIndex[chunk];
1698
if (tiles128x128.collisionFlags[cPath][chunk] != SOLID_TOP && tiles128x128.collisionFlags[cPath][chunk] < SOLID_NONE) {
1699
switch (tiles128x128.direction[chunk]) {
1700
case 0: {
1701
c = (YPos & 15) + (tileIndex << 4);
1702
if ((XPos & 15) <= collisionMasks[cPath].lWallMasks[c]) {
1703
break;
1704
}
1705
XPos = collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
1706
scriptEng.checkResult = true;
1707
break;
1708
}
1709
case 1: {
1710
c = (YPos & 15) + (tileIndex << 4);
1711
if ((XPos & 15) <= 15 - collisionMasks[cPath].rWallMasks[c]) {
1712
break;
1713
}
1714
XPos = 15 - collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
1715
scriptEng.checkResult = true;
1716
break;
1717
}
1718
case 2: {
1719
c = 15 - (YPos & 15) + (tileIndex << 4);
1720
if ((XPos & 15) <= collisionMasks[cPath].lWallMasks[c]) {
1721
break;
1722
}
1723
XPos = collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
1724
scriptEng.checkResult = true;
1725
break;
1726
}
1727
case 3: {
1728
c = 15 - (YPos & 15) + (tileIndex << 4);
1729
if ((XPos & 15) <= 15 - collisionMasks[cPath].rWallMasks[c]) {
1730
break;
1731
}
1732
XPos = 15 - collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
1733
scriptEng.checkResult = true;
1734
break;
1735
}
1736
}
1737
}
1738
if (scriptEng.checkResult) {
1739
entity->XPos = (XPos - xOffset) << 16;
1740
}
1741
}
1742
}
1743
void RSDK::Legacy::v3::ObjectRoofCollision(int32 xOffset, int32 yOffset, int32 cPath)
1744
{
1745
int32 c;
1746
scriptEng.checkResult = false;
1747
Entity *entity = &objectEntityList[objectLoop];
1748
int32 XPos = (entity->XPos >> 16) + xOffset;
1749
int32 YPos = (entity->YPos >> 16) + yOffset;
1750
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7) {
1751
int32 chunkX = XPos >> 7;
1752
int32 tileX = (XPos & 0x7F) >> 4;
1753
int32 chunkY = YPos >> 7;
1754
int32 tileY = (YPos & 0x7F) >> 4;
1755
int32 chunk = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
1756
chunk = chunk + tileX + (tileY << 3);
1757
int32 tileIndex = tiles128x128.tileIndex[chunk];
1758
if (tiles128x128.collisionFlags[cPath][chunk] != SOLID_TOP && tiles128x128.collisionFlags[cPath][chunk] < SOLID_NONE) {
1759
switch (tiles128x128.direction[chunk]) {
1760
case 0: {
1761
c = (XPos & 15) + (tileIndex << 4);
1762
if ((YPos & 15) >= collisionMasks[cPath].roofMasks[c]) {
1763
break;
1764
}
1765
YPos = collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
1766
scriptEng.checkResult = true;
1767
break;
1768
}
1769
case 1: {
1770
c = 15 - (XPos & 15) + (tileIndex << 4);
1771
if ((YPos & 15) >= collisionMasks[cPath].roofMasks[c]) {
1772
break;
1773
}
1774
YPos = collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
1775
scriptEng.checkResult = true;
1776
break;
1777
}
1778
case 2: {
1779
c = (XPos & 15) + (tileIndex << 4);
1780
if ((YPos & 15) >= 15 - collisionMasks[cPath].floorMasks[c]) {
1781
break;
1782
}
1783
YPos = 15 - collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
1784
scriptEng.checkResult = true;
1785
break;
1786
}
1787
case 3: {
1788
c = 15 - (XPos & 15) + (tileIndex << 4);
1789
if ((YPos & 15) >= 15 - collisionMasks[cPath].floorMasks[c]) {
1790
break;
1791
}
1792
YPos = 15 - collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
1793
scriptEng.checkResult = true;
1794
break;
1795
}
1796
}
1797
}
1798
if (scriptEng.checkResult) {
1799
entity->YPos = (YPos - yOffset) << 16;
1800
}
1801
}
1802
}
1803
void RSDK::Legacy::v3::ObjectRWallCollision(int32 xOffset, int32 yOffset, int32 cPath)
1804
{
1805
int32 c;
1806
scriptEng.checkResult = false;
1807
Entity *entity = &objectEntityList[objectLoop];
1808
int32 XPos = (entity->XPos >> 16) + xOffset;
1809
int32 YPos = (entity->YPos >> 16) + yOffset;
1810
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7) {
1811
int32 chunkX = XPos >> 7;
1812
int32 tileX = (XPos & 0x7F) >> 4;
1813
int32 chunkY = YPos >> 7;
1814
int32 tileY = (YPos & 0x7F) >> 4;
1815
int32 chunk = stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6;
1816
chunk = chunk + tileX + (tileY << 3);
1817
int32 tileIndex = tiles128x128.tileIndex[chunk];
1818
if (tiles128x128.collisionFlags[cPath][chunk] != SOLID_TOP && tiles128x128.collisionFlags[cPath][chunk] < SOLID_NONE) {
1819
switch (tiles128x128.direction[chunk]) {
1820
case 0: {
1821
c = (YPos & 15) + (tileIndex << 4);
1822
if ((XPos & 15) >= collisionMasks[cPath].rWallMasks[c]) {
1823
break;
1824
}
1825
XPos = collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
1826
scriptEng.checkResult = true;
1827
break;
1828
}
1829
case 1: {
1830
c = (YPos & 15) + (tileIndex << 4);
1831
if ((XPos & 15) >= 15 - collisionMasks[cPath].lWallMasks[c]) {
1832
break;
1833
}
1834
XPos = 15 - collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
1835
scriptEng.checkResult = true;
1836
break;
1837
}
1838
case 2: {
1839
c = 15 - (YPos & 15) + (tileIndex << 4);
1840
if ((XPos & 15) >= collisionMasks[cPath].rWallMasks[c]) {
1841
break;
1842
}
1843
XPos = collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
1844
scriptEng.checkResult = true;
1845
break;
1846
}
1847
case 3: {
1848
c = 15 - (YPos & 15) + (tileIndex << 4);
1849
if ((XPos & 15) >= 15 - collisionMasks[cPath].lWallMasks[c]) {
1850
break;
1851
}
1852
XPos = 15 - collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
1853
scriptEng.checkResult = true;
1854
break;
1855
}
1856
}
1857
}
1858
if (scriptEng.checkResult) {
1859
entity->XPos = (XPos - xOffset) << 16;
1860
}
1861
}
1862
}
1863
1864
void RSDK::Legacy::v3::ObjectFloorGrip(int32 xOffset, int32 yOffset, int32 cPath)
1865
{
1866
int32 c;
1867
scriptEng.checkResult = false;
1868
Entity *entity = &objectEntityList[objectLoop];
1869
int32 XPos = (entity->XPos >> 16) + xOffset;
1870
int32 YPos = (entity->YPos >> 16) + yOffset;
1871
int32 chunkX = YPos;
1872
YPos = YPos - 16;
1873
for (int32 i = 3; i > 0; i--) {
1874
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7 && !scriptEng.checkResult) {
1875
int32 chunkX = XPos >> 7;
1876
int32 tileX = (XPos & 0x7F) >> 4;
1877
int32 chunkY = YPos >> 7;
1878
int32 tileY = (YPos & 0x7F) >> 4;
1879
int32 chunk = (stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6) + tileX + (tileY << 3);
1880
int32 tileIndex = tiles128x128.tileIndex[chunk];
1881
if (tiles128x128.collisionFlags[cPath][chunk] != SOLID_LRB && tiles128x128.collisionFlags[cPath][chunk] != SOLID_NONE) {
1882
switch (tiles128x128.direction[chunk]) {
1883
case 0: {
1884
c = (XPos & 15) + (tileIndex << 4);
1885
if (collisionMasks[cPath].floorMasks[c] >= 64) {
1886
break;
1887
}
1888
entity->YPos = collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
1889
scriptEng.checkResult = true;
1890
break;
1891
}
1892
case 1: {
1893
c = 15 - (XPos & 15) + (tileIndex << 4);
1894
if (collisionMasks[cPath].floorMasks[c] >= 64) {
1895
break;
1896
}
1897
entity->YPos = collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
1898
scriptEng.checkResult = true;
1899
break;
1900
}
1901
case 2: {
1902
c = (XPos & 15) + (tileIndex << 4);
1903
if (collisionMasks[cPath].roofMasks[c] <= -64) {
1904
break;
1905
}
1906
entity->YPos = 15 - collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
1907
scriptEng.checkResult = true;
1908
break;
1909
}
1910
case 3: {
1911
c = 15 - (XPos & 15) + (tileIndex << 4);
1912
if (collisionMasks[cPath].roofMasks[c] <= -64) {
1913
break;
1914
}
1915
entity->YPos = 15 - collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
1916
scriptEng.checkResult = true;
1917
break;
1918
}
1919
}
1920
}
1921
}
1922
YPos += 16;
1923
}
1924
if (scriptEng.checkResult) {
1925
if (abs(entity->YPos - chunkX) < 16) {
1926
entity->YPos = (entity->YPos - yOffset) << 16;
1927
return;
1928
}
1929
entity->YPos = (chunkX - yOffset) << 16;
1930
scriptEng.checkResult = false;
1931
}
1932
}
1933
void RSDK::Legacy::v3::ObjectLWallGrip(int32 xOffset, int32 yOffset, int32 cPath)
1934
{
1935
int32 c;
1936
scriptEng.checkResult = false;
1937
Entity *entity = &objectEntityList[objectLoop];
1938
int32 XPos = (entity->XPos >> 16) + xOffset;
1939
int32 YPos = (entity->YPos >> 16) + yOffset;
1940
int32 startX = XPos;
1941
XPos = XPos - 16;
1942
int32 chunk = xOffset;
1943
for (int32 i = 3; i > 0; i--) {
1944
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7 && !scriptEng.checkResult) {
1945
int32 chunkX = XPos >> 7;
1946
int32 tileX = (XPos & 0x7F) >> 4;
1947
int32 chunkY = YPos >> 7;
1948
int32 tileY = (YPos & 0x7F) >> 4;
1949
chunk = (stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6) + tileX + (tileY << 3);
1950
int32 tileIndex = tiles128x128.tileIndex[chunk];
1951
if (tiles128x128.collisionFlags[cPath][chunk] < SOLID_NONE) {
1952
switch (tiles128x128.direction[chunk]) {
1953
case 0: {
1954
c = (YPos & 15) + (tileIndex << 4);
1955
if (collisionMasks[cPath].lWallMasks[c] >= 64) {
1956
break;
1957
}
1958
entity->XPos = collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
1959
scriptEng.checkResult = true;
1960
break;
1961
}
1962
case 1: {
1963
c = (YPos & 15) + (tileIndex << 4);
1964
if (collisionMasks[cPath].rWallMasks[c] <= -64) {
1965
break;
1966
}
1967
entity->XPos = 15 - collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
1968
scriptEng.checkResult = true;
1969
break;
1970
}
1971
case 2: {
1972
c = 15 - (YPos & 15) + (tileIndex << 4);
1973
if (collisionMasks[cPath].lWallMasks[c] >= 64) {
1974
break;
1975
}
1976
entity->XPos = collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
1977
scriptEng.checkResult = true;
1978
break;
1979
}
1980
case 3: {
1981
c = 15 - (YPos & 15) + (tileIndex << 4);
1982
if (collisionMasks[cPath].rWallMasks[c] <= -64) {
1983
break;
1984
}
1985
entity->XPos = 15 - collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
1986
scriptEng.checkResult = true;
1987
break;
1988
}
1989
}
1990
}
1991
}
1992
XPos += 16;
1993
}
1994
if (scriptEng.checkResult) {
1995
if (abs(entity->XPos - startX) < 16) {
1996
entity->XPos = (entity->XPos - xOffset) << 16;
1997
return;
1998
}
1999
entity->XPos = (startX - xOffset) << 16;
2000
scriptEng.checkResult = tiles128x128.collisionFlags[cPath][chunk] == 1;
2001
}
2002
}
2003
void RSDK::Legacy::v3::ObjectRoofGrip(int32 xOffset, int32 yOffset, int32 cPath)
2004
{
2005
int32 c;
2006
scriptEng.checkResult = false;
2007
Entity *entity = &objectEntityList[objectLoop];
2008
int32 XPos = (entity->XPos >> 16) + xOffset;
2009
int32 YPos = (entity->YPos >> 16) + yOffset;
2010
int32 startY = YPos;
2011
YPos = YPos + 16;
2012
for (int32 i = 3; i > 0; i--) {
2013
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7 && !scriptEng.checkResult) {
2014
int32 chunkX = XPos >> 7;
2015
int32 tileX = (XPos & 0x7F) >> 4;
2016
int32 chunkY = YPos >> 7;
2017
int32 tileY = (YPos & 0x7F) >> 4;
2018
int32 chunk = (stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6) + tileX + (tileY << 3);
2019
int32 tileIndex = tiles128x128.tileIndex[chunk];
2020
if (tiles128x128.collisionFlags[cPath][chunk] < SOLID_NONE) {
2021
switch (tiles128x128.direction[chunk]) {
2022
case 0: {
2023
c = (XPos & 15) + (tileIndex << 4);
2024
if (collisionMasks[cPath].roofMasks[c] <= -64) {
2025
break;
2026
}
2027
entity->YPos = collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
2028
scriptEng.checkResult = true;
2029
break;
2030
}
2031
case 1: {
2032
c = 15 - (XPos & 15) + (tileIndex << 4);
2033
if (collisionMasks[cPath].roofMasks[c] <= -64) {
2034
break;
2035
}
2036
entity->YPos = collisionMasks[cPath].roofMasks[c] + (chunkY << 7) + (tileY << 4);
2037
scriptEng.checkResult = true;
2038
break;
2039
}
2040
case 2: {
2041
c = (XPos & 15) + (tileIndex << 4);
2042
if (collisionMasks[cPath].floorMasks[c] >= 64) {
2043
break;
2044
}
2045
entity->YPos = 15 - collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
2046
scriptEng.checkResult = true;
2047
break;
2048
}
2049
case 3: {
2050
c = 15 - (XPos & 15) + (tileIndex << 4);
2051
if (collisionMasks[cPath].floorMasks[c] >= 64) {
2052
break;
2053
}
2054
entity->YPos = 15 - collisionMasks[cPath].floorMasks[c] + (chunkY << 7) + (tileY << 4);
2055
scriptEng.checkResult = true;
2056
break;
2057
}
2058
}
2059
}
2060
}
2061
YPos -= 16;
2062
}
2063
if (scriptEng.checkResult) {
2064
if (abs(entity->YPos - startY) < 16) {
2065
entity->YPos = (entity->YPos - yOffset) << 16;
2066
return;
2067
}
2068
entity->YPos = (startY - yOffset) << 16;
2069
scriptEng.checkResult = false;
2070
}
2071
}
2072
void RSDK::Legacy::v3::ObjectRWallGrip(int32 xOffset, int32 yOffset, int32 cPath)
2073
{
2074
int32 c;
2075
scriptEng.checkResult = false;
2076
Entity *entity = &objectEntityList[objectLoop];
2077
int32 XPos = (entity->XPos >> 16) + xOffset;
2078
int32 YPos = (entity->YPos >> 16) + yOffset;
2079
int32 startX = XPos;
2080
XPos = XPos + 16;
2081
int32 chunk = xOffset;
2082
for (int32 i = 3; i > 0; i--) {
2083
if (XPos > 0 && XPos < stageLayouts[0].xsize << 7 && YPos > 0 && YPos < stageLayouts[0].ysize << 7 && !scriptEng.checkResult) {
2084
int32 chunkX = XPos >> 7;
2085
int32 tileX = (XPos & 0x7F) >> 4;
2086
int32 chunkY = YPos >> 7;
2087
int32 tileY = (YPos & 0x7F) >> 4;
2088
chunk = (stageLayouts[0].tiles[chunkX + (chunkY << 8)] << 6) + tileX + (tileY << 3);
2089
int32 tileIndex = tiles128x128.tileIndex[chunk];
2090
if (tiles128x128.collisionFlags[cPath][chunk] < SOLID_NONE) {
2091
switch (tiles128x128.direction[chunk]) {
2092
case 0: {
2093
c = (YPos & 15) + (tileIndex << 4);
2094
if (collisionMasks[cPath].rWallMasks[c] <= -64) {
2095
break;
2096
}
2097
entity->XPos = collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
2098
scriptEng.checkResult = true;
2099
break;
2100
}
2101
case 1: {
2102
c = (YPos & 15) + (tileIndex << 4);
2103
if (collisionMasks[cPath].lWallMasks[c] >= 64) {
2104
break;
2105
}
2106
entity->XPos = 15 - collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
2107
scriptEng.checkResult = true;
2108
break;
2109
}
2110
case 2: {
2111
c = 15 - (YPos & 15) + (tileIndex << 4);
2112
if (collisionMasks[cPath].rWallMasks[c] <= -64) {
2113
break;
2114
}
2115
entity->XPos = collisionMasks[cPath].rWallMasks[c] + (chunkX << 7) + (tileX << 4);
2116
scriptEng.checkResult = true;
2117
break;
2118
}
2119
case 3: {
2120
c = 15 - (YPos & 15) + (tileIndex << 4);
2121
if (collisionMasks[cPath].lWallMasks[c] >= 64) {
2122
break;
2123
}
2124
entity->XPos = 15 - collisionMasks[cPath].lWallMasks[c] + (chunkX << 7) + (tileX << 4);
2125
scriptEng.checkResult = true;
2126
break;
2127
}
2128
}
2129
}
2130
}
2131
XPos -= 16;
2132
}
2133
if (scriptEng.checkResult) {
2134
if (abs(entity->XPos - startX) < 16) {
2135
entity->XPos = (entity->XPos - xOffset) << 16;
2136
return;
2137
}
2138
entity->XPos = (startX - xOffset) << 16;
2139
scriptEng.checkResult = tiles128x128.collisionFlags[cPath][chunk] == 1;
2140
}
2141
}
2142
2143
void RSDK::Legacy::v3::ObjectEntityGrip(int32 direction, int32 extendBottomCol, int32 effect)
2144
{
2145
Player *player = &playerList[activePlayer];
2146
Hitbox *playerHitbox = GetPlayerHitbox(player);
2147
2148
collisionLeft = playerHitbox->left[0];
2149
collisionTop = playerHitbox->top[0];
2150
collisionRight = playerHitbox->right[0];
2151
collisionBottom = playerHitbox->bottom[0];
2152
2153
int32 storePos = 0;
2154
int32 storeCount = 0;
2155
2156
scriptEng.checkResult = false;
2157
2158
for (int32 i = 0; i < COLSTORE_COUNT; i++) {
2159
if (collisionStorage[i].entityNo != -1) {
2160
storeCount++;
2161
storePos = i;
2162
scriptEng.checkResult = true;
2163
}
2164
}
2165
2166
switch (effect) {
2167
case ECEFFECT_NONE:
2168
case ECEFFECT_RESETSTORAGE: {
2169
if (storeCount == 1) {
2170
scriptEng.checkResult = false;
2171
int32 extendedBottomCol = extendBottomCol ? collisionBottom + 5 : -5;
2172
Entity *entity = &objectEntityList[collisionStorage[storePos].entityNo];
2173
int32 yCheck1 = ((collisionStorage[storePos].top + extendedBottomCol) << 16) + entity->YPos;
2174
int32 yCheck2 = ((collisionStorage[storePos].bottom + extendedBottomCol) << 16) + entity->YPos;
2175
int32 xCheck1 = (collisionStorage[storePos].left << 16) + entity->XPos;
2176
int32 xCheck2 = (collisionStorage[storePos].right << 16) + entity->XPos;
2177
2178
if (direction) {
2179
if (((collisionLeft << 16) + player->XPos) <= xCheck2 && xCheck2 < (player->XPos - player->XVelocity)) {
2180
if (yCheck1 < (player->YPos + (collisionBottom << 16)) && (player->YPos + (collisionTop << 16)) < yCheck2) {
2181
player->XPos = xCheck2 - (collisionLeft << 16);
2182
scriptEng.checkResult = true;
2183
}
2184
else {
2185
if (effect == ECEFFECT_RESETSTORAGE) {
2186
for (int32 i = 0; i < COLSTORE_COUNT; i++) {
2187
CollisionStore *entityHitbox = &collisionStorage[i];
2188
entityHitbox->entityNo = -1;
2189
entityHitbox->type = -1;
2190
entityHitbox->left = 0;
2191
entityHitbox->top = 0;
2192
entityHitbox->right = 0;
2193
entityHitbox->bottom = 0;
2194
}
2195
}
2196
}
2197
}
2198
}
2199
else {
2200
if (((collisionRight << 16) + player->XPos) >= xCheck1 && xCheck1 > (player->XPos - player->XVelocity)) {
2201
player->XPos = xCheck1 - (collisionRight << 16);
2202
if (yCheck1 < (player->YPos + (collisionBottom << 16)) && (player->YPos + (collisionTop << 16)) < yCheck2) {
2203
scriptEng.checkResult = true;
2204
player->XPos = xCheck1 - (collisionRight << 16);
2205
}
2206
else {
2207
if (effect == ECEFFECT_RESETSTORAGE) {
2208
for (int32 i = 0; i < COLSTORE_COUNT; i++) {
2209
CollisionStore *entityHitbox = &collisionStorage[i];
2210
entityHitbox->entityNo = -1;
2211
entityHitbox->type = -1;
2212
entityHitbox->left = 0;
2213
entityHitbox->top = 0;
2214
entityHitbox->right = 0;
2215
entityHitbox->bottom = 0;
2216
}
2217
}
2218
}
2219
}
2220
}
2221
}
2222
else {
2223
if (effect == ECEFFECT_RESETSTORAGE) {
2224
for (int32 i = 0; i < COLSTORE_COUNT; i++) {
2225
CollisionStore *entityHitbox = &collisionStorage[i];
2226
entityHitbox->entityNo = -1;
2227
entityHitbox->type = -1;
2228
entityHitbox->left = 0;
2229
entityHitbox->top = 0;
2230
entityHitbox->right = 0;
2231
entityHitbox->bottom = 0;
2232
}
2233
}
2234
}
2235
break;
2236
}
2237
case ECEFFECT_BOXCOL3: {
2238
CollisionStore *entityHitbox = &collisionStorage[storePos];
2239
for (int32 o = 0; o < LEGACY_v3_ENTITY_COUNT; o++) {
2240
Entity *entity = &objectEntityList[o];
2241
if (entityHitbox->type == entity->type) {
2242
BoxCollision3(entity->XPos + (entityHitbox->left << 16), entity->YPos + (entityHitbox->top << 16),
2243
entity->XPos + (entityHitbox->right << 16), entity->YPos + (entityHitbox->bottom << 16));
2244
}
2245
}
2246
break;
2247
}
2248
default: break;
2249
}
2250
}
2251
2252
void RSDK::Legacy::v3::TouchCollision(int32 left, int32 top, int32 right, int32 bottom)
2253
{
2254
Player *player = &playerList[activePlayer];
2255
Hitbox *playerHitbox = GetPlayerHitbox(player);
2256
2257
collisionLeft = player->XPos >> 16;
2258
collisionTop = player->YPos >> 16;
2259
collisionRight = collisionLeft;
2260
collisionBottom = collisionTop;
2261
collisionLeft += playerHitbox->left[0];
2262
collisionTop += playerHitbox->top[0];
2263
collisionRight += playerHitbox->right[0];
2264
collisionBottom += playerHitbox->bottom[0];
2265
scriptEng.checkResult = collisionRight > left && collisionLeft < right && collisionBottom > top && collisionTop < bottom;
2266
2267
#if !RETRO_USE_ORIGINAL_CODE
2268
if (showHitboxes) {
2269
Entity *entity = &objectEntityList[objectLoop];
2270
left -= entity->XPos >> 16;
2271
top -= entity->YPos >> 16;
2272
right -= entity->XPos >> 16;
2273
bottom -= entity->YPos >> 16;
2274
2275
int32 thisHitboxID = AddDebugHitbox(H_TYPE_TOUCH, entity, left, top, right, bottom);
2276
if (thisHitboxID >= 0 && scriptEng.checkResult)
2277
debugHitboxList[thisHitboxID].collision |= 1;
2278
2279
int32 otherHitboxID =
2280
AddDebugHitbox(H_TYPE_TOUCH, NULL, playerHitbox->left[0], playerHitbox->top[0], playerHitbox->right[0], playerHitbox->bottom[0]);
2281
if (otherHitboxID >= 0) {
2282
debugHitboxList[otherHitboxID].pos.x = player->XPos;
2283
debugHitboxList[otherHitboxID].pos.y = player->YPos;
2284
2285
if (scriptEng.checkResult)
2286
debugHitboxList[otherHitboxID].collision |= 1;
2287
}
2288
}
2289
#endif
2290
}
2291
void RSDK::Legacy::v3::BoxCollision(int32 left, int32 top, int32 right, int32 bottom)
2292
{
2293
Player *player = &playerList[activePlayer];
2294
Hitbox *playerHitbox = GetPlayerHitbox(player);
2295
2296
collisionLeft = playerHitbox->left[0];
2297
collisionTop = playerHitbox->top[0];
2298
collisionRight = playerHitbox->right[0];
2299
collisionBottom = playerHitbox->bottom[0];
2300
scriptEng.checkResult = false;
2301
2302
int32 spd = 0;
2303
switch (player->collisionMode) {
2304
case CMODE_FLOOR:
2305
case CMODE_ROOF:
2306
if (player->XVelocity)
2307
spd = abs(player->XVelocity);
2308
else
2309
spd = abs(player->speed);
2310
break;
2311
case CMODE_LWALL:
2312
case CMODE_RWALL: spd = abs(player->XVelocity); break;
2313
default: break;
2314
}
2315
if (spd <= abs(player->YVelocity)) {
2316
sensors[0].collided = false;
2317
sensors[1].collided = false;
2318
sensors[2].collided = false;
2319
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2320
sensors[1].XPos = player->XPos;
2321
sensors[2].XPos = player->XPos + ((collisionRight - 2) << 16);
2322
sensors[0].YPos = player->YPos + (collisionBottom << 16);
2323
sensors[1].YPos = sensors[0].YPos;
2324
sensors[2].YPos = sensors[0].YPos;
2325
if (player->YVelocity > -1) {
2326
for (int32 i = 0; i < 3; ++i) {
2327
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos >= top && player->YPos - player->YVelocity < top) {
2328
sensors[i].collided = true;
2329
player->flailing[i] = true;
2330
}
2331
}
2332
}
2333
if (sensors[2].collided || sensors[1].collided || sensors[0].collided) {
2334
if (!player->gravity && (player->collisionMode == CMODE_RWALL || player->collisionMode == CMODE_LWALL)) {
2335
player->XVelocity = 0;
2336
player->speed = 0;
2337
}
2338
player->YPos = top - (collisionBottom << 16);
2339
player->gravity = 0;
2340
player->YVelocity = 0;
2341
player->angle = 0;
2342
player->boundEntity->rotation = 0;
2343
player->controlLock = 0;
2344
scriptEng.checkResult = true;
2345
}
2346
else {
2347
sensors[0].collided = false;
2348
sensors[1].collided = false;
2349
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2350
sensors[1].XPos = player->XPos + ((collisionRight - 2) << 16);
2351
sensors[0].YPos = player->YPos + (collisionTop << 16);
2352
sensors[1].YPos = sensors[0].YPos;
2353
for (int32 i = 0; i < 2; ++i) {
2354
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos <= bottom && player->YPos - player->YVelocity > bottom) {
2355
sensors[i].collided = true;
2356
}
2357
}
2358
if (sensors[1].collided || sensors[0].collided) {
2359
if (player->gravity == 1) {
2360
player->YPos = bottom - (collisionTop << 16);
2361
}
2362
if (player->YVelocity < 1)
2363
player->YVelocity = 0;
2364
scriptEng.checkResult = 4;
2365
}
2366
else {
2367
sensors[0].collided = false;
2368
sensors[1].collided = false;
2369
sensors[0].XPos = player->XPos + (collisionRight << 16);
2370
sensors[1].XPos = sensors[0].XPos;
2371
sensors[0].YPos = player->YPos - 0x20000;
2372
sensors[1].YPos = player->YPos + 0x80000;
2373
for (int32 i = 0; i < 2; ++i) {
2374
if (sensors[i].XPos >= left && player->XPos - player->XVelocity < left && sensors[1].YPos > top && sensors[0].YPos < bottom) {
2375
sensors[i].collided = true;
2376
}
2377
}
2378
if (sensors[1].collided || sensors[0].collided) {
2379
player->XPos = left - (collisionRight << 16);
2380
if (player->XVelocity > 0) {
2381
if (!player->boundEntity->direction)
2382
player->pushing = 2;
2383
player->XVelocity = 0;
2384
player->speed = 0;
2385
}
2386
scriptEng.checkResult = 2;
2387
}
2388
else {
2389
sensors[0].collided = false;
2390
sensors[1].collided = false;
2391
sensors[0].XPos = player->XPos + (collisionLeft << 16);
2392
sensors[1].XPos = sensors[0].XPos;
2393
sensors[0].YPos = player->YPos - 0x20000;
2394
sensors[1].YPos = player->YPos + 0x80000;
2395
for (int32 i = 0; i < 2; ++i) {
2396
if (sensors[i].XPos <= right && player->XPos - player->XVelocity > right && sensors[1].YPos > top
2397
&& sensors[0].YPos < bottom) {
2398
sensors[i].collided = true;
2399
}
2400
}
2401
2402
if (sensors[1].collided || (sensors[0].collided)) {
2403
player->XPos = right - (collisionLeft << 16);
2404
if (player->XVelocity < 0) {
2405
if (player->boundEntity->direction == FLIP_X)
2406
player->pushing = 2;
2407
player->XVelocity = 0;
2408
player->speed = 0;
2409
}
2410
scriptEng.checkResult = 3;
2411
}
2412
}
2413
}
2414
}
2415
}
2416
else {
2417
sensors[0].collided = false;
2418
sensors[1].collided = false;
2419
sensors[0].XPos = player->XPos + (collisionRight << 16);
2420
sensors[1].XPos = sensors[0].XPos;
2421
sensors[0].YPos = player->YPos - 0x20000;
2422
sensors[1].YPos = player->YPos + 0x80000;
2423
for (int32 i = 0; i < 2; ++i) {
2424
if (sensors[i].XPos >= left && player->XPos - player->XVelocity < left && sensors[1].YPos > top && sensors[0].YPos < bottom) {
2425
sensors[i].collided = true;
2426
}
2427
}
2428
if (sensors[1].collided || sensors[0].collided) {
2429
player->XPos = left - (collisionRight << 16);
2430
if (player->XVelocity > 0) {
2431
if (!player->boundEntity->direction)
2432
player->pushing = 2;
2433
player->XVelocity = 0;
2434
player->speed = 0;
2435
}
2436
scriptEng.checkResult = 2;
2437
}
2438
else {
2439
sensors[0].collided = false;
2440
sensors[1].collided = false;
2441
sensors[0].XPos = player->XPos + (collisionLeft << 16);
2442
sensors[1].XPos = sensors[0].XPos;
2443
sensors[0].YPos = player->YPos - 0x20000;
2444
sensors[1].YPos = player->YPos + 0x80000;
2445
for (int32 i = 0; i < 2; ++i) {
2446
if (sensors[i].XPos <= right && player->XPos - player->XVelocity > right && sensors[1].YPos > top && sensors[0].YPos < bottom) {
2447
sensors[i].collided = true;
2448
}
2449
}
2450
if (sensors[1].collided || sensors[0].collided) {
2451
player->XPos = right - (collisionLeft << 16);
2452
if (player->XVelocity < 0) {
2453
if (player->boundEntity->direction == FLIP_X) {
2454
player->pushing = 2;
2455
}
2456
player->XVelocity = 0;
2457
player->speed = 0;
2458
}
2459
scriptEng.checkResult = 3;
2460
}
2461
else {
2462
sensors[0].collided = false;
2463
sensors[1].collided = false;
2464
sensors[2].collided = false;
2465
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2466
sensors[1].XPos = player->XPos;
2467
sensors[2].XPos = player->XPos + ((collisionRight - 2) << 16);
2468
sensors[0].YPos = player->YPos + (collisionBottom << 16);
2469
sensors[1].YPos = sensors[0].YPos;
2470
sensors[2].YPos = sensors[0].YPos;
2471
if (player->YVelocity > -1) {
2472
for (int32 i = 0; i < 3; ++i) {
2473
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos >= top && player->YPos - player->YVelocity < top) {
2474
sensors[i].collided = true;
2475
player->flailing[i] = true;
2476
}
2477
}
2478
}
2479
if (sensors[2].collided || sensors[1].collided || sensors[0].collided) {
2480
if (!player->gravity && (player->collisionMode == CMODE_RWALL || player->collisionMode == CMODE_LWALL)) {
2481
player->XVelocity = 0;
2482
player->speed = 0;
2483
}
2484
player->YPos = top - (collisionBottom << 16);
2485
player->gravity = 0;
2486
player->YVelocity = 0;
2487
player->angle = 0;
2488
player->boundEntity->rotation = 0;
2489
player->controlLock = 0;
2490
scriptEng.checkResult = true;
2491
}
2492
else {
2493
sensors[0].collided = false;
2494
sensors[1].collided = false;
2495
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2496
sensors[1].XPos = player->XPos + ((collisionRight - 2) << 16);
2497
sensors[0].YPos = player->YPos + (collisionTop << 16);
2498
sensors[1].YPos = sensors[0].YPos;
2499
for (int32 i = 0; i < 2; ++i) {
2500
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos <= bottom
2501
&& player->YPos - player->YVelocity > bottom) {
2502
sensors[i].collided = true;
2503
}
2504
}
2505
2506
if (sensors[1].collided || sensors[0].collided) {
2507
if (player->gravity == 1) {
2508
player->YPos = bottom - (collisionTop << 16);
2509
}
2510
if (player->YVelocity < 1)
2511
player->YVelocity = 0;
2512
scriptEng.checkResult = 4;
2513
}
2514
}
2515
}
2516
}
2517
}
2518
2519
#if !RETRO_USE_ORIGINAL_CODE
2520
int32 thisHitboxID = 0;
2521
if (showHitboxes) {
2522
Entity *entity = &objectEntityList[objectLoop];
2523
left -= entity->XPos;
2524
top -= entity->YPos;
2525
right -= entity->XPos;
2526
bottom -= entity->YPos;
2527
2528
thisHitboxID = AddDebugHitbox(H_TYPE_BOX, &objectEntityList[objectLoop], left >> 16, top >> 16, right >> 16, bottom >> 16);
2529
if (thisHitboxID >= 0 && scriptEng.checkResult)
2530
debugHitboxList[thisHitboxID].collision |= 1 << (scriptEng.checkResult - 1);
2531
2532
int32 otherHitboxID =
2533
AddDebugHitbox(H_TYPE_BOX, NULL, playerHitbox->left[0], playerHitbox->top[0], playerHitbox->right[0], playerHitbox->bottom[0]);
2534
if (otherHitboxID >= 0) {
2535
debugHitboxList[otherHitboxID].pos.x = player->XPos;
2536
debugHitboxList[otherHitboxID].pos.y = player->YPos;
2537
2538
if (scriptEng.checkResult)
2539
debugHitboxList[otherHitboxID].collision |= 1 << (4 - scriptEng.checkResult);
2540
}
2541
}
2542
#endif
2543
}
2544
void RSDK::Legacy::v3::BoxCollision2(int32 left, int32 top, int32 right, int32 bottom)
2545
{
2546
Player *player = &playerList[activePlayer];
2547
Hitbox *playerHitbox = GetPlayerHitbox(player);
2548
2549
collisionLeft = playerHitbox->left[0];
2550
collisionTop = playerHitbox->top[0];
2551
collisionRight = playerHitbox->right[0];
2552
collisionBottom = playerHitbox->bottom[0];
2553
scriptEng.checkResult = false;
2554
int32 spd = 0;
2555
switch (player->collisionMode) {
2556
case CMODE_FLOOR:
2557
case CMODE_ROOF:
2558
if (player->XVelocity)
2559
spd = abs(player->XVelocity);
2560
else
2561
spd = abs(player->speed);
2562
break;
2563
case CMODE_LWALL:
2564
case CMODE_RWALL: spd = abs(player->XVelocity); break;
2565
default: break;
2566
}
2567
2568
if (spd <= abs(player->YVelocity)) {
2569
sensors[0].collided = false;
2570
sensors[1].collided = false;
2571
sensors[2].collided = false;
2572
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2573
sensors[1].XPos = player->XPos;
2574
sensors[2].XPos = player->XPos + ((collisionRight - 2) << 16);
2575
sensors[0].YPos = player->YPos + (collisionBottom << 16);
2576
sensors[1].YPos = sensors[0].YPos;
2577
sensors[2].YPos = sensors[0].YPos;
2578
if (player->YVelocity > -1) {
2579
for (int32 i = 0; i < 3; ++i) {
2580
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos >= top && player->YPos - player->YVelocity < top) {
2581
sensors[i].collided = true;
2582
player->flailing[i] = true;
2583
}
2584
}
2585
}
2586
if (sensors[2].collided || sensors[1].collided || sensors[0].collided) {
2587
if (!player->gravity && (player->collisionMode == CMODE_RWALL || player->collisionMode == CMODE_LWALL)) {
2588
player->XVelocity = 0;
2589
player->speed = 0;
2590
}
2591
player->YPos = top - (collisionBottom << 16);
2592
player->gravity = 0;
2593
player->YVelocity = 0;
2594
player->angle = 0;
2595
player->boundEntity->rotation = 0;
2596
player->controlLock = 0;
2597
scriptEng.checkResult = 1;
2598
}
2599
else {
2600
sensors[0].collided = false;
2601
sensors[1].collided = false;
2602
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2603
sensors[1].XPos = player->XPos + ((collisionRight - 2) << 16);
2604
sensors[0].YPos = player->YPos + (collisionTop << 16);
2605
sensors[1].YPos = player->YPos + (collisionTop << 16);
2606
2607
for (int32 i = 0; i < 2; ++i) {
2608
if (left < sensors[i].XPos && right > sensors[i].XPos && bottom >= sensors[i].YPos && bottom < player->YPos - player->YVelocity) {
2609
sensors[i].collided = true;
2610
}
2611
}
2612
2613
if (sensors[1].collided || sensors[0].collided) {
2614
if (player->gravity == 1)
2615
player->YPos = bottom - (collisionTop << 16);
2616
2617
if (player->YVelocity < 1)
2618
player->YVelocity = 0;
2619
scriptEng.checkResult = 4;
2620
}
2621
else {
2622
sensors[0].collided = false;
2623
sensors[1].collided = false;
2624
sensors[0].XPos = player->XPos + (collisionRight << 16);
2625
sensors[1].XPos = player->XPos + (collisionRight << 16);
2626
sensors[0].YPos = player->YPos + ((collisionBottom - 2) << 16);
2627
sensors[1].YPos = player->YPos + ((collisionTop + 2) << 16);
2628
for (int32 i = 0; i < 2; ++i) {
2629
if (sensors[i].XPos >= left && player->XPos - player->XVelocity < left && sensors[0].YPos > top && sensors[1].YPos < bottom) {
2630
sensors[i].collided = true;
2631
}
2632
}
2633
2634
if (sensors[1].collided || sensors[0].collided) {
2635
player->XPos = left - (collisionRight << 16);
2636
if (player->XVelocity > 0) {
2637
if (player->boundEntity->direction == FLIP_NONE)
2638
player->pushing = 2;
2639
player->XVelocity = 0;
2640
player->speed = 0;
2641
}
2642
scriptEng.checkResult = 2;
2643
}
2644
else {
2645
sensors[0].collided = false;
2646
sensors[1].collided = false;
2647
sensors[0].XPos = sensors[0].XPos;
2648
sensors[1].XPos = player->XPos + (collisionLeft << 16);
2649
sensors[0].YPos = player->YPos + ((collisionBottom - 2) << 16);
2650
sensors[1].YPos = player->YPos + ((collisionTop + 2) << 16);
2651
for (int32 i = 0; i < 2; ++i) {
2652
if (sensors[i].XPos <= right && player->XPos - player->XVelocity > right && sensors[0].YPos > top
2653
&& sensors[1].YPos < bottom) {
2654
sensors[i].collided = true;
2655
}
2656
}
2657
2658
if (sensors[1].collided || (sensors[0].collided)) {
2659
player->XPos = right - (collisionLeft << 16);
2660
if (player->XVelocity < 0) {
2661
if (player->boundEntity->direction == FLIP_X)
2662
player->pushing = 2;
2663
player->XVelocity = 0;
2664
player->speed = 0;
2665
}
2666
scriptEng.checkResult = 3;
2667
}
2668
}
2669
}
2670
}
2671
}
2672
else {
2673
sensors[0].collided = false;
2674
sensors[1].collided = false;
2675
sensors[0].XPos = player->XPos + (collisionRight << 16);
2676
sensors[1].XPos = player->XPos + (collisionRight << 16);
2677
sensors[0].YPos = player->YPos + ((collisionBottom - 2) << 16);
2678
sensors[1].YPos = player->YPos + ((collisionTop + 2) << 16);
2679
for (int32 i = 0; i < 2; ++i) {
2680
if (sensors[i].XPos >= left && player->XPos - player->XVelocity < left && sensors[0].YPos > top && sensors[1].YPos < bottom) {
2681
sensors[i].collided = true;
2682
}
2683
}
2684
2685
if (sensors[1].collided || sensors[0].collided) {
2686
player->XPos = left - (collisionRight << 16);
2687
if (player->XVelocity > 0) {
2688
if (!player->boundEntity->direction)
2689
player->pushing = 2;
2690
player->XVelocity = 0;
2691
player->speed = 0;
2692
}
2693
scriptEng.checkResult = 2;
2694
}
2695
else {
2696
sensors[0].collided = false;
2697
sensors[1].collided = false;
2698
sensors[0].XPos = sensors[0].XPos;
2699
sensors[1].XPos = player->XPos + (collisionLeft << 16);
2700
sensors[0].YPos = player->YPos + ((collisionBottom - 2) << 16);
2701
sensors[1].YPos = player->YPos + ((collisionTop + 2) << 16);
2702
for (int32 i = 0; i < 2; ++i) {
2703
if (sensors[i].XPos <= right && player->XPos - player->XVelocity > right && sensors[0].YPos > top && sensors[1].YPos < bottom) {
2704
sensors[i].collided = true;
2705
}
2706
}
2707
2708
if (sensors[1].collided || sensors[0].collided) {
2709
player->XPos = right - (collisionLeft << 16);
2710
if (player->XVelocity < 0) {
2711
if (player->boundEntity->direction == FLIP_X) {
2712
player->pushing = 2;
2713
}
2714
player->XVelocity = 0;
2715
player->speed = 0;
2716
}
2717
scriptEng.checkResult = 3;
2718
}
2719
else {
2720
sensors[0].collided = false;
2721
sensors[1].collided = false;
2722
sensors[2].collided = false;
2723
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2724
sensors[1].XPos = player->XPos;
2725
sensors[2].XPos = player->XPos + ((collisionRight - 2) << 16);
2726
sensors[0].YPos = player->YPos + (collisionBottom << 16);
2727
sensors[1].YPos = sensors[0].YPos;
2728
sensors[2].YPos = sensors[0].YPos;
2729
if (player->YVelocity > -1) {
2730
for (int32 i = 0; i < 3; ++i) {
2731
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos >= top && player->YPos - player->YVelocity < top) {
2732
sensors[i].collided = true;
2733
player->flailing[i] = true;
2734
}
2735
}
2736
}
2737
if (sensors[2].collided || sensors[1].collided || sensors[0].collided) {
2738
if (!player->gravity && (player->collisionMode == CMODE_RWALL || player->collisionMode == CMODE_LWALL)) {
2739
player->XVelocity = 0;
2740
player->speed = 0;
2741
}
2742
player->YPos = top - (collisionBottom << 16);
2743
player->gravity = 0;
2744
player->YVelocity = 0;
2745
player->angle = 0;
2746
player->boundEntity->rotation = 0;
2747
player->controlLock = 0;
2748
scriptEng.checkResult = 1;
2749
}
2750
else {
2751
sensors[0].collided = false;
2752
sensors[1].collided = false;
2753
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2754
sensors[1].XPos = player->XPos + ((collisionRight - 2) << 16);
2755
sensors[0].YPos = player->YPos + (collisionTop << 16);
2756
sensors[1].YPos = player->YPos + (collisionTop << 16);
2757
2758
for (int32 i = 0; i < 2; ++i) {
2759
if (left < sensors[i].XPos && right > sensors[i].XPos && bottom >= sensors[i].YPos
2760
&& bottom < player->YPos - player->YVelocity) {
2761
sensors[i].collided = true;
2762
}
2763
}
2764
2765
if (sensors[1].collided || sensors[0].collided) {
2766
if (player->gravity == 1) {
2767
player->YPos = bottom - (collisionTop << 16);
2768
}
2769
if (player->YVelocity < 1)
2770
player->YVelocity = 0;
2771
scriptEng.checkResult = 4;
2772
}
2773
}
2774
}
2775
}
2776
}
2777
2778
#if !RETRO_USE_ORIGINAL_CODE
2779
int32 thisHitboxID = 0;
2780
if (showHitboxes) {
2781
Entity *entity = &objectEntityList[objectLoop];
2782
left -= entity->XPos;
2783
top -= entity->YPos;
2784
right -= entity->XPos;
2785
bottom -= entity->YPos;
2786
2787
thisHitboxID = AddDebugHitbox(H_TYPE_BOX, &objectEntityList[objectLoop], left >> 16, top >> 16, right >> 16, bottom >> 16);
2788
if (thisHitboxID >= 0 && scriptEng.checkResult)
2789
debugHitboxList[thisHitboxID].collision |= 1 << (scriptEng.checkResult - 1);
2790
2791
int32 otherHitboxID =
2792
AddDebugHitbox(H_TYPE_BOX, NULL, playerHitbox->left[0], playerHitbox->top[0], playerHitbox->right[0], playerHitbox->bottom[0]);
2793
if (otherHitboxID >= 0) {
2794
debugHitboxList[otherHitboxID].pos.x = player->XPos;
2795
debugHitboxList[otherHitboxID].pos.y = player->YPos;
2796
2797
if (scriptEng.checkResult)
2798
debugHitboxList[otherHitboxID].collision |= 1 << (4 - scriptEng.checkResult);
2799
}
2800
}
2801
#endif
2802
}
2803
void RSDK::Legacy::v3::PlatformCollision(int32 left, int32 top, int32 right, int32 bottom)
2804
{
2805
Player *player = &playerList[activePlayer];
2806
Hitbox *playerHitbox = GetPlayerHitbox(player);
2807
2808
collisionLeft = playerHitbox->left[0];
2809
collisionTop = playerHitbox->top[0];
2810
collisionRight = playerHitbox->right[0];
2811
collisionBottom = playerHitbox->bottom[0];
2812
sensors[0].collided = false;
2813
sensors[1].collided = false;
2814
sensors[2].collided = false;
2815
sensors[0].XPos = player->XPos + ((collisionLeft + 1) << 16);
2816
sensors[1].XPos = player->XPos;
2817
sensors[2].XPos = player->XPos + (collisionRight << 16);
2818
sensors[0].YPos = player->YPos + (collisionBottom << 16);
2819
sensors[1].YPos = sensors[0].YPos;
2820
sensors[2].YPos = sensors[0].YPos;
2821
scriptEng.checkResult = false;
2822
for (int32 i = 0; i < 3; ++i) {
2823
if (sensors[i].XPos > left && sensors[i].XPos < right && sensors[i].YPos > top - 2 && sensors[i].YPos < bottom && player->YVelocity >= 0) {
2824
sensors[i].collided = 1;
2825
player->flailing[i] = 1;
2826
}
2827
}
2828
2829
if (sensors[0].collided || sensors[1].collided || sensors[2].collided) {
2830
if (!player->gravity && (player->collisionMode == CMODE_RWALL || player->collisionMode == CMODE_LWALL)) {
2831
player->XVelocity = 0;
2832
player->speed = 0;
2833
}
2834
player->YPos = top - (collisionBottom << 16);
2835
player->gravity = 0;
2836
player->YVelocity = 0;
2837
player->angle = 0;
2838
player->boundEntity->rotation = 0;
2839
player->controlLock = 0;
2840
scriptEng.checkResult = true;
2841
}
2842
2843
#if !RETRO_USE_ORIGINAL_CODE
2844
int32 thisHitboxID = 0;
2845
if (showHitboxes) {
2846
Entity *entity = &objectEntityList[objectLoop];
2847
left -= entity->XPos;
2848
top -= entity->YPos;
2849
right -= entity->XPos;
2850
bottom -= entity->YPos;
2851
2852
thisHitboxID = AddDebugHitbox(H_TYPE_PLAT, &objectEntityList[objectLoop], left >> 16, top >> 16, right >> 16, bottom >> 16);
2853
if (thisHitboxID >= 0 && scriptEng.checkResult)
2854
debugHitboxList[thisHitboxID].collision |= 1 << 0;
2855
2856
int32 otherHitboxID =
2857
AddDebugHitbox(H_TYPE_PLAT, NULL, playerHitbox->left[0], playerHitbox->top[0], playerHitbox->right[0], playerHitbox->bottom[0]);
2858
if (otherHitboxID >= 0) {
2859
debugHitboxList[otherHitboxID].pos.x = player->XPos;
2860
debugHitboxList[otherHitboxID].pos.y = player->YPos;
2861
2862
if (scriptEng.checkResult)
2863
debugHitboxList[otherHitboxID].collision |= 1 << 3;
2864
}
2865
}
2866
#endif
2867
}
2868
2869
void RSDK::Legacy::v3::BoxCollision3(int32 left, int32 top, int32 right, int32 bottom)
2870
{
2871
Player *player = &playerList[activePlayer];
2872
Hitbox *playerHitbox = GetPlayerHitbox(player);
2873
2874
collisionLeft = playerHitbox->left[0];
2875
collisionTop = playerHitbox->top[0];
2876
collisionRight = playerHitbox->right[0];
2877
collisionBottom = playerHitbox->bottom[0];
2878
2879
scriptEng.checkResult = false;
2880
2881
sensors[0].collided = false;
2882
sensors[1].collided = false;
2883
sensors[2].collided = false;
2884
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2885
sensors[1].XPos = player->XPos;
2886
sensors[2].XPos = player->XPos + ((collisionRight - 2) << 16);
2887
sensors[0].YPos = (collisionBottom << 16) + player->YPos;
2888
sensors[1].YPos = sensors[0].YPos;
2889
sensors[2].YPos = sensors[0].YPos;
2890
2891
if (player->YVelocity > -1) {
2892
for (int32 i = 0; i < 3; ++i) {
2893
if ((left < sensors[i].XPos) && (sensors[i].XPos < right) && (top <= sensors[i].YPos) && ((player->YPos - player->YVelocity) < top)) {
2894
sensors[i].collided = true;
2895
player->flailing[i] = 1;
2896
}
2897
}
2898
}
2899
if (sensors[0].collided || sensors[1].collided || sensors[2].collided) {
2900
if ((!player->gravity) && (player->collisionMode == CMODE_RWALL || player->collisionMode == CMODE_LWALL)) {
2901
player->XVelocity = 0;
2902
player->speed = 0;
2903
}
2904
player->gravity = 0;
2905
player->YPos = top - (collisionBottom << 16);
2906
player->YVelocity = 0;
2907
player->angle = 0;
2908
player->boundEntity->rotation = 0;
2909
player->controlLock = 0;
2910
scriptEng.checkResult = true;
2911
}
2912
else {
2913
sensors[0].collided = false;
2914
sensors[1].collided = false;
2915
sensors[0].XPos = player->XPos + ((collisionLeft + 2) << 16);
2916
sensors[1].XPos = player->XPos + ((collisionRight - 2) << 16);
2917
sensors[0].YPos = player->YPos + (collisionTop << 16);
2918
sensors[1].YPos = sensors[0].YPos;
2919
for (int32 i = 0; i < 2; ++i) {
2920
if ((left < sensors[i].XPos && sensors[i].XPos < right) && (sensors[i].YPos <= bottom && bottom < player->YPos - player->YVelocity)) {
2921
sensors[i].collided = true;
2922
}
2923
}
2924
if (sensors[0].collided || sensors[1].collided) {
2925
if (player->gravity == 1) {
2926
player->YPos = bottom - (collisionTop << 16);
2927
}
2928
if (player->YVelocity < 1) {
2929
player->YVelocity = 0;
2930
}
2931
scriptEng.checkResult = 4;
2932
}
2933
else {
2934
sensors[0].collided = false;
2935
sensors[1].collided = false;
2936
2937
if (left <= (player->XPos + (collisionRight << 16)) && (player->XPos - player->XVelocity) < left) {
2938
for (int32 i = 0; i < 2; ++i) {
2939
if (top < (player->YPos + (collisionBottom << 16)) && sensors[i].YPos < bottom) {
2940
sensors[i].collided = true;
2941
}
2942
}
2943
}
2944
if (sensors[0].collided || sensors[1].collided) {
2945
scriptEng.checkResult = 2;
2946
player->XPos = left - (collisionRight << 16);
2947
for (int32 i = 0; i < COLSTORE_COUNT; i++) {
2948
CollisionStore *entityHitbox = &collisionStorage[i];
2949
if (entityHitbox->entityNo == objectLoop)
2950
break;
2951
2952
if (entityHitbox->entityNo == -1) {
2953
entityHitbox->entityNo = objectLoop;
2954
entityHitbox->type = objectEntityList[objectLoop].type;
2955
entityHitbox->left = scriptEng.operands[1];
2956
entityHitbox->top = scriptEng.operands[2];
2957
entityHitbox->right = scriptEng.operands[3];
2958
entityHitbox->bottom = scriptEng.operands[4];
2959
break;
2960
}
2961
}
2962
}
2963
else {
2964
sensors[0].collided = false;
2965
sensors[1].collided = false;
2966
if (((collisionLeft << 16) + player->XPos) <= right && right < (player->XPos - player->XVelocity)) {
2967
for (int32 i = 0; i < 2; ++i) {
2968
if (top < ((collisionBottom << 16) + player->YPos) && sensors[i].YPos < bottom) {
2969
sensors[i].collided = true;
2970
}
2971
}
2972
}
2973
if (sensors[0].collided || sensors[1].collided) {
2974
scriptEng.checkResult = 3;
2975
player->XPos = right - (collisionLeft << 16);
2976
for (int32 i = 0; i < COLSTORE_COUNT; i++) {
2977
CollisionStore *entityHitbox = &collisionStorage[i];
2978
if (entityHitbox->entityNo == objectLoop)
2979
break;
2980
2981
if (entityHitbox->entityNo == -1) {
2982
entityHitbox->entityNo = objectLoop;
2983
entityHitbox->type = objectEntityList[objectLoop].type;
2984
entityHitbox->left = scriptEng.operands[1];
2985
entityHitbox->top = scriptEng.operands[2];
2986
entityHitbox->right = scriptEng.operands[3];
2987
entityHitbox->bottom = scriptEng.operands[4];
2988
break;
2989
}
2990
}
2991
}
2992
}
2993
}
2994
}
2995
2996
#if !RETRO_USE_ORIGINAL_CODE
2997
int32 thisHitboxID = 0;
2998
if (showHitboxes) {
2999
Entity *entity = &objectEntityList[objectLoop];
3000
left -= entity->XPos;
3001
top -= entity->YPos;
3002
right -= entity->XPos;
3003
bottom -= entity->YPos;
3004
3005
thisHitboxID = AddDebugHitbox(H_TYPE_BOX, &objectEntityList[objectLoop], left >> 16, top >> 16, right >> 16, bottom >> 16);
3006
if (thisHitboxID >= 0 && scriptEng.checkResult)
3007
debugHitboxList[thisHitboxID].collision |= 1 << 0;
3008
3009
int32 otherHitboxID =
3010
AddDebugHitbox(H_TYPE_BOX, NULL, playerHitbox->left[0], playerHitbox->top[0], playerHitbox->right[0], playerHitbox->bottom[0]);
3011
if (otherHitboxID >= 0) {
3012
debugHitboxList[otherHitboxID].pos.x = player->XPos;
3013
debugHitboxList[otherHitboxID].pos.y = player->YPos;
3014
3015
if (scriptEng.checkResult)
3016
debugHitboxList[otherHitboxID].collision |= 1 << 3;
3017
}
3018
}
3019
#endif
3020
}
3021
3022
// Note for those that care: This is not a direct decomp of this function
3023
// We did try to make one, but the original function was too much of a mess to comprehend fully, so we opted to instead take what we could understand
3024
// from it and make a new one that replicates the behavior the best we could. If anyone out there wants to take a shot at fully decompiling the
3025
// original function, feel free to do so and send a PR, but this should be good enough as is
3026
void RSDK::Legacy::v3::EnemyCollision(int32 left, int32 top, int32 right, int32 bottom)
3027
{
3028
TouchCollision(left, top, right, bottom);
3029
3030
#if RSDK_AUTOBUILD
3031
// Skip the hammer hitboxes on autobuilds, just in case
3032
return;
3033
#endif
3034
3035
Player *player = &playerList[activePlayer];
3036
3037
int32 hammerHitboxLeft = 0;
3038
int32 hammerHitboxRight = 0;
3039
int32 hammerHitboxTop = 0;
3040
int32 hammerHitboxBottom = 0;
3041
3042
#if !RETRO_USE_ORIGINAL_CODE
3043
bool32 miniPlayerFlag = GetGlobalVariableByName("Mini_PlayerFlag");
3044
int8 playerAmy = GetGlobalVariableByName("PLAYER_AMY") ? GetGlobalVariableByName("PLAYER_AMY") : 5;
3045
int8 aniHammerJump = GetGlobalVariableByName("ANI_HAMMER_JUMP") ? GetGlobalVariableByName("ANI_HAMMER_JUMP") : 45;
3046
int8 aniHammerDash = GetGlobalVariableByName("ANI_HAMMER_DASH") ? GetGlobalVariableByName("ANI_HAMMER_DASH") : 46;
3047
#else
3048
bool32 mini_PlayerFlag = globalVariables[62];
3049
int8 playerAmy = 5;
3050
int8 aniHammerJump = 45;
3051
int8 aniHammerDash = 46;
3052
#endif
3053
3054
collisionLeft = player->XPos >> 16;
3055
collisionTop = player->YPos >> 16;
3056
collisionRight = collisionLeft;
3057
collisionBottom = collisionTop;
3058
3059
if (!scriptEng.checkResult) {
3060
if (playerListPos == playerAmy) {
3061
if (player->boundEntity->animation == aniHammerDash) {
3062
int32 frame = (miniPlayerFlag ? player->boundEntity->frame % 3 : player->boundEntity->frame % 8) * 4;
3063
3064
hammerHitboxLeft = miniPlayerFlag ? chibiHammerDashHitbox[frame] : hammerDashHitbox[frame];
3065
hammerHitboxTop = miniPlayerFlag ? chibiHammerDashHitbox[frame + 1] : hammerDashHitbox[frame + 1];
3066
hammerHitboxRight = miniPlayerFlag ? chibiHammerDashHitbox[frame + 2] : hammerDashHitbox[frame + 2];
3067
hammerHitboxBottom = miniPlayerFlag ? chibiHammerDashHitbox[frame + 3] : hammerDashHitbox[frame + 3];
3068
}
3069
if (player->boundEntity->animation == aniHammerJump) {
3070
int32 frame = (miniPlayerFlag ? player->boundEntity->frame % 2 : player->boundEntity->frame % 4) * 4;
3071
3072
hammerHitboxLeft = miniPlayerFlag ? chibiHammerJumpHitbox[frame] : hammerJumpHitbox[frame];
3073
hammerHitboxTop = miniPlayerFlag ? chibiHammerJumpHitbox[frame + 1] : hammerJumpHitbox[frame + 1];
3074
hammerHitboxRight = miniPlayerFlag ? chibiHammerJumpHitbox[frame + 2] : hammerJumpHitbox[frame + 2];
3075
hammerHitboxBottom = miniPlayerFlag ? chibiHammerJumpHitbox[frame + 3] : hammerJumpHitbox[frame + 3];
3076
}
3077
if (player->boundEntity->direction) {
3078
int32 storeHitboxLeft = hammerHitboxLeft;
3079
hammerHitboxLeft = -hammerHitboxRight;
3080
hammerHitboxRight = -storeHitboxLeft;
3081
}
3082
scriptEng.checkResult = collisionRight + hammerHitboxRight > left && collisionLeft + hammerHitboxLeft < right
3083
&& collisionBottom + hammerHitboxBottom > top && collisionTop + hammerHitboxTop < bottom;
3084
}
3085
}
3086
3087
#if !RETRO_USE_ORIGINAL_CODE
3088
if (showHitboxes) {
3089
Entity *entity = &objectEntityList[objectLoop];
3090
left -= entity->XPos >> 16;
3091
top -= entity->YPos >> 16;
3092
right -= entity->XPos >> 16;
3093
bottom -= entity->YPos >> 16;
3094
3095
Hitbox *playerHitbox = GetPlayerHitbox(player);
3096
3097
int32 thisHitboxID = AddDebugHitbox(H_TYPE_HAMMER, entity, left, top, right, bottom);
3098
if (thisHitboxID >= 0 && scriptEng.checkResult)
3099
debugHitboxList[thisHitboxID].collision |= 1;
3100
3101
int32 otherHitboxID = AddDebugHitbox(H_TYPE_HAMMER, NULL, hammerHitboxLeft, hammerHitboxTop, hammerHitboxRight, hammerHitboxBottom);
3102
if (otherHitboxID >= 0) {
3103
debugHitboxList[otherHitboxID].pos.x = player->XPos;
3104
debugHitboxList[otherHitboxID].pos.y = player->YPos;
3105
3106
if (scriptEng.checkResult)
3107
debugHitboxList[otherHitboxID].collision |= 1;
3108
}
3109
}
3110
#endif
3111
}
3112
3113