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