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