From 169ed48bdcbfb3b568b028bd5bebb27680073514 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 15 Mar 2025 09:33:59 +1000 Subject: [PATCH] Name almost all collision and movement functions --- docs/piracychecks.md | 2 +- src/game/bg.c | 1 + src/game/body.c | 4 +- src/game/bondbike.c | 134 +- src/game/bondeyespy.c | 68 +- src/game/bondgrab.c | 104 +- src/game/bondgun.c | 2 +- src/game/bondmove.c | 8 +- src/game/bondwalk.c | 278 ++- src/game/bot.c | 2 +- src/game/botact.c | 2 +- src/game/chr.c | 267 +-- src/game/chraction.c | 186 +- src/game/collisionutils.c | 58 +- src/game/explosions.c | 4 +- src/game/mplayer/scenarios/kingofthehill.inc | 4 +- src/game/padhalllv.c | 8 +- src/game/player.c | 6 +- src/game/playerreset.c | 2 +- src/game/prop.c | 22 +- src/game/propobj.c | 196 +- src/game/setup.c | 2 +- src/game/setupcover.c | 4 +- src/game/setuppads.c | 2 +- src/include/bss.h | 2 +- src/include/data.h | 4 +- src/include/game/bondwalk.h | 2 +- src/include/lib/collision.h | 91 +- src/include/types.h | 4 +- src/lib/collision.c | 2182 +++++++++--------- src/lib/portal.c | 4 +- 31 files changed, 1921 insertions(+), 1734 deletions(-) diff --git a/docs/piracychecks.md b/docs/piracychecks.md index dfb31aabb..71b722f7b 100644 --- a/docs/piracychecks.md +++ b/docs/piracychecks.md @@ -56,7 +56,7 @@ The decomp project wraps all decompiled piracy checks in `#if PIRACYCHECKS` stat **What It Checks:** Checksums `bot_pickup_prop` to make sure it hasn't been modified. -**Payload:** Disables the ability for the player and other characters to go up or down slopes. This is done by nopping the `jr ra` instruction in `cd_find_ground_info_at_cyl`, which causes it to flow into the following function, which unconditionally returns false and only exists for this purpose. +**Payload:** Disables the ability for the player and other characters to go up or down slopes. This is done by nopping the `jr ra` instruction in `cd_find_ground_at_cyl_ctfril`, which causes it to flow into the following function, which unconditionally returns false and only exists for this purpose. --- diff --git a/src/game/bg.c b/src/game/bg.c index 2b51e187a..7dac70a56 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -5745,6 +5745,7 @@ void bg_tick_portals(void) if (!g_BgRoomTestsDisabled) { if (g_BgPortals[0].verticesoffset == 0) { + // Unreachable because all BGs have portals for (room = 1; room < g_Vars.roomcount; room++) { if (bg_room_intersects_screen_box(room, &box) && ((g_StageIndex != STAGEINDEX_INFILTRATION && g_StageIndex != STAGEINDEX_RESCUE && g_StageIndex != STAGEINDEX_ESCAPE) || room != 0xf) diff --git a/src/game/body.c b/src/game/body.c index b52f9c8c5..230cc8680 100644 --- a/src/game/body.c +++ b/src/game/body.c @@ -361,7 +361,7 @@ void body_instantiate_chr(s32 stagenum, struct packedchr *packed, s32 cmdindex) rooms[0] = pad.room; rooms[1] = -1; - if (cd_test_volume(&pad.pos, 20, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, 200, -200) == CDRESULT_COLLISION + if (cd_test_volume_simple(&pad.pos, 20, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, 200, -200) == CDRESULT_COLLISION && packed->chair == -1 && (packed->spawnflags & SPAWNFLAG_IGNORECOLLISION) == 0) { return; @@ -587,7 +587,7 @@ struct prop *body_instantiate_eyespy(struct pad *pad, RoomNum room) chr->visionrange = 0; chr->race = body_get_race(chr->bodynum); - ground = cd_find_ground_info_at_cyl(&pad->pos, 30, rooms, NULL, NULL, NULL, NULL, &inlift, &lift); + ground = cd_find_ground_at_cyl_ctfril(&pad->pos, 30, rooms, NULL, NULL, NULL, NULL, &inlift, &lift); chr->ground = ground; chr->manground = ground; diff --git a/src/game/bondbike.c b/src/game/bondbike.c index 10eb7eaf3..2d6dbc5d3 100644 --- a/src/game/bondbike.c +++ b/src/game/bondbike.c @@ -139,15 +139,15 @@ void bbike_try_dismount_angle(f32 relativeangle, f32 distance) los_find_final_room_exhaustive(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &pos, rooms); bmove_find_entered_rooms_by_pos(g_Vars.currentplayer, &pos, rooms); - result = cd_test_cyl_move02(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, - &pos, rooms, CDTYPE_ALL, true, + result = cd_test_cylmove_oobfail(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, + &pos, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); prop_set_perim_enabled(g_Vars.currentplayer->hoverbike, true); if (result == CDRESULT_NOCOLLISION) { - result = cd_test_volume(&pos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, + result = cd_test_volume_simple(&pos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); } @@ -369,7 +369,7 @@ void bbike0f0d2b40(struct defaultobj *bike, struct coord *arg1, f32 arg2, struct } } -s32 bbike_calculate_new_position(struct coord *vel, f32 angledelta) +s32 bbike_try_delta_nopush(struct coord *vel, f32 angledelta) { s32 result = CDRESULT_NOCOLLISION; struct coord dstpos; @@ -416,20 +416,20 @@ s32 bbike_calculate_new_position(struct coord *vel, f32 angledelta) zdiff = dstpos.z - g_Vars.currentplayer->hoverbike->pos.z; if (xdiff > halfradius || zdiff > halfradius || xdiff < -halfradius || zdiff < -halfradius) { - result = cd_exam_cyl_move06(&g_Vars.currentplayer->hoverbike->pos, + result = cd_test_cylmove_oobfail_findclosest_finddist(&g_Vars.currentplayer->hoverbike->pos, g_Vars.currentplayer->hoverbike->rooms, - &dstpos, dstrooms, radius, CDTYPE_ALL, 1, + &dstpos, dstrooms, radius, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->hoverbike->pos.y, ymin - g_Vars.currentplayer->hoverbike->pos.y); if (result == CDRESULT_NOCOLLISION) { - result = cd_exam_cyl_move02(&g_Vars.currentplayer->hoverbike->pos, - &dstpos, radius, dstrooms, CDTYPE_ALL, true, + result = cd_test_volume_fromdir(&g_Vars.currentplayer->hoverbike->pos, + &dstpos, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->hoverbike->pos.y, ymin - g_Vars.currentplayer->hoverbike->pos.y); } } else { - result = cd_exam_cyl_move02(&g_Vars.currentplayer->hoverbike->pos, + result = cd_test_volume_fromdir(&g_Vars.currentplayer->hoverbike->pos, &dstpos, radius, spa8, CDTYPE_ALL, true, ymax - g_Vars.currentplayer->hoverbike->pos.y, ymin - g_Vars.currentplayer->hoverbike->pos.y); @@ -470,9 +470,9 @@ s32 bbike_calculate_new_position(struct coord *vel, f32 angledelta) return result; } -s32 bbike_calculate_new_position_with_push(struct coord *arg0, f32 arg1) +s32 bbike_try_delta(struct coord *arg0, f32 arg1) { - s32 result = bbike_calculate_new_position(arg0, arg1); + s32 result = bbike_try_delta_nopush(arg0, arg1); if (result != CDRESULT_NOCOLLISION) { struct prop *obstacle = cd_get_obstacle_prop(); @@ -516,7 +516,7 @@ s32 bbike_calculate_new_position_with_push(struct coord *arg0, f32 arg1) } if (moved) { - result = bbike_calculate_new_position(arg0, arg1); + result = bbike_try_delta_nopush(arg0, arg1); } } } @@ -565,7 +565,7 @@ void bbike_update_vertical(struct coord *pos) g_Vars.currentplayer->prop->pos.y = pos->y; g_Vars.currentplayer->prop->pos.z = pos->z; - ground = cd_find_ground_info_at_cyl(&g_Vars.currentplayer->prop->pos, + ground = cd_find_ground_at_cyl_ctfril(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->bond2.radius, g_Vars.currentplayer->prop->rooms, &g_Vars.currentplayer->floorcol, @@ -607,67 +607,67 @@ void bbike_update_vertical(struct coord *pos) bmove_update_look(); } -s32 bbike0f0d363c(f32 arg0) +s32 bbike_resolve_turndelta(f32 turndelta) { struct coord coord = {0, 0, 0}; - return bbike_calculate_new_position_with_push(&coord, arg0); + return bbike_try_delta(&coord, turndelta); } -s32 bbike0f0d3680(struct coord *arg0, struct coord *arg1, struct coord *arg2) +s32 bbike_try_fulldelta(struct coord *deltapos, struct coord *edgevtx1, struct coord *edgevtx2) { - s32 result = bbike_calculate_new_position_with_push(arg0, 0); + s32 result = bbike_try_delta(deltapos, 0); - if (!result) { + if (result == CDRESULT_COLLISION) { #if VERSION >= VERSION_NTSC_1_0 - cd_get_edge(arg1, arg2, 659, "bondbike.c"); + cd_get_edge(edgevtx1, edgevtx2, 659, "bondbike.c"); #else - cd_get_edge(arg1, arg2, 656, "bondbike.c"); + cd_get_edge(edgevtx1, edgevtx2, 656, "bondbike.c"); #endif } return result; } -s32 bbike0f0d36d4(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct coord *arg3, struct coord *arg4) +s32 bbike_try_quarterdelta(struct coord *posdelta, struct coord *prevedge_vtx1, struct coord *prevedge_vtx2, struct coord *edge_vtx1, struct coord *edge_vtx2) { if (cd_has_distance()) { - struct coord sp24; - f32 somefloat = cd_get_distance(); - s32 someint; + struct coord quarter; + f32 distance = cd_get_distance(); + s32 result; - sp24.x = arg0->x * somefloat * 0.25f; - sp24.y = arg0->y * somefloat * 0.25f; - sp24.z = arg0->z * somefloat * 0.25f; + quarter.x = posdelta->x * distance / 4.0f; + quarter.y = posdelta->y * distance / 4.0f; + quarter.z = posdelta->z * distance / 4.0f; - someint = bbike_calculate_new_position_with_push(&sp24, 0); + result = bbike_try_delta(&quarter, 0); - if (someint == 1) { - return 1; + if (result == CDRESULT_NOCOLLISION) { + return CDRESULT_NOCOLLISION; } - if (someint == 0) { + if (result == CDRESULT_COLLISION) { #if VERSION >= VERSION_NTSC_1_0 - cd_get_edge(arg3, arg4, 685, "bondbike.c"); + cd_get_edge(edge_vtx1, edge_vtx2, 685, "bondbike.c"); #else - cd_get_edge(arg3, arg4, 682, "bondbike.c"); + cd_get_edge(edge_vtx1, edge_vtx2, 682, "bondbike.c"); #endif - if (arg3->f[0] != arg1->f[0] - || arg3->f[1] != arg1->f[1] - || arg3->f[2] != arg1->f[2] - || arg4->f[0] != arg2->f[0] - || arg4->f[1] != arg2->f[1] - || arg4->f[2] != arg2->f[2]) { - return 0; + if (edge_vtx1->f[0] != prevedge_vtx1->f[0] + || edge_vtx1->f[1] != prevedge_vtx1->f[1] + || edge_vtx1->f[2] != prevedge_vtx1->f[2] + || edge_vtx2->f[0] != prevedge_vtx2->f[0] + || edge_vtx2->f[1] != prevedge_vtx2->f[1] + || edge_vtx2->f[2] != prevedge_vtx2->f[2]) { + return CDRESULT_COLLISION; } } } - return -1; + return CDRESULT_ERROR; } -s32 bbike0f0d3840(struct coord *arg0, struct coord *arg1, struct coord *arg2) +s32 bbike_try_slide_along_edge(struct coord *arg0, struct coord *arg1, struct coord *arg2) { s32 result; @@ -690,7 +690,7 @@ s32 bbike0f0d3840(struct coord *arg0, struct coord *arg1, struct coord *arg2) sp24.y = 0; sp24.z = sp30.z * tmp; - result = bbike_calculate_new_position_with_push(&sp24, 0); + result = bbike_try_delta(&sp24, 0); } else { result = -1; } @@ -698,7 +698,7 @@ s32 bbike0f0d3840(struct coord *arg0, struct coord *arg1, struct coord *arg2) return result; } -s32 bbike0f0d3940(struct coord *arg0, struct coord *arg1, struct coord *arg2) +s32 bbike_try_slide_along_corner(struct coord *arg0, struct coord *arg1, struct coord *arg2) { struct coord sp34; struct coord sp28; @@ -732,7 +732,7 @@ s32 bbike0f0d3940(struct coord *arg0, struct coord *arg1, struct coord *arg2) sp28.y = 0; sp28.z = sp34.z; - if (bbike_calculate_new_position_with_push(&sp28, 0) == CDRESULT_NOCOLLISION) { + if (bbike_try_delta(&sp28, 0) == CDRESULT_NOCOLLISION) { return true; } } @@ -760,7 +760,7 @@ s32 bbike0f0d3940(struct coord *arg0, struct coord *arg1, struct coord *arg2) sp28.y = 0; sp28.z = sp34.z; - if (bbike_calculate_new_position_with_push(&sp28, 0) == CDRESULT_NOCOLLISION) { + if (bbike_try_delta(&sp28, 0) == CDRESULT_NOCOLLISION) { return true; } } @@ -770,31 +770,31 @@ s32 bbike0f0d3940(struct coord *arg0, struct coord *arg1, struct coord *arg2) return false; } -void bbike0f0d3c60(struct coord *arg0) +void bbike_resolve_posdelta(struct coord *arg0) { - struct coord sp64; - struct coord sp58; - struct coord sp4c; - struct coord sp40; - s32 value; - struct coord sp30; - struct coord sp24; + struct coord edgea_vtx1; + struct coord edgea_vtx2; + struct coord edgeb_vtx1; + struct coord edgeb_vtx2; + s32 result; + struct coord edgec_vtx1; + struct coord edgec_vtx2; - if (bbike0f0d3680(arg0, &sp64, &sp58) == 0) { - value = bbike0f0d36d4(arg0, &sp64, &sp58, &sp4c, &sp40); + if (bbike_try_fulldelta(arg0, &edgea_vtx1, &edgea_vtx2) == CDRESULT_COLLISION) { + result = bbike_try_quarterdelta(arg0, &edgea_vtx1, &edgea_vtx2, &edgeb_vtx1, &edgeb_vtx2); - if (value > 0 || value < 0) { - if (bbike0f0d3840(arg0, &sp64, &sp58) <= 0 - && bbike0f0d3940(arg0, &sp64, &sp58) <= 0) { + if (result >= CDRESULT_NOCOLLISION || result <= CDRESULT_ERROR) { + if (bbike_try_slide_along_edge(arg0, &edgea_vtx1, &edgea_vtx2) <= CDRESULT_COLLISION + && bbike_try_slide_along_corner(arg0, &edgea_vtx1, &edgea_vtx2) <= CDRESULT_COLLISION) { // empty } - } else if (value == 0) { - bbike0f0d36d4(arg0, &sp4c, &sp40, &sp30, &sp24); + } else if (result == CDRESULT_COLLISION) { + result = bbike_try_quarterdelta(arg0, &edgeb_vtx1, &edgeb_vtx2, &edgec_vtx1, &edgec_vtx2); - if (bbike0f0d3840(arg0, &sp4c, &sp40) <= 0 - && bbike0f0d3840(arg0, &sp64, &sp58) <= 0 - && bbike0f0d3940(arg0, &sp4c, &sp40) <= 0 - && bbike0f0d3940(arg0, &sp64, &sp58) <= 0) { + if (bbike_try_slide_along_edge(arg0, &edgeb_vtx1, &edgeb_vtx2) <= CDRESULT_COLLISION + && bbike_try_slide_along_edge(arg0, &edgea_vtx1, &edgea_vtx2) <= CDRESULT_COLLISION + && bbike_try_slide_along_corner(arg0, &edgeb_vtx1, &edgeb_vtx2) <= CDRESULT_COLLISION + && bbike_try_slide_along_corner(arg0, &edgea_vtx1, &edgea_vtx2) <= CDRESULT_COLLISION) { if (&arg0); } } @@ -887,7 +887,7 @@ void bbike_tick(void) if (1); - bbike0f0d363c(bike->w * g_Vars.lvupdate60freal); + bbike_resolve_turndelta(bike->w * g_Vars.lvupdate60freal); sp20c.x = bike->speed[0] * g_Vars.lvupdate60freal; sp20c.y = 0.0f; @@ -896,7 +896,7 @@ void bbike_tick(void) bike->prevpos[0] = bike->base.prop->pos.x; bike->prevpos[1] = bike->base.prop->pos.z; - bbike0f0d3c60(&sp20c); + bbike_resolve_posdelta(&sp20c); sp1f8 = (bike->base.prop->pos.x - bike->prevpos[0]) / g_Vars.lvupdate60freal; sp1f4 = (bike->base.prop->pos.z - bike->prevpos[1]) / g_Vars.lvupdate60freal; diff --git a/src/game/bondeyespy.c b/src/game/bondeyespy.c index 7c2e6943e..5cb290d0f 100644 --- a/src/game/bondeyespy.c +++ b/src/game/bondeyespy.c @@ -60,7 +60,7 @@ f32 eyespy_find_ground(RoomNum *floorroom) pos.y = prop->pos.y + yoffset; pos.z = prop->pos.z; - ground = cd_find_ground_info_at_cyl(&pos, 26, prop->rooms, NULL, NULL, NULL, floorroom, &inlift, &lift); + ground = cd_find_ground_at_cyl_ctfril(&pos, 26, prop->rooms, NULL, NULL, NULL, floorroom, &inlift, &lift); if (ground < -30000) { ground = -30000; @@ -100,7 +100,7 @@ s32 eyespy_try_move_upwards(f32 yvel) f0 -= 0.1f; - result = cd_test_volume(&dstpos, 26, dstrooms, types, CHECKVERTICAL_YES, 15, f0); + result = cd_test_volume_simple(&dstpos, 26, dstrooms, types, CHECKVERTICAL_YES, 15, f0); prop_set_perim_enabled(prop, true); if (result == CDRESULT_NOCOLLISION) { @@ -112,7 +112,7 @@ s32 eyespy_try_move_upwards(f32 yvel) return result; } -s32 eyespy_calculate_new_position(struct coord *vel) +s32 eyespy_try_delta_nopush(struct coord *vel) { bool cdresult = CDRESULT_NOCOLLISION; struct prop *eyespyprop = g_Vars.currentplayer->eyespy->prop; @@ -176,13 +176,13 @@ s32 eyespy_calculate_new_position(struct coord *vel) halfradius = radius * 0.5f; if (xdiff > halfradius || zdiff > halfradius || xdiff < -halfradius || zdiff < -halfradius) { - cdresult = cd_exam_cyl_move06(&eyespyprop->pos, eyespyprop->rooms, &dstpos, dstrooms, radius, types, 1, 15, ymin); + cdresult = cd_test_cylmove_oobfail_findclosest_finddist(&eyespyprop->pos, eyespyprop->rooms, &dstpos, dstrooms, radius, types, CHECKVERTICAL_YES, 15, ymin); if (cdresult == CDRESULT_NOCOLLISION) { - cdresult = cd_exam_cyl_move02(&eyespyprop->pos, &dstpos, radius, dstrooms, types, true, 15, ymin); + cdresult = cd_test_volume_fromdir(&eyespyprop->pos, &dstpos, radius, dstrooms, types, CHECKVERTICAL_YES, 15, ymin); } } else { - cdresult = cd_exam_cyl_move02(&eyespyprop->pos, &dstpos, radius, sp74, types, true, 15, ymin); + cdresult = cd_test_volume_fromdir(&eyespyprop->pos, &dstpos, radius, sp74, types, CHECKVERTICAL_YES, 15, ymin); } if (cdresult == CDRESULT_COLLISION) { @@ -214,9 +214,9 @@ s32 eyespy_calculate_new_position(struct coord *vel) return cdresult; } -bool eyespy_calculate_new_position_with_push(struct coord *vel) +bool eyespy_try_delta(struct coord *vel) { - s32 cdresult = eyespy_calculate_new_position(vel); + s32 cdresult = eyespy_try_delta_nopush(vel); struct prop *prop; if (cdresult != CDRESULT_NOCOLLISION) { @@ -269,7 +269,7 @@ bool eyespy_calculate_new_position_with_push(struct coord *vel) return cdresult; } -s32 eyespy_try_quarterstep(struct coord *vel, struct coord *prevedge1, struct coord *prevedge2, struct coord *newedge1, struct coord *newedge2) +s32 eyespy_try_quarterdelta(struct coord *vel, struct coord *prevedge1, struct coord *prevedge2, struct coord *newedge1, struct coord *newedge2) { if (cd_has_distance()) { struct coord tryvel; @@ -280,7 +280,7 @@ s32 eyespy_try_quarterstep(struct coord *vel, struct coord *prevedge1, struct co tryvel.y = vel->y * distance * 0.25f; tryvel.z = vel->z * distance * 0.25f; - cdresult = eyespy_calculate_new_position_with_push(&tryvel); + cdresult = eyespy_try_delta(&tryvel); if (cdresult == CDRESULT_NOCOLLISION) { return CDRESULT_NOCOLLISION; @@ -303,7 +303,7 @@ s32 eyespy_try_quarterstep(struct coord *vel, struct coord *prevedge1, struct co return CDRESULT_ERROR; } -s32 eyespy_try_move_to_edge(struct coord *vel, struct coord *edge1, struct coord *edge2) +s32 eyespy_try_slide_along_edge(struct coord *vel, struct coord *edge1, struct coord *edge2) { f32 frac; struct coord tri; @@ -326,13 +326,13 @@ s32 eyespy_try_move_to_edge(struct coord *vel, struct coord *edge1, struct coord tryvel.y = 0; tryvel.z = tri.z * frac; - return eyespy_calculate_new_position_with_push(&tryvel); + return eyespy_try_delta(&tryvel); } return CDRESULT_ERROR; } -s32 eyespy_try_grind(struct coord *vel, struct coord *edge1, struct coord *edge2) +s32 eyespy_try_slide_along_corner(struct coord *vel, struct coord *edge1, struct coord *edge2) { struct coord tri; struct coord tryvel; @@ -363,7 +363,7 @@ s32 eyespy_try_grind(struct coord *vel, struct coord *edge1, struct coord *edge2 tryvel.y = 0; tryvel.z = tri.z; - if (eyespy_calculate_new_position_with_push(&tryvel) == CDRESULT_NOCOLLISION) { + if (eyespy_try_delta(&tryvel) == CDRESULT_NOCOLLISION) { return CDRESULT_NOCOLLISION; } } @@ -391,7 +391,7 @@ s32 eyespy_try_grind(struct coord *vel, struct coord *edge1, struct coord *edge2 tryvel.y = 0; tryvel.z = tri.z; - if (eyespy_calculate_new_position_with_push(&tryvel) == CDRESULT_NOCOLLISION) { + if (eyespy_try_delta(&tryvel) == CDRESULT_NOCOLLISION) { return CDRESULT_NOCOLLISION; } } @@ -401,9 +401,9 @@ s32 eyespy_try_grind(struct coord *vel, struct coord *edge1, struct coord *edge2 return CDRESULT_COLLISION; } -s32 eyespy_try_fullstep(struct coord *vel, struct coord *edge1, struct coord *edge2) +s32 eyespy_try_fulldelta(struct coord *vel, struct coord *edge1, struct coord *edge2) { - bool cdresult = eyespy_calculate_new_position_with_push(vel); + bool cdresult = eyespy_try_delta(vel); if (cdresult != CDRESULT_NOCOLLISION) { cd_get_edge(edge1, edge2, 473, "bondeyespy.c"); @@ -414,8 +414,8 @@ s32 eyespy_try_fullstep(struct coord *vel, struct coord *edge1, struct coord *ed void eyespy_update_position(void) { - struct coord fulledge1; - struct coord fulledge2; + struct coord edgea_vtx1; + struct coord edgea_vtx2; struct prop *prop = g_Vars.currentplayer->eyespy->prop; struct coord vel; f32 newground; @@ -425,11 +425,11 @@ void eyespy_update_position(void) f32 maxfallspeed; u8 hit = EYESPYHIT_NONE; f32 newy; - struct coord quarteredge1; - struct coord quarteredge2; + struct coord edgeb_vtx1; + struct coord edgeb_vtx2; u32 stack; - struct coord throwawayedge1; - struct coord throwawayedge2; + struct coord edgec_vtx1; + struct coord edgec_vtx2; origpos.f[0] = prop->pos.x; origpos.f[1] = prop->pos.y; @@ -440,18 +440,18 @@ void eyespy_update_position(void) vel.y = 0; vel.z = g_Vars.currentplayer->eyespy->vel.z; - if (eyespy_try_fullstep(&vel, &fulledge1, &fulledge2) == CDRESULT_COLLISION) { - if (eyespy_try_quarterstep(&vel, &fulledge1, &fulledge2, &quarteredge1, &quarteredge2) != CDRESULT_COLLISION) { - if (eyespy_try_move_to_edge(&vel, &fulledge1, &fulledge2) <= CDRESULT_COLLISION) { - eyespy_try_grind(&vel, &fulledge1, &fulledge2); + if (eyespy_try_fulldelta(&vel, &edgea_vtx1, &edgea_vtx2) == CDRESULT_COLLISION) { + if (eyespy_try_quarterdelta(&vel, &edgea_vtx1, &edgea_vtx2, &edgeb_vtx1, &edgeb_vtx2) != CDRESULT_COLLISION) { + if (eyespy_try_slide_along_edge(&vel, &edgea_vtx1, &edgea_vtx2) <= CDRESULT_COLLISION) { + eyespy_try_slide_along_corner(&vel, &edgea_vtx1, &edgea_vtx2); } } else { - eyespy_try_quarterstep(&vel, &quarteredge1, &quarteredge2, &throwawayedge1, &throwawayedge2); + eyespy_try_quarterdelta(&vel, &edgeb_vtx1, &edgeb_vtx2, &edgec_vtx1, &edgec_vtx2); - if (eyespy_try_move_to_edge(&vel, &quarteredge1, &quarteredge2) <= CDRESULT_COLLISION - && eyespy_try_move_to_edge(&vel, &fulledge1, &fulledge2) <= CDRESULT_COLLISION - && eyespy_try_grind(&vel, &quarteredge1, &quarteredge2) <= CDRESULT_COLLISION) { - eyespy_try_grind(&vel, &fulledge1, &fulledge2); + if (eyespy_try_slide_along_edge(&vel, &edgeb_vtx1, &edgeb_vtx2) <= CDRESULT_COLLISION + && eyespy_try_slide_along_edge(&vel, &edgea_vtx1, &edgea_vtx2) <= CDRESULT_COLLISION + && eyespy_try_slide_along_corner(&vel, &edgeb_vtx1, &edgeb_vtx2) <= CDRESULT_COLLISION) { + eyespy_try_slide_along_corner(&vel, &edgea_vtx1, &edgea_vtx2); } } } @@ -634,7 +634,7 @@ bool eyespy_try_launch(void) player_set_perim_enabled(g_Vars.currentplayer->prop, false); - if (insafe || !cd_exam_los08(&testfrompos, g_Vars.currentplayer->prop->rooms, + if (insafe || !cd_test_los_oobok_findclosest(&testfrompos, g_Vars.currentplayer->prop->rooms, &g_Vars.currentplayer->eyespy->prop->pos, CDTYPE_ALL, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2 | GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT)) { @@ -1143,7 +1143,7 @@ void eyespy_process_input(bool allowbuttons) g_EyespyPickup = false; } - cdresult = cd_test_los05(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, + cdresult = cd_test_los_oobfail(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &g_Vars.currentplayer->eyespy->prop->pos, g_Vars.currentplayer->eyespy->prop->rooms, CDTYPE_DOORS | CDTYPE_BG, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); diff --git a/src/game/bondgrab.c b/src/game/bondgrab.c index 7ede6a7b5..f757bafb1 100644 --- a/src/game/bondgrab.c +++ b/src/game/bondgrab.c @@ -27,7 +27,7 @@ u32 var8009de8c; bool var80070e80 = false; -void bgrab0f0ce0bc(struct coord *arg0); +void bgrab_resolve_posdelta(struct coord *arg0); void bgrab_init(void) { @@ -98,12 +98,12 @@ void bgrab_init(void) obj->hidden |= OBJHFLAG_GRABBED; if (obj->flags3 & OBJFLAG3_GEOCYL) { - cdresult = cd_000276c8_cyl(obj->geocyl, + cdresult = cd_cyl_collides_with_cyl_laterally(obj->geocyl, g_Vars.currentplayer->prop->pos.x, g_Vars.currentplayer->prop->pos.z, VERSION >= VERSION_NTSC_1_0 ? 45 : 40, 0, 0); } else { - cdresult = cd_000274e0_block(obj->geoblock, + cdresult = cd_block_collides_with_cyl_laterally(obj->geoblock, g_Vars.currentplayer->prop->pos.x, g_Vars.currentplayer->prop->pos.z, VERSION >= VERSION_NTSC_1_0 ? 45 : 40, 0, 0); @@ -222,7 +222,7 @@ void bgrab0f0ccbf0(struct coord *delta, f32 angle, struct defaultobj *obj) cd_get_edge(&sp68, &sp5c, 227, "bondgrab.c"); #endif - if (cd_get_saved_pos(&sp50, &sp44)) { + if (cd_get_block_edge(&sp50, &sp44)) { sp44.x -= sp50.x; sp44.y -= sp50.y; sp44.z -= sp50.z; @@ -300,7 +300,7 @@ bool bgrab_try_move_upwards(f32 y) ymin -= 0.1f; - result = cd_test_volume(&newpos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, + result = cd_test_volume_simple(&newpos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); @@ -315,7 +315,7 @@ bool bgrab_try_move_upwards(f32 y) return result; } -s32 bgrab_calculate_new_position(struct coord *delta, f32 angle, bool arg2) +s32 bgrab_try_delta_nopush(struct coord *delta, f32 angle, bool arg2) { s32 cdresult = CDRESULT_NOCOLLISION; s32 i; @@ -369,13 +369,13 @@ s32 bgrab_calculate_new_position(struct coord *delta, f32 angle, bool arg2) ismoving = true; - cdresult = cd_exam_cyl_move05(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, - &pos, rooms, CDTYPE_ALL, true, + cdresult = cd_test_cylmove_oobfail_findclosest(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, + &pos, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); if (cdresult == CDRESULT_NOCOLLISION) { - cdresult = cd_exam_cyl_move01(&g_Vars.currentplayer->prop->pos, &pos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, + cdresult = cd_test_volume_closestedge(&g_Vars.currentplayer->prop->pos, &pos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); } @@ -538,9 +538,9 @@ s32 bgrab_calculate_new_position(struct coord *delta, f32 angle, bool arg2) return cdresult; } -bool bgrab_calculate_new_positiont_with_push(struct coord *delta, f32 angle, bool arg2) +bool bgrab_try_delta(struct coord *delta, f32 angle, bool arg2) { - s32 result = bgrab_calculate_new_position(delta, angle, arg2); + s32 result = bgrab_try_delta_nopush(delta, angle, arg2); if (result != CDRESULT_NOCOLLISION) { struct prop *obstacle = cd_get_obstacle_prop(); @@ -585,7 +585,7 @@ bool bgrab_calculate_new_positiont_with_push(struct coord *delta, f32 angle, boo } if (moved) { - result = bgrab_calculate_new_position(delta, angle, arg2); + result = bgrab_try_delta_nopush(delta, angle, arg2); } } } @@ -597,13 +597,13 @@ bool bgrab_calculate_new_positiont_with_push(struct coord *delta, f32 angle, boo return result; } -bool bgrab0f0cdb04(f32 angle, bool arg2) +bool bgrab_try_turndelta(f32 angle, bool arg2) { struct coord coord = {0, 0, 0}; bool result; g_Vars.currentplayer->grabbeddoextra = true; - result = bgrab_calculate_new_positiont_with_push(&coord, angle, arg2); + result = bgrab_try_delta(&coord, angle, arg2); g_Vars.currentplayer->grabbeddoextra = false; return result; @@ -654,9 +654,9 @@ bool bgrab0f0cdb68(f32 angle) f22 = -f22; } - if (g_CdHasSavedBlock) { - for (i = 0; i < g_CdSavedBlock.header.numvertices; i++) { - f0 = (g_CdSavedBlock.vertices[i][0] - spa4.f[0]) * f20 + (g_CdSavedBlock.vertices[i][1] - spa4.f[2]) * f22; + if (g_CdHasBlock) { + for (i = 0; i < g_CdBlock.header.numvertices; i++) { + f0 = (g_CdBlock.vertices[i][0] - spa4.f[0]) * f20 + (g_CdBlock.vertices[i][1] - spa4.f[2]) * f22; if (f0 < 0.0f) { f0 = -f0; @@ -667,7 +667,7 @@ bool bgrab0f0cdb68(f32 angle) } } } else { - if (cd_get_saved_pos(&sp8c, &sp80)) { + if (cd_get_block_edge(&sp8c, &sp80)) { f32 f0 = (sp8c.f[0] - spa4.f[0]) * f20 + f22 * (sp8c.f[2] - spa4.f[2]); f32 f16 = (sp80.f[0] - spa4.f[0]) * f20 + f22 * (sp80.f[2] - spa4.f[2]); @@ -709,30 +709,30 @@ bool bgrab0f0cdb68(f32 angle) sp54.y = 0.0f; sp54.z = sp60 * f22 * 1.01f; - bgrab0f0ce0bc(&sp54); + bgrab_resolve_posdelta(&sp54); - return bgrab0f0cdb04(angle, true); + return bgrab_try_turndelta(angle, true); } return false; } -void bgrab0f0cdef0(void) +void bgrab_resolve_turndelta(void) { if (g_Vars.lvupdate240 > 0) { f32 angle = g_Vars.currentplayer->speedtheta * g_Vars.lvupdate60freal * 0.017450513318181f * 3.5f; - if (bgrab0f0cdb04(angle, true) == 0) { + if (bgrab_try_turndelta(angle, true) == CDRESULT_COLLISION) { bgrab0f0cdb68(angle); } } } -bool bgrab0f0cdf64(struct coord *delta, struct coord *arg1, struct coord *arg2) +bool bgrab_try_fulldelta(struct coord *delta, struct coord *arg1, struct coord *arg2) { - bool result = bgrab_calculate_new_positiont_with_push(delta, 0, true); + bool result = bgrab_try_delta(delta, 0, true); - if (!result) { + if (result == CDRESULT_COLLISION) { #if VERSION >= VERSION_NTSC_1_0 cd_get_edge(arg1, arg2, 815, "bondgrab.c"); #else @@ -743,7 +743,7 @@ bool bgrab0f0cdf64(struct coord *delta, struct coord *arg1, struct coord *arg2) return result; } -s32 bgrab0f0cdfbc(struct coord *delta, struct coord *arg1, struct coord *arg2) +s32 bgrab_try_slide_along_edge(struct coord *delta, struct coord *arg1, struct coord *arg2) { if (arg1->f[0] != arg2->f[0] || arg1->f[2] != arg2->f[2]) { f32 tmp; @@ -764,29 +764,27 @@ s32 bgrab0f0cdfbc(struct coord *delta, struct coord *arg1, struct coord *arg2) sp24.y = 0; sp24.z = sp30.z * tmp; - return bgrab_calculate_new_positiont_with_push(&sp24, 0, true); + return bgrab_try_delta(&sp24, 0, true); } - return -1; + return CDRESULT_ERROR; } -void bgrab0f0ce0bc(struct coord *arg0) +void bgrab_resolve_posdelta(struct coord *arg0) { struct coord a; struct coord b; - s32 value = bgrab0f0cdf64(arg0, &a, &b); + s32 result = bgrab_try_fulldelta(arg0, &a, &b); - if (value == 0) { - value = bgrab0f0cdfbc(arg0, &a, &b); + if (result == CDRESULT_COLLISION) { + result = bgrab_try_slide_along_edge(arg0, &a, &b); - if (value <= 0) { - value = 1; + if (result <= CDRESULT_COLLISION) { + result = CDRESULT_NOCOLLISION; } } - if (value) { - // empty - } + if (result); } void bgrab_update_prev_pos(void) @@ -815,11 +813,11 @@ void bgrab_update_vertical(void) s32 inlift; struct prop *lift = NULL; f32 dist; - f32 f14; - f32 fVar3; + f32 ground; + f32 sumground; f32 f0; - f14 = cd_find_ground_info_at_cyl(&g_Vars.currentplayer->prop->pos, + ground = cd_find_ground_at_cyl_ctfril(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->bond2.radius, g_Vars.currentplayer->prop->rooms, &g_Vars.currentplayer->floorcol, @@ -827,8 +825,8 @@ void bgrab_update_vertical(void) &g_Vars.currentplayer->floorflags, &g_Vars.currentplayer->floorroom, &inlift, &lift); - if (f14 < -30000) { - f14 = -30000; + if (ground < -30000) { + ground = -30000; } if (g_Vars.currentplayer->inlift && inlift) { @@ -836,7 +834,7 @@ void bgrab_update_vertical(void) dist = g_Vars.currentplayer->liftground - g_Vars.currentplayer->vv_manground; if (dist < 1.0f && dist > -1.0f) { - f0 = f14 - g_Vars.currentplayer->vv_ground; + f0 = ground - g_Vars.currentplayer->vv_ground; g_Vars.currentplayer->vv_ground += f0; g_Vars.currentplayer->vv_manground += f0; g_Vars.currentplayer->sumground = g_Vars.currentplayer->vv_manground / (PAL ? 0.054400026798248f : 0.045499980449677f); @@ -849,18 +847,18 @@ void bgrab_update_vertical(void) g_Vars.currentplayer->inlift = inlift; if (inlift) { - g_Vars.currentplayer->liftground = f14; + g_Vars.currentplayer->liftground = ground; } g_Vars.currentplayer->lift = lift; - g_Vars.currentplayer->vv_ground = f14; + g_Vars.currentplayer->vv_ground = ground; g_Vars.currentplayer->vv_height = (g_Vars.currentplayer->headpos.y / g_Vars.currentplayer->standheight) * g_Vars.currentplayer->vv_eyeheight; - fVar3 = g_Vars.currentplayer->vv_manground / (PAL ? 0.054400026798248f : 0.045499980449677f); + sumground = g_Vars.currentplayer->vv_manground / (PAL ? 0.054400026798248f : 0.045499980449677f); for (i = 0; i < g_Vars.lvupdate240; i++) { - fVar3 = (PAL ? 0.94559997320175f : 0.9545f) * fVar3 + g_Vars.currentplayer->vv_ground; + sumground = (PAL ? 0.94559997320175f : 0.9545f) * sumground + g_Vars.currentplayer->vv_ground; } f0 = g_Vars.currentplayer->vv_height; @@ -869,7 +867,7 @@ void bgrab_update_vertical(void) f0 = 30; } - tmp = fVar3 * (PAL ? 0.054400026798248f : 0.045499980449677f) + f0 - g_Vars.currentplayer->prop->pos.y; + tmp = sumground * (PAL ? 0.054400026798248f : 0.045499980449677f) + f0 - g_Vars.currentplayer->prop->pos.y; #if VERSION >= VERSION_NTSC_1_0 if (g_Vars.currentplayer->prop->pos.y + tmp < g_Vars.currentplayer->vv_ground + 10.0f) { @@ -878,8 +876,8 @@ void bgrab_update_vertical(void) #endif if (bgrab_try_move_upwards(tmp)) { - g_Vars.currentplayer->sumground = fVar3; - g_Vars.currentplayer->vv_manground = fVar3 * (PAL ? 0.054400026798248f : 0.045499980449677f); + g_Vars.currentplayer->sumground = sumground; + g_Vars.currentplayer->vv_manground = sumground * (PAL ? 0.054400026798248f : 0.045499980449677f); } if ((g_Vars.currentplayer->floorflags & GEOFLAG_DIE) && @@ -1104,7 +1102,7 @@ void bgrab0f0ce924(void) sp74.z += (g_Vars.currentplayer->bond2.theta.f[2] * g_Vars.currentplayer->speedforwards + (g_Vars.currentplayer->bond2.theta.f[0] * g_Vars.currentplayer->speedsideways)) * g_Vars.lvupdate60freal * 10.0f; } - bgrab0f0ce0bc(&sp74); + bgrab_resolve_posdelta(&sp74); xdelta = g_Vars.currentplayer->prop->pos.f[0] - g_Vars.currentplayer->bondprevpos.f[0]; zdelta = g_Vars.currentplayer->prop->pos.f[2] - g_Vars.currentplayer->bondprevpos.f[2]; @@ -1162,7 +1160,7 @@ void bgrab0f0ce924(void) void bgrab_tick(void) { bgrab_update_prev_pos(); - bgrab0f0cdef0(); + bgrab_resolve_turndelta(); bmove_update_look(); bgrab0f0ce924(); bgrab_onmoved(); @@ -1219,7 +1217,7 @@ void bgrab_tick(void) if (g_Vars.currentplayer->vv_ground <= -30000 || ydiff < -100 || ydiff > 100 || g_Vars.currentplayer->vv_ground < g_Vars.currentplayer->vv_manground - 50 - || !cd_test_los05(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, + || !cd_test_los_oobfail(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &g_Vars.currentplayer->grabbedprop->pos, g_Vars.currentplayer->grabbedprop->rooms, CDTYPE_ALL, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT)) { diff --git a/src/game/bondgun.c b/src/game/bondgun.c index 49d8ef940..1238a272a 100644 --- a/src/game/bondgun.c +++ b/src/game/bondgun.c @@ -4354,7 +4354,7 @@ void bgun_create_thrown_projectile(s32 handnum, struct gset *gset) player_set_perim_enabled(playerprop, false); - if (cd_test_los11(&playerprop->pos, playerprop->rooms, &muzzlepos, spawnrooms, CDTYPE_ALL) != CDRESULT_COLLISION) { + if (cd_test_los_oobok_getfinalroom_autoflags(&playerprop->pos, playerprop->rooms, &muzzlepos, spawnrooms, CDTYPE_ALL) != CDRESULT_COLLISION) { spawnpos.x = muzzlepos.x; spawnpos.y = muzzlepos.y; spawnpos.z = muzzlepos.z; diff --git a/src/game/bondmove.c b/src/game/bondmove.c index e837014c6..0ae63c185 100644 --- a/src/game/bondmove.c +++ b/src/game/bondmove.c @@ -432,10 +432,10 @@ f32 bmove_calculate_lookahead(void) sp150.y = spf0.y + sp100.y * 400; sp150.z = spf0.z + sp100.z * 400; - if (cd_exam_los08(&spf0, spe0, &sp150, + if (cd_test_los_oobok_findclosest(&spf0, spe0, &sp150, CDTYPE_BG | CDTYPE_CLOSEDDOORS, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2 | GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT) == CDRESULT_COLLISION) { - cd_get_pos(&sp150, 455, "bondmove.c"); + cd_get_obstacle_pos(&sp150, 455, "bondmove.c"); flags = cd_get_geo_flags(); sp160 = sqrtf((sp150.x - spf0.x) * (sp150.x - spf0.x) @@ -462,9 +462,9 @@ f32 bmove_calculate_lookahead(void) if ( #if VERSION >= VERSION_NTSC_1_0 - cd_find_floor_room_y_colour_flags_at_pos(&spbc, sp80, &sp78, NULL, NULL) > 0 + cd_find_room_at_pos_ycf(&spbc, sp80, &sp78, NULL, NULL) > 0 #else - cd_find_floor_room_y_colour_flags_at_pos(&spbc, sp80, &sp78, NULL) > 0 + cd_find_room_at_pos_ycf(&spbc, sp80, &sp78, NULL) > 0 #endif && sp78 - ground < 200 && sp78 - ground > -200) { diff --git a/src/game/bondwalk.c b/src/game/bondwalk.c index d42240098..8a3ffad3d 100644 --- a/src/game/bondwalk.c +++ b/src/game/bondwalk.c @@ -27,7 +27,7 @@ #include "data.h" #include "types.h" -bool bwalk_calculate_new_position_with_push(struct coord *delta, f32 rotateamount, bool apply, f32 extrawidth, s32 types); +s32 bwalk_try_delta(struct coord *delta, f32 rotateamount, bool apply, f32 extrawidth, s32 types); void bwalk_update_crouch_offset_real(void); void bwalk_init(void) @@ -114,7 +114,7 @@ void bwalk_init(void) delta.z = g_Vars.currentplayer->walkinitpos.z - g_Vars.currentplayer->prop->pos.z; prop_set_perim_enabled(g_Vars.currentplayer->hoverbike, false); - bwalk_calculate_new_position_with_push(&delta, 0, true, 0, CDTYPE_ALL); + bwalk_try_delta(&delta, 0, true, 0, CDTYPE_ALL); prop_set_perim_enabled(g_Vars.currentplayer->hoverbike, true); } else if (prevmode != MOVEMODE_GRAB && prevmode != MOVEMODE_WALK) { g_Vars.currentplayer->moveinitspeed.x = 0; @@ -216,7 +216,7 @@ s32 bwalk_try_move_upwards(f32 amount) ymin -= 0.1f; - result = cd_test_volume(&newpos, radius, rooms, types, CHECKVERTICAL_YES, + result = cd_test_volume_simple(&newpos, radius, rooms, types, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); @@ -233,14 +233,14 @@ s32 bwalk_try_move_upwards(f32 amount) return result; } -bool bwalk_calculate_new_position(struct coord *vel, f32 rotateamount, bool apply, f32 extrawidth, s32 checktypes) +s32 bwalk_try_delta_nopush(struct coord *deltapos, f32 rotateamount, bool apply, f32 extrawidth, s32 checktypes) { s32 result = CDRESULT_NOCOLLISION; f32 halfradius; struct coord dstpos; RoomNum dstrooms[8]; bool copyrooms = false; - RoomNum sp64[22]; + RoomNum throughrooms[22]; s32 types; f32 ymax; f32 ymin; @@ -259,24 +259,38 @@ bool bwalk_calculate_new_position(struct coord *vel, f32 rotateamount, bool appl dstpos.y = g_Vars.currentplayer->prop->pos.y; dstpos.z = g_Vars.currentplayer->prop->pos.z; - if (vel->x || vel->y || vel->z) { + if (deltapos->x || deltapos->y || deltapos->z) { if (g_Vars.currentplayer->ontank) { prop_set_perim_enabled(g_Vars.currentplayer->ontank, false); } prop_set_perim_enabled(g_Vars.currentplayer->prop, false); - dstpos.x += vel->x; - dstpos.y += vel->y; - dstpos.z += vel->z; + dstpos.x += deltapos->x; + dstpos.y += deltapos->y; + dstpos.z += deltapos->z; types = g_Vars.bondcollisions ? checktypes : CDTYPE_BG; player_get_bbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin); radius += extrawidth; + /** + * Populate dstrooms with the room that dstpos is in, using portals to trace the path. + * If that fails: + * If dstpos is in the bounding box of the last portalled room, use that room. + * If that fails: + * Search all rooms for a bounding box that covers dstpos and use those rooms. + * If that fails: + * Search all rooms for a bounding box that is underneath dstpos and use those rooms. + * If that fails: + * Use the player's previous rooms list. + * + * The throughrooms list will contain all rooms that the portal test went through, + * as well as any rooms in dstrooms. + */ los_find_intersecting_rooms_exhaustive(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, - &dstpos, dstrooms, sp64, 20); + &dstpos, dstrooms, throughrooms, 20); #if VERSION < VERSION_NTSC_1_0 for (i = 0; dstrooms[i] != -1; i++) { @@ -288,33 +302,40 @@ bool bwalk_calculate_new_position(struct coord *vel, f32 rotateamount, bool appl } #endif + /** + * If the dstpos + player's bounding box overlaps a portal, + * include that portal's rooms in dstrooms. + * In this case the bounding box is 50cm in each direction. + */ bmove_find_entered_rooms_by_pos(g_Vars.currentplayer, &dstpos, dstrooms); copyrooms = true; - // Check if the player is moving at least half their radius along the - // X or Z axis in a single frame. If less, only do a collision check for - // the dst position. If more, do a halfway check too? + /** + * Check if the player is moving at least half their radius along the X or Z axis in a single frame. + * If less, only do a cylinder volume test at the dst position. + * If more, do a cylinder move test as well. + */ xdiff = dstpos.x - g_Vars.currentplayer->prop->pos.x; zdiff = dstpos.z - g_Vars.currentplayer->prop->pos.z; halfradius = radius * 0.5f; if (xdiff > halfradius || zdiff > halfradius || xdiff < -halfradius || zdiff < -halfradius) { - result = cd_exam_cyl_move06(&g_Vars.currentplayer->prop->pos, + result = cd_test_cylmove_oobfail_findclosest_finddist(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, - &dstpos, dstrooms, radius, types, 1, + &dstpos, dstrooms, radius, types, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); if (result == CDRESULT_NOCOLLISION) { - result = cd_exam_cyl_move02(&g_Vars.currentplayer->prop->pos, - &dstpos, radius, dstrooms, types, true, + result = cd_test_volume_fromdir(&g_Vars.currentplayer->prop->pos, + &dstpos, radius, dstrooms, types, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); } } else { - result = cd_exam_cyl_move02(&g_Vars.currentplayer->prop->pos, - &dstpos, radius, sp64, types, true, + result = cd_test_volume_fromdir(&g_Vars.currentplayer->prop->pos, + &dstpos, radius, throughrooms, types, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y); } @@ -354,9 +375,9 @@ bool bwalk_calculate_new_position(struct coord *vel, f32 rotateamount, bool appl return result; } -bool bwalk_calculate_new_position_with_push(struct coord *delta, f32 rotateamount, bool apply, f32 extrawidth, s32 types) +s32 bwalk_try_delta(struct coord *delta, f32 rotateamount, bool apply, f32 extrawidth, s32 types) { - s32 result = bwalk_calculate_new_position(delta, rotateamount, apply, extrawidth, types); + s32 result = bwalk_try_delta_nopush(delta, rotateamount, apply, extrawidth, types); if (result != CDRESULT_NOCOLLISION) { struct prop *obstacle = cd_get_obstacle_prop(); @@ -448,7 +469,7 @@ bool bwalk_calculate_new_position_with_push(struct coord *delta, f32 rotateamoun chr_detect_rooms(chr); model_set_root_position(chr->model, &newpos); - result = bwalk_calculate_new_position(delta, rotateamount, apply, extrawidth, types); + result = bwalk_try_delta_nopush(delta, rotateamount, apply, extrawidth, types); } } } @@ -489,7 +510,7 @@ bool bwalk_calculate_new_position_with_push(struct coord *delta, f32 rotateamoun } if (moved) { - result = bwalk_calculate_new_position(delta, rotateamount, apply, extrawidth, types); + result = bwalk_try_delta_nopush(delta, rotateamount, apply, extrawidth, types); } } } @@ -502,33 +523,35 @@ bool bwalk_calculate_new_position_with_push(struct coord *delta, f32 rotateamoun return result; } -s32 bwalk0f0c4764(struct coord *delta, struct coord *arg1, struct coord *arg2, s32 types) +s32 bwalk_try_fulldelta(struct coord *delta, struct coord *edge1, struct coord *edge2, s32 types) { - s32 result = bwalk_calculate_new_position_with_push(delta, 0, true, 0, types); + s32 result = bwalk_try_delta(delta, 0, true, 0, types); if (result == CDRESULT_COLLISION) { #if VERSION >= VERSION_NTSC_1_0 - cd_get_edge(arg1, arg2, 607, "bondwalk.c"); + cd_get_edge(edge1, edge2, 607, "bondwalk.c"); #else - cd_get_edge(arg1, arg2, 602, "bondwalk.c"); + cd_get_edge(edge1, edge2, 602, "bondwalk.c"); #endif } return result; } -s32 bwalk0f0c47d0(struct coord *a, struct coord *b, struct coord *c, - struct coord *d, struct coord *e, s32 types) +s32 bwalk_try_quarterdelta(struct coord *posdelta, struct coord *prevedge1, struct coord *prevedge2, + struct coord *edge1, struct coord *edge2, s32 types) { struct coord quarter; bool result; if (cd_has_distance()) { - f32 mult = cd_get_distance(); - quarter.x = a->x * mult * 0.25f; - quarter.y = a->y * mult * 0.25f; - quarter.z = a->z * mult * 0.25f; - result = bwalk_calculate_new_position_with_push(&quarter, 0, true, 0, types); + f32 distance = cd_get_distance(); + + quarter.x = posdelta->x * distance / 4.0f; + quarter.y = posdelta->y * distance / 4.0f; + quarter.z = posdelta->z * distance / 4.0f; + + result = bwalk_try_delta(&quarter, 0, true, 0, types); if (result == CDRESULT_NOCOLLISION) { return CDRESULT_NOCOLLISION; @@ -536,17 +559,17 @@ s32 bwalk0f0c47d0(struct coord *a, struct coord *b, struct coord *c, if (result == CDRESULT_COLLISION) { #if VERSION >= VERSION_NTSC_1_0 - cd_get_edge(d, e, 635, "bondwalk.c"); + cd_get_edge(edge1, edge2, 635, "bondwalk.c"); #else - cd_get_edge(d, e, 630, "bondwalk.c"); + cd_get_edge(edge1, edge2, 630, "bondwalk.c"); #endif - if (b->x != d->x - || b->y != d->y - || b->z != d->z - || c->x != e->x - || c->y != e->y - || c->z != e->z) { + if (prevedge1->x != edge1->x + || prevedge1->y != edge1->y + || prevedge1->z != edge1->z + || prevedge2->x != edge2->x + || prevedge2->y != edge2->y + || prevedge2->z != edge2->z) { return CDRESULT_COLLISION; } } @@ -555,38 +578,45 @@ s32 bwalk0f0c47d0(struct coord *a, struct coord *b, struct coord *c, return CDRESULT_ERROR; } -s32 bwalk0f0c494c(struct coord *a, struct coord *b, struct coord *c, s32 types) +/** + * This test fails when sliding past the corner of Jo's desk. + * When this happens, the caller uses bwalk_try_slide_along_corner. + * + * Maybe the edge on the other side of the corner interferes with the + * collision test due to float precision? + */ +s32 bwalk_try_slide_along_edge(struct coord *deltapos, struct coord *edge_vtx1, struct coord *edge_vtx2, s32 types) { - if (b->f[0] != c->f[0] || b->f[2] != c->f[2]) { + if (edge_vtx1->f[0] != edge_vtx2->f[0] || edge_vtx1->f[2] != edge_vtx2->f[2]) { f32 tmp; - struct coord sp38; - struct coord sp2c; + struct coord edgedir; + struct coord newdeltapos; - sp38.x = c->x - b->x; - sp38.y = 0; - sp38.z = c->z - b->z; + edgedir.x = edge_vtx2->x - edge_vtx1->x; + edgedir.y = 0; + edgedir.z = edge_vtx2->z - edge_vtx1->z; - tmp = sqrtf(sp38.f[0] * sp38.f[0] + sp38.f[2] * sp38.f[2]); + tmp = sqrtf(edgedir.f[0] * edgedir.f[0] + edgedir.f[2] * edgedir.f[2]); - sp38.x *= 1.0f / tmp; - sp38.z *= 1.0f / tmp; + edgedir.x *= 1.0f / tmp; + edgedir.z *= 1.0f / tmp; - tmp = a->f[0] * sp38.f[0] + a->f[2] * sp38.f[2]; + tmp = deltapos->f[0] * edgedir.f[0] + deltapos->f[2] * edgedir.f[2]; - sp2c.x = sp38.x * tmp; - sp2c.y = 0; - sp2c.z = sp38.z * tmp; + newdeltapos.x = edgedir.x * tmp; + newdeltapos.y = 0; + newdeltapos.z = edgedir.z * tmp; - return bwalk_calculate_new_position_with_push(&sp2c, 0, true, 0, types); + return bwalk_try_delta(&newdeltapos, 0, true, 0, types); } - return -1; + return CDRESULT_ERROR; } -s32 bwalk0f0c4a5c(struct coord *arg0, struct coord *arg1, struct coord *arg2, s32 types) +s32 bwalk_try_slide_along_corner(struct coord *deltapos, struct coord *edgevtx1, struct coord *edgevtx2, s32 types) { struct coord sp34; - struct coord sp28; + struct coord newdeltapos; f32 ymax; f32 ymin; f32 tmp; @@ -594,68 +624,68 @@ s32 bwalk0f0c4a5c(struct coord *arg0, struct coord *arg1, struct coord *arg2, s3 player_get_bbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin); - sp34.x = arg1->x - (g_Vars.currentplayer->prop->pos.x + arg0->f[0]); - sp34.z = arg1->z - (g_Vars.currentplayer->prop->pos.z + arg0->f[2]); + sp34.x = edgevtx1->x - (g_Vars.currentplayer->prop->pos.x + deltapos->f[0]); + sp34.z = edgevtx1->z - (g_Vars.currentplayer->prop->pos.z + deltapos->f[2]); if (sp34.f[0] * sp34.f[0] + sp34.f[2] * sp34.f[2] <= radius * radius) { - if (arg1->f[0] != g_Vars.currentplayer->prop->pos.f[0] || arg1->f[2] != g_Vars.currentplayer->prop->pos.f[2]) { - sp34.x = -(arg1->z - g_Vars.currentplayer->prop->pos.z); + if (edgevtx1->f[0] != g_Vars.currentplayer->prop->pos.f[0] || edgevtx1->f[2] != g_Vars.currentplayer->prop->pos.f[2]) { + sp34.x = -(edgevtx1->z - g_Vars.currentplayer->prop->pos.z); sp34.y = 0; - sp34.z = arg1->x - g_Vars.currentplayer->prop->pos.x; + sp34.z = edgevtx1->x - g_Vars.currentplayer->prop->pos.x; tmp = sqrtf(sp34.f[0] * sp34.f[0] + sp34.f[2] * sp34.f[2]); sp34.x = sp34.f[0] * (1.0f / tmp); sp34.z = sp34.f[2] * (1.0f / tmp); - tmp = arg0->f[0] * sp34.f[0] + arg0->f[2] * sp34.f[2]; + tmp = deltapos->f[0] * sp34.f[0] + deltapos->f[2] * sp34.f[2]; sp34.x = sp34.x * tmp; sp34.z = sp34.z * tmp; - sp28.x = sp34.x; - sp28.y = 0; - sp28.z = sp34.z; + newdeltapos.x = sp34.x; + newdeltapos.y = 0; + newdeltapos.z = sp34.z; - if (bwalk_calculate_new_position_with_push(&sp28, 0, true, 0, types) == CDRESULT_NOCOLLISION) { - return true; + if (bwalk_try_delta(&newdeltapos, 0, true, 0, types) == CDRESULT_NOCOLLISION) { + return CDRESULT_NOCOLLISION; } } } else { - sp34.x = arg2->x - (g_Vars.currentplayer->prop->pos.x + arg0->f[0]); - sp34.z = arg2->z - (g_Vars.currentplayer->prop->pos.z + arg0->f[2]); + sp34.x = edgevtx2->x - (g_Vars.currentplayer->prop->pos.x + deltapos->f[0]); + sp34.z = edgevtx2->z - (g_Vars.currentplayer->prop->pos.z + deltapos->f[2]); if (sp34.f[0] * sp34.f[0] + sp34.f[2] * sp34.f[2] <= radius * radius) { - if (arg2->f[0] != g_Vars.currentplayer->prop->pos.f[0] || arg2->f[2] != g_Vars.currentplayer->prop->pos.f[2]) { - sp34.x = -(arg2->z - g_Vars.currentplayer->prop->pos.z); + if (edgevtx2->f[0] != g_Vars.currentplayer->prop->pos.f[0] || edgevtx2->f[2] != g_Vars.currentplayer->prop->pos.f[2]) { + sp34.x = -(edgevtx2->z - g_Vars.currentplayer->prop->pos.z); sp34.y = 0; - sp34.z = arg2->x - g_Vars.currentplayer->prop->pos.x; + sp34.z = edgevtx2->x - g_Vars.currentplayer->prop->pos.x; tmp = sqrtf(sp34.f[0] * sp34.f[0] + sp34.f[2] * sp34.f[2]); sp34.x = sp34.f[0] * (1.0f / tmp); sp34.z = sp34.f[2] * (1.0f / tmp); - tmp = arg0->f[0] * sp34.f[0] + arg0->f[2] * sp34.f[2]; + tmp = deltapos->f[0] * sp34.f[0] + deltapos->f[2] * sp34.f[2]; sp34.x = sp34.x * tmp; sp34.z = sp34.z * tmp; - sp28.x = sp34.x; - sp28.y = 0; - sp28.z = sp34.z; + newdeltapos.x = sp34.x; + newdeltapos.y = 0; + newdeltapos.z = sp34.z; - if (bwalk_calculate_new_position_with_push(&sp28, 0, true, 0, types) == CDRESULT_NOCOLLISION) { - return true; + if (bwalk_try_delta(&newdeltapos, 0, true, 0, types) == CDRESULT_NOCOLLISION) { + return CDRESULT_NOCOLLISION; } } } } - return false; + return CDRESULT_COLLISION; } -void bwalk0f0c4d98(void) +void bwalk_stub(void) { // empty } @@ -745,7 +775,7 @@ void bwalk_update_vertical(void) if (g_Vars.antiplayernum >= 0 && g_Vars.currentplayer == g_Vars.anti && g_Vars.currentplayer->bond2.radius != 30 - && cd_test_volume(&g_Vars.currentplayer->prop->pos, 30, g_Vars.currentplayer->prop->rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y)) { + && cd_test_volume_simple(&g_Vars.currentplayer->prop->pos, 30, g_Vars.currentplayer->prop->rooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - g_Vars.currentplayer->prop->pos.y, ymin - g_Vars.currentplayer->prop->pos.y)) { g_Vars.currentplayer->prop->chr->radius = 30; g_Vars.currentplayer->bond2.radius = 30; radius = 30; @@ -784,7 +814,7 @@ void bwalk_update_vertical(void) rooms_copy(g_Vars.currentplayer->prop->rooms, rooms); bmove_find_entered_rooms_by_pos(g_Vars.currentplayer, &testpos, rooms); - ground = cd_find_ground_info_at_cyl(&testpos, g_Vars.currentplayer->bond2.radius, rooms, + ground = cd_find_ground_at_cyl_ctfril(&testpos, g_Vars.currentplayer->bond2.radius, rooms, &g_Vars.currentplayer->floorcol, &g_Vars.currentplayer->floortype, &g_Vars.currentplayer->floorflags, &g_Vars.currentplayer->floorroom, &newinlift, &lift); @@ -1217,53 +1247,73 @@ void bwalk_update_theta(void) rotateamount = g_Vars.currentplayer->speedtheta * mult * g_Vars.lvupdate60freal * 0.0174505133f * 3.5f; - bwalk_calculate_new_position_with_push(&delta, rotateamount, true, 0, CDTYPE_ALL); + bwalk_try_delta(&delta, rotateamount, true, 0, CDTYPE_ALL); } -void bwalk0f0c63bc(struct coord *arg0, u32 arg1, s32 types) +/** + * Given a delta position (the desired distance to move in one frame), + * figure out the actual final position and apply it. + */ +void bwalk_resolve_posdelta(struct coord *deltapos, bool notrleaning, s32 cdtypes) { - struct coord sp100; - struct coord sp88; + struct coord edgea_vtx1; + struct coord edgea_vtx2; g_Vars.currentplayer->bondonturret = false; g_Vars.currentplayer->autocrouchpos = CROUCHPOS_STAND; - bwalk0f0c4d98(); + bwalk_stub(); - if (bwalk0f0c4764(arg0, &sp100, &sp88, types) == CDRESULT_COLLISION) { - struct coord sp76; - struct coord sp64; + // Try to move the delta's full distance. If there's something in the way, + // the vertices of the obstacle's edge will be written to the edge pointers. + if (bwalk_try_fulldelta(deltapos, &edgea_vtx1, &edgea_vtx2, cdtypes) == CDRESULT_COLLISION) { + struct coord edgeb_vtx1; + struct coord edgeb_vtx2; + s32 result; + struct coord edgec_vtx1; + struct coord edgec_vtx2; - s32 result = bwalk0f0c47d0(arg0, &sp100, &sp88, &sp76, &sp64, types); + // Take the distance to the obstacle and try a quarter of that distance. + result = bwalk_try_quarterdelta(deltapos, &edgea_vtx1, &edgea_vtx2, &edgeb_vtx1, &edgeb_vtx2, cdtypes); if (result >= CDRESULT_NOCOLLISION || result <= CDRESULT_ERROR) { if (result >= CDRESULT_NOCOLLISION) { - bwalk0f0c4d98(); + bwalk_stub(); } - if (arg1 - && bwalk0f0c494c(arg0, &sp100, &sp88, types) <= CDRESULT_COLLISION - && bwalk0f0c4a5c(arg0, &sp100, &sp88, types) <= CDRESULT_COLLISION) { + // The quarter distance had no collision, so try to move the player + // right up to the obstacle and slide along the edge a bit. + if (notrleaning + && bwalk_try_slide_along_edge(deltapos, &edgea_vtx1, &edgea_vtx2, cdtypes) <= CDRESULT_COLLISION + && bwalk_try_slide_along_corner(deltapos, &edgea_vtx1, &edgea_vtx2, cdtypes) <= CDRESULT_COLLISION) { // empty } } else if (result == CDRESULT_COLLISION) { - struct coord sp48; - struct coord sp36; + // The quarter delta also had an obstacle. This must have been a + // different obstacle to the one that was hit in the full delta. - if (bwalk0f0c47d0(arg0, &sp76, &sp64, &sp48, &sp36, types) >= CDRESULT_NOCOLLISION) { - bwalk0f0c4d98(); + // Try again with a quarter of the way to the closer obstacle. + result = bwalk_try_quarterdelta(deltapos, &edgeb_vtx1, &edgeb_vtx2, &edgec_vtx1, &edgec_vtx2, cdtypes); + + if (result >= CDRESULT_NOCOLLISION) { + bwalk_stub(); } - if (arg1 - && bwalk0f0c494c(arg0, &sp76, &sp64, types) <= CDRESULT_COLLISION - && bwalk0f0c494c(arg0, &sp100, &sp88, types) <= CDRESULT_COLLISION - && bwalk0f0c4a5c(arg0, &sp76, &sp64, types) <= CDRESULT_COLLISION) { - bwalk0f0c4a5c(arg0, &sp100, &sp88, types); + // Regardless of what happened above, try to move them to the edge of the closer obstacle. + // If that fails, try to move them to the edge of the further obstacle? This will surely fail though? + // Then try to slide along the closer obstacle's edge, which may work. + // Then try to slide along the further obstacle's edge, which will fail. + if (notrleaning + && bwalk_try_slide_along_edge(deltapos, &edgeb_vtx1, &edgeb_vtx2, cdtypes) <= CDRESULT_COLLISION + && bwalk_try_slide_along_edge(deltapos, &edgea_vtx1, &edgea_vtx2, cdtypes) <= CDRESULT_COLLISION + && bwalk_try_slide_along_corner(deltapos, &edgeb_vtx1, &edgeb_vtx2, cdtypes) <= CDRESULT_COLLISION + && bwalk_try_slide_along_corner(deltapos, &edgea_vtx1, &edgea_vtx2, cdtypes) <= CDRESULT_COLLISION) { + // empty } } } - bwalk0f0c4d98(); + bwalk_stub(); } void bwalk_update_prev_pos(void) @@ -1372,7 +1422,7 @@ void bwalk_update_speed_theta(void) } } -void bwalk0f0c69b8(void) +void bwalk_update_horizontal(void) { s32 i; f32 spe0; @@ -1450,7 +1500,7 @@ void bwalk0f0c69b8(void) g_Vars.currentplayer->gunspeed = 0.0f; bmove_update_move_init_speed(&spcc); - bwalk_calculate_new_position_with_push(&spcc, 0.0f, true, 0.0f, CDTYPE_ALL); + bwalk_try_delta(&spcc, 0.0f, true, 0.0f, CDTYPE_ALL); } else { bwalk_apply_crouch_speed(); bwalk_update_crouch_offset(); @@ -1597,7 +1647,7 @@ void bwalk0f0c69b8(void) } else { player_get_bbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin); - if (!cd_0002a13c(&g_Vars.currentplayer->prop->pos, + if (!is_cyl_touching_tile_with_flags(&g_Vars.currentplayer->prop->pos, radius * 1.1f, ymax - g_Vars.currentplayer->prop->pos.y, (g_Vars.currentplayer->vv_manground - g_Vars.currentplayer->prop->pos.y) + 1.0f, g_Vars.currentplayer->prop->rooms, GEOFLAG_LADDER | GEOFLAG_LADDER_PLAYERONLY)) { @@ -1628,7 +1678,7 @@ void bwalk0f0c69b8(void) sp8c = g_Vars.currentplayer->prop->pos.x; sp88 = g_Vars.currentplayer->prop->pos.z; - bwalk0f0c63bc(&spcc, g_Vars.currentplayer->swaytarget == 0.0f, CDTYPE_ALL); + bwalk_resolve_posdelta(&spcc, g_Vars.currentplayer->swaytarget == 0.0f, CDTYPE_ALL); xdelta = g_Vars.currentplayer->prop->pos.x - g_Vars.currentplayer->bondprevpos.x; zdelta = g_Vars.currentplayer->prop->pos.z - g_Vars.currentplayer->bondprevpos.z; @@ -1743,7 +1793,7 @@ void bwalk_tick(void) bwalk_update_prev_pos(); bwalk_update_theta(); bmove_update_look(); - bwalk0f0c69b8(); + bwalk_update_horizontal(); bwalk_update_vertical(); #if VERSION >= VERSION_NTSC_1_0 diff --git a/src/game/bot.c b/src/game/bot.c index 27c226e68..372ad4296 100644 --- a/src/game/bot.c +++ b/src/game/bot.c @@ -648,7 +648,7 @@ bool bot_test_prop_for_pickup(struct prop *prop, struct chrdata *chr) dprint(); if ((obj->flags2 & OBJFLAG2_PICKUPWITHOUTLOS) == 0 - && !cd_test_los06(&chrprop->pos, chrprop->rooms, &prop->pos, prop->rooms, CDTYPE_DOORS | CDTYPE_BG)) { + && !cd_test_los_oobtail_autoflags(&chrprop->pos, chrprop->rooms, &prop->pos, prop->rooms, CDTYPE_DOORS | CDTYPE_BG)) { sp3c = false; } } diff --git a/src/game/botact.c b/src/game/botact.c index 028d0fb9f..14bf93aad 100644 --- a/src/game/botact.c +++ b/src/game/botact.c @@ -484,7 +484,7 @@ void botact_get_rocket_next_step_pos(u16 padnum, struct coord *pos) rooms[1] = -1; pos->x = pad.pos.x; - pos->y = cd_find_floor_y_colour_type_at_pos(&pad.pos, rooms, 0, 0) + 150; + pos->y = cd_find_ground_at_pos_ct(&pad.pos, rooms, 0, 0) + 150; pos->z = pad.pos.z; } diff --git a/src/game/chr.c b/src/game/chr.c index b3f791a4b..f5f6c666e 100644 --- a/src/game/chr.c +++ b/src/game/chr.c @@ -268,98 +268,154 @@ void chr_calculate_push_pos(struct chrdata *chr, struct coord *dstpos, RoomNum * movez = dstpos->z - prop->pos.z; if (movex > halfradius || movez > halfradius || movex < -halfradius || movez < -halfradius) { - cdresult = cd_exam_cyl_move05(&prop->pos, prop->rooms, dstpos, dstrooms, CDTYPE_ALL, 1, ymax - prop->pos.y, ymin - prop->pos.y); + cdresult = cd_test_cylmove_oobfail_findclosest(&prop->pos, prop->rooms, dstpos, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); if (cdresult == CDRESULT_NOCOLLISION) { - cdresult = cd_exam_cyl_move01(&prop->pos, dstpos, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + cdresult = cd_test_volume_closestedge(&prop->pos, dstpos, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); } } else { - cdresult = cd_exam_cyl_move01(&prop->pos, dstpos, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + cdresult = cd_test_volume_closestedge(&prop->pos, dstpos, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); } - if (cdresult != CDRESULT_ERROR) { - if (cdresult == CDRESULT_NOCOLLISION) { - // The move was completely valid - if (arg3) { - chr->invalidmove = 0; - chr->lastmoveok60 = g_Vars.lvframe60; - } + if (cdresult == CDRESULT_ERROR) { + // empty + } else if (cdresult == CDRESULT_NOCOLLISION) { + // The move was completely valid + if (arg3) { + chr->invalidmove = 0; + chr->lastmoveok60 = g_Vars.lvframe60; + } - moveok = true; - } else { + moveok = true; + } else { + // Collision #if VERSION >= VERSION_PAL_FINAL - cd_get_edge(&sp78, &sp6c, 453, "chr/chr.c"); + cd_get_edge(&sp78, &sp6c, 453, "chr/chr.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_edge(&sp78, &sp6c, 453, "chr.c"); + cd_get_edge(&sp78, &sp6c, 453, "chr.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_edge(&sp78, &sp6c, 453, "chr/chr.c"); + cd_get_edge(&sp78, &sp6c, 453, "chr/chr.c"); #else - cd_get_edge(&sp78, &sp6c, 451, "chr.c"); + cd_get_edge(&sp78, &sp6c, 451, "chr.c"); #endif - // Attempt to find a valid position - method #1 - sp60.x = dstpos->x - prop->pos.x; - sp60.z = dstpos->z - prop->pos.z; + // Attempt to find a valid position - method #1 + sp60.x = dstpos->x - prop->pos.x; + sp60.z = dstpos->z - prop->pos.z; - if (sp78.f[0] != sp6c.f[0] || sp78.f[2] != sp6c.f[2]) { - sp54.x = sp6c.x - sp78.x; - sp54.z = sp6c.z - sp78.z; + if (sp78.f[0] != sp6c.f[0] || sp78.f[2] != sp6c.f[2]) { + sp54.x = sp6c.x - sp78.x; + sp54.z = sp6c.z - sp78.z; - value = 1.0f / sqrtf(sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2]); + value = 1.0f / sqrtf(sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2]); - sp54.x *= value; - sp54.z *= value; + sp54.x *= value; + sp54.z *= value; - value = sp60.f[0] * sp54.f[0] + sp60.f[2] * sp54.f[2]; + value = sp60.f[0] * sp54.f[0] + sp60.f[2] * sp54.f[2]; - sp44.x = sp54.x * value + prop->pos.x; - sp44.y = dstpos->y; - sp44.z = sp54.z * value + prop->pos.z; + sp44.x = sp54.x * value + prop->pos.x; + sp44.y = dstpos->y; + sp44.z = sp54.z * value + prop->pos.z; - los_find_intersecting_rooms_exhaustive(&prop->pos, prop->rooms, &sp44, dstrooms, sp84, 20); + los_find_intersecting_rooms_exhaustive(&prop->pos, prop->rooms, &sp44, dstrooms, sp84, 20); #if VERSION < VERSION_NTSC_1_0 - for (j = 0; dstrooms[j] != -1; j++) { - if (dstrooms[j] == chr->floorroom) { - dstrooms[0] = chr->floorroom; - dstrooms[1] = -1; - break; - } - } -#endif - - chr_find_entered_rooms_at_pos(chr, &sp44, dstrooms); - - movex = sp44.x - prop->pos.x; - movez = sp44.z - prop->pos.z; - - if (movex > halfradius || movez > halfradius || movex < -halfradius || movez < -halfradius) { - cdresult = cd_test_cyl_move02(&prop->pos, prop->rooms, &sp44, dstrooms, CDTYPE_ALL, true, ymax - prop->pos.y, ymin - prop->pos.y); - - if (cdresult == CDRESULT_NOCOLLISION) { - cdresult = cd_test_volume(&sp44, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); - } - } else { - cdresult = cd_test_volume(&sp44, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); - } - - if (cdresult == CDRESULT_NOCOLLISION) { - dstpos->x = sp44.x; - dstpos->z = sp44.z; - chr->invalidmove = 2; - moveok = true; + for (j = 0; dstrooms[j] != -1; j++) { + if (dstrooms[j] == chr->floorroom) { + dstrooms[0] = chr->floorroom; + dstrooms[1] = -1; + break; } } +#endif - if (!moveok) { - // Attempt to find a valid position - method #2 - sp54.x = sp78.x - dstpos->x; - sp54.z = sp78.z - dstpos->z; + chr_find_entered_rooms_at_pos(chr, &sp44, dstrooms); + + movex = sp44.x - prop->pos.x; + movez = sp44.z - prop->pos.z; + + if (movex > halfradius || movez > halfradius || movex < -halfradius || movez < -halfradius) { + cdresult = cd_test_cylmove_oobfail(&prop->pos, prop->rooms, &sp44, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + + if (cdresult == CDRESULT_NOCOLLISION) { + cdresult = cd_test_volume_simple(&sp44, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + } + } else { + cdresult = cd_test_volume_simple(&sp44, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + } + + if (cdresult == CDRESULT_NOCOLLISION) { + dstpos->x = sp44.x; + dstpos->z = sp44.z; + chr->invalidmove = 2; + moveok = true; + } + } + + if (!moveok) { + // Attempt to find a valid position - method #2 + sp54.x = sp78.x - dstpos->x; + sp54.z = sp78.z - dstpos->z; + + if (sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2] <= radius * radius) { + if (sp78.f[0] != prop->pos.f[0] || sp78.f[2] != prop->pos.f[2]) { + sp54.x = -(sp78.z - prop->pos.z); + sp54.z = sp78.x - prop->pos.x; + + value = 1.0f / sqrtf(sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2]); + + sp54.x *= value; + sp54.z *= value; + + value = sp60.f[0] * sp54.f[0] + sp60.f[2] * sp54.f[2]; + + sp44.x = sp54.x * value + prop->pos.x; + sp44.y = dstpos->y; + sp44.z = sp54.z * value + prop->pos.z; + + los_find_intersecting_rooms_exhaustive(&prop->pos, prop->rooms, &sp44, dstrooms, sp84, 20); + +#if VERSION < VERSION_NTSC_1_0 + for (k = 0; dstrooms[k] != -1; k++) { + if (dstrooms[k] == chr->floorroom) { + dstrooms[0] = chr->floorroom; + dstrooms[1] = -1; + break; + } + } +#endif + + chr_find_entered_rooms_at_pos(chr, &sp44, dstrooms); + + movex = sp44.x - prop->pos.x; + movez = sp44.z - prop->pos.z; + + if (movex > halfradius || movez > halfradius || movex < -halfradius || movez < -halfradius) { + cdresult = cd_test_cylmove_oobfail(&prop->pos, prop->rooms, &sp44, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + + if (cdresult == CDRESULT_NOCOLLISION) { + cdresult = cd_test_volume_simple(&sp44, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + } + } else { + cdresult = cd_test_volume_simple(&sp44, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + } + + if (cdresult == CDRESULT_NOCOLLISION) { + dstpos->x = sp44.x; + dstpos->z = sp44.z; + chr->invalidmove = 2; + moveok = true; + } + } + } else { + sp54.x = sp6c.x - dstpos->x; + sp54.z = sp6c.z - dstpos->z; if (sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2] <= radius * radius) { - if (sp78.f[0] != prop->pos.f[0] || sp78.f[2] != prop->pos.f[2]) { - sp54.x = -(sp78.z - prop->pos.z); - sp54.z = sp78.x - prop->pos.x; + if (sp6c.f[0] != prop->pos.f[0] || sp6c.f[2] != prop->pos.f[2]) { + sp54.x = -(sp6c.z - prop->pos.z); + sp54.z = sp6c.x - prop->pos.x; value = 1.0f / sqrtf(sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2]); @@ -375,8 +431,8 @@ void chr_calculate_push_pos(struct chrdata *chr, struct coord *dstpos, RoomNum * los_find_intersecting_rooms_exhaustive(&prop->pos, prop->rooms, &sp44, dstrooms, sp84, 20); #if VERSION < VERSION_NTSC_1_0 - for (k = 0; dstrooms[k] != -1; k++) { - if (dstrooms[k] == chr->floorroom) { + for (l = 0; dstrooms[l] != -1; l++) { + if (dstrooms[l] == chr->floorroom) { dstrooms[0] = chr->floorroom; dstrooms[1] = -1; break; @@ -390,13 +446,13 @@ void chr_calculate_push_pos(struct chrdata *chr, struct coord *dstpos, RoomNum * movez = sp44.z - prop->pos.z; if (movex > halfradius || movez > halfradius || movex < -halfradius || movez < -halfradius) { - cdresult = cd_test_cyl_move02(&prop->pos, prop->rooms, &sp44, dstrooms, CDTYPE_ALL, true, ymax - prop->pos.y, ymin - prop->pos.y); + cdresult = cd_test_cylmove_oobfail(&prop->pos, prop->rooms, &sp44, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); if (cdresult == CDRESULT_NOCOLLISION) { - cdresult = cd_test_volume(&sp44, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + cdresult = cd_test_volume_simple(&sp44, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); } } else { - cdresult = cd_test_volume(&sp44, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); + cdresult = cd_test_volume_simple(&sp44, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); } if (cdresult == CDRESULT_NOCOLLISION) { @@ -406,61 +462,6 @@ void chr_calculate_push_pos(struct chrdata *chr, struct coord *dstpos, RoomNum * moveok = true; } } - } else { - sp54.x = sp6c.x - dstpos->x; - sp54.z = sp6c.z - dstpos->z; - - if (sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2] <= radius * radius) { - if (sp6c.f[0] != prop->pos.f[0] || sp6c.f[2] != prop->pos.f[2]) { - sp54.x = -(sp6c.z - prop->pos.z); - sp54.z = sp6c.x - prop->pos.x; - - value = 1.0f / sqrtf(sp54.f[0] * sp54.f[0] + sp54.f[2] * sp54.f[2]); - - sp54.x *= value; - sp54.z *= value; - - value = sp60.f[0] * sp54.f[0] + sp60.f[2] * sp54.f[2]; - - sp44.x = sp54.x * value + prop->pos.x; - sp44.y = dstpos->y; - sp44.z = sp54.z * value + prop->pos.z; - - los_find_intersecting_rooms_exhaustive(&prop->pos, prop->rooms, &sp44, dstrooms, sp84, 20); - -#if VERSION < VERSION_NTSC_1_0 - for (l = 0; dstrooms[l] != -1; l++) { - if (dstrooms[l] == chr->floorroom) { - dstrooms[0] = chr->floorroom; - dstrooms[1] = -1; - break; - } - } -#endif - - chr_find_entered_rooms_at_pos(chr, &sp44, dstrooms); - - movex = sp44.x - prop->pos.x; - movez = sp44.z - prop->pos.z; - - if (movex > halfradius || movez > halfradius || movex < -halfradius || movez < -halfradius) { - cdresult = cd_test_cyl_move02(&prop->pos, prop->rooms, &sp44, dstrooms, CDTYPE_ALL, true, ymax - prop->pos.y, ymin - prop->pos.y); - - if (cdresult == CDRESULT_NOCOLLISION) { - cdresult = cd_test_volume(&sp44, radius, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); - } - } else { - cdresult = cd_test_volume(&sp44, radius, sp84, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); - } - - if (cdresult == CDRESULT_NOCOLLISION) { - dstpos->x = sp44.x; - dstpos->z = sp44.z; - chr->invalidmove = 2; - moveok = true; - } - } - } } } } @@ -502,7 +503,7 @@ bool chr_ascend(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 amou los_find_final_room_exhaustive(pos, rooms, &newpos, newrooms); chr_find_entered_rooms_at_pos(chr, &newpos, newrooms); chr_set_perim_enabled(chr, false); - result = cd_test_volume(&newpos, radius, newrooms, CDTYPE_ALL, CHECKVERTICAL_YES, + result = cd_test_volume_simple(&newpos, radius, newrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - chr->prop->pos.y, ymin - chr->prop->pos.y); chr_set_perim_enabled(chr, true); @@ -558,7 +559,7 @@ bool chr_update_position(struct model *model, struct coord *arg1, struct coord * los_find_final_room_exhaustive(&prop->pos, prop->rooms, arg2, spfc); } - ground = cd_find_ground_info_at_cyl(arg2, chr->radius, spfc, &chr->floorcol, &chr->floortype, &floorflags, &chr->floorroom, &inlift, &lift); + ground = cd_find_ground_at_cyl_ctfril(arg2, chr->radius, spfc, &chr->floorcol, &chr->floortype, &floorflags, &chr->floorroom, &inlift, &lift); if (ground < -1000000) { ground = 0.0f; @@ -630,12 +631,12 @@ bool chr_update_position(struct model *model, struct coord *arg1, struct coord * chr->height = 135.0f; } else if (chr->actiontype == ACT_GOPOS && (chr->act_gopos.flags & GOPOSFLAG_CROUCH)) { chr->height = 90.0f; - } else if (cd_0002a13c(&chr->prop->pos, chr->radius * 1.1f, + } else if (is_cyl_touching_tile_with_flags(&chr->prop->pos, chr->radius * 1.1f, chr->manground + 185.0f - chr->prop->pos.y, chr->manground - 10.0f - chr->prop->pos.y, chr->prop->rooms, GEOFLAG_AIBOTDUCK)) { chr->height = 135.0f; - } else if (cd_0002a13c(&chr->prop->pos, chr->radius * 1.1f, + } else if (is_cyl_touching_tile_with_flags(&chr->prop->pos, chr->radius * 1.1f, chr->manground + 135.0f - chr->prop->pos.y, chr->manground - 10.0f - chr->prop->pos.y, chr->prop->rooms, GEOFLAG_AIBOTCROUCH)) { @@ -827,7 +828,7 @@ bool chr_update_position(struct model *model, struct coord *arg1, struct coord * sp94 = spfc; } - ground = cd_find_ground_info_at_cyl(sp98, chr->radius, sp94, + ground = cd_find_ground_at_cyl_ctfril(sp98, chr->radius, sp94, &chr->floorcol, &chr->floortype, &floorflags, &chr->floorroom, &inlift, &lift); #if VERSION >= VERSION_NTSC_1_0 @@ -850,7 +851,7 @@ bool chr_update_position(struct model *model, struct coord *arg1, struct coord * lvupdate60freal = 0.0f; - ground = cd_find_ground_info_at_cyl(arg2, chr->radius, spfc, + ground = cd_find_ground_at_cyl_ctfril(arg2, chr->radius, spfc, &chr->floorcol, &chr->floortype, &floorflags, &chr->floorroom, &inlift, &lift); } #endif @@ -1328,7 +1329,7 @@ struct prop *chr_place(struct prop *prop, struct model *model, testpos.y = pos->y + 100; testpos.z = pos->z; - chr->ground = chr->manground = ground = cd_find_ground_info_at_cyl(&testpos, chr->radius, rooms, &chr->floorcol, &chr->floortype, NULL, &chr->floorroom, NULL, NULL); + chr->ground = chr->manground = ground = cd_find_ground_at_cyl_ctfril(&testpos, chr->radius, rooms, &chr->floorcol, &chr->floortype, NULL, &chr->floorroom, NULL, NULL); chr->sumground = ground * (PAL ? 8.4175090789795f : 9.999998f); diff --git a/src/game/chraction.c b/src/game/chraction.c index 04760e59d..2ec9c5738 100644 --- a/src/game/chraction.c +++ b/src/game/chraction.c @@ -1631,15 +1631,15 @@ f32 chr_prop_get_available_dist_at_angle(struct prop *prop, f32 angle, f32 scand chr_set_perim_enabled(chr, false); - if (cd_exam_cyl_move03(&prop->pos, prop->rooms, &farpos, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest(&prop->pos, prop->rooms, &farpos, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { result = scandist; } else { #if VERSION >= VERSION_PAL_FINAL - cd_get_pos(&sp3c, 2377, "chr/chraction.c"); + cd_get_obstacle_pos(&sp3c, 2377, "chr/chraction.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&sp3c, 2377, "chraction.c"); + cd_get_obstacle_pos(&sp3c, 2377, "chraction.c"); #else - cd_get_pos(&sp3c, 2417, "chraction.c"); + cd_get_obstacle_pos(&sp3c, 2417, "chraction.c"); #endif xdiff = sp3c.x - prop->pos.x; @@ -5136,7 +5136,7 @@ void chr_die(struct chrdata *chr, s32 aplayernum) */ bool chr_can_move_directly_to_pos(struct chrdata *chr, struct coord *frompos, RoomNum *fromrooms, - struct coord *topos, struct coord *torooms, s32 arg5) + struct coord *topos, struct coord *torooms, s32 cdtypes) { bool result = false; f32 ymax; @@ -5148,8 +5148,8 @@ bool chr_can_move_directly_to_pos(struct chrdata *chr, chr_get_bbox(prop, &radius, &ymax, &ymin); chr_set_perim_enabled(chr, false); - if (cd_test_cyl_move04(frompos, fromrooms, topos, rooms, arg5, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { - if (cd_test_cyl_move01(topos, rooms, torooms, arg5, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_getfinalroom(frompos, fromrooms, topos, rooms, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok(topos, rooms, torooms, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { result = true; } } @@ -5194,8 +5194,8 @@ bool chr_prop_can_move_to_pos_without_nav(struct chrdata *chr, chr_get_bbox(prop, &radius, &ymax, &ymin); // Test if the chr has cylindar gap to topos - if ((torooms != NULL && cd_test_cyl_move02(frompos, fromrooms, topos, torooms, cdtypes, true, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) - || (torooms == NULL && cd_test_cyl_move01(frompos, fromrooms, topos, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) { + if ((torooms != NULL && cd_test_cylmove_oobfail(frompos, fromrooms, topos, torooms, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) + || (torooms == NULL && cd_test_cylmove_oobok(frompos, fromrooms, topos, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) { // If no dir was given to this function, calculate it if (dir == NULL) { dir = &tmpdir; @@ -5228,8 +5228,8 @@ bool chr_prop_can_move_to_pos_without_nav(struct chrdata *chr, neartopos.y = topos->y; neartopos.z = topos->z - turndistx; - if (cd_test_cyl_move04(frompos, fromrooms, &nearfrompos, nearfromrooms, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION - && cd_test_cyl_move01(&nearfrompos, nearfromrooms, &neartopos, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_getfinalroom(frompos, fromrooms, &nearfrompos, nearfromrooms, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION + && cd_test_cylmove_oobok(&nearfrompos, nearfromrooms, &neartopos, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { // And again, but perpendicular on the other side nearfrompos.x = frompos->x - turndistz; nearfrompos.y = frompos->y; @@ -5239,8 +5239,8 @@ bool chr_prop_can_move_to_pos_without_nav(struct chrdata *chr, neartopos.y = topos->y; neartopos.z = topos->z + turndistx; - if (cd_test_cyl_move04(frompos, fromrooms, &nearfrompos, nearfromrooms, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION - && cd_test_cyl_move01(&nearfrompos, nearfromrooms, &neartopos, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_getfinalroom(frompos, fromrooms, &nearfrompos, nearfromrooms, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION + && cd_test_cylmove_oobok(&nearfrompos, nearfromrooms, &neartopos, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { result = true; } } @@ -5723,7 +5723,7 @@ void chr_nav_tick_magic(struct chrdata *chr, struct waydata *waydata, f32 speed, rooms_copy(rooms, sp118); chr_find_entered_rooms_at_pos(chr, arg3, sp118); - ground = cd_find_ground_info_at_cyl(arg3, chr->radius, sp118, &floorcol, &floortype, 0, &floorroom, NULL, NULL); + ground = cd_find_ground_at_cyl_ctfril(arg3, chr->radius, sp118, &floorcol, &floortype, 0, &floorroom, NULL, NULL); spf4.x = arg3->x; spf4.y = prop->pos.y - chr->ground + ground; @@ -5733,7 +5733,7 @@ void chr_nav_tick_magic(struct chrdata *chr, struct waydata *waydata, f32 speed, chr_find_entered_rooms_at_pos(chr, &spf4, sp118); chr_get_bbox(chr->prop, &radius, &ymax, &ymin); - if (cd_test_volume(&spf4, chr->radius, sp118, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { + if (cd_test_volume_simple(&spf4, chr->radius, sp118, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { // Reached end of segment with no collision prop->pos.x = spf4.x; prop->pos.y = spf4.y; @@ -6319,7 +6319,7 @@ void chr_start_patrol(struct chrdata *chr, struct path *path) chr_set_perim_enabled(chr, false); - if (cd_test_cyl_move04(&prop->pos, prop->rooms, &pad.pos, rooms, CDTYPE_BG, 1, + if (cd_test_cylmove_oobok_getfinalroom(&prop->pos, prop->rooms, &pad.pos, rooms, CDTYPE_BG, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) { nextstep = chr->patrolnextstep; } @@ -6458,12 +6458,12 @@ bool chr_has_los_to_entity(struct chrdata *chr, struct coord *chrpos, RoomNum *c los_find_final_room_properly(chrpos, chrrooms, &frompos, fromrooms); - if (cd_test_los05(&frompos, fromrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { + if (cd_test_los_oobfail(&frompos, fromrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { chr_record_last_visible_target_time(chr); result = true; } } else { - if (cd_test_los05(chrpos, chrrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { + if (cd_test_los_oobfail(chrpos, chrrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { chr_record_last_visible_target_time(chr); result = true; } @@ -6480,13 +6480,13 @@ bool chr_has_los_to_entity(struct chrdata *chr, struct coord *chrpos, RoomNum *c chr_set_perim_enabled(targetchr, false); - if (cd_test_los05(chrpos, chrrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { + if (cd_test_los_oobfail(chrpos, chrrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { result = true; } chr_set_perim_enabled(targetchr, true); } else if (attackflags & ATTACKFLAG_AIMATPAD) { - if (cd_test_los05(chrpos, chrrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { + if (cd_test_los_oobfail(chrpos, chrrooms, &targetpos, targetrooms, types, GEOFLAG_BLOCK_SHOOT)) { result = true; } } @@ -6530,7 +6530,7 @@ bool chr_has_los_to_chr(struct chrdata *chr, struct chrdata *target, RoomNum *ro los_find_final_room_exhaustive(&prop->pos, prop->rooms, &pos, rooms); - if (cd_test_los07(&pos, rooms, &target->prop->pos, target->prop->rooms, sp88, + if (cd_test_los_oobfail_getfinalroom(&pos, rooms, &target->prop->pos, target->prop->rooms, sp88, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SIGHT)) { cansee = true; @@ -6589,7 +6589,7 @@ bool chr_has_los_to_pos(struct chrdata *chr, struct coord *pos, RoomNum *rooms) chr_set_perim_enabled(chr, false); los_find_final_room_exhaustive(&prop->pos, prop->rooms, &eyepos, chrrooms); - if (cd_test_los05(&eyepos, chrrooms, pos, rooms, + if (cd_test_los_oobfail(&eyepos, chrrooms, pos, rooms, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SIGHT)) { result = true; @@ -7443,17 +7443,17 @@ bool chr_try_run_from_target(struct chrdata *chr) prop_get_bbox(prop, &radius, &ymax, &ymin); // If dst runs into a wall, set it to closest valid spot - if (cd_exam_cyl_move03(&prop->pos, prop->rooms, &dst, + if (cd_test_cylmove_oobok_findclosest(&prop->pos, prop->rooms, &dst, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG, - 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { + CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { #if VERSION >= VERSION_JPN_FINAL - cd_get_pos(&dst, 8796, "chr/chraction.c"); + cd_get_obstacle_pos(&dst, 8796, "chr/chraction.c"); #elif VERSION >= VERSION_PAL_FINAL - cd_get_pos(&dst, 8793, "chr/chraction.c"); + cd_get_obstacle_pos(&dst, 8793, "chr/chraction.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&dst, 8788, "chraction.c"); + cd_get_obstacle_pos(&dst, 8788, "chraction.c"); #else - cd_get_pos(&dst, 8782, "chraction.c"); + cd_get_obstacle_pos(&dst, 8782, "chraction.c"); #endif } @@ -7547,7 +7547,7 @@ bool chr_go_to_cover_prop(struct chrdata *chr) if (propheight > chrheight * 0.4f && propheight < chrheight * 0.9f) { prop_set_perim_enabled(prop, false); - if (cd_test_los04(&chrprop->pos, chrprop->rooms, &prop->pos, CDTYPE_DOORS | CDTYPE_BG)) { + if (cd_test_los_oobok_autoflags(&chrprop->pos, chrprop->rooms, &prop->pos, CDTYPE_DOORS | CDTYPE_BG)) { prop_set_perim_enabled(prop, true); dstpos.x = prop->pos.x - (targetprop->pos.x - prop->pos.x) / targetdist * (propradius * 1.25f + chrradius); @@ -7623,7 +7623,7 @@ bool chr_consider_grenade_throw(struct chrdata *chr, u32 attackflags, u32 entity pos.z = target->pos.z; } - if (target && cd_test_los04(&chr->prop->pos, chr->prop->rooms, &pos, + if (target && cd_test_los_oobok_autoflags(&chr->prop->pos, chr->prop->rooms, &pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG)) { struct prop *leftprop = chr_get_held_prop(chr, HAND_LEFT); struct prop *rightprop = chr_get_held_prop(chr, HAND_RIGHT); @@ -7742,7 +7742,7 @@ void chr_punch_inflict_damage(struct chrdata *chr, s32 damage, s32 range, u8 rev if (chr_is_target_in_fov(chr, 20, reverse) && chr_get_distance_to_target(chr) < range - && cd_test_los04(&chr->prop->pos, chr->prop->rooms, &targetprop->pos, + && cd_test_los_oobok_autoflags(&chr->prop->pos, chr->prop->rooms, &targetprop->pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG)) { vector.x = targetprop->pos.x - chr->prop->pos.x; vector.y = 0; @@ -10022,7 +10022,7 @@ void chr_shoot(struct chrdata *chr, s32 handnum) // How nice of the developers to check for this! chr_set_perim_enabled(chr, false); - if (cd_test_los10(&chrprop->pos, chrprop->rooms, &gunpos, gunrooms, + if (cd_test_los_oobok_getfinalroom(&chrprop->pos, chrprop->rooms, &gunpos, gunrooms, CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_BG | CDTYPE_DOORSWITHOUTFLAG | extracdtypes, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { firingthisframe = false; @@ -10090,16 +10090,16 @@ void chr_shoot(struct chrdata *chr, s32 handnum) g_Vars.useperimshoot = true; } - if (cd_exam_los08(&gunpos, gunrooms, &hitpos, cdtypes, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { + if (cd_test_los_oobok_findclosest(&gunpos, gunrooms, &hitpos, cdtypes, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { hitsomething = true; #if VERSION >= VERSION_JPN_FINAL - cd_get_pos(&hitpos, 12080, "chr/chraction.c"); + cd_get_obstacle_pos(&hitpos, 12080, "chr/chraction.c"); #elif VERSION >= VERSION_PAL_FINAL - cd_get_pos(&hitpos, 12077, "chr/chraction.c"); + cd_get_obstacle_pos(&hitpos, 12077, "chr/chraction.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&hitpos, 12072, "chraction.c"); + cd_get_obstacle_pos(&hitpos, 12072, "chraction.c"); #else - cd_get_pos(&hitpos, 12086, "chraction.c"); + cd_get_obstacle_pos(&hitpos, 12086, "chraction.c"); #endif hitprop = cd_get_obstacle_prop(); } @@ -11896,8 +11896,8 @@ bool chr_nav_can_see_next_pos(struct chrdata *chr, struct coord *chrpos, RoomNum sp60.y = aimpos->y; sp60.z = (spd4.z * negchrradius) + (aimpos->z - spc8); - if (cd_exam_cyl_move07(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION - || cd_exam_cyl_move03(&sp6c, sp50, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest_getfinalroom(chrpos, chrrooms, &sp6c, sp50, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION + || cd_test_cylmove_oobok_findclosest(&sp6c, sp50, &sp60, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { spbc = true; #if VERSION >= VERSION_JPN_FINAL cd_get_edge(&spac, &spa0, 14154, "chr/chraction.c"); @@ -11921,8 +11921,8 @@ bool chr_nav_can_see_next_pos(struct chrdata *chr, struct coord *chrpos, RoomNum sp60.y = aimpos->y; sp60.z = (spd4.z * negchrradius) + (aimpos->z + spc8); - if (cd_exam_cyl_move07(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION - || cd_exam_cyl_move03(&sp6c, chrrooms, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest_getfinalroom(chrpos, chrrooms, &sp6c, sp50, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION + || cd_test_cylmove_oobok_findclosest(&sp6c, chrrooms, &sp60, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { spb8 = true; #if VERSION >= VERSION_JPN_FINAL cd_get_edge(&sp94, &sp88, 14169, "chr/chraction.c"); @@ -11965,8 +11965,8 @@ bool chr_nav_can_see_next_pos(struct chrdata *chr, struct coord *chrpos, RoomNum rightpos->x = sp88.x; rightpos->y = sp88.y; rightpos->z = sp88.z; - } else if (cd_exam_cyl_move07(chrpos, chrrooms, aimpos, sp40, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION - && (!arg9 || cd_exam_cyl_move01(chrpos, aimpos, chrradius, sp40, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) { + } else if (cd_test_cylmove_oobok_findclosest_getfinalroom(chrpos, chrrooms, aimpos, sp40, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION + && (!arg9 || cd_test_volume_closestedge(chrpos, aimpos, chrradius, sp40, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) { result = true; } else { #if VERSION >= VERSION_JPN_FINAL @@ -12051,12 +12051,13 @@ bool chr_nav_check_for_obstacle(struct chrdata *chr, struct coord *chrpos, RoomN sp6c.x = chrpos->x + spcc; sp6c.y = chrpos->y; sp6c.z = chrpos->z - spd0; + sp60.x = (spd4.x * negchrradius) + (aimpos->x + spc4); sp60.y = aimpos->y; sp60.z = (spd4.z * negchrradius) + (aimpos->z - spc8); - if (cd_exam_cyl_move07(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION - || cd_exam_cyl_move03(&sp6c, sp50, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest_getfinalroom(chrpos, chrrooms, &sp6c, sp50, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION + || cd_test_cylmove_oobok_findclosest(&sp6c, sp50, &sp60, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { spbc = true; #if VERSION >= VERSION_JPN_FINAL cd_get_edge(&spac, &spa0, 14319, "chr/chraction.c"); @@ -12070,7 +12071,7 @@ bool chr_nav_check_for_obstacle(struct chrdata *chr, struct coord *chrpos, RoomN cd_get_edge(&spac, &spa0, 14323, "chraction.c"); #endif chr_nav_consider_swap_edges(&spac, &spa0, &spd4); - value1 = cd_00024e40(); + value1 = cd_get_sqdistance(); } sp6c.x = chrpos->x - spcc; @@ -12081,8 +12082,8 @@ bool chr_nav_check_for_obstacle(struct chrdata *chr, struct coord *chrpos, RoomN sp60.y = aimpos->y; sp60.z = (spd4.z * negchrradius) + (aimpos->z + spc8); - if (cd_exam_cyl_move07(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION - || cd_exam_cyl_move03(&sp6c, chrrooms, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest_getfinalroom(chrpos, chrrooms, &sp6c, sp50, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION + || cd_test_cylmove_oobok_findclosest(&sp6c, chrrooms, &sp60, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) { spb8 = true; #if VERSION >= VERSION_JPN_FINAL cd_get_edge(&sp94, &sp88, 14334, "chr/chraction.c"); @@ -12096,7 +12097,7 @@ bool chr_nav_check_for_obstacle(struct chrdata *chr, struct coord *chrpos, RoomN cd_get_edge(&sp94, &sp88, 14338, "chraction.c"); #endif chr_nav_consider_swap_edges(&sp94, &sp88, &spd4); - value2 = cd_00024e40(); + value2 = cd_get_sqdistance(); } if (spbc && spb8) { @@ -12133,8 +12134,8 @@ bool chr_nav_check_for_obstacle(struct chrdata *chr, struct coord *chrpos, RoomN rightpos->x = sp88.x; rightpos->y = sp88.y; rightpos->z = sp88.z; - } else if (cd_exam_cyl_move07(chrpos, chrrooms, aimpos, sp40, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION - && (!hasobstacle || cd_exam_cyl_move01(chrpos, aimpos, chrradius, sp40, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) { + } else if (cd_test_cylmove_oobok_findclosest_getfinalroom(chrpos, chrrooms, aimpos, sp40, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION + && (!hasobstacle || cd_test_volume_closestedge(chrpos, aimpos, chrradius, sp40, cdtypes, CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) { result = true; } else { #if VERSION >= VERSION_JPN_FINAL @@ -12261,9 +12262,9 @@ struct prop *chr_open_door(struct chrdata *chr, struct coord *rangepos) { struct prop *doorprop = NULL; - if (cd_exam_cyl_move03(&chr->prop->pos, chr->prop->rooms, rangepos, + if (cd_test_cylmove_oobok_findclosest(&chr->prop->pos, chr->prop->rooms, rangepos, CDTYPE_BG | CDTYPE_CLOSEDDOORS | CDTYPE_AJARDOORS, - 1, 0, 0) == CDRESULT_COLLISION) { + CHECKVERTICAL_YES, 0, 0) == CDRESULT_COLLISION) { doorprop = cd_get_obstacle_prop(); } @@ -12734,7 +12735,7 @@ bool chr_gopos_update_lift_action(struct chrdata *chr, u32 curpadflags, bool arg rooms[0] = nextpad.room; - nextground = cd_find_floor_y_colour_type_at_pos(&nextpad.pos, rooms, NULL, NULL); + nextground = cd_find_ground_at_pos_ct(&nextpad.pos, rooms, NULL, NULL); // Begin exiting lift if lift is 30cm under destination or higher advance = (lifty >= nextground - 30); @@ -13182,7 +13183,7 @@ bool chr_skjump(struct chrdata *chr, u8 pouncebits, u8 arg2, s32 arg3, u8 arg4) f32 ymin; struct prop *prop = chr->prop; struct prop *target = chr_get_target_prop(chr); - bool iVar2; + bool cdresult; f32 distance = chr_get_distance_to_coord(chr, &target->pos); f32 diffs[2]; f32 thing; @@ -13195,13 +13196,13 @@ bool chr_skjump(struct chrdata *chr, u8 pouncebits, u8 arg2, s32 arg3, u8 arg4) chr_get_bbox(prop, &radius, &ymax, &ymin); chr_set_perim_enabled(chr, false); prop_set_perim_enabled(target, false); - iVar2 = cd_test_cyl_move01(&prop->pos, prop->rooms, &target->pos, + cdresult = cd_test_cylmove_oobok(&prop->pos, prop->rooms, &target->pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG, - 1, ymax - prop->pos.y, ymin - prop->pos.y); + CHECKVERTICAL_YES, ymax - prop->pos.y, ymin - prop->pos.y); chr_set_perim_enabled(chr, true); prop_set_perim_enabled(target, true); - if (iVar2) { + if (cdresult != CDRESULT_COLLISION) { diffs[0] = target->pos.x - chr->prop->pos.x; diffs[1] = target->pos.z - chr->prop->pos.z; thing = sqrtf(diffs[0] * diffs[0] + diffs[1] * diffs[1]) * 2.5f / PALUPF(21.0f); @@ -13217,7 +13218,7 @@ bool chr_skjump(struct chrdata *chr, u8 pouncebits, u8 arg2, s32 arg3, u8 arg4) chr->act_skjump.hit = false; chr->act_skjump.timer60 = time60; chr->act_skjump.total60 = time60; - chr->act_skjump.ground = cd_find_ground_at_cyl(&chr->prop->pos, chr->radius, chr->prop->rooms, NULL, NULL); + chr->act_skjump.ground = cd_find_ground_at_cyl_ct(&chr->prop->pos, chr->radius, chr->prop->rooms, NULL, NULL); } else { return false; } @@ -14516,9 +14517,9 @@ bool chr_is_target_aiming_at_me(struct chrdata *chr) if (target->type == PROPTYPE_PLAYER) { if (g_Vars.bondvisible && - (cd_test_los05(&target->pos, target->rooms, &chr->prop->pos, chr->prop->rooms, - CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG, - GEOFLAG_BLOCK_SIGHT))) { + cd_test_los_oobfail(&target->pos, target->rooms, &chr->prop->pos, chr->prop->rooms, + CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG, + GEOFLAG_BLOCK_SIGHT)) { struct model *model = chr->model; struct coord playerpos; struct coord playeraimdir; @@ -14950,7 +14951,7 @@ bool chr_set_pad_preset_to_pad_on_route_to_target(struct chrdata *chr) struct pad pad; if (target->type != PROPTYPE_PLAYER || g_Vars.bondvisible) { - if (cd_test_los04(&prop->pos, prop->rooms, &target->pos, CDTYPE_BG)) { + if (cd_test_los_oobok_autoflags(&prop->pos, prop->rooms, &target->pos, CDTYPE_BG)) { return false; } @@ -14969,8 +14970,8 @@ bool chr_set_pad_preset_to_pad_on_route_to_target(struct chrdata *chr) pad_unpack(wp->padnum, PADFIELD_POS, &pad); - if (cd_test_los04(&target->pos, target->rooms, &pad.pos, CDTYPE_BG)) { - if (cd_test_los04(&prop->pos, prop->rooms, &pad.pos, CDTYPE_BG)) { + if (cd_test_los_oobok_autoflags(&target->pos, target->rooms, &pad.pos, CDTYPE_BG)) { + if (cd_test_los_oobok_autoflags(&prop->pos, prop->rooms, &pad.pos, CDTYPE_BG)) { chr->padpreset1 = wp->padnum; return true; } @@ -15048,13 +15049,13 @@ bool chr_adjust_pos_for_spawn(f32 chrradius, struct coord *pos, RoomNum *rooms, // because if the chr was being spawned on top of another chr or object // then the calculated ground value would be raised. ymin = -200; - ground = cd_find_ground_at_cyl(pos, chrradius, rooms, NULL, NULL); + ground = cd_find_ground_at_cyl_ct(pos, chrradius, rooms, NULL, NULL); if (ground > -100000 && ground - pos->y < -200) { ymin = ground - pos->y; } - if (cd_test_volume(pos, chrradius, rooms, types, CHECKVERTICAL_YES, ymax, ymin) != CDRESULT_COLLISION + if (cd_test_volume_simple(pos, chrradius, rooms, types, CHECKVERTICAL_YES, ymax, ymin) != CDRESULT_COLLISION && (allowonscreen || chr_is_pos_offscreen(pos, rooms))) { return true; } @@ -15066,17 +15067,17 @@ bool chr_adjust_pos_for_spawn(f32 chrradius, struct coord *pos, RoomNum *rooms, testpos.y = pos->y; testpos.z = pos->z + cosf(curangle) * 60; - if ((onlysurrounding && cd_test_cyl_move04(pos, rooms, &testpos, testrooms, CDTYPE_ALL & ~CDTYPE_PLAYERS, 1, ymax, -200) != CDRESULT_COLLISION) - || (!onlysurrounding && cd_test_los11(pos, rooms, &testpos, testrooms, CDTYPE_BG))) { + if ((onlysurrounding && cd_test_cylmove_oobok_getfinalroom(pos, rooms, &testpos, testrooms, CDTYPE_ALL & ~CDTYPE_PLAYERS, CHECKVERTICAL_YES, ymax, -200) != CDRESULT_COLLISION) + || (!onlysurrounding && cd_test_los_oobok_getfinalroom_autoflags(pos, rooms, &testpos, testrooms, CDTYPE_BG))) { chr_find_entered_rooms_at_pos(NULL, &testpos, testrooms); - ground = cd_find_ground_at_cyl(&testpos, chrradius, testrooms, 0, 0); + ground = cd_find_ground_at_cyl_ct(&testpos, chrradius, testrooms, 0, 0); ymin = -200; if (ground > -100000 && ground - pos->y < -200) { ymin = ground - pos->y; } - if (cd_test_volume(&testpos, chrradius, testrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax, ymin) != CDRESULT_COLLISION + if (cd_test_volume_simple(&testpos, chrradius, testrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax, ymin) != CDRESULT_COLLISION && (allowonscreen || chr_is_pos_offscreen(&testpos, testrooms)) && (!onlysurrounding || ground > -100000)) { pos->x = testpos.x; @@ -15116,7 +15117,7 @@ bool chr_adjust_pos_for_spawn(f32 chrradius, struct coord *pos, RoomNum *rooms, types = CDTYPE_ALL; } - if (cd_test_volume(pos, chrradius, rooms, types, CHECKVERTICAL_YES, 200, -200) != CDRESULT_COLLISION + if (cd_test_volume_simple(pos, chrradius, rooms, types, CHECKVERTICAL_YES, 200, -200) != CDRESULT_COLLISION && (allowonscreen || chr_is_pos_offscreen(pos, rooms))) { return true; } @@ -15126,8 +15127,8 @@ bool chr_adjust_pos_for_spawn(f32 chrradius, struct coord *pos, RoomNum *rooms, testpos.y = pos->y; testpos.z = cosf(curangle) * 60 + pos->z; - if (cd_test_los11(pos, rooms, &testpos, testrooms, CDTYPE_BG) - && cd_test_volume(&testpos, chrradius, testrooms, CDTYPE_ALL, CHECKVERTICAL_YES, 200, -200.0f) != CDRESULT_COLLISION + if (cd_test_los_oobok_getfinalroom_autoflags(pos, rooms, &testpos, testrooms, CDTYPE_BG) + && cd_test_volume_simple(&testpos, chrradius, testrooms, CDTYPE_ALL, CHECKVERTICAL_YES, 200, -200.0f) != CDRESULT_COLLISION && (allowonscreen || chr_is_pos_offscreen(&testpos, testrooms))) { pos->x = testpos.x; pos->y = testpos.y; @@ -15302,7 +15303,7 @@ bool chr_is_prop_preset_blocking_sight_to_target(struct chrdata *chr) chr_set_perim_enabled(chr, false); prop_set_perim_enabled(target, false); - if (!cd_test_los04(&prop->pos, prop->rooms, &target->pos, + if (!cd_test_los_oobok_autoflags(&prop->pos, prop->rooms, &target->pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG)) { struct prop *obstacle = cd_get_obstacle_prop(); @@ -15347,7 +15348,7 @@ bool chr_move_to_pos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 if (chr_adjust_pos_for_spawn(chr->radius, &pos2, rooms2, angle, (chr->hidden & CHRHFLAG_WARPONSCREEN) != 0, force)) #endif { - ground = cd_find_ground_info_at_cyl(&pos2, chr->radius, rooms2, &chr->floorcol, + ground = cd_find_ground_at_cyl_ctfril(&pos2, chr->radius, rooms2, &chr->floorcol, &chr->floortype, NULL, &chr->floorroom, NULL, NULL); chr->ground = ground; @@ -15407,7 +15408,7 @@ bool chr_check_cover_out_of_sight(struct chrdata *chr, s32 covernum, bool soft) } if (soft) { - targetcanseecover = cd_test_los03(&target->pos, target->rooms, cover.pos, + targetcanseecover = cd_test_los_oobok(&target->pos, target->rooms, cover.pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_BG, GEOFLAG_BLOCK_SIGHT); } else { @@ -15705,22 +15706,25 @@ bool chr_run_from_pos(struct chrdata *chr, u32 goposflags, f32 rundist, struct c } curdistfrompos = sqrtf(delta.f[0] * delta.f[0] + delta.f[2] * delta.f[2]); + + // @bug: delta needs to be turned into an absolute position before being + // passed to cd_test_los_oobok_findclosest. The position being tested is near 0,0,0. delta.x *= rundist / curdistfrompos; delta.z *= rundist / curdistfrompos; chr_set_perim_enabled(chr, false); - if (cd_exam_los08(&chr->prop->pos, chr->prop->rooms, &delta, CDTYPE_ALL, GEOFLAG_WALL) == CDRESULT_COLLISION) { + if (cd_test_los_oobok_findclosest(&chr->prop->pos, chr->prop->rooms, &delta, CDTYPE_ALL, GEOFLAG_WALL) == CDRESULT_COLLISION) { #if VERSION >= VERSION_JPN_FINAL - cd_get_pos(&delta, 18592, "chr/chraction.c"); + cd_get_obstacle_pos(&delta, 18592, "chr/chraction.c"); #elif VERSION >= VERSION_PAL_FINAL - cd_get_pos(&delta, 18555, "chr/chraction.c"); + cd_get_obstacle_pos(&delta, 18555, "chr/chraction.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&delta, 18550, "chraction.c"); + cd_get_obstacle_pos(&delta, 18550, "chraction.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&delta, 18547, "chraction.c"); + cd_get_obstacle_pos(&delta, 18547, "chraction.c"); #else - cd_get_pos(&delta, 18277, "chraction.c"); + cd_get_obstacle_pos(&delta, 18277, "chraction.c"); #endif } @@ -15857,8 +15861,8 @@ bool chr_flank(struct chrdata *chr, u32 angle360, struct coord *pos, u8 use_clos chr_get_bbox(chr->prop, &radius, &ymax, &ymin); - result = cd_exam_cyl_move03(&chrpos, chr->prop->rooms, pos, - CDTYPE_BG | CDTYPE_OBJS | CDTYPE_DOORS, 1, + result = cd_test_cylmove_oobok_findclosest(&chrpos, chr->prop->rooms, pos, + CDTYPE_BG | CDTYPE_OBJS | CDTYPE_DOORS, CHECKVERTICAL_YES, ymax - chrpos.f[1], ymin - chrpos.f[1]); @@ -15868,15 +15872,15 @@ bool chr_flank(struct chrdata *chr, u32 angle360, struct coord *pos, u8 use_clos f32 tmp; #if VERSION >= VERSION_JPN_FINAL - cd_get_pos(pos, 18731, "chr/chraction.c"); + cd_get_obstacle_pos(pos, 18731, "chr/chraction.c"); #elif VERSION >= VERSION_PAL_FINAL - cd_get_pos(pos, 18694, "chr/chraction.c"); + cd_get_obstacle_pos(pos, 18694, "chr/chraction.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(pos, 18689, "chraction.c"); + cd_get_obstacle_pos(pos, 18689, "chraction.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(pos, 18686, "chraction.c"); + cd_get_obstacle_pos(pos, 18686, "chraction.c"); #else - cd_get_pos(pos, 18416, "chraction.c"); + cd_get_obstacle_pos(pos, 18416, "chraction.c"); #endif xdiff = pos->x - chrpos.x; @@ -16251,7 +16255,7 @@ void chr_avoid(struct chrdata *chr) zdiff = dstpos.z - chr->prop->pos.z; if (xdiff > halfchrradius || zdiff > halfchrradius || xdiff < -halfchrradius || zdiff < -halfchrradius) { - cdresult = cd_exam_cyl_move05(&chr->prop->pos, chr->prop->rooms, &dstpos, dstrooms, CDTYPE_ALL, true, ymax - chr->prop->pos.y, ymin - chr->prop->pos.y); + cdresult = cd_test_cylmove_oobfail_findclosest(&chr->prop->pos, chr->prop->rooms, &dstpos, dstrooms, CDTYPE_ALL, CHECKVERTICAL_YES, ymax - chr->prop->pos.y, ymin - chr->prop->pos.y); } if (cdresult == CDRESULT_ERROR) { diff --git a/src/game/collisionutils.c b/src/game/collisionutils.c index e81fd6164..3c584710e 100644 --- a/src/game/collisionutils.c +++ b/src/game/collisionutils.c @@ -32,7 +32,7 @@ f32 func0f1577f0(f32 arg0[2], f32 arg1[2], f32 arg2[2], f32 arg3[2]) return a; } -f32 func0f1578c8(struct widthxz *arg0, struct xz *arg1, struct xz *arg2) +f32 func0f1578c8(struct radiusxz *arg0, struct xz *arg1, struct xz *arg2) { f32 value2; f32 value1; @@ -46,7 +46,7 @@ f32 func0f1578c8(struct widthxz *arg0, struct xz *arg1, struct xz *arg2) value1 = mult2 * arg1->x - mult1 * arg1->z; value2 = mult1 * arg1->x + mult2 * arg1->z; - sp24 = (arg0->width - value1) * (arg0->width + value1); + sp24 = (arg0->radius - value1) * (arg0->radius + value1); if (sp24 < 0.0f) { return MAXFLOAT; @@ -55,7 +55,7 @@ f32 func0f1578c8(struct widthxz *arg0, struct xz *arg1, struct xz *arg2) value2 -= sqrtf(sp24); if (value2 < 0.0f) { - if (value2 * value2 + value1 * value1 <= arg0->width * arg0->width) { + if (value2 * value2 + value1 * value1 <= arg0->radius * arg0->radius) { return 0.0f; } @@ -65,7 +65,7 @@ f32 func0f1578c8(struct widthxz *arg0, struct xz *arg1, struct xz *arg2) return value2; } -f32 func0f1579cc(struct widthxz *arg0, struct xz *arg1, struct xz *arg2, struct xz *arg3) +f32 func0f1579cc(struct radiusxz *rxz, struct xz *edge_vtx1, struct xz *edge_vtx2, struct xz *diff) { f32 spac; f32 spa8; @@ -90,17 +90,17 @@ f32 func0f1579cc(struct widthxz *arg0, struct xz *arg1, struct xz *arg2, struct f32 sp58; f32 sp54; - spac = sqrtf(arg3->x * arg3->x + arg3->z * arg3->z); + spac = sqrtf(diff->x * diff->x + diff->z * diff->z); if (spac == 0.0f) { return 1.0f; } - spa0.x = arg3->x * (1.0f / spac); - spa0.z = arg3->z * (1.0f / spac); + spa0.x = diff->x * (1.0f / spac); + spa0.z = diff->z * (1.0f / spac); - sp98 = arg2->x - arg1->x; - sp9c = arg2->z - arg1->z; + sp98 = edge_vtx2->x - edge_vtx1->x; + sp9c = edge_vtx2->z - edge_vtx1->z; sp94 = sqrtf(sp98 * sp98 + sp9c * sp9c); @@ -112,22 +112,22 @@ f32 func0f1579cc(struct widthxz *arg0, struct xz *arg1, struct xz *arg2, struct sp88 = sp9c * sp90; sp8c = -sp98 * sp90; - sp84 = arg0->width * sp88; - sp80 = arg0->width * sp8c; + sp84 = rxz->radius * sp88; + sp80 = rxz->radius * sp8c; - if (sp84 * (arg0->x - arg1->x) + sp80 * (arg0->z - arg1->z) < 0.0f) { + if (sp84 * (rxz->x - edge_vtx1->x) + sp80 * (rxz->z - edge_vtx1->z) < 0.0f) { sp84 = -sp84; sp80 = -sp80; } - sp78 = arg1->x + sp84; - sp7c = arg1->z + sp80; - sp70 = arg2->x + sp84; - sp74 = arg2->z + sp80; + sp78 = edge_vtx1->x + sp84; + sp7c = edge_vtx1->z + sp80; + sp70 = edge_vtx2->x + sp84; + sp74 = edge_vtx2->z + sp80; - sp68 = (arg3->z * sp78) - (sp7c * arg3->x); - sp6c = (arg0->x * arg3->z) - (arg0->z * arg3->x); - sp64 = (arg3->z * sp70) - (sp74 * arg3->x); + sp68 = (diff->z * sp78) - (sp7c * diff->x); + sp6c = (rxz->x * diff->z) - (rxz->z * diff->x); + sp64 = (diff->z * sp70) - (sp74 * diff->x); if (sp64 < sp68) { struct xz *tmp; @@ -136,35 +136,35 @@ f32 func0f1579cc(struct widthxz *arg0, struct xz *arg1, struct xz *arg2, struct sp68 = sp64; sp64 = spa8; - tmp = arg1; - arg1 = arg2; - arg2 = tmp; + tmp = edge_vtx1; + edge_vtx1 = edge_vtx2; + edge_vtx2 = tmp; sp88 = -sp88; sp8c = -sp8c; } if (sp64 == sp68) { - sp60 = func0f1578c8(arg0, &spa0, arg1); - sp5c = func0f1578c8(arg0, &spa0, arg2); + sp60 = func0f1578c8(rxz, &spa0, edge_vtx1); + sp5c = func0f1578c8(rxz, &spa0, edge_vtx2); if (sp5c < sp60) { sp60 = sp5c; } } else if (sp64 < sp6c) { handlezero: - sp60 = func0f1578c8(arg0, &spa0, arg2); + sp60 = func0f1578c8(rxz, &spa0, edge_vtx2); } else if (sp6c < sp68) { - sp60 = func0f1578c8(arg0, &spa0, arg1); + sp60 = func0f1578c8(rxz, &spa0, edge_vtx1); } else { - sp58 = sp88 * (arg0->x - arg1->x) + sp8c * (arg0->z - arg1->z); - sp54 = sp88 * (arg0->x + arg3->x - arg1->x) + sp8c * (arg0->z + arg3->z - arg1->z); + sp58 = sp88 * (rxz->x - edge_vtx1->x) + sp8c * (rxz->z - edge_vtx1->z); + sp54 = sp88 * (rxz->x + diff->x - edge_vtx1->x) + sp8c * (rxz->z + diff->z - edge_vtx1->z); if (sp58 == sp54) { return 1.0f; } - sp60 = (sp58 - arg0->width) * spac / (sp58 - sp54); + sp60 = (sp58 - rxz->radius) * spac / (sp58 - sp54); } if (spac < sp60) { diff --git a/src/game/explosions.c b/src/game/explosions.c index 2e9df2dc2..ded68fa3f 100644 --- a/src/game/explosions.c +++ b/src/game/explosions.c @@ -103,12 +103,12 @@ bool explosion_create_complex(struct prop *prop, struct coord *pos, RoomNum *roo } if (prop) { - room = cd_find_floor_room_y_colour_normal_prop_at_pos(&prop->pos, prop->rooms, &y, NULL, &sp88, &collisionprop); + room = cd_find_room_at_pos_ycnp(&prop->pos, prop->rooms, &y, NULL, &sp88, &collisionprop); sp100.x = prop->pos.x; sp100.y = y; sp100.z = prop->pos.z; } else { - room = cd_find_floor_room_y_colour_normal_prop_at_pos(pos, rooms, &y, NULL, &sp88, &collisionprop); + room = cd_find_room_at_pos_ycnp(pos, rooms, &y, NULL, &sp88, &collisionprop); sp100.x = pos->x; sp100.y = y; sp100.z = pos->z; diff --git a/src/game/mplayer/scenarios/kingofthehill.inc b/src/game/mplayer/scenarios/kingofthehill.inc index fa3f6175f..59204a83f 100644 --- a/src/game/mplayer/scenarios/kingofthehill.inc +++ b/src/game/mplayer/scenarios/kingofthehill.inc @@ -202,7 +202,7 @@ void koh_init_props(void) g_ScenarioData.koh.hillpos.x = pad.pos.x; g_ScenarioData.koh.hillpos.y = pad.pos.y; g_ScenarioData.koh.hillpos.z = pad.pos.z; - g_ScenarioData.koh.hillpos.y = cd_find_floor_y_colour_type_at_pos(&g_ScenarioData.koh.hillpos, &g_ScenarioData.koh.hillrooms[0], 0, 0); + g_ScenarioData.koh.hillpos.y = cd_find_ground_at_pos_ct(&g_ScenarioData.koh.hillpos, &g_ScenarioData.koh.hillrooms[0], 0, 0); g_ScenarioData.koh.movehill = false; room_set_light_op(g_ScenarioData.koh.hillrooms[0], LIGHTOP_HIGHLIGHT, 0, 0, 0); @@ -294,7 +294,7 @@ void koh_tick(void) g_ScenarioData.koh.hillpos.y = pad.pos.y; g_ScenarioData.koh.hillpos.z = pad.pos.z; - g_ScenarioData.koh.hillpos.y = cd_find_floor_y_colour_type_at_pos(&g_ScenarioData.koh.hillpos, g_ScenarioData.koh.hillrooms, NULL, NULL); + g_ScenarioData.koh.hillpos.y = cd_find_ground_at_pos_ct(&g_ScenarioData.koh.hillpos, g_ScenarioData.koh.hillrooms, NULL, NULL); room_set_light_op(g_ScenarioData.koh.hillrooms[0], LIGHTOP_HIGHLIGHT, 0, 0, 0); diff --git a/src/game/padhalllv.c b/src/game/padhalllv.c index 3c511c53b..3ef9f290d 100644 --- a/src/game/padhalllv.c +++ b/src/game/padhalllv.c @@ -159,8 +159,8 @@ struct waypoint *waypoint_find_closest_to_pos(struct coord *pos, RoomNum *rooms) padrooms[0] = pad.room; padrooms[1] = -1; - if (cd_test_los05(pos, rooms, &pad.pos, padrooms, CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2) != CDRESULT_COLLISION) { - s32 cdresult = cd_exam_cyl_move05(pos, rooms, &pad.pos, padrooms, CDTYPE_BG | CDTYPE_PATHBLOCKER, true, 0.0f, 0.0f); + if (cd_test_los_oobfail(pos, rooms, &pad.pos, padrooms, CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2) != CDRESULT_COLLISION) { + s32 cdresult = cd_test_cylmove_oobfail_findclosest(pos, rooms, &pad.pos, padrooms, CDTYPE_BG | CDTYPE_PATHBLOCKER, CHECKVERTICAL_YES, 0.0f, 0.0f); if (cdresult == CDRESULT_ERROR) { checkmore[i] = false; @@ -209,7 +209,7 @@ struct waypoint *waypoint_find_closest_to_pos(struct coord *pos, RoomNum *rooms) tmppos.y = pos->y; tmppos.z = sp250[i].f[2] + sp98.f[2]; - if (cd_test_cyl_move04(pos, rooms, &tmppos, tmprooms, CDTYPE_BG | CDTYPE_PATHBLOCKER, 1, 0.0f, 0.0f) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_getfinalroom(pos, rooms, &tmppos, tmprooms, CDTYPE_BG | CDTYPE_PATHBLOCKER, CHECKVERTICAL_YES, 0.0f, 0.0f) != CDRESULT_COLLISION) { closest = candwaypoints[i]; break; } @@ -218,7 +218,7 @@ struct waypoint *waypoint_find_closest_to_pos(struct coord *pos, RoomNum *rooms) tmppos.y = pos->y; tmppos.z = sp1d8[i].z - sp98.z; - if (cd_test_cyl_move04(pos, rooms, &tmppos, tmprooms, CDTYPE_BG | CDTYPE_PATHBLOCKER, 1, 0.0f, 0.0f) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_getfinalroom(pos, rooms, &tmppos, tmprooms, CDTYPE_BG | CDTYPE_PATHBLOCKER, CHECKVERTICAL_YES, 0.0f, 0.0f) != CDRESULT_COLLISION) { closest = candwaypoints[i]; break; } diff --git a/src/game/player.c b/src/game/player.c index 9dc1f6d95..a902260e1 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -527,7 +527,7 @@ void player_start_new_life(void) angle = BADDTOR(360) - scenario_choose_spawn_location(30, &pos, rooms, g_Vars.currentplayer->prop); - groundy = cd_find_ground_info_at_cyl(&pos, 30, rooms, + groundy = cd_find_ground_at_cyl_ctfril(&pos, 30, rooms, &g_Vars.currentplayer->floorcol, &g_Vars.currentplayer->floortype, &g_Vars.currentplayer->floorflags, @@ -5019,7 +5019,7 @@ void player_move_camera_from_pos_rooms(struct coord *pos, struct coord *up, stru bg_find_rooms_by_pos(pos, inrooms, aboverooms, 20, &bestroom); if (inrooms[0] != -1) { - tmp = room = cd_find_floor_room_at_pos(pos, inrooms); + tmp = room = cd_find_room_at_pos(pos, inrooms); if (room > 0) { player_set_cam_properties_in_bounds(pos, up, look, tmp); @@ -5027,7 +5027,7 @@ void player_move_camera_from_pos_rooms(struct coord *pos, struct coord *up, stru player_set_cam_properties_in_bounds(pos, up, look, inrooms[0]); } } else if (aboverooms[0] != -1) { - tmp = room = cd_find_floor_room_at_pos(pos, aboverooms); + tmp = room = cd_find_room_at_pos(pos, aboverooms); if (room > 0) { player_set_cam_properties_out_of_bounds(pos, up, look, tmp); diff --git a/src/game/playerreset.c b/src/game/playerreset.c index d0b55536e..9153347d0 100644 --- a/src/game/playerreset.c +++ b/src/game/playerreset.c @@ -409,7 +409,7 @@ void player_reset(void) } } - groundy = cd_find_ground_info_at_cyl(&pos, 30, rooms, + groundy = cd_find_ground_at_cyl_ctfril(&pos, 30, rooms, &g_Vars.currentplayer->floorcol, &g_Vars.currentplayer->floortype, &g_Vars.currentplayer->floorflags, diff --git a/src/game/prop.c b/src/game/prop.c index 494f554ba..f683e87d5 100644 --- a/src/game/prop.c +++ b/src/game/prop.c @@ -1221,7 +1221,7 @@ void hand_inflict_melee_damage(s32 handnum, struct gset *gset, bool arg2) cdtypes = 0; } - if (cd_test_los04(&playerprop->pos, playerprop->rooms, &prop->pos, cdtypes)) { + if (cd_test_los_oobok_autoflags(&playerprop->pos, playerprop->rooms, &prop->pos, cdtypes)) { if (isglass) { struct model *model = obj->model; struct coord gunpos2d; @@ -2467,11 +2467,11 @@ f32 prop_calculate_autoaim_score(struct prop *prop, struct coord *screenpos, f32 player_set_perim_enabled(playerprop, false); if (throughobjects) { - ok = cd_test_los03(&playerprop->pos, playerprop->rooms, &prop->pos, + ok = cd_test_los_oobok(&playerprop->pos, playerprop->rooms, &prop->pos, CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG, GEOFLAG_BLOCK_SHOOT); } else { - ok = cd_test_los03(&playerprop->pos, playerprop->rooms, &prop->pos, + ok = cd_test_los_oobok(&playerprop->pos, playerprop->rooms, &prop->pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG, GEOFLAG_BLOCK_SHOOT); } @@ -3089,24 +3089,24 @@ void prop_register_rooms(struct prop *prop) * If the line goes out of bounds, the intersecting list up until that point * will be returned. */ -void los_find_intersecting_rooms_properly(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, RoomNum *intersecting, s32 maxintersecting) +void los_find_intersecting_rooms_properly(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalroomsptr, RoomNum *intersecting, s32 maxintersecting) { - RoomNum tmprooms[8]; + RoomNum finalrooms[8]; s32 len; s32 i; - portal_find_rooms(frompos, topos, fromrooms, tmprooms, intersecting, maxintersecting); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, intersecting, maxintersecting); len = 0; - for (i = 0; tmprooms[i] != -1; i++) { - if (bg_room_contains_coord(topos, tmprooms[i])) { - finalrooms[len] = tmprooms[i]; + for (i = 0; finalrooms[i] != -1; i++) { + if (bg_room_contains_coord(topos, finalrooms[i])) { + finalroomsptr[len] = finalrooms[i]; len++; } } - finalrooms[len] = -1; + finalroomsptr[len] = -1; } /** @@ -3173,7 +3173,7 @@ void los_find_final_room_fast(struct coord *frompos, RoomNum *fromrooms, struct } if (ptr) { - s32 room = cd_find_floor_room_at_pos(topos, ptr); + s32 room = cd_find_room_at_pos(topos, ptr); if (room > 0) { finalrooms[0] = room; diff --git a/src/game/propobj.c b/src/game/propobj.c index 9243f508f..8e0f6564c 100644 --- a/src/game/propobj.c +++ b/src/game/propobj.c @@ -1022,7 +1022,7 @@ struct defaultobj *obj_find_by_pos(struct coord *pos, RoomNum *rooms) if (prop->type == PROPTYPE_OBJ && array_intersects(prop->rooms, rooms) && prop_get_geometry(prop, &start, &end) - && cd_is_2d_point_in_geo(pos->x, pos->z, (struct geo *)start)) { + && cd_is_xz_in_geo(pos->x, pos->z, (struct geo *)start)) { return prop->obj; } @@ -2207,9 +2207,9 @@ void obj_place_grounded(struct defaultobj *obj, struct coord *pos, Mtxf *rotmtx, bbox = model_find_bbox_rodata(obj->model); #if VERSION >= VERSION_NTSC_1_0 - room = cd_find_floor_room_y_colour_flags_at_pos(pos, rooms, &ground, &obj->floorcol, NULL); + room = cd_find_room_at_pos_ycf(pos, rooms, &ground, &obj->floorcol, NULL); #else - room = cd_find_floor_room_y_colour_flags_at_pos(pos, rooms, &ground, &obj->floorcol); + room = cd_find_room_at_pos_ycf(pos, rooms, &ground, &obj->floorcol); #endif if (room > 0) { @@ -2322,9 +2322,9 @@ void obj_place_3d(struct defaultobj *obj, struct coord *arg1, Mtxf *mtx, RoomNum los_find_final_room_exhaustive(arg1, rooms, &pos2, rooms2); #if VERSION >= VERSION_NTSC_1_0 - if (cd_find_floor_room_y_colour_flags_at_pos(&pos2, rooms2, &y, &obj->floorcol, NULL) > 0) + if (cd_find_room_at_pos_ycf(&pos2, rooms2, &y, &obj->floorcol, NULL) > 0) #else - if (cd_find_floor_room_y_colour_flags_at_pos(&pos2, rooms2, &y, &obj->floorcol) > 0) + if (cd_find_room_at_pos_ycf(&pos2, rooms2, &y, &obj->floorcol) > 0) #endif { s32 stack; @@ -2630,19 +2630,19 @@ bool projectile_0f06b488(struct prop *prop, struct coord *arg1, struct coord *ar f32 f0; struct coord sp20; - if (!cd_0002ded8(arg1, arg2, prop)) { + if (!cd_test_line_intersects_prop(arg1, arg2, prop)) { #if VERSION >= VERSION_PAL_FINAL cd_get_edge(&sp3c, &sp30, 2910, "prop/propobj.c"); - cd_get_pos(&sp20, 2911, "prop/propobj.c"); + cd_get_obstacle_pos(&sp20, 2911, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA cd_get_edge(&sp3c, &sp30, 2910, "propobj.c"); - cd_get_pos(&sp20, 2911, "propobj.c"); + cd_get_obstacle_pos(&sp20, 2911, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 cd_get_edge(&sp3c, &sp30, 2909, "propobj.c"); - cd_get_pos(&sp20, 2910, "propobj.c"); + cd_get_obstacle_pos(&sp20, 2910, "propobj.c"); #else cd_get_edge(&sp3c, &sp30, 2898, "propobj.c"); - cd_get_pos(&sp20, 2899, "propobj.c"); + cd_get_obstacle_pos(&sp20, 2899, "propobj.c"); #endif f0 = (sp20.f[0] - arg1->f[0]) * arg3->f[0] @@ -3320,16 +3320,16 @@ s32 func0f06cd00(struct defaultobj *obj, struct coord *pos, struct coord *arg2, spa0[0] = spcc[i]; spa0[1] = -1; - if (cd_exam_los09(&prop->pos, spa0, &sp1c4, CDTYPE_BG) == CDRESULT_COLLISION) { + if (cd_test_los_oobok_findclosest_autoflags(&prop->pos, spa0, &sp1c4, CDTYPE_BG) == CDRESULT_COLLISION) { s0 = true; #if VERSION >= VERSION_PAL_FINAL - cd_get_pos(&hitthing.pos, 4258, "prop/propobj.c"); + cd_get_obstacle_pos(&hitthing.pos, 4258, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&hitthing.pos, 4258, "propobj.c"); + cd_get_obstacle_pos(&hitthing.pos, 4258, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&hitthing.pos, 4257, "propobj.c"); + cd_get_obstacle_pos(&hitthing.pos, 4257, "propobj.c"); #else - cd_get_pos(&hitthing.pos, 4246, "propobj.c"); + cd_get_obstacle_pos(&hitthing.pos, 4246, "propobj.c"); #endif cd_get_obstacle_normal(&hitthing.unk0c); } @@ -3421,10 +3421,10 @@ bool func0f06d37c(struct defaultobj *obj, struct coord *arg1, struct coord *arg2 if (prop->pos.x != arg1->x || prop->pos.y != arg1->y || prop->pos.z != arg1->z) { if (obj->hidden & OBJHFLAG_PROJECTILE) { - if (cd_exam_cyl_move08(&prop->pos, prop->rooms, &sp80, rooms, radius, CDTYPE_ALL, false, 0.0f, 0.0f) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest_getfinalroom_finddist(&prop->pos, prop->rooms, &sp80, rooms, radius, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0.0f) != CDRESULT_COLLISION) { obj_find_rooms(obj, &sp80, obj->realrot, rooms); - if (cd_exam_cyl_move02(&prop->pos, &sp80, radius, rooms, CDTYPE_ALL, false, 0.0f, 0.0f) != CDRESULT_COLLISION) { + if (cd_test_volume_fromdir(&prop->pos, &sp80, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0.0f) != CDRESULT_COLLISION) { prop->pos.x = sp80.x; prop->pos.y = sp80.y; prop->pos.z = sp80.z; @@ -3514,10 +3514,10 @@ bool func0f06d37c(struct defaultobj *obj, struct coord *arg1, struct coord *arg2 sp4c.y = sp80.y; sp4c.z = sp8c.z * f2 + prop->pos.z; - if (cd_exam_cyl_move07(&prop->pos, prop->rooms, &sp4c, rooms, CDTYPE_ALL, false, 0.0f, 0.0f) != CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest_getfinalroom(&prop->pos, prop->rooms, &sp4c, rooms, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0.0f) != CDRESULT_COLLISION) { obj_find_rooms(obj, &sp4c, obj->realrot, rooms); - if (cd_test_volume(&sp4c, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0.0f) != CDRESULT_COLLISION) { + if (cd_test_volume_simple(&sp4c, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0.0f) != CDRESULT_COLLISION) { prop->pos.x = sp4c.x; prop->pos.y = sp4c.y; prop->pos.z = sp4c.z; @@ -5227,7 +5227,7 @@ void hov_update_ground(struct defaultobj *obj, struct hov *hov, struct coord *po rooms_copy(rooms, testrooms); obj_find_rooms(obj, &testpos, matrix, testrooms); - ground = cd_find_ground_at_cyl(pos, 5, testrooms, &obj->floorcol, NULL); + ground = cd_find_ground_at_cyl_ct(pos, 5, testrooms, &obj->floorcol, NULL); if (ground < -30000) { ground = hov->ground; @@ -5313,11 +5313,11 @@ void hov_tick(struct defaultobj *obj, struct hov *hov) los_find_final_room_exhaustive(&prop->pos, prop->rooms, &sp1b4, sp198); rooms_append(sp9c, sp198, ARRAYCOUNT(sp198)); - ground1 = cd_find_ground_at_cyl(&sp1b4, 5, sp198, &obj->floorcol, NULL); + ground1 = cd_find_ground_at_cyl_ct(&sp1b4, 5, sp198, &obj->floorcol, NULL); los_find_final_room_exhaustive(&prop->pos, prop->rooms, &sp1a8, sp188); rooms_append(sp9c, sp188, ARRAYCOUNT(sp188)); - ground2 = cd_find_ground_at_cyl(&sp1a8, 5, sp188, NULL, NULL); + ground2 = cd_find_ground_at_cyl_ct(&sp1a8, 5, sp188, NULL, NULL); if (ground1 >= -30000.0f && ground2 >= -30000.0f) { groundangle = atan2f(ground1 - ground2, sp1cc - sp1d0); @@ -5611,12 +5611,12 @@ s32 func0f072144(struct defaultobj *obj, struct coord *arg1, f32 arg2, bool arg3 pos.y += hov->ground - prevhov.ground; } - cdresult = cd_exam_cyl_move05(&prop->pos, prop->rooms, &pos, rooms, CDTYPE_ALL, true, 0.0f, 0.0f); + cdresult = cd_test_cylmove_oobfail_findclosest(&prop->pos, prop->rooms, &pos, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, 0.0f, 0.0f); if (cdresult == CDRESULT_ERROR) { // empty } else if (cdresult == CDRESULT_COLLISION) { - cd_set_saved_pos(&prop->pos, &pos); + cd_set_block_edge(&prop->pos, &pos); } } else { rooms_copy(prop->rooms, rooms); @@ -5627,10 +5627,10 @@ s32 func0f072144(struct defaultobj *obj, struct coord *arg1, f32 arg2, bool arg3 obj_update_core_geo(obj, &pos, sp460, &geounion.cyl); if (obj->flags3 & OBJFLAG3_GEOCYL) { - cdresult = cd_exam_cyl_move01(&prop->pos, &pos, geounion.cyl.radius, rooms, CDTYPE_ALL, + cdresult = cd_test_volume_closestedge(&prop->pos, &pos, geounion.cyl.radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES, geounion.cyl.ymax - pos.y, geounion.cyl.ymin - pos.y); } else { - cdresult = cd_0002f02c(&geounion.block, rooms, CDTYPE_ALL); + cdresult = cd_test_blockmove(&geounion.block, rooms, CDTYPE_ALL); } } @@ -5771,7 +5771,7 @@ f32 obj_collide(struct defaultobj *movingobj, struct coord *movingvel, f32 rotat cd_get_edge(&sp70, &sp64, 7308, "propobj.c"); #endif - if (cd_get_saved_pos(&sp58, &sp4c)) { + if (cd_get_block_edge(&sp58, &sp4c)) { sp4c.x -= sp58.x; sp4c.y -= sp58.y; sp4c.z -= sp58.z; @@ -6020,7 +6020,7 @@ void platform_displace_props2(struct prop *platform, Mtxf *arg1) if (prop->pos.y > platform->pos.y && (obj->hidden & OBJHFLAG_ONANOTHEROBJ) - && cd_is_2d_point_in_geo(prop->pos.x, prop->pos.z, (struct geo *)start)) { + && cd_is_xz_in_geo(prop->pos.x, prop->pos.z, (struct geo *)start)) { mtx3_to_mtx4(obj->realrot, &mtx); mtx4_set_translation(&prop->pos, &mtx); mtx4_mult_mtx4_in_place(arg1, &mtx); @@ -6194,7 +6194,7 @@ bool rocket_tick_fbw(struct weaponobj *rocket) // Check if rocket can fly directly to target if (chr_get_target_prop(ownerchr) == chr->prop && mp_chr_to_chrindex(ownerchr) == g_Vars.lvframenum % g_MpNumChrs - && cd_test_los05(&rocketprop->pos, rocketprop->rooms, &chr->prop->pos, chr->prop->rooms, + && cd_test_los_oobfail(&rocketprop->pos, rocketprop->rooms, &chr->prop->pos, chr->prop->rooms, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SIGHT)) { projectile->nextsteppos.x = chr->prop->pos.x; @@ -6503,7 +6503,7 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) struct coord sp3ac; f32 f0_2; - if (cd_get_saved_pos(&sp3d0, &sp3c4)) { + if (cd_get_block_edge(&sp3d0, &sp3c4)) { sp3c4.x -= sp3d0.x; sp3c4.y -= sp3d0.y; sp3c4.z -= sp3d0.z; @@ -6718,7 +6718,7 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) } if (cdresult == CDRESULT_NOCOLLISION) { - ground = cd_find_ground_at_cyl(&prop->pos, 2, prop->rooms, &obj->floorcol, NULL); + ground = cd_find_ground_at_cyl_ct(&prop->pos, 2, prop->rooms, &obj->floorcol, NULL); if (ground > -30000.0f) { prop->pos.y = ground + obj_get_hov_bob_offset_y(obj); @@ -7276,16 +7276,16 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) sp5ac.y = prop->pos.y + sp37c; sp5ac.z = prop->pos.z; - roomnum = cd_find_ceiling_room_y_colour_flags_normal_at_pos(&sp5ac, prop->rooms, &sp390, &obj->floorcol, &geoflags, &sp380); + roomnum = cd_find_ceiling_room_at_pos_ycfn(&sp5ac, prop->rooms, &sp390, &obj->floorcol, &geoflags, &sp380); #if VERSION >= VERSION_NTSC_1_0 if (roomnum > 0 && prop->pos.y + sp37c < sp390 - && !cd_test_los03(&prevpos, prevrooms, &sp5ac, CDTYPE_OBJS | CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) + && !cd_test_los_oobok(&prevpos, prevrooms, &sp5ac, CDTYPE_OBJS | CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) #else if (roomnum > 0 && prop->pos.y + sp37c < sp390 - && !cd_test_los03(&prevpos, prevrooms, &sp5ac, CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) + && !cd_test_los_oobok(&prevpos, prevrooms, &sp5ac, CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) #endif { settle = true; @@ -7305,18 +7305,18 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) obj->hidden |= OBJHFLAG_DELETING; } } else { - roomnum = cd_find_floor_room_y_colour_normal_prop_at_pos(&prop->pos, prop->rooms, &sp390, &obj->floorcol, &sp380, NULL); + roomnum = cd_find_room_at_pos_ycnp(&prop->pos, prop->rooms, &sp390, &obj->floorcol, &sp380, NULL); #if VERSION >= VERSION_NTSC_1_0 // If the projectile has gone out of bounds, the room // search above wll have failed. It's likely that - // cd_find_floor_room_at_pos is a more expensive room + // cd_find_room_at_pos is a more expensive room // search, due to it only being run once per projectile. if (roomnum <= 0 && (projectile->flags & PROJECTILEFLAG_STICKY) == 0) { if ((projectile->flags & PROJECTILEFLAG_DONEOOBSEARCH) == 0) { projectile->flags |= PROJECTILEFLAG_DONEOOBSEARCH; - if (cd_find_floor_room_at_pos(&prevpos, prevrooms) > 0) { + if (cd_find_room_at_pos(&prevpos, prevrooms) > 0) { projectile->flags |= PROJECTILEFLAG_INROOM; } } @@ -7329,7 +7329,7 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) prop_deregister_rooms(prop); rooms_copy(prevrooms, prop->rooms); - roomnum = cd_find_floor_room_y_colour_flags_at_pos(&prop->pos, prop->rooms, &sp390, &obj->floorcol, NULL); + roomnum = cd_find_room_at_pos_ycf(&prop->pos, prop->rooms, &sp390, &obj->floorcol, NULL); projectile->speed.x = 0.0f; projectile->speed.z = 0.0f; @@ -7594,16 +7594,16 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) sp5ac.z = prop->pos.z; #if VERSION >= VERSION_NTSC_1_0 - roomnum = cd_find_ceiling_room_y_colour_flags_at_pos(&sp5ac, prop->rooms, &spa4, &obj->floorcol, &geoflags); + roomnum = cd_find_ceiling_room_at_pos_ycf(&sp5ac, prop->rooms, &spa4, &obj->floorcol, &geoflags); - if (roomnum <= 0 || cd_test_los03(&prevpos, prevrooms, &sp5ac, CDTYPE_OBJS | CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) { - roomnum = cd_find_floor_room_y_colour_flags_at_pos(&prop->pos, prop->rooms, &spa4, &obj->floorcol, &geoflags); + if (roomnum <= 0 || cd_test_los_oobok(&prevpos, prevrooms, &sp5ac, CDTYPE_OBJS | CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) { + roomnum = cd_find_room_at_pos_ycf(&prop->pos, prop->rooms, &spa4, &obj->floorcol, &geoflags); } #else - roomnum = cd_find_ceiling_room_y_colour_flags_at_pos(&sp5ac, prop->rooms, &spa4, &obj->floorcol); + roomnum = cd_find_ceiling_room_at_pos_ycf(&sp5ac, prop->rooms, &spa4, &obj->floorcol); - if (roomnum <= 0 || cd_test_los03(&prevpos, prevrooms, &sp5ac, CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) { - roomnum = cd_find_floor_room_y_colour_flags_at_pos(&prop->pos, prop->rooms, &spa4, &obj->floorcol); + if (roomnum <= 0 || cd_test_los_oobok(&prevpos, prevrooms, &sp5ac, CDTYPE_BG, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2)) { + roomnum = cd_find_room_at_pos_ycf(&prop->pos, prop->rooms, &spa4, &obj->floorcol); } #endif @@ -7615,9 +7615,9 @@ bool projectile_tick(struct defaultobj *obj, bool *embedded) rooms_copy(prevrooms, prop->rooms); #if VERSION >= VERSION_NTSC_1_0 - roomnum = cd_find_floor_room_y_colour_flags_at_pos(&prop->pos, prop->rooms, &spa4, &obj->floorcol, &geoflags); + roomnum = cd_find_room_at_pos_ycf(&prop->pos, prop->rooms, &spa4, &obj->floorcol, &geoflags); #else - roomnum = cd_find_floor_room_y_colour_flags_at_pos(&prop->pos, prop->rooms, &spa4, &obj->floorcol); + roomnum = cd_find_room_at_pos_ycf(&prop->pos, prop->rooms, &spa4, &obj->floorcol); #endif projectile->speed.x = 0.0f; @@ -7972,7 +7972,7 @@ void platform_displace_props(struct prop *platform, s16 *propnums, struct coord prevplayernum = g_Vars.currentplayernum; set_current_player_num(playernum); - bwalk0f0c63bc(&sp8c, 1, CDTYPE_BG); + bwalk_resolve_posdelta(&sp8c, true, CDTYPE_BG); player_update_perim_info(); bmove_update_rooms(g_Vars.players[playernum]); set_current_player_num(prevplayernum); @@ -8038,7 +8038,7 @@ void platform_displace_props(struct prop *platform, s16 *propnums, struct coord sp8c.z = newpos->z - prevpos->z; set_current_player_num(playernum); - bwalk0f0c63bc(&sp8c, 1, CDTYPE_BG); + bwalk_resolve_posdelta(&sp8c, true, CDTYPE_BG); prop->pos.y += newpos->y - prevpos->y; @@ -8256,7 +8256,7 @@ void escastep_tick(struct prop *prop) prop->pos.z = newpos.z; if ((obj->flags & OBJFLAG_IGNOREFLOORCOLOUR) == 0) { - cd_find_floor_y_colour_type_at_pos(&prop->pos, prop->rooms, &obj->floorcol, 0); + cd_find_ground_at_pos_ct(&prop->pos, prop->rooms, &obj->floorcol, 0); } obj_onmoved(obj, true, true); @@ -8374,7 +8374,7 @@ void cctv_tick(struct prop *camprop) if (canseeplayer) { player_set_perim_enabled(playerprop, false); - if (!cd_test_los05(&camprop->pos, camprop->rooms, &playerprop->pos, playerprop->rooms, + if (!cd_test_los_oobfail(&camprop->pos, camprop->rooms, &playerprop->pos, playerprop->rooms, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SIGHT)) { canseeplayer = false; @@ -8865,7 +8865,7 @@ void autogun_tick(struct prop *prop) if (relangleh <= autogun->ymaxleft && relangleh >= autogun->ymaxright && track - && cd_test_los05(&prop->pos, prop->rooms, &target->pos, target->rooms, CDTYPE_ALL, GEOFLAG_BLOCK_SIGHT)) { + && cd_test_los_oobfail(&prop->pos, prop->rooms, &target->pos, target->rooms, CDTYPE_ALL, GEOFLAG_BLOCK_SIGHT)) { // Target is in sight obj->flags |= OBJFLAG_AUTOGUN_SEENTARGET; insight = true; @@ -9164,7 +9164,7 @@ void autogun_tick_shoot(struct prop *autogunprop) mtx00015be4(cam_get_projection_mtxf(), sp108, &spc8); mtx4_transform_vec_in_place(&spc8, &gunpos); - if (cd_test_los10(&autogunprop->pos, autogunprop->rooms, &gunpos, gunrooms, CDTYPE_BG, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { + if (cd_test_los_oobok_getfinalroom(&autogunprop->pos, autogunprop->rooms, &gunpos, gunrooms, CDTYPE_BG, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { gunpos.x = autogunprop->pos.x; gunpos.y = autogunprop->pos.y; gunpos.z = autogunprop->pos.z; @@ -9192,15 +9192,15 @@ void autogun_tick_shoot(struct prop *autogunprop) if (g_Vars.normmplayerisrunning || (targetprop && (targetprop->type == PROPTYPE_CHR)) || (g_Vars.antiplayernum >= 0 && targetprop && targetprop == g_Vars.anti->prop)) { - if (cd_exam_los08(&gunpos, gunrooms, &hitpos, CDTYPE_ALL, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { + if (cd_test_los_oobok_findclosest(&gunpos, gunrooms, &hitpos, CDTYPE_ALL, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { #if VERSION >= VERSION_PAL_FINAL - cd_get_pos(&hitpos, 11480, "prop/propobj.c"); + cd_get_obstacle_pos(&hitpos, 11480, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&hitpos, 11480, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11480, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&hitpos, 11458, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11458, "propobj.c"); #else - cd_get_pos(&hitpos, 11296, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11296, "propobj.c"); #endif hitprop = cd_get_obstacle_prop(); @@ -9247,17 +9247,17 @@ void autogun_tick_shoot(struct prop *autogunprop) // Laptop in firing range struct prop *hitprop = NULL; - if (cd_exam_los08(&gunpos, gunrooms, &hitpos, + if (cd_test_los_oobok_findclosest(&gunpos, gunrooms, &hitpos, CDTYPE_ALL & ~CDTYPE_PLAYERS, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { #if VERSION >= VERSION_PAL_FINAL - cd_get_pos(&hitpos, 11535, "prop/propobj.c"); + cd_get_obstacle_pos(&hitpos, 11535, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&hitpos, 11535, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11535, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&hitpos, 11513, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11513, "propobj.c"); #else - cd_get_pos(&hitpos, 11351, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11351, "propobj.c"); #endif hitprop = cd_get_obstacle_prop(); @@ -9285,17 +9285,17 @@ void autogun_tick_shoot(struct prop *autogunprop) } } else { // Enemy autogun in solo - if (cd_exam_los08(&gunpos, gunrooms, &hitpos, + if (cd_test_los_oobok_findclosest(&gunpos, gunrooms, &hitpos, CDTYPE_DOORS | CDTYPE_BG, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { #if VERSION >= VERSION_PAL_FINAL - cd_get_pos(&hitpos, 11561, "prop/propobj.c"); + cd_get_obstacle_pos(&hitpos, 11561, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&hitpos, 11561, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11561, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&hitpos, 11539, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11539, "propobj.c"); #else - cd_get_pos(&hitpos, 11377, "propobj.c"); + cd_get_obstacle_pos(&hitpos, 11377, "propobj.c"); #endif missed = true; @@ -9565,7 +9565,7 @@ bool chopper_check_target_in_sight(struct chopperobj *obj) struct prop *target = chopper_get_target_prop(chopper); if (target->type != PROPTYPE_PLAYER || g_Vars.bondvisible) { - visible = cd_test_los05(&target->pos, target->rooms, &chopper->base.prop->pos, chopper->base.prop->rooms, + visible = cd_test_los_oobfail(&target->pos, target->rooms, &chopper->base.prop->pos, chopper->base.prop->rooms, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SHOOT); } @@ -10162,7 +10162,7 @@ void chopper_tick_fall(struct prop *chopperprop) newpos.y = chopperprop->pos.y + newspeed.f[1] * g_Vars.lvupdate60freal; newpos.z = chopperprop->pos.z + newspeed.f[2] * g_Vars.lvupdate60freal; - if (cd_exam_los09(&chopperprop->pos, chopperprop->rooms, &newpos, CDTYPE_BG) == CDRESULT_COLLISION) { + if (cd_test_los_oobok_findclosest_autoflags(&chopperprop->pos, chopperprop->rooms, &newpos, CDTYPE_BG) == CDRESULT_COLLISION) { struct coord sp74; RoomNum room; struct coord sp64; @@ -10170,17 +10170,17 @@ void chopper_tick_fall(struct prop *chopperprop) RoomNum newrooms[8]; chopperprop->pos.y += 100; - ground = cd_find_ground_at_cyl(&chopperprop->pos, 5, chopperprop->rooms, NULL, NULL); + ground = cd_find_ground_at_cyl_ct(&chopperprop->pos, 5, chopperprop->rooms, NULL, NULL); chopperprop->pos.y -= 100; #if VERSION >= VERSION_PAL_FINAL - cd_get_pos(&sp64, 12476, "prop/propobj.c"); + cd_get_obstacle_pos(&sp64, 12476, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&sp64, 12476, "propobj.c"); + cd_get_obstacle_pos(&sp64, 12476, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&sp64, 12449, "propobj.c"); + cd_get_obstacle_pos(&sp64, 12449, "propobj.c"); #else - cd_get_pos(&sp64, 12286, "propobj.c"); + cd_get_obstacle_pos(&sp64, 12286, "propobj.c"); #endif newpos.x = sp64.x; @@ -10409,7 +10409,7 @@ void chopper_tick_combat(struct prop *chopperprop) goalpos.y = sp6c.y; goalpos.z = sp6c.z; } - } else if (cd_test_los03(&targetprop->pos, targetprop->rooms, &goalpos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SHOOT) == 0) { + } else if (cd_test_los_oobok(&targetprop->pos, targetprop->rooms, &goalpos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_AIOPAQUE, GEOFLAG_BLOCK_SHOOT) == 0) { pad_unpack(chopper->path->pads[chopper->cw ? (sp8c + 1) % chopper->path->len : sp8c], PADFIELD_POS, &pad); pad.pos.y += -250.0f; @@ -10579,7 +10579,7 @@ void hovercar_tick(struct prop *prop) sp210[0] = pad.room; sp210[1] = -1; - sp214.y = cd_find_ground_at_cyl(&pad.pos, 5, sp210, NULL, NULL) + 35; + sp214.y = cd_find_ground_at_cyl_ct(&pad.pos, 5, sp210, NULL, NULL) + 35; } else { sp214.y = pad.pos.y; } @@ -10608,8 +10608,8 @@ void hovercar_tick(struct prop *prop) } if (ishoverbot) { - if (cd_exam_cyl_move03(&prop->pos, prop->rooms, &sp214, - CDTYPE_CLOSEDDOORS | CDTYPE_AJARDOORS, 0, 0, 0) == CDRESULT_COLLISION) { + if (cd_test_cylmove_oobok_findclosest(&prop->pos, prop->rooms, &sp214, + CDTYPE_CLOSEDDOORS | CDTYPE_AJARDOORS, CHECKVERTICAL_NO, 0, 0) == CDRESULT_COLLISION) { doorprop = cd_get_obstacle_prop(); } @@ -10744,7 +10744,7 @@ void hovercar_tick(struct prop *prop) los_find_final_room_exhaustive(&prop->pos, prop->rooms, &sp150, sp140); if (ishoverbot) { - sp150.y = cd_find_ground_at_cyl(&sp150, 5, sp140, NULL, NULL) + 35; + sp150.y = cd_find_ground_at_cyl_ct(&sp150, 5, sp140, NULL, NULL) + 35; #if VERSION >= VERSION_NTSC_1_0 if (sp150.y < -100000) { @@ -11197,7 +11197,7 @@ s32 obj_tick_player(struct prop *prop) } if ((obj->flags & OBJFLAG_IGNOREFLOORCOLOUR) == 0) { - cd_find_floor_y_colour_type_at_pos(&prop->pos, prop->rooms, &obj->floorcol, 0); + cd_find_ground_at_pos_ct(&prop->pos, prop->rooms, &obj->floorcol, 0); } obj_onmoved(obj, true, true); @@ -11294,7 +11294,7 @@ s32 obj_tick_player(struct prop *prop) rooms_copy(sp220, prop->rooms); if (sp148 <= sp144) { - prop->pos.y = cd_find_ground_at_cyl(&prop->pos, 5, prop->rooms, &obj->floorcol, NULL) + prop->pos.y = cd_find_ground_at_cyl_ct(&prop->pos, 5, prop->rooms, &obj->floorcol, NULL) + obj_get_ground_clearance(obj) + sp112; } @@ -11303,7 +11303,7 @@ s32 obj_tick_player(struct prop *prop) if (obj_get_geometry(prop, (u8 **)geos, &end) && geos[0]->type == GEOTYPE_BLOCK - && cd_test_block_overlaps_any_prop((struct geoblock *) geos[0], prop->rooms, CDTYPE_PLAYERS) == CDRESULT_COLLISION) { + && cd_test_blockvolume((struct geoblock *) geos[0], prop->rooms, CDTYPE_PLAYERS) == CDRESULT_COLLISION) { damage = ((obj->maxdamage - obj->damage) + 1) / 250.0f; obj->flags &= ~OBJFLAG_INVINCIBLE; obj_damage(obj, damage, &prop->pos, WEAPON_REMOTEMINE, -1); @@ -12648,9 +12648,9 @@ Gfx *obj_render_shadow(struct defaultobj *obj, Gfx *gdl) f32 y; #if VERSION >= VERSION_NTSC_1_0 - s32 room = cd_find_floor_room_y_colour_flags_at_pos(&obj->prop->pos, obj->prop->rooms, &y, NULL, NULL); + s32 room = cd_find_room_at_pos_ycf(&obj->prop->pos, obj->prop->rooms, &y, NULL, NULL); #else - s32 room = cd_find_floor_room_y_colour_flags_at_pos(&obj->prop->pos, obj->prop->rooms, &y, NULL); + s32 room = cd_find_room_at_pos_ycf(&obj->prop->pos, obj->prop->rooms, &y, NULL); #endif if (room > 0 && (obj->modelnum == MODEL_HOOVERBOT || obj->modelnum == MODEL_TESTERBOT)) { @@ -13651,10 +13651,10 @@ bool obj_drop(struct prop *prop, bool lazy) spe4.y = spf0.m[3][1]; spe4.z = spf0.m[3][2]; - if (cd_test_los10(&root->pos, root->rooms, &spe4, rooms, CDTYPE_ALL, + if (cd_test_los_oobok_getfinalroom(&root->pos, root->rooms, &spe4, rooms, CDTYPE_ALL, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2 | GEOFLAG_WALL) == CDRESULT_COLLISION || (projectile->flags & PROJECTILEFLAG_STICKY) == 0) { - if (cd_test_volume(&spe4, obj_get_radius(obj), rooms, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0) == CDRESULT_COLLISION) { + if (cd_test_volume_simple(&spe4, obj_get_radius(obj), rooms, CDTYPE_ALL, CHECKVERTICAL_NO, 0.0f, 0) == CDRESULT_COLLISION) { spf0.m[3][0] = root->pos.x; spf0.m[3][2] = root->pos.z; } @@ -13799,7 +13799,7 @@ void obj_destroy_supported_objects(struct prop *tableprop, s32 playernum) { if (prop->pos.y > tableprop->pos.y && (obj->hidden & OBJHFLAG_ONANOTHEROBJ) - && cd_is_2d_point_in_geo(prop->pos.x, prop->pos.z, (struct geo *)start)) { + && cd_is_xz_in_geo(prop->pos.x, prop->pos.z, (struct geo *)start)) { obj_fall(obj, playernum); } } @@ -15108,7 +15108,7 @@ bool obj_test_for_interact(struct prop *prop) if (angle <= BADDTOR(22.5f)) { if ((obj->flags2 & OBJFLAG2_INTERACTCHECKLOS) == 0 - || cd_test_los06(&playerprop->pos, playerprop->rooms, &prop->pos, prop->rooms, CDTYPE_BG)) { + || cd_test_los_oobtail_autoflags(&playerprop->pos, playerprop->rooms, &prop->pos, prop->rooms, CDTYPE_BG)) { g_InteractProp = prop; } } @@ -16737,7 +16737,7 @@ s32 obj_test_for_pickup(struct prop *prop) if (pickup && (obj->flags2 & OBJFLAG2_PICKUPWITHOUTLOS) == 0 && !usebigrange - && cd_test_los05(&playerprop->pos, playerprop->rooms, &prop->pos, prop->rooms, + && cd_test_los_oobfail(&playerprop->pos, playerprop->rooms, &prop->pos, prop->rooms, CDTYPE_DOORS | CDTYPE_BG, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT) == false) { pickup = false; @@ -19265,7 +19265,7 @@ void doors_calc_frac(struct doorobj *door) { prop_set_perim_enabled(loopprop, false); - cdresult = cd_test_block_overlaps_any_prop(loopdoor->base.geoblock, loopprop->rooms, + cdresult = cd_test_blockvolume(loopdoor->base.geoblock, loopprop->rooms, CDTYPE_OBJS | CDTYPE_PLAYERS | CDTYPE_CHRS | CDTYPE_PATHBLOCKER | CDTYPE_OBJSNOTSAFEORHELI); prop_set_perim_enabled(loopprop, true); @@ -19657,7 +19657,7 @@ bool door_test_for_interact(struct prop *prop) if (maybe) { if ((door->base.flags2 & OBJFLAG2_INTERACTCHECKLOS) == 0 - || cd_test_los06(&playerprop->pos, playerprop->rooms, &prop->pos, prop->rooms, CDTYPE_BG)) { + || cd_test_los_oobtail_autoflags(&playerprop->pos, playerprop->rooms, &prop->pos, prop->rooms, CDTYPE_BG)) { checkmore = door_test_interact_angle(door, false); if (checkmore && (door->base.flags2 & OBJFLAG2_DOOR_ALTCOORDSYSTEM)) { @@ -20341,20 +20341,20 @@ void projectile_create(struct prop *fromprop, struct fireslotthing *arg1, struct prop_set_perim_enabled(fromprop, false); - if (cd_exam_los08(pos, fromprop->rooms, &endpos, - CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_PATHBLOCKER| CDTYPE_BG, + if (cd_test_los_oobok_findclosest(pos, fromprop->rooms, &endpos, + CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_PATHBLOCKER | CDTYPE_BG, GEOFLAG_BLOCK_SHOOT) == CDRESULT_COLLISION) { blocked = true; #if VERSION >= VERSION_JPN_FINAL - cd_get_pos(&endpos, 24883, "prop/propobj.c"); + cd_get_obstacle_pos(&endpos, 24883, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_FINAL - cd_get_pos(&endpos, 24873, "prop/propobj.c"); + cd_get_obstacle_pos(&endpos, 24873, "prop/propobj.c"); #elif VERSION >= VERSION_PAL_BETA - cd_get_pos(&endpos, 24873, "propobj.c"); + cd_get_obstacle_pos(&endpos, 24873, "propobj.c"); #elif VERSION >= VERSION_NTSC_1_0 - cd_get_pos(&endpos, 24482, "propobj.c"); + cd_get_obstacle_pos(&endpos, 24482, "propobj.c"); #else - cd_get_pos(&endpos, 24137, "propobj.c"); + cd_get_obstacle_pos(&endpos, 24137, "propobj.c"); #endif obstacle = cd_get_obstacle_prop(); } diff --git a/src/game/setup.c b/src/game/setup.c index f85c6bdeb..936303506 100644 --- a/src/game/setup.c +++ b/src/game/setup.c @@ -1783,7 +1783,7 @@ void setup_create_props(s32 stagenum) car->nextstep = 0; if (obj->flags & OBJFLAG_CHOPPER_INACTIVE) { - prop->pos.y = cd_find_floor_y_colour_type_at_pos(&prop->pos, prop->rooms, NULL, 0) + 30; + prop->pos.y = cd_find_ground_at_pos_ct(&prop->pos, prop->rooms, NULL, 0) + 30; } prop->forcetick = true; diff --git a/src/game/setupcover.c b/src/game/setupcover.c index a4b4aa821..52b388b27 100644 --- a/src/game/setupcover.c +++ b/src/game/setupcover.c @@ -77,7 +77,7 @@ void setup_prepare_cover(void) g_CoverRooms[i] = -1; if (roomsptr != NULL) { - s32 room = cd_find_floor_room_at_pos(cover.pos, roomsptr); + s32 room = cd_find_room_at_pos(cover.pos, roomsptr); if (room > 0) { g_CoverRooms[i] = (RoomNum)room; @@ -103,7 +103,7 @@ void setup_prepare_cover(void) } if (roomsptr) { - s32 aimroom = cd_find_floor_room_at_pos(&aimpos, roomsptr); + s32 aimroom = cd_find_room_at_pos(&aimpos, roomsptr); if (aimroom > 0) { g_CoverFlags[i] |= (g_CoverRooms[i] == (RoomNum)aimroom) ? COVERFLAG_AIMSAMEROOM : COVERFLAG_AIMDIFFROOM; diff --git a/src/game/setuppads.c b/src/game/setuppads.c index 0bdfddea1..f545da73a 100644 --- a/src/game/setuppads.c +++ b/src/game/setuppads.c @@ -61,7 +61,7 @@ void setup_prepare_pads(void) } if (roomsptr != NULL) { - roomnum = cd_find_floor_room_at_pos(&pad.pos, roomsptr); + roomnum = cd_find_room_at_pos(&pad.pos, roomsptr); if (roomnum > 0) { packedpad->room = roomnum; diff --git a/src/include/bss.h b/src/include/bss.h index 41bbdc89e..4aa843d16 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -39,7 +39,7 @@ extern u8 **g_AnimHeaderBytes; extern union filedataptr g_TileFileData; extern s32 g_TileNumRooms; extern u32 *g_TileRooms; -extern struct geoblock g_CdSavedBlock; +extern struct geoblock g_CdBlock; extern u8 g_RdpDramStack[SP_DRAM_STACK_SIZE8]; extern N_ALSndPlayer var8009c2d0; extern struct var8009c340 var8009c340; diff --git a/src/include/data.h b/src/include/data.h index f38012dd9..4e1a3d517 100644 --- a/src/include/data.h +++ b/src/include/data.h @@ -62,8 +62,8 @@ extern s32 g_AnimMaxBytesPerFrame; extern s32 g_AnimMaxHeaderLength; extern bool g_AnimHostEnabled; extern s32 var8005f030; -extern s32 g_CdHasSavedBlock; -extern s32 var8005f038; +extern s32 g_CdHasBlock; +extern s32 g_CdHasGeo; extern u16 *g_RdpOutBufferEnd; extern u16 *g_RdpOutBufferStart; extern struct rdptask *g_RdpCurTask; diff --git a/src/include/game/bondwalk.h b/src/include/game/bondwalk.h index 267405aaa..274b3f11d 100644 --- a/src/include/game/bondwalk.h +++ b/src/include/game/bondwalk.h @@ -7,7 +7,7 @@ void bwalk_init(void); void bwalk_adjust_crouch_pos(s32 value); s32 bwalk_try_move_upwards(f32 amount); -void bwalk0f0c63bc(struct coord *arg0, u32 arg1, s32 types); +void bwalk_resolve_posdelta(struct coord *deltapos, bool notrleaning, s32 cdtypes); void bwalk_handle_activate(void); void bwalk_apply_move_data(struct movedata *data); void bwalk_update_speed_theta(void); diff --git a/src/include/lib/collision.h b/src/include/lib/collision.h index dcebceea8..a48aa5436 100644 --- a/src/include/lib/collision.h +++ b/src/include/lib/collision.h @@ -5,63 +5,68 @@ #include "types.h" f32 func0f1577f0(f32 arg0[2], f32 arg1[2], f32 arg2[2], f32 arg3[2]); -f32 func0f1579cc(struct widthxz *arg0, struct xz *arg1, struct xz *arg2, struct xz *arg3); +f32 func0f1579cc(struct radiusxz *arg0, struct xz *arg1, struct xz *arg2, struct xz *arg3); -f32 cd_00024e40(void); +f32 cd_get_sqdistance(void); void cd_get_edge(struct coord *pos1, struct coord *pos2, u32 line, char *file); f32 cd_get_distance(void); bool cd_has_distance(void); struct prop *cd_get_obstacle_prop(void); -void cd_get_pos(struct coord *pos, u32 line, char *file); +void cd_get_obstacle_pos(struct coord *pos, u32 line, char *file); void cd_get_obstacle_normal(struct coord *normal); u32 cd_get_geo_flags(void); -void cd_set_saved_pos(struct coord *pos1, struct coord *pos2); -bool cd_get_saved_pos(struct coord *arg0, struct coord *arg1); -bool cd_is_2d_point_in_geo(f32 x, f32 z, struct geo *tile); +void cd_set_block_edge(struct coord *vtx1, struct coord *vtx2); +bool cd_get_block_edge(struct coord *vtx1, struct coord *vtx2); + +bool cd_is_xz_in_geo(f32 x, f32 z, struct geo *tile); void cd_get_props_on_platform(struct prop *platform, s16 *propnums, s32 len); -s32 cd_000274e0_block(struct geoblock *tile, f32 x, f32 z, f32 width, struct prop *prop, struct collision *collision); -bool cd_000276c8_cyl(struct geocyl *tile, f32 x, f32 z, f32 width, struct prop *prop, struct collision *collision); +s32 cd_block_collides_with_cyl_laterally(struct geoblock *tile, f32 x, f32 z, f32 width, struct prop *prop, struct collision *collision); +bool cd_cyl_collides_with_cyl_laterally(struct geocyl *tile, f32 x, f32 z, f32 width, struct prop *prop, struct collision *collision); bool cd_find_ladder(struct coord *pos, f32 width, f32 ymax, f32 ymin, RoomNum *rooms, u16 geoflags, struct coord *laddernormal); -bool cd_0002a13c(struct coord *pos, f32 radius, f32 arg2, f32 arg3, RoomNum *rooms, u16 geoflags); -f32 cd_find_ground_info_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, u8 *floortype, u16 *floorflags, RoomNum *floorroom, s32 *inlift, struct prop **lift); +bool is_cyl_touching_tile_with_flags(struct coord *pos, f32 radius, f32 ymax, f32 ymin, RoomNum *rooms, u16 geoflags); +f32 cd_find_ground_at_cyl_ctfril(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, u8 *floortype, u16 *floorflags, RoomNum *floorroom, s32 *inlift, struct prop **lift); f32 cd_return_zero(void); -f32 cd_find_ground_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, u8 *floortype); -f32 cd_find_floor_y_colour_type_at_pos(struct coord *pos, RoomNum *rooms, u16 *floorcol, u8 *floortype); -s32 cd_find_floor_room_at_pos(struct coord *pos, RoomNum *nearrooms); +f32 cd_find_ground_at_cyl_ct(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, u8 *floortype); +f32 cd_find_ground_at_pos_ct(struct coord *pos, RoomNum *rooms, u16 *floorcol, u8 *floortype); +RoomNum cd_find_room_at_pos(struct coord *pos, RoomNum *nearrooms); #if VERSION >= VERSION_NTSC_1_0 -RoomNum cd_find_floor_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr, u16 *flagsptr); -RoomNum cd_find_ceiling_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr, u16 *flagsptr); +RoomNum cd_find_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *y, u16 *floorcolptr, u16 *flagsptr); +RoomNum cd_find_ceiling_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *y, u16 *floorcolptr, u16 *flagsptr); #else -RoomNum cd_find_floor_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr); -RoomNum cd_find_ceiling_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr); +RoomNum cd_find_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *y, u16 *floorcolptr); +RoomNum cd_find_ceiling_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *y, u16 *floorcolptr); #endif -RoomNum cd_find_floor_room_y_colour_normal_prop_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcol, struct coord *normal, struct prop **propptr); -RoomNum cd_find_ceiling_room_y_colour_flags_normal_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcol, u16 *geoflags, struct coord *normal); -s32 cd_test_volume(struct coord *pos, f32 radius, RoomNum *rooms, s32 types, bool checkvertical, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move01(struct coord *pos, struct coord *pos2, f32 radius, RoomNum *rooms, s32 types, bool checkvertical, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move02(struct coord *origpos, struct coord *dstpos, f32 width, RoomNum *dstrooms, s32 types, bool checkvertical, f32 ymax, f32 ymin); -bool cd_test_cyl_move01(struct coord *pos, RoomNum *rooms, struct coord *targetpos, u32 types, u32 arg4, f32 ymax, f32 ymin); -s32 cd_test_cyl_move02(struct coord *pos, RoomNum *rooms, struct coord *coord2, RoomNum *rooms2, u32 types, bool arg5, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move03(struct coord *pos, RoomNum *rooms, struct coord *arg2, u32 types, u32 arg4, f32 ymax, f32 ymin); -s32 cd_test_cyl_move04(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types, s32 arg5, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move05(struct coord *pos, RoomNum *rooms, struct coord *pos2, RoomNum *rooms2, s32 types, bool arg5, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move06(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, f32 arg4, s32 types, s32 arg6, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move07(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types, s32 arg5, f32 ymax, f32 ymin); -s32 cd_exam_cyl_move08(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, f32 width, u32 types, s32 arg6, f32 ymax, f32 ymin); -bool cd_test_los03(struct coord *viewpos, RoomNum *rooms, struct coord *targetpos, u32 types, u16 geoflags); -bool cd_test_los04(struct coord *coord, RoomNum *rooms, struct coord *coord2, s32 arg3); -bool cd_test_los05(struct coord *coord, RoomNum *rooms, struct coord *coord2, RoomNum *rooms2, s32 cdtypes, u16 geoflags); -bool cd_test_los06(struct coord *arg0, RoomNum *rooms1, struct coord *arg2, RoomNum *rooms2, u32 types); -bool cd_test_los07(struct coord *pos, RoomNum *rooms, struct coord *pos2, RoomNum *rooms2, RoomNum *rooms3, u32 types, u16 geoflags); -s32 cd_exam_los08(struct coord *pos, RoomNum *rooms, struct coord *pos2, u32 types, u16 geoflags); -s32 cd_exam_los09(struct coord *pos, RoomNum *rooms, struct coord *pos2, u32 types); -s32 cd_test_los10(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types, u16 geoflags); -s32 cd_test_los11(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types); -bool cd_0002ded8(struct coord *arg0, struct coord *arg1, struct prop *prop); -s32 cd_test_block_overlaps_any_prop(struct geoblock *geo, RoomNum *rooms, u32 types); -s32 cd_0002f02c(struct geoblock *block, RoomNum *rooms, s32 types); -bool cd_is_nearly_in_sight(struct coord *viewpos, RoomNum *rooms, struct coord *targetpos, f32 distance, s32 arg4); +RoomNum cd_find_room_at_pos_ycnp(struct coord *pos, RoomNum *rooms, f32 *y, u16 *floorcol, struct coord *normal, struct prop **propptr); +RoomNum cd_find_ceiling_room_at_pos_ycfn(struct coord *pos, RoomNum *rooms, f32 *y, u16 *floorcol, u16 *geoflags, struct coord *normal); + +s32 cd_test_volume_simple(struct coord *pos, f32 radius, RoomNum *rooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_volume_closestedge(struct coord *frompos, struct coord *topos, f32 radius, RoomNum *rooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_volume_fromdir(struct coord *frompos, struct coord *topos, f32 radius, RoomNum *dstrooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); + +s32 cd_test_cylmove_oobok(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobfail(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobok_findclosest(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobok_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobfail_findclosest(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobfail_findclosest_finddist(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, f32 radius, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobok_findclosest_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types, bool checkvertical, f32 ymax, f32 ymin); +s32 cd_test_cylmove_oobok_findclosest_getfinalroom_finddist(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, f32 radius, u32 types, bool checkvertical, f32 ymax, f32 ymin); + +s32 cd_test_los_oobok(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, u16 geoflags); +s32 cd_test_los_oobok_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types); +s32 cd_test_los_oobfail(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types, u16 geoflags); +s32 cd_test_los_oobtail_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types); +s32 cd_test_los_oobfail_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, RoomNum *finalrooms, u32 types, u16 geoflags); +s32 cd_test_los_oobok_findclosest(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, u16 geoflags); +s32 cd_test_los_oobok_findclosest_autoflags(struct coord *pos, RoomNum *rooms, struct coord *pos2, u32 types); +s32 cd_test_los_oobok_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types, u16 geoflags); +s32 cd_test_los_oobok_getfinalroom_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types); + +bool cd_test_line_intersects_prop(struct coord *frompos, struct coord *topos, struct prop *prop); +s32 cd_test_blockvolume(struct geoblock *block, RoomNum *rooms, u32 types); +s32 cd_test_blockmove(struct geoblock *block, RoomNum *rooms, u32 types); +bool cd_is_nearly_in_sight(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, f32 distance, u32 types); #endif diff --git a/src/include/types.h b/src/include/types.h index c1b250d2e..9899dcaf1 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -5810,8 +5810,8 @@ struct xraydata { /*0x24a*/ s16 numtris; }; -struct widthxz { - f32 width; +struct radiusxz { + f32 radius; f32 x; f32 z; }; diff --git a/src/lib/collision.c b/src/lib/collision.c index 1c2c65c0d..a2a4301c6 100644 --- a/src/lib/collision.c +++ b/src/lib/collision.c @@ -18,6 +18,9 @@ #define SURFACE_FLOOR 0 #define SURFACE_CEILING 1 +#define ATOBTYPE_CYL 0 +#define ATOBTYPE_LOS 1 + struct debugtri { s16 vertices[3][3]; u8 unk12; @@ -26,37 +29,39 @@ struct debugtri { union filedataptr g_TileFileData; s32 g_TileNumRooms; u32 *g_TileRooms; -bool var8009a8ac; -f32 var8009a8b0; -s32 var8009a8b4; -struct coord g_CdEdgeVtx1; -s32 var8009a8c4; -struct coord g_CdEdgeVtx2; -struct prop *g_CdObstacleProp; -s32 var8009a8d8; -s32 var8009a8dc; -struct coord g_CdObstaclePos; -s32 var8009a8ec; -f32 var8009a8f0; -bool g_CdHasSavedPos; -struct coord g_CdPos1; -s32 var8009a904; -struct coord g_CdPos2; -s32 var8009a914; -struct geoblock g_CdSavedBlock; -struct geo *g_CdObstacleGeo; -s32 var8009a968; -s32 var8009a96c; -s32 var8005f030 = 0; -bool g_CdHasSavedBlock = false; -s32 var8005f038 = 0; +bool g_CdReverseVertices = false; + +bool g_CdHasDistance; +f32 g_CdDistance; + +bool g_CdHasEdge; +struct coord g_CdEdgeVtx1; +struct coord g_CdEdgeVtx2; + +struct prop *g_CdProp; + +bool g_CdHasPos; +struct coord g_CdPos; + +bool g_CdHasDistance2; +f32 g_CdSquaredDistance; + +bool g_CdHasBlockEdge; +struct coord g_CdBlockEdgeVtx1; +struct coord g_CdBlockEdgeVtx2; + +bool g_CdHasBlock = false; +struct geoblock g_CdBlock; + +bool g_CdHasGeo = false; +struct geo *g_CdGeo; void cd_get_geo_normal(struct geo *geo, struct coord *normal); -f32 cd_00024e40(void) +f32 cd_get_sqdistance(void) { - return var8009a8f0; + return g_CdSquaredDistance; } void cd_get_edge(struct coord *vtx1, struct coord *vtx2, u32 line, char *file) @@ -72,47 +77,47 @@ void cd_get_edge(struct coord *vtx1, struct coord *vtx2, u32 line, char *file) f32 cd_get_distance(void) { - return var8009a8b0; + return g_CdDistance; } bool cd_has_distance(void) { - return var8009a8ac; + return g_CdHasDistance; } struct prop *cd_get_obstacle_prop(void) { - return g_CdObstacleProp; + return g_CdProp; } -void cd_get_pos(struct coord *pos, u32 line, char *file) +void cd_get_obstacle_pos(struct coord *pos, u32 line, char *file) { - pos->x = g_CdObstaclePos.x; - pos->y = g_CdObstaclePos.y; - pos->z = g_CdObstaclePos.z; + pos->x = g_CdPos.x; + pos->y = g_CdPos.y; + pos->z = g_CdPos.z; } void cd_get_obstacle_normal(struct coord *normal) { - cd_get_geo_normal(g_CdObstacleGeo, normal); + cd_get_geo_normal(g_CdGeo, normal); } u32 cd_get_geo_flags(void) { u32 flags = 0; - switch (g_CdObstacleGeo->type) { + switch (g_CdGeo->type) { case GEOTYPE_TILE_I: - flags = g_CdObstacleGeo->flags; + flags = g_CdGeo->flags; break; case GEOTYPE_TILE_F: - flags = g_CdObstacleGeo->flags; + flags = g_CdGeo->flags; break; case GEOTYPE_BLOCK: flags = GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT; break; case GEOTYPE_CYL: - flags = g_CdObstacleGeo->flags; + flags = g_CdGeo->flags; break; } @@ -121,95 +126,119 @@ u32 cd_get_geo_flags(void) void cd_clear_results(void) { - var8009a8b4 = 0; - var8009a8ac = false; - g_CdObstacleProp = NULL; - var8009a8d8 = 0; - var8009a8ec = 0; - g_CdHasSavedPos = false; - g_CdHasSavedBlock = false; - var8005f038 = 0; + g_CdHasEdge = false; + g_CdHasDistance = false; + g_CdProp = NULL; + g_CdHasPos = false; + g_CdHasDistance2 = false; + g_CdHasBlockEdge = false; + g_CdHasBlock = false; + g_CdHasGeo = false; } -void cd_set_obstacle_vtx_prop(struct coord *vtx1, struct coord *vtx2, struct prop *prop) +void cd_set_obstacle_edge_prop(struct coord *edgevtx1, struct coord *edgevtx2, struct prop *prop) { - g_CdEdgeVtx1.x = vtx1->x; - g_CdEdgeVtx1.y = vtx1->y; - g_CdEdgeVtx1.z = vtx1->z; + g_CdEdgeVtx1.x = edgevtx1->x; + g_CdEdgeVtx1.y = edgevtx1->y; + g_CdEdgeVtx1.z = edgevtx1->z; - g_CdEdgeVtx2.x = vtx2->x; - g_CdEdgeVtx2.y = vtx2->y; - g_CdEdgeVtx2.z = vtx2->z; + g_CdEdgeVtx2.x = edgevtx2->x; + g_CdEdgeVtx2.y = edgevtx2->y; + g_CdEdgeVtx2.z = edgevtx2->z; - var8009a8b4 = 1; - var8009a8ac = false; - g_CdObstacleProp = prop; - var8009a8d8 = 0; - var8009a8ec = 0; - g_CdHasSavedPos = false; - g_CdHasSavedBlock = false; - var8005f038 = 0; + g_CdHasEdge = true; + g_CdHasDistance = false; + g_CdProp = prop; + g_CdHasPos = false; + g_CdHasDistance2 = false; + g_CdHasBlockEdge = false; + g_CdHasBlock = false; + g_CdHasGeo = false; } -void cd_set_obstacle_vtx_prop_flt(struct coord *vtx1, struct coord *vtx2, struct prop *prop, f32 arg3) +void cd_set_obstacle_edge_prop_dist(struct coord *edgevtx1, struct coord *edgevtx2, struct prop *prop, f32 dist) { - var8009a8b0 = arg3; + g_CdDistance = dist; - g_CdEdgeVtx1.x = vtx1->x; - g_CdEdgeVtx1.y = vtx1->y; - g_CdEdgeVtx1.z = vtx1->z; + g_CdEdgeVtx1.x = edgevtx1->x; + g_CdEdgeVtx1.y = edgevtx1->y; + g_CdEdgeVtx1.z = edgevtx1->z; - g_CdEdgeVtx2.x = vtx2->x; - g_CdEdgeVtx2.y = vtx2->y; - g_CdEdgeVtx2.z = vtx2->z; + g_CdEdgeVtx2.x = edgevtx2->x; + g_CdEdgeVtx2.y = edgevtx2->y; + g_CdEdgeVtx2.z = edgevtx2->z; - var8009a8b4 = 1; - var8009a8ac = true; - g_CdObstacleProp = prop; - var8009a8d8 = 0; - var8009a8ec = 0; - g_CdHasSavedPos = false; - g_CdHasSavedBlock = false; - var8005f038 = 0; + g_CdHasEdge = true; + g_CdHasDistance = true; + g_CdProp = prop; + g_CdHasPos = false; + g_CdHasDistance2 = false; + g_CdHasBlockEdge = false; + g_CdHasBlock = false; + g_CdHasGeo = false; } -void cd_000250cc(struct coord *arg0, struct coord *arg1, f32 width) +void cd_set_obstacle_distance(struct coord *frompos, struct coord *diff, f32 radius) { - struct widthxz sp34; - struct xz sp2c; - struct xz sp24; - struct xz sp1c; + struct radiusxz rxz; + struct xz edge_vtx1; + struct xz edge_vtx2; + struct xz diffxz; - sp34.width = width; - sp34.x = arg0->x; - sp34.z = arg0->z; + rxz.radius = radius; + rxz.x = frompos->x; + rxz.z = frompos->z; - sp1c.x = arg1->x; - sp1c.z = arg1->z; + diffxz.x = diff->x; + diffxz.z = diff->z; - sp2c.x = g_CdEdgeVtx1.x; - sp2c.z = g_CdEdgeVtx1.z; + edge_vtx1.x = g_CdEdgeVtx1.x; + edge_vtx1.z = g_CdEdgeVtx1.z; - sp24.x = g_CdEdgeVtx2.x; - sp24.z = g_CdEdgeVtx2.z; + edge_vtx2.x = g_CdEdgeVtx2.x; + edge_vtx2.z = g_CdEdgeVtx2.z; - var8009a8b0 = func0f1579cc(&sp34, &sp2c, &sp24, &sp1c); - var8009a8ac = true; + g_CdDistance = func0f1579cc(&rxz, &edge_vtx1, &edge_vtx2, &diffxz); + g_CdHasDistance = true; } void cd_set_obstacle_prop(struct prop *prop) { - var8009a8b4 = 0; - var8009a8ac = false; - g_CdObstacleProp = prop; - var8009a8d8 = 0; - var8009a8ec = 0; - g_CdHasSavedPos = false; - g_CdHasSavedBlock = false; - var8005f038 = 0; + g_CdHasEdge = false; + g_CdHasDistance = false; + g_CdProp = prop; + g_CdHasPos = false; + g_CdHasDistance2 = false; + g_CdHasBlockEdge = false; + g_CdHasBlock = false; + g_CdHasGeo = false; } -void cd_set_obstacle_vtx_col_prop(struct coord *vtxpos1, struct coord *vtxpos2, struct coord *collisionpos, struct prop *prop) +void cd_set_obstacle_edge_pos_prop(struct coord *edgevtx1, struct coord *edgevtx2, struct coord *collisionpos, struct prop *prop) +{ + g_CdEdgeVtx1.x = edgevtx1->x; + g_CdEdgeVtx1.y = edgevtx1->y; + g_CdEdgeVtx1.z = edgevtx1->z; + + g_CdEdgeVtx2.x = edgevtx2->x; + g_CdEdgeVtx2.y = edgevtx2->y; + g_CdEdgeVtx2.z = edgevtx2->z; + + g_CdPos.x = collisionpos->x; + g_CdPos.y = collisionpos->y; + g_CdPos.z = collisionpos->z; + + g_CdHasEdge = true; + g_CdHasDistance = false; + g_CdProp = prop; + g_CdHasPos = true; + g_CdHasDistance2 = false; + g_CdHasBlockEdge = false; + g_CdHasBlock = false; + g_CdHasGeo = false; +} + +void cd_set_obstacle_edge_pos_prop_sqdist_geo(struct coord *vtxpos1, struct coord *vtxpos2, struct coord *collisionpos, struct prop *prop, f32 sqdist, struct geo *geo) { g_CdEdgeVtx1.x = vtxpos1->x; g_CdEdgeVtx1.y = vtxpos1->y; @@ -219,84 +248,60 @@ void cd_set_obstacle_vtx_col_prop(struct coord *vtxpos1, struct coord *vtxpos2, g_CdEdgeVtx2.y = vtxpos2->y; g_CdEdgeVtx2.z = vtxpos2->z; - g_CdObstaclePos.x = collisionpos->x; - g_CdObstaclePos.y = collisionpos->y; - g_CdObstaclePos.z = collisionpos->z; + g_CdPos.x = collisionpos->x; + g_CdPos.y = collisionpos->y; + g_CdPos.z = collisionpos->z; - var8009a8b4 = 1; - var8009a8ac = false; - g_CdObstacleProp = prop; - var8009a8d8 = 1; - var8009a8ec = 0; - g_CdHasSavedPos = false; - g_CdHasSavedBlock = false; - var8005f038 = 0; + g_CdHasEdge = true; + g_CdHasDistance = false; + g_CdProp = prop; + g_CdHasPos = true; + g_CdSquaredDistance = sqdist; + g_CdHasDistance2 = true; + g_CdHasBlockEdge = false; + g_CdHasBlock = false; + g_CdGeo = geo; + g_CdHasGeo = true; } -void cd_set_obstacle_vtx_col_prop_flt_geo(struct coord *vtxpos1, struct coord *vtxpos2, struct coord *collisionpos, struct prop *prop, f32 arg4, struct geo *geo) +void cd_set_block_edge(struct coord *vtx1, struct coord *vtx2) { - g_CdEdgeVtx1.x = vtxpos1->x; - g_CdEdgeVtx1.y = vtxpos1->y; - g_CdEdgeVtx1.z = vtxpos1->z; + g_CdBlockEdgeVtx1.x = vtx1->x; + g_CdBlockEdgeVtx1.y = vtx1->y; + g_CdBlockEdgeVtx1.z = vtx1->z; - g_CdEdgeVtx2.x = vtxpos2->x; - g_CdEdgeVtx2.y = vtxpos2->y; - g_CdEdgeVtx2.z = vtxpos2->z; + g_CdBlockEdgeVtx2.x = vtx2->x; + g_CdBlockEdgeVtx2.y = vtx2->y; + g_CdBlockEdgeVtx2.z = vtx2->z; - g_CdObstaclePos.x = collisionpos->x; - g_CdObstaclePos.y = collisionpos->y; - g_CdObstaclePos.z = collisionpos->z; - - var8009a8b4 = 1; - var8009a8ac = false; - g_CdObstacleProp = prop; - var8009a8d8 = 1; - var8009a8f0 = arg4; - var8009a8ec = 1; - g_CdHasSavedPos = false; - g_CdHasSavedBlock = false; - g_CdObstacleGeo = geo; - var8005f038 = 1; + g_CdHasBlockEdge = true; } -void cd_set_saved_pos(struct coord *pos1, struct coord *pos2) +bool cd_get_block_edge(struct coord *vtx1, struct coord *vtx2) { - g_CdPos1.x = pos1->x; - g_CdPos1.y = pos1->y; - g_CdPos1.z = pos1->z; + if (g_CdHasBlockEdge) { + vtx1->x = g_CdBlockEdgeVtx1.x; + vtx1->y = g_CdBlockEdgeVtx1.y; + vtx1->z = g_CdBlockEdgeVtx1.z; - g_CdPos2.x = pos2->x; - g_CdPos2.y = pos2->y; - g_CdPos2.z = pos2->z; - - g_CdHasSavedPos = true; -} - -bool cd_get_saved_pos(struct coord *pos1, struct coord *pos2) -{ - if (g_CdHasSavedPos) { - pos1->x = g_CdPos1.x; - pos1->y = g_CdPos1.y; - pos1->z = g_CdPos1.z; - - pos2->x = g_CdPos2.x; - pos2->y = g_CdPos2.y; - pos2->z = g_CdPos2.z; + vtx2->x = g_CdBlockEdgeVtx2.x; + vtx2->y = g_CdBlockEdgeVtx2.y; + vtx2->z = g_CdBlockEdgeVtx2.z; } - return g_CdHasSavedPos; + return g_CdHasBlockEdge; } -void cd_set_saved_block(struct geoblock *block) +void cd_set_block(struct geoblock *block) { - g_CdSavedBlock = *block; - g_CdHasSavedBlock = true; + g_CdBlock = *block; + g_CdHasBlock = true; } -s32 cd_00025410(f32 arg0, f32 arg1, f32 arg2, f32 arg3) +s32 cd_00025410(f32 x1, f32 z1, f32 x2, f32 z2) { - f32 f0 = arg0 * arg3; - f32 f2 = arg1 * arg2; + f32 f0 = x1 * z2; + f32 f2 = z1 * x2; if (f2 < f0) { return 1; @@ -306,18 +311,18 @@ s32 cd_00025410(f32 arg0, f32 arg1, f32 arg2, f32 arg3) return -1; } - if (arg0 * arg2 < 0.0f || arg1 * arg3 < 0.0f) { + if (x1 * x2 < 0.0f || z1 * z2 < 0.0f) { return -1; } - if (arg0 * arg0 + arg1 * arg1 < arg2 * arg2 + arg3 * arg3) { + if (x1 * x1 + z1 * z1 < x2 * x2 + z2 * z2) { return 1; } return 0; } -s32 cd_000254d8(struct coord *arg0, struct coord *arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, s32 *arg6) +s32 cd_000254d8(struct coord *frompos, struct coord *topos, f32 x1, f32 z1, f32 x2, f32 z2, bool *first) { f32 sp54; f32 sp50; @@ -331,19 +336,19 @@ s32 cd_000254d8(struct coord *arg0, struct coord *arg1, f32 arg2, f32 arg3, f32 s32 sp30; bool result = false; - sp54 = arg0->x - arg2; - sp50 = arg0->z - arg3; + sp54 = frompos->x - x1; + sp50 = frompos->z - z1; - sp3c = cd_00025410(arg4 - arg2, arg5 - arg3, sp54, sp50); - sp44 = cd_00025410(arg4 - arg2, arg5 - arg3, arg1->x - arg2, arg1->z - arg3); + sp3c = cd_00025410(x2 - x1, z2 - z1, sp54, sp50); + sp44 = cd_00025410(x2 - x1, z2 - z1, topos->x - x1, topos->z - z1); sp38 = sp3c * sp44; if (sp38 <= 0) { - sp4c = arg1->x - arg0->x; - sp48 = arg1->z - arg0->z; + sp4c = topos->x - frompos->x; + sp48 = topos->z - frompos->z; sp34 = cd_00025410(sp4c, sp48, -sp54, -sp50); - sp40 = cd_00025410(sp4c, sp48, arg4 - arg0->x, arg5 - arg0->z); + sp40 = cd_00025410(sp4c, sp48, x2 - frompos->x, z2 - frompos->z); sp30 = sp34 * sp40; if (sp30 <= 0) { @@ -351,73 +356,86 @@ s32 cd_000254d8(struct coord *arg0, struct coord *arg1, f32 arg2, f32 arg3, f32 } } - if (*arg6 && (result || sp3c <= 0)) { - *arg6 = 0; + if (*first && (result || sp3c <= 0)) { + *first = false; } return result; } -f32 cd_00025654(f32 x1, f32 z1, f32 x2, f32 z2, f32 x3, f32 z3) +/** + * Given a line between two vertices, draw a perpendicular line to pos and + * return the distance of that line. + */ +f32 cd_pos_get_dist_to_line(f32 x1, f32 z1, f32 x2, f32 z2, f32 posx, f32 posz) { u32 stack[8]; - f32 result; + f32 length; - result = sqrtf((x2 - x1) * (x2 - x1) + (z2 - z1) * (z2 - z1)); + length = sqrtf((x2 - x1) * (x2 - x1) + (z2 - z1) * (z2 - z1)); - if (result == 0.0f) { - return sqrtf((x3 - x2) * (x3 - x2) + (z3 - z2) * (z3 - z2)); + if (length == 0.0f) { + return sqrtf((posx - x2) * (posx - x2) + (posz - z2) * (posz - z2)); } - return ((x3 - x1) * (z2 - z1) + -(x2 - x1) * (z3 - z1)) / result; + return ((posx - x1) * (z2 - z1) + -(x2 - x1) * (posz - z1)) / length; } -f32 cd_00025724(f32 x1, f32 z1, f32 x2, f32 z2) +f32 cd_pos_get_dist_to_vtx(f32 x1, f32 z1, f32 posx, f32 posz) { - x2 -= x1; - z2 -= z1; + posx -= x1; + posz -= z1; - return sqrtf(x2 * x2 + z2 * z2); + return sqrtf(posx * posx + posz * posz); } -bool cd_00025774(f32 x1, f32 z1, f32 x2, f32 z2, f32 x3, f32 z3) +/** + * Given a line between two vertices, figure out which side of the line the + * position is on. + */ +s32 cd_pos_get_side(f32 x1, f32 z1, f32 x2, f32 z2, f32 posx, f32 posz) { - f32 f0; - f32 f2; + f32 x2_2; + f32 z2_2; f32 f16; f32 f18; - x3 -= x1; - z3 -= z1; + posx -= x1; + posz -= z1; - f0 = x2 - x1; - f2 = z2 - z1; + x2_2 = x2 - x1; + z2_2 = z2 - z1; - f16 = x3 * f0 + z3 * f2; - f18 = f0 * f0 + f2 * f2; + f16 = posx * x2_2 + posz * z2_2; + f18 = x2_2 * x2_2 + z2_2 * z2_2; - return (f18 < f16 && f16 < 0) || (f16 > 0 && f16 < f18); + return (f18 < f16 && f16 < 0) || (f16 > 0 && f18 > f16); } -void cd_00025848(f32 tilex, f32 tilez, f32 tilewidth, f32 posx, f32 posz, f32 *x1, f32 *z1, f32 *x2, f32 *z2) +/** + * Given a 2D cylinder/circle, and a pos that is inside the circle, + * move pos out to the edge of the circle then calculate a "wall" that + * separates pos from the circle. Return the vertices of that wall. + */ +void cd_pos_get_cyl_edge(f32 cylx, f32 cylz, f32 cylradius, f32 posx, f32 posz, f32 *x1, f32 *z1, f32 *x2, f32 *z2) { - posx -= tilex; - posz -= tilez; + posx -= cylx; + posz -= cylz; if (posx != 0 || posz != 0) { f32 dist = sqrtf(posx * posx + posz * posz); if (dist > 0) { - dist = tilewidth / dist; + dist = cylradius / dist; posx *= dist; posz *= dist; } } - *x1 = tilex + posx + posz; - *z1 = tilez + posz - posx; - *x2 = tilex + posx - posz; - *z2 = tilez + posz + posx; + *x1 = cylx + posx + posz; + *z1 = cylz + posz - posx; + *x2 = cylx + posx - posz; + *z2 = cylz + posz + posx; } void cd_get_geo_normal(struct geo *geo, struct coord *normal) @@ -539,7 +557,7 @@ void cd_get_floor_type(struct geo *geo, u8 *floortype) } } -f32 cd_find_ground_in_int_tile_at_vertex(struct geotilei *tile, f32 x, f32 z, s32 vertexindex) +f32 cd_find_y_tilei_vtx(struct geotilei *tile, f32 x, f32 z, s32 vertexindex) { struct coord sp7c; struct coord sp70; @@ -592,13 +610,13 @@ f32 cd_find_ground_in_int_tile_at_vertex(struct geotilei *tile, f32 x, f32 z, s3 } #if VERSION < VERSION_NTSC_1_0 -f32 cd_find_ground_in_tile_type0_at_vertex1(struct geotilei *tile, f32 x, f32 z) +f32 cd_find_y_tilei_vtx1(struct geotilei *tile, f32 x, f32 z) { - return cd_find_ground_in_int_tile_at_vertex(tile, x, z, 1); + return cd_find_y_tilei_vtx(tile, x, z, 1); } #endif -f32 cd_find_ground_in_int_tile(struct geotilei *tile, f32 x, f32 z) +f32 cd_find_y_tilei(struct geotilei *tile, f32 x, f32 z) { s32 i = 1; s32 ival = -1; @@ -628,10 +646,10 @@ f32 cd_find_ground_in_int_tile(struct geotilei *tile, f32 x, f32 z) } } - return cd_find_ground_in_int_tile_at_vertex(tile, x, z, i); + return cd_find_y_tilei_vtx(tile, x, z, i); } -f32 cd_find_ground_in_flt_tile(struct geotilef *tile, f32 x, f32 z) +f32 cd_find_y_tilef(struct geotilef *tile, f32 x, f32 z) { struct coord sp24; struct coord sp18; @@ -670,7 +688,7 @@ f32 cd_find_ground_in_flt_tile(struct geotilef *tile, f32 x, f32 z) return ground; } -bool cd_is2d_point_in_int_tile(struct geotilei *tile, f32 x, f32 z) +bool cd_is_xz_in_tilei(struct geotilei *tile, f32 x, f32 z) { s32 result = -1; s32 numvertices = tile->header.numvertices; @@ -704,7 +722,7 @@ bool cd_is2d_point_in_int_tile(struct geotilei *tile, f32 x, f32 z) return true; } -bool cd_is2d_point_in_flt_tile(struct geotilef *tile, f32 x, f32 z) +bool cd_is_xz_in_tilef(struct geotilef *tile, f32 x, f32 z) { s32 result = -1; s32 numvertices = tile->header.numvertices; @@ -738,7 +756,7 @@ bool cd_is2d_point_in_flt_tile(struct geotilef *tile, f32 x, f32 z) return true; } -bool cd_is_2d_point_in_block(struct geoblock *tile, f32 x, f32 z) +bool cd_is_xz_in_block(struct geoblock *tile, f32 x, f32 z) { s32 result = -1; s32 numvertices = tile->header.numvertices; @@ -772,7 +790,7 @@ bool cd_is_2d_point_in_block(struct geoblock *tile, f32 x, f32 z) return true; } -bool cd_is_2d_point_in_cyl(struct geocyl *cyl, f32 x, f32 z) +bool cd_is_xz_in_cyl(struct geocyl *cyl, f32 x, f32 z) { f32 xdiff = x - cyl->x; f32 zdiff = z - cyl->z; @@ -780,18 +798,18 @@ bool cd_is_2d_point_in_cyl(struct geocyl *cyl, f32 x, f32 z) return xdiff * xdiff + zdiff * zdiff <= cyl->radius * cyl->radius; } -bool cd_is_2d_point_in_geo(f32 x, f32 z, struct geo *geo) +bool cd_is_xz_in_geo(f32 x, f32 z, struct geo *geo) { if (geo == NULL) { return false; } if (geo->type == GEOTYPE_BLOCK) { - return cd_is_2d_point_in_block((struct geoblock *) geo, x, z); + return cd_is_xz_in_block((struct geoblock *) geo, x, z); } if (geo->type == GEOTYPE_CYL) { - return cd_is_2d_point_in_cyl((struct geocyl *) geo, x, z); + return cd_is_xz_in_cyl((struct geocyl *) geo, x, z); } return false; @@ -834,8 +852,8 @@ void cd_get_props_on_platform(struct prop *platform, s16 *propnums, s32 maxlen) && pos->z >= tile->vertices[tile->min[2]].z && pos->z <= tile->vertices[tile->max[2]].z && pos->y >= tile->vertices[tile->min[1]].y - && cd_is2d_point_in_flt_tile(tile, pos->x, pos->z) - && pos->y >= cd_find_ground_in_flt_tile(tile, pos->x, pos->z)) { + && cd_is_xz_in_tilef(tile, pos->x, pos->z) + && pos->y >= cd_find_y_tilef(tile, pos->x, pos->z)) { break; } @@ -896,7 +914,7 @@ void cd_set_prop_y_bounds(struct prop *prop, f32 ymax, f32 ymin) } #endif -bool cd_00026a04(struct coord *pos, u8 *start, u8 *end, u16 geoflags, s32 room, struct geo **tileptr, s32 *roomptr, f32 *groundptr, bool ceiling) +bool cd_find_y_from_bytes(struct coord *pos, u8 *start, u8 *end, u16 geoflags, s32 room, struct geo **tileptr, s32 *roomptr, f32 *yptr, bool ceiling) { bool result = false; struct geo *geo = (struct geo *) start; @@ -914,12 +932,12 @@ bool cd_00026a04(struct coord *pos, u8 *start, u8 *end, u16 geoflags, s32 room, && pos->z <= *(s16 *)(tile->zmax + (uintptr_t)tile)) { if ((!ceiling && pos->y >= *(s16 *)(tile->ymin + (uintptr_t)tile)) || (ceiling && pos->y <= *(s16 *)(tile->ymax + (uintptr_t)tile))) { - if (cd_is2d_point_in_int_tile(tile, pos->x, pos->z)) { - f32 ground = cd_find_ground_in_int_tile(tile, pos->x, pos->z); + if (cd_is_xz_in_tilei(tile, pos->x, pos->z)) { + f32 y = cd_find_y_tilei(tile, pos->x, pos->z); - if ((!ceiling && ground <= pos->y && ground > *groundptr) - || (ceiling && ground >= pos->y && ground < *groundptr)) { - *groundptr = ground; + if ((!ceiling && y <= pos->y && y > *yptr) + || (ceiling && y >= pos->y && y < *yptr)) { + *yptr = y; *tileptr = geo; *roomptr = room; result = true; @@ -939,12 +957,12 @@ bool cd_00026a04(struct coord *pos, u8 *start, u8 *end, u16 geoflags, s32 room, && pos->z <= tile->vertices[tile->max[2]].z) { if ((!ceiling && pos->y >= tile->vertices[tile->min[1]].y) || (ceiling && pos->y <= tile->vertices[tile->max[1]].y)) { - if (cd_is2d_point_in_flt_tile(tile, pos->x, pos->z)) { - f32 ground = cd_find_ground_in_flt_tile(tile, pos->x, pos->z); + if (cd_is_xz_in_tilef(tile, pos->x, pos->z)) { + f32 y = cd_find_y_tilef(tile, pos->x, pos->z); - if ((!ceiling && pos->y >= ground && ground > *groundptr) - || (ceiling && pos->y <= ground && ground < *groundptr)) { - *groundptr = ground; + if ((!ceiling && pos->y >= y && y > *yptr) + || (ceiling && pos->y <= y && y < *yptr)) { + *yptr = y; *tileptr = geo; *roomptr = room; result = true; @@ -964,7 +982,7 @@ bool cd_00026a04(struct coord *pos, u8 *start, u8 *end, u16 geoflags, s32 room, return result; } -void cd_find_closest_vertical(struct coord *pos, RoomNum *rooms, u16 geoflags, struct geo **geoptr, RoomNum *roomptr, f32 *groundptr, struct prop **propptr, bool ceiling) +void cd_find_y(struct coord *pos, RoomNum *rooms, u16 geoflags, struct geo **geoptr, RoomNum *roomptr, f32 *yptr, struct prop **propptr, bool ceiling) { RoomNum *roomptr2; s32 roomnum; @@ -983,6 +1001,7 @@ void cd_find_closest_vertical(struct coord *pos, RoomNum *rooms, u16 geoflags, s closesty = -4294967296; } + // Check BG roomptr2 = rooms; roomnum = rooms[0]; @@ -991,13 +1010,14 @@ void cd_find_closest_vertical(struct coord *pos, RoomNum *rooms, u16 geoflags, s start = g_TileFileData.u8 + g_TileRooms[roomnum]; end = g_TileFileData.u8 + g_TileRooms[roomnum + 1]; - cd_00026a04(pos, start, end, geoflags, roomnum, &geo, &room, &closesty, ceiling); + cd_find_y_from_bytes(pos, start, end, geoflags, roomnum, &geo, &room, &closesty, ceiling); } roomptr2++; roomnum = *roomptr2; } + // Check props room_get_props(rooms, propnums, 256); propnumptr = propnums; @@ -1005,7 +1025,7 @@ void cd_find_closest_vertical(struct coord *pos, RoomNum *rooms, u16 geoflags, s struct prop *prop = &g_Vars.props[*propnumptr]; if (prop_get_geometry(prop, &start, &end) - && cd_00026a04(pos, start, end, geoflags, prop->rooms[0], &geo, &room, &closesty, ceiling)) { + && cd_find_y_from_bytes(pos, start, end, geoflags, prop->rooms[0], &geo, &room, &closesty, ceiling)) { bestprop = prop; } @@ -1014,18 +1034,18 @@ void cd_find_closest_vertical(struct coord *pos, RoomNum *rooms, u16 geoflags, s *geoptr = geo; *roomptr = room; - *groundptr = closesty; + *yptr = closesty; if (propptr != NULL) { *propptr = bestprop; } } -bool cd_0002709c_int_tile(struct geotilei *tile, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) +bool cd_volume_collect_tilei(struct geotilei *tile, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) { bool result = false; - if (cd_is2d_point_in_int_tile(tile, x, z)) { + if (cd_is_xz_in_tilei(tile, x, z)) { collision->geo = &tile->header; collision->vertexindex = 0; collision->prop = prop; @@ -1036,16 +1056,16 @@ bool cd_0002709c_int_tile(struct geotilei *tile, f32 x, f32 z, f32 radius, struc for (i = 0; i < numvertices; i++) { s32 next = (i + 1) % numvertices; - f32 value = cd_00025654(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], x, z); + f32 value = cd_pos_get_dist_to_line(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], x, z); if (value < 0) { value = -value; } if (value <= radius - && (cd_00025724(tile->vertices[i][0], tile->vertices[i][2], x, z) <= radius - || cd_00025724(tile->vertices[next][0], tile->vertices[next][2], x, z) <= radius - || cd_00025774(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], x, z))) { + && (cd_pos_get_dist_to_vtx(tile->vertices[i][0], tile->vertices[i][2], x, z) <= radius + || cd_pos_get_dist_to_vtx(tile->vertices[next][0], tile->vertices[next][2], x, z) <= radius + || cd_pos_get_side(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], x, z))) { collision->geo = &tile->header; collision->vertexindex = i; collision->prop = prop; @@ -1058,11 +1078,11 @@ bool cd_0002709c_int_tile(struct geotilei *tile, f32 x, f32 z, f32 radius, struc return result; } -bool cd_000272f8_flt_tile(struct geotilef *tile, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) +bool cd_volume_collect_tilef(struct geotilef *tile, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) { bool result = false; - if (cd_is2d_point_in_flt_tile(tile, x, z)) { + if (cd_is_xz_in_tilef(tile, x, z)) { collision->geo = &tile->header; collision->vertexindex = 0; collision->prop = prop; @@ -1073,16 +1093,16 @@ bool cd_000272f8_flt_tile(struct geotilef *tile, f32 x, f32 z, f32 radius, struc for (i = 0; i < numvertices; i++) { s32 next = (i + 1) % numvertices; - f32 value = cd_00025654(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, x, z); + f32 value = cd_pos_get_dist_to_line(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, x, z); if (value < 0) { value = -value; } if (value <= radius - && (cd_00025724(tile->vertices[i].x, tile->vertices[i].z, x, z) <= radius - || cd_00025724(tile->vertices[next].x, tile->vertices[next].z, x, z) <= radius - || cd_00025774(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, x, z))) { + && (cd_pos_get_dist_to_vtx(tile->vertices[i].x, tile->vertices[i].z, x, z) <= radius + || cd_pos_get_dist_to_vtx(tile->vertices[next].x, tile->vertices[next].z, x, z) <= radius + || cd_pos_get_side(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, x, z))) { collision->geo = &tile->header; collision->vertexindex = i; collision->prop = prop; @@ -1095,11 +1115,11 @@ bool cd_000272f8_flt_tile(struct geotilef *tile, f32 x, f32 z, f32 radius, struc return result; } -s32 cd_000274e0_block(struct geoblock *tile, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) +s32 cd_block_collides_with_cyl_laterally(struct geoblock *tile, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) { bool result = false; - if (cd_is_2d_point_in_block(tile, x, z)) { + if (cd_is_xz_in_block(tile, x, z)) { if (collision) { collision->geo = &tile->header; collision->vertexindex = 0; @@ -1113,7 +1133,7 @@ s32 cd_000274e0_block(struct geoblock *tile, f32 x, f32 z, f32 radius, struct pr for (i = 0; i < numvertices; i++) { s32 next = (i + 1) % numvertices; - f32 value = cd_00025654(tile->vertices[i][0], tile->vertices[i][1], + f32 value = cd_pos_get_dist_to_line(tile->vertices[i][0], tile->vertices[i][1], tile->vertices[next][0], tile->vertices[next][1], x, z); @@ -1122,9 +1142,9 @@ s32 cd_000274e0_block(struct geoblock *tile, f32 x, f32 z, f32 radius, struct pr } if (value <= radius - && (cd_00025724(tile->vertices[i][0], tile->vertices[i][1], x, z) <= radius - || cd_00025724(tile->vertices[next][0], tile->vertices[next][1], x, z) <= radius - || cd_00025774(tile->vertices[i][0], tile->vertices[i][1], tile->vertices[next][0], tile->vertices[next][1], x, z))) { + && (cd_pos_get_dist_to_vtx(tile->vertices[i][0], tile->vertices[i][1], x, z) <= radius + || cd_pos_get_dist_to_vtx(tile->vertices[next][0], tile->vertices[next][1], x, z) <= radius + || cd_pos_get_side(tile->vertices[i][0], tile->vertices[i][1], tile->vertices[next][0], tile->vertices[next][1], x, z))) { if (collision) { collision->geo = &tile->header; collision->vertexindex = i; @@ -1140,7 +1160,7 @@ s32 cd_000274e0_block(struct geoblock *tile, f32 x, f32 z, f32 radius, struct pr return result; } -bool cd_000276c8_cyl(struct geocyl *cyl, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) +bool cd_cyl_collides_with_cyl_laterally(struct geocyl *cyl, f32 x, f32 z, f32 radius, struct prop *prop, struct collision *collision) { bool result = false; @@ -1163,8 +1183,8 @@ bool cd_000276c8_cyl(struct geocyl *cyl, f32 x, f32 z, f32 radius, struct prop * s32 cd_test_ramp_wall(struct geotilei *tile, struct coord *pos, f32 width, f32 y1, f32 y2); -void cd_collect_geo_for_cyl_from_list(struct coord *pos, f32 radius, u8 *start, u8 *end, u16 geoflags, - bool checkvertical, f32 arg6, f32 arg7, struct prop *prop, +void cd_volume_collect_from_bytes(struct coord *pos, f32 radius, u8 *start, u8 *end, u16 geoflags, + bool checkvertical, f32 ymax, f32 ymin, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions, s32 roomnum) { struct geo *geo = (struct geo *) start; @@ -1179,16 +1199,16 @@ void cd_collect_geo_for_cyl_from_list(struct coord *pos, f32 radius, u8 *start, && pos->x <= *(s16 *)(tile->xmax + (uintptr_t)tile) + radius && pos->z >= *(s16 *)(tile->zmin + (uintptr_t)tile) - radius && pos->z <= *(s16 *)(tile->zmax + (uintptr_t)tile) + radius - && (!checkvertical || (pos->y + arg6 >= *(s16 *)(tile->ymin + (uintptr_t)tile) - && pos->y + arg7 <= *(s16 *)(tile->ymax + (uintptr_t)tile)))) { + && (!checkvertical || (pos->y + ymax >= *(s16 *)(tile->ymin + (uintptr_t)tile) + && pos->y + ymin <= *(s16 *)(tile->ymax + (uintptr_t)tile)))) { if (geo->flags & GEOFLAG_RAMPWALL) { - result = cd_test_ramp_wall(tile, pos, radius, pos->y + arg7, pos->y + arg6); + result = cd_test_ramp_wall(tile, pos, radius, pos->y + ymin, pos->y + ymax); } else { result = 1; } if (result != 0) { - if (cd_0002709c_int_tile(tile, pos->x, pos->z, radius, prop, &collisions[*numcollisions])) { + if (cd_volume_collect_tilei(tile, pos->x, pos->z, radius, prop, &collisions[*numcollisions])) { collisions[*numcollisions].room = roomnum; *numcollisions = *numcollisions + 1; @@ -1208,9 +1228,9 @@ void cd_collect_geo_for_cyl_from_list(struct coord *pos, f32 radius, u8 *start, && pos->x <= tile->vertices[tile->max[0]].x + radius && pos->z >= tile->vertices[tile->min[2]].z - radius && pos->z <= tile->vertices[tile->max[2]].z + radius - && (!checkvertical || (pos->y + arg6 >= tile->vertices[tile->min[1]].y - && pos->y + arg7 <= tile->vertices[tile->max[1]].y))) { - result = cd_000272f8_flt_tile(tile, pos->x, pos->z, radius, prop, &collisions[*numcollisions]); + && (!checkvertical || (pos->y + ymax >= tile->vertices[tile->min[1]].y + && pos->y + ymin <= tile->vertices[tile->max[1]].y))) { + result = cd_volume_collect_tilef(tile, pos->x, pos->z, radius, prop, &collisions[*numcollisions]); if (result != 0) { collisions[*numcollisions].room = roomnum; @@ -1227,8 +1247,8 @@ void cd_collect_geo_for_cyl_from_list(struct coord *pos, f32 radius, u8 *start, struct geoblock *block = (struct geoblock *) geo; if ((geoflags & (GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT)) - && (!checkvertical || (pos->y + arg6 >= block->ymin && pos->y + arg7 <= block->ymax))) { - result = cd_000274e0_block(block, pos->x, pos->z, radius, prop, &collisions[*numcollisions]); + && (!checkvertical || (pos->y + ymax >= block->ymin && pos->y + ymin <= block->ymax))) { + result = cd_block_collides_with_cyl_laterally(block, pos->x, pos->z, radius, prop, &collisions[*numcollisions]); if (result) { collisions[*numcollisions].room = roomnum; @@ -1245,8 +1265,8 @@ void cd_collect_geo_for_cyl_from_list(struct coord *pos, f32 radius, u8 *start, struct geocyl *cyl = (struct geocyl *) geo; if ((geoflags & geo->flags) - && (!checkvertical || (pos->y + arg6 >= cyl->ymin && pos->y + arg7 <= cyl->ymax))) { - result = cd_000276c8_cyl(cyl, pos->x, pos->z, radius, prop, &collisions[*numcollisions]); + && (!checkvertical || (pos->y + ymax >= cyl->ymin && pos->y + ymin <= cyl->ymax))) { + result = cd_cyl_collides_with_cyl_laterally(cyl, pos->x, pos->z, radius, prop, &collisions[*numcollisions]); if (result) { collisions[*numcollisions].room = roomnum; @@ -1263,7 +1283,7 @@ void cd_collect_geo_for_cyl_from_list(struct coord *pos, f32 radius, u8 *start, } } -void cd_collect_geo_for_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u32 types, u16 geoflags, bool checkvertical, f32 ymax, f32 ymin, struct collision *collisions, s32 maxcollisions) +void cd_volume_collect(struct coord *pos, f32 radius, RoomNum *rooms, u32 types, u16 geoflags, bool checkvertical, f32 ymax, f32 ymin, struct collision *collisions, s32 maxcollisions) { RoomNum *roomptr; s32 roomnum; @@ -1283,7 +1303,7 @@ void cd_collect_geo_for_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u32 t start = g_TileFileData.u8 + g_TileRooms[roomnum]; end = g_TileFileData.u8 + g_TileRooms[roomnum + 1]; - cd_collect_geo_for_cyl_from_list(pos, radius, start, end, geoflags, checkvertical, ymax, ymin, NULL, collisions, maxcollisions, &numcollisions, roomnum); + cd_volume_collect_from_bytes(pos, radius, start, end, geoflags, checkvertical, ymax, ymin, NULL, collisions, maxcollisions, &numcollisions, roomnum); if (numcollisions >= maxcollisions) { goto end; @@ -1303,7 +1323,7 @@ void cd_collect_geo_for_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u32 t struct prop *prop = &g_Vars.props[*propnumptr]; if (prop_is_of_cd_type(prop, types) && prop_get_geometry(prop, &start, &end)) { - cd_collect_geo_for_cyl_from_list(pos, radius, start, end, geoflags, checkvertical, ymax, ymin, prop, collisions, maxcollisions, &numcollisions, prop->rooms[0]); + cd_volume_collect_from_bytes(pos, radius, start, end, geoflags, checkvertical, ymax, ymin, prop, collisions, maxcollisions, &numcollisions, prop->rooms[0]); if (numcollisions >= maxcollisions) { break; @@ -1317,7 +1337,7 @@ end: collisions[numcollisions].geo = NULL; } -void cd_00027f78(struct geotilei *tile, f32 arg1, f32 arg2, f32 arg3, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) +void cd_volumefromdir_collect_tilei(struct geotilei *tile, f32 posx, f32 posz, f32 radius, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) { s32 i; s32 numvertices = tile->header.numvertices; @@ -1326,16 +1346,16 @@ void cd_00027f78(struct geotilei *tile, f32 arg1, f32 arg2, f32 arg3, struct pro s32 next = (i + 1) % numvertices; if (tile->vertices[i][0] != tile->vertices[next][0] || tile->vertices[i][2] != tile->vertices[next][2]) { - f32 f0 = cd_00025654(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], arg1, arg2); + f32 dist = cd_pos_get_dist_to_line(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], posx, posz); - if (f0 < 0.0f) { - f0 = -f0; + if (dist < 0.0f) { + dist = -dist; } - if (f0 <= arg3 - && (cd_00025724(tile->vertices[i][0], tile->vertices[i][2], arg1, arg2) <= arg3 - || cd_00025724(tile->vertices[next][0], tile->vertices[next][2], arg1, arg2) <= arg3 - || cd_00025774(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], arg1, arg2))) { + if (dist <= radius + && (cd_pos_get_dist_to_vtx(tile->vertices[i][0], tile->vertices[i][2], posx, posz) <= radius + || cd_pos_get_dist_to_vtx(tile->vertices[next][0], tile->vertices[next][2], posx, posz) <= radius + || cd_pos_get_side(tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], posx, posz))) { if (*numcollisions < maxcollisions) { collisions[*numcollisions].geo = &tile->header; collisions[*numcollisions].vertexindex = i; @@ -1443,7 +1463,7 @@ s32 cd_test_ramp_wall(struct geotilei *tile, struct coord *pos, f32 width, f32 y return count; } -void cd_0002840c(struct geotilef *tile, f32 arg1, f32 arg2, f32 arg3, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) +void cd_volumefromdir_collect_tilef(struct geotilef *tile, f32 posx, f32 posz, f32 radius, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) { s32 i; s32 numvertices = tile->header.numvertices; @@ -1452,16 +1472,16 @@ void cd_0002840c(struct geotilef *tile, f32 arg1, f32 arg2, f32 arg3, struct pro s32 next = (i + 1) % numvertices; if (tile->vertices[i].x != tile->vertices[next].x || tile->vertices[i].z != tile->vertices[next].z) { - f32 f0 = cd_00025654(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, arg1, arg2); + f32 dist = cd_pos_get_dist_to_line(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, posx, posz); - if (f0 < 0.0f) { - f0 = -f0; + if (dist < 0.0f) { + dist = -dist; } - if (f0 <= arg3 - && (cd_00025724(tile->vertices[i].x, tile->vertices[i].z, arg1, arg2) <= arg3 - || cd_00025724(tile->vertices[next].x, tile->vertices[next].z, arg1, arg2) <= arg3 - || cd_00025774(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, arg1, arg2))) { + if (dist <= radius + && (cd_pos_get_dist_to_vtx(tile->vertices[i].x, tile->vertices[i].z, posx, posz) <= radius + || cd_pos_get_dist_to_vtx(tile->vertices[next].x, tile->vertices[next].z, posx, posz) <= radius + || cd_pos_get_side(tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, posx, posz))) { if (*numcollisions < maxcollisions) { collisions[*numcollisions].geo = &tile->header; collisions[*numcollisions].vertexindex = i; @@ -1475,7 +1495,7 @@ void cd_0002840c(struct geotilef *tile, f32 arg1, f32 arg2, f32 arg3, struct pro } } -void cd_00028638(struct geoblock *block, f32 arg1, f32 arg2, f32 arg3, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) +void cd_volumefromdir_collect_block(struct geoblock *block, f32 posx, f32 posz, f32 radius, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) { s32 i; s32 numvertices = block->header.numvertices; @@ -1484,16 +1504,16 @@ void cd_00028638(struct geoblock *block, f32 arg1, f32 arg2, f32 arg3, struct pr s32 next = (i + 1) % numvertices; if (block->vertices[i][0] != block->vertices[next][0] || block->vertices[i][1] != block->vertices[next][1]) { - f32 f0 = cd_00025654(block->vertices[i][0], block->vertices[i][1], block->vertices[next][0], block->vertices[next][1], arg1, arg2); + f32 dist = cd_pos_get_dist_to_line(block->vertices[i][0], block->vertices[i][1], block->vertices[next][0], block->vertices[next][1], posx, posz); - if (f0 < 0.0f) { - f0 = -f0; + if (dist < 0.0f) { + dist = -dist; } - if (f0 <= arg3 - && (cd_00025724(block->vertices[i][0], block->vertices[i][1], arg1, arg2) <= arg3 - || cd_00025724(block->vertices[next][0], block->vertices[next][1], arg1, arg2) <= arg3 - || cd_00025774(block->vertices[i][0], block->vertices[i][1], block->vertices[next][0], block->vertices[next][1], arg1, arg2))) { + if (dist <= radius + && (cd_pos_get_dist_to_vtx(block->vertices[i][0], block->vertices[i][1], posx, posz) <= radius + || cd_pos_get_dist_to_vtx(block->vertices[next][0], block->vertices[next][1], posx, posz) <= radius + || cd_pos_get_side(block->vertices[i][0], block->vertices[i][1], block->vertices[next][0], block->vertices[next][1], posx, posz))) { if (*numcollisions < maxcollisions) { collisions[*numcollisions].geo = &block->header; collisions[*numcollisions].vertexindex = i; @@ -1507,11 +1527,11 @@ void cd_00028638(struct geoblock *block, f32 arg1, f32 arg2, f32 arg3, struct pr } } -void cd_0002885c(struct geocyl *cyl, f32 x, f32 z, f32 arg3, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) +void cd_volumefromdir_collect_cyl(struct geocyl *cyl, f32 posx, f32 posz, f32 radius, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) { - f32 xdiff = x - cyl->x; - f32 zdiff = z - cyl->z; - f32 f16 = arg3 + cyl->radius; + f32 xdiff = posx - cyl->x; + f32 zdiff = posz - cyl->z; + f32 f16 = radius + cyl->radius; if (xdiff * xdiff + zdiff * zdiff <= f16 * f16) { if (*numcollisions < maxcollisions) { @@ -1523,8 +1543,8 @@ void cd_0002885c(struct geocyl *cyl, f32 x, f32 z, f32 arg3, struct prop *prop, } } -void cd_collect_geo_for_cyl_move_from_list(u8 *start, u8 *end, struct coord *pos, f32 radius, u16 geoflags, - bool checkvertical, f32 arg6, f32 arg7, struct prop *prop, +void cd_volumefromdir_collect_from_bytes(u8 *start, u8 *end, struct coord *pos, f32 radius, u16 geoflags, + bool checkvertical, f32 ymax, f32 ymin, struct prop *prop, struct collision *collisions, s32 maxcollisions, s32 *numcollisions) { struct geo *geo = (struct geo *) start; @@ -1538,18 +1558,18 @@ void cd_collect_geo_for_cyl_move_from_list(u8 *start, u8 *end, struct coord *pos && pos->x <= *(s16 *)(tile->xmax + (uintptr_t)tile) + radius && pos->z >= *(s16 *)(tile->zmin + (uintptr_t)tile) - radius && pos->z <= *(s16 *)(tile->zmax + (uintptr_t)tile) + radius - && (!checkvertical || (pos->y + arg6 >= *(s16 *)(tile->ymin + (uintptr_t)tile) - && pos->y + arg7 <= *(s16 *)(tile->ymax + (uintptr_t)tile)))) { + && (!checkvertical || (pos->y + ymax >= *(s16 *)(tile->ymin + (uintptr_t)tile) + && pos->y + ymin <= *(s16 *)(tile->ymax + (uintptr_t)tile)))) { bool pass; if (geo->flags & GEOFLAG_RAMPWALL) { - pass = cd_test_ramp_wall(tile, pos, radius, pos->y + arg7, pos->y + arg6); + pass = cd_test_ramp_wall(tile, pos, radius, pos->y + ymin, pos->y + ymax); } else { pass = true; } if (pass) { - cd_00027f78(tile, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); + cd_volumefromdir_collect_tilei(tile, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); } } } @@ -1563,9 +1583,9 @@ void cd_collect_geo_for_cyl_move_from_list(u8 *start, u8 *end, struct coord *pos && pos->x <= tile->vertices[tile->max[0]].x + radius && pos->z >= tile->vertices[tile->min[2]].z - radius && pos->z <= tile->vertices[tile->max[2]].z + radius - && (!checkvertical || (pos->y + arg6 >= tile->vertices[tile->min[1]].y - && pos->y + arg7 <= tile->vertices[tile->max[1]].y))) { - cd_0002840c(tile, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); + && (!checkvertical || (pos->y + ymax >= tile->vertices[tile->min[1]].y + && pos->y + ymin <= tile->vertices[tile->max[1]].y))) { + cd_volumefromdir_collect_tilef(tile, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); } geo = (struct geo *)((uintptr_t)geo + GEOTILEF_SIZE(tile)); @@ -1573,8 +1593,8 @@ void cd_collect_geo_for_cyl_move_from_list(u8 *start, u8 *end, struct coord *pos struct geoblock *block = (struct geoblock *) geo; if ((geoflags & (GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT)) - && (!checkvertical || (pos->y + arg6 >= block->ymin && pos->y + arg7 <= block->ymax))) { - cd_00028638(block, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); + && (!checkvertical || (pos->y + ymax >= block->ymin && pos->y + ymin <= block->ymax))) { + cd_volumefromdir_collect_block(block, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); } geo = (struct geo *)((uintptr_t)geo + GEOBLOCK_SIZE(block)); @@ -1582,8 +1602,8 @@ void cd_collect_geo_for_cyl_move_from_list(u8 *start, u8 *end, struct coord *pos struct geocyl *cyl = (struct geocyl *) geo; if ((geoflags & geo->flags) - && (!checkvertical || (pos->y + arg6 >= cyl->ymin && pos->y + arg7 <= cyl->ymax))) { - cd_0002885c(cyl, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); + && (!checkvertical || (pos->y + ymax >= cyl->ymin && pos->y + ymin <= cyl->ymax))) { + cd_volumefromdir_collect_cyl(cyl, pos->x, pos->z, radius, prop, collisions, maxcollisions, numcollisions); } geo = (struct geo *)((uintptr_t)geo + GEOCYL_SIZE(cyl)); @@ -1591,7 +1611,7 @@ void cd_collect_geo_for_cyl_move_from_list(u8 *start, u8 *end, struct coord *pos } } -void cd_collect_geo_for_cyl_move(struct coord *pos, f32 width, RoomNum *rooms, u32 types, u16 geoflags, bool checkvertical, f32 ymax, f32 ymin, struct collision *collisions, s32 maxcollisions) +void cd_volumefromdir_collect(struct coord *pos, f32 width, RoomNum *rooms, u32 types, u16 geoflags, bool checkvertical, f32 ymax, f32 ymin, struct collision *collisions, s32 maxcollisions) { RoomNum *roomptr; s32 roomnum; @@ -1611,7 +1631,7 @@ void cd_collect_geo_for_cyl_move(struct coord *pos, f32 width, RoomNum *rooms, u start = g_TileFileData.u8 + g_TileRooms[roomnum]; end = g_TileFileData.u8 + g_TileRooms[roomnum + 1]; - cd_collect_geo_for_cyl_move_from_list(start, end, pos, width, geoflags, checkvertical, ymax, ymin, NULL, collisions, maxcollisions, &numcollisions); + cd_volumefromdir_collect_from_bytes(start, end, pos, width, geoflags, checkvertical, ymax, ymin, NULL, collisions, maxcollisions, &numcollisions); } roomptr++; @@ -1627,7 +1647,7 @@ void cd_collect_geo_for_cyl_move(struct coord *pos, f32 width, RoomNum *rooms, u struct prop *prop = &g_Vars.props[*propnumptr]; if (prop_is_of_cd_type(prop, types) && prop_get_geometry(prop, &start, &end)) { - cd_collect_geo_for_cyl_move_from_list(start, end, pos, width, geoflags, checkvertical, ymax, ymin, prop, collisions, maxcollisions, &numcollisions); + cd_volumefromdir_collect_from_bytes(start, end, pos, width, geoflags, checkvertical, ymax, ymin, prop, collisions, maxcollisions, &numcollisions); } propnumptr++; @@ -1636,10 +1656,10 @@ void cd_collect_geo_for_cyl_move(struct coord *pos, f32 width, RoomNum *rooms, u collisions[numcollisions].geo = NULL; } -void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collision *collisions) +void cd_volumefromdir_finalise(struct coord *frompos, struct coord *dist, f32 radius, struct collision *collisions) { s32 i; - struct widthxz spf8; + struct radiusxz spf8; struct xz spf0; struct xz spe8; struct xz spe0; @@ -1649,8 +1669,8 @@ void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collis f32 value; s32 curr; s32 next; - struct coord vtx1; - struct coord vtx2; + struct coord edgevtx1; + struct coord edgevtx2; struct geo *geo; for (i = 0; (geo = collisions[i].geo) != NULL; i++) { @@ -1658,9 +1678,9 @@ void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collis if (geo->type == GEOTYPE_TILE_I) { struct geotilei *tile = (struct geotilei *) geo; - spf8.width = width; - spf8.x = pos->x; - spf8.z = pos->z; + spf8.radius = radius; + spf8.x = frompos->x; + spf8.z = frompos->z; spe0.x = dist->x; spe0.z = dist->z; @@ -1683,9 +1703,9 @@ void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collis } else if (geo->type == GEOTYPE_TILE_F) { struct geotilef *tile = (struct geotilef *) geo; - spf8.width = width; - spf8.x = pos->x; - spf8.z = pos->z; + spf8.radius = radius; + spf8.x = frompos->x; + spf8.z = frompos->z; spe0.x = dist->x; spe0.z = dist->z; @@ -1708,9 +1728,9 @@ void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collis } else if (geo->type == GEOTYPE_BLOCK) { struct geoblock *block = (struct geoblock *) geo; - spf8.width = width; - spf8.x = pos->x; - spf8.z = pos->z; + spf8.radius = radius; + spf8.x = frompos->x; + spf8.z = frompos->z; spe0.x = dist->x; spe0.z = dist->z; @@ -1733,9 +1753,9 @@ void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collis } else if (geo->type == GEOTYPE_CYL) { struct geocyl *cyl = (struct geocyl *) geo; - spf8.width = cyl->radius + width; - spf8.x = pos->x; - spf8.z = pos->z; + spf8.radius = cyl->radius + radius; + spf8.x = frompos->x; + spf8.z = frompos->z; spe0.x = dist->x; spe0.z = dist->z; @@ -1760,50 +1780,50 @@ void cd_0002901c(struct coord *pos, struct coord *dist, f32 width, struct collis s32 curr = collisions[bestindex].vertexindex; s32 next = (curr + 1) % tile->header.numvertices; - vtx1.x = tile->vertices[curr][0]; - vtx1.y = tile->vertices[curr][1]; - vtx1.z = tile->vertices[curr][2]; + edgevtx1.x = tile->vertices[curr][0]; + edgevtx1.y = tile->vertices[curr][1]; + edgevtx1.z = tile->vertices[curr][2]; - vtx2.x = tile->vertices[next][0]; - vtx2.y = tile->vertices[next][1]; - vtx2.z = tile->vertices[next][2]; + edgevtx2.x = tile->vertices[next][0]; + edgevtx2.y = tile->vertices[next][1]; + edgevtx2.z = tile->vertices[next][2]; } else if (collisions[bestindex].geo->type == GEOTYPE_TILE_F) { struct geotilef *tile = (struct geotilef *) collisions[bestindex].geo; s32 curr = collisions[bestindex].vertexindex; s32 next = (curr + 1) % tile->header.numvertices; - vtx1.x = tile->vertices[curr].x; - vtx1.y = tile->vertices[curr].y; - vtx1.z = tile->vertices[curr].z; + edgevtx1.x = tile->vertices[curr].x; + edgevtx1.y = tile->vertices[curr].y; + edgevtx1.z = tile->vertices[curr].z; - vtx2.x = tile->vertices[next].x; - vtx2.y = tile->vertices[next].y; - vtx2.z = tile->vertices[next].z; + edgevtx2.x = tile->vertices[next].x; + edgevtx2.y = tile->vertices[next].y; + edgevtx2.z = tile->vertices[next].z; } else if (collisions[bestindex].geo->type == GEOTYPE_BLOCK) { struct geoblock *block = (struct geoblock *) collisions[bestindex].geo; s32 curr = collisions[bestindex].vertexindex; s32 next = (curr + 1) % block->header.numvertices; - vtx1.x = block->vertices[curr][0]; - vtx1.y = pos->y; - vtx1.z = block->vertices[curr][1]; + edgevtx1.x = block->vertices[curr][0]; + edgevtx1.y = frompos->y; + edgevtx1.z = block->vertices[curr][1]; - vtx2.x = block->vertices[next][0]; - vtx2.y = pos->y; - vtx2.z = block->vertices[next][1]; + edgevtx2.x = block->vertices[next][0]; + edgevtx2.y = frompos->y; + edgevtx2.z = block->vertices[next][1]; } else if (collisions[bestindex].geo->type == GEOTYPE_CYL) { struct geocyl *cyl = (struct geocyl *) collisions[bestindex].geo; - cd_00025848(cyl->x, cyl->z, cyl->radius, pos->x, pos->z, &vtx1.x, &vtx1.z, &vtx2.x, &vtx2.z); + cd_pos_get_cyl_edge(cyl->x, cyl->z, cyl->radius, frompos->x, frompos->z, &edgevtx1.x, &edgevtx1.z, &edgevtx2.x, &edgevtx2.z); - vtx1.y = pos->y; - vtx2.y = pos->y; + edgevtx1.y = frompos->y; + edgevtx2.y = frompos->y; } - cd_set_obstacle_vtx_prop_flt(&vtx1, &vtx2, collisions[bestindex].prop, bestvalue); + cd_set_obstacle_edge_prop_dist(&edgevtx1, &edgevtx2, collisions[bestindex].prop, bestvalue); } -f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, struct collision **collisionptr, f32 width) +f32 cd_find_ground_finalise(struct collision *collisions, struct coord *pos, struct collision **collisionptr, f32 width) { struct collision *collision; s32 i; @@ -1860,7 +1880,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st hasflag0100 = true; } - collision->intile = cd_is2d_point_in_int_tile(tile, pos->x, pos->z); + collision->intile = cd_is_xz_in_tilei(tile, pos->x, pos->z); if (collision->intile) { anyintile = true; @@ -1869,7 +1889,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st } else if (collision->geo->type == GEOTYPE_TILE_F) { struct geotilef *tile = (struct geotilef *) collision->geo; - collision->intile = cd_is2d_point_in_flt_tile(tile, pos->x, pos->z); + collision->intile = cd_is_xz_in_tilef(tile, pos->x, pos->z); if (collision->intile) { anyintile = true; @@ -1884,7 +1904,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st struct geotilei *tile = (struct geotilei *) collision->geo; if ((tile->header.flags & GEOFLAG_STEP) == 0) { - ground = cd_find_ground_in_int_tile((void *)collision->geo, pos->x, pos->z); + ground = cd_find_y_tilei((void *)collision->geo, pos->x, pos->z); if (ground >= curground && ground < pos->y) { curground = ground; @@ -1895,7 +1915,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st } else if (collision->geo->type == GEOTYPE_TILE_F) { struct geotilef *tile = (struct geotilef *) collision->geo; - ground = cd_find_ground_in_flt_tile((void *)collision->geo, pos->x, pos->z); + ground = cd_find_y_tilef((void *)collision->geo, pos->x, pos->z); if (ground >= curground && ground < pos->y) { curground = ground; @@ -1912,7 +1932,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st struct geotilei *tile = (struct geotilei *) collision->geo; if (tile->header.flags & GEOFLAG_STEP) { - ground = cd_find_ground_in_int_tile((void *)collision->geo, pos->x, pos->z); + ground = cd_find_y_tilei((void *)collision->geo, pos->x, pos->z); if (ground >= curground && (ground < pos->y || !hasground)) { curground = ground; @@ -1961,7 +1981,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st nextx = tile->vertices[next][0]; nextz = tile->vertices[next][2]; - spd4 = cd_00025654(thisx, thisz, nextx, nextz, pos->x, pos->z); + spd4 = cd_pos_get_dist_to_line(thisx, thisz, nextx, nextz, pos->x, pos->z); f30 = spd4; if (f30 < 0.0f) { @@ -1974,14 +1994,14 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st if (f30 < spe4) #endif { - if (cd_00025774(thisx, thisz, nextx, nextz, pos->x, pos->z)) { + if (cd_pos_get_side(thisx, thisz, nextx, nextz, pos->x, pos->z)) { spb8 = nextx - thisx; spb4 = nextz - thisz; f14 = spd4 / sqrtf(spb8 * spb8 + spb4 * spb4); x = pos->x + f14 * -spb4; z = pos->z + f14 * spb8; - ground = cd_find_ground_in_int_tile_at_vertex(tile, x, z, i); + ground = cd_find_y_tilei_vtx(tile, x, z, i); if (ground < pos->y || (collision->geo->flags & GEOFLAG_STEP)) { curground = ground; @@ -1993,8 +2013,8 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st #endif } } else { - thisvalue = cd_00025724(thisx, thisz, pos->x, pos->z); - nextvalue = cd_00025724(nextx, nextz, pos->x, pos->z); + thisvalue = cd_pos_get_dist_to_vtx(thisx, thisz, pos->x, pos->z); + nextvalue = cd_pos_get_dist_to_vtx(nextx, nextz, pos->x, pos->z); if (thisvalue < nextvalue) { #if VERSION >= VERSION_NTSC_1_0 @@ -2005,7 +2025,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st { x = tile->vertices[i][0]; z = tile->vertices[i][2]; - ground = cd_find_ground_in_int_tile_at_vertex(tile, x, z, i); + ground = cd_find_y_tilei_vtx(tile, x, z, i); if (ground < pos->y || (collision->geo->flags & GEOFLAG_STEP)) { curground = ground; @@ -2026,7 +2046,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st { x = tile->vertices[next][0]; z = tile->vertices[next][2]; - ground = cd_find_ground_in_int_tile_at_vertex(tile, x, z, i); + ground = cd_find_y_tilei_vtx(tile, x, z, i); if (ground < pos->y || (collision->geo->flags & GEOFLAG_STEP)) { curground = ground; @@ -2057,7 +2077,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st nextx = tile->vertices[next].x; nextz = tile->vertices[next].z; - sp94 = cd_00025654(thisx, thisz, nextx, nextz, pos->x, pos->z); + sp94 = cd_pos_get_dist_to_line(thisx, thisz, nextx, nextz, pos->x, pos->z); f30 = sp94; if (f30 < 0.0f) { @@ -2065,14 +2085,14 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st } if (f30 < spe4) { - if (cd_00025774(thisx, thisz, nextx, nextz, pos->x, pos->z)) { + if (cd_pos_get_side(thisx, thisz, nextx, nextz, pos->x, pos->z)) { sp78 = nextx - thisx; sp74 = nextz - thisz; f14 = sp94 / sqrtf(sp78 * sp78 + sp74 * sp74); x = pos->x + f14 * -sp74; z = pos->z + f14 * sp78; - ground = cd_find_ground_in_flt_tile(tile, x, z); + ground = cd_find_y_tilef(tile, x, z); if (ground < pos->y) { curground = ground; @@ -2084,14 +2104,14 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st #endif } } else { - thisvalue = cd_00025724(thisx, thisz, pos->x, pos->z); - nextvalue = cd_00025724(nextx, nextz, pos->x, pos->z); + thisvalue = cd_pos_get_dist_to_vtx(thisx, thisz, pos->x, pos->z); + nextvalue = cd_pos_get_dist_to_vtx(nextx, nextz, pos->x, pos->z); if (thisvalue < nextvalue) { if (thisvalue < spe4) { x = tile->vertices[i].x; z = tile->vertices[i].z; - ground = cd_find_ground_in_flt_tile(tile, x, z); + ground = cd_find_y_tilef(tile, x, z); if (ground < pos->y) { curground = ground; @@ -2107,7 +2127,7 @@ f32 cd_find_ground_from_list(struct collision *collisions, struct coord *pos, st if (nextvalue < spe4) { x = tile->vertices[next].x; z = tile->vertices[next].z; - ground = cd_find_ground_in_flt_tile(tile, x, z); + ground = cd_find_y_tilef(tile, x, z); if (ground < pos->y) { curground = ground; @@ -2144,7 +2164,7 @@ bool cd_find_ladder(struct coord *pos, f32 width, f32 ymax, f32 ymin, RoomNum *r { struct collision collisions[2]; - cd_collect_geo_for_cyl(pos, width, rooms, CDTYPE_BG, geoflags, CHECKVERTICAL_YES, ymax, ymin, collisions, 1); + cd_volume_collect(pos, width, rooms, CDTYPE_BG, geoflags, CHECKVERTICAL_YES, ymax, ymin, collisions, 1); if (collisions[0].geo) { struct geotilei *tile = (struct geotilei *) collisions[0].geo; @@ -2168,11 +2188,11 @@ bool cd_find_ladder(struct coord *pos, f32 width, f32 ymax, f32 ymin, RoomNum *r return false; } -bool cd_0002a13c(struct coord *pos, f32 radius, f32 ymax, f32 ymin, RoomNum *rooms, u16 geoflags) +bool is_cyl_touching_tile_with_flags(struct coord *pos, f32 radius, f32 ymax, f32 ymin, RoomNum *rooms, u16 geoflags) { struct collision collisions[2]; - cd_collect_geo_for_cyl(pos, radius, rooms, CDTYPE_BG, geoflags, CHECKVERTICAL_YES, ymax, ymin, collisions, 1); + cd_volume_collect(pos, radius, rooms, CDTYPE_BG, geoflags, CHECKVERTICAL_YES, ymax, ymin, collisions, 1); if (collisions[0].geo) { return true; @@ -2181,19 +2201,34 @@ bool cd_0002a13c(struct coord *pos, f32 radius, f32 ymax, f32 ymin, RoomNum *roo return false; } -f32 cd_find_ground_info_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, - u8 *floortype, u16 *floorflags, RoomNum *floorroom, s32 *inlift, struct prop **lift) +/** + * For the following ground/ceiling functions, the suffix on the function name + * denotes which pointer arguments will be populated by the collision system. + * + * c = floor colour + * f = floor flags (geoflags) + * i = inlift + * l = lift + * n = normal + * p = prop + * r = room number + * t = floor type + * y = y coordinate + */ + +f32 cd_find_ground_at_cyl_ctfril(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, + u8 *floortype, u16 *floorflags, RoomNum *floorroom, bool *inlift, struct prop **lift) { struct collision collisions[21]; - struct collision *sp72 = NULL; + struct collision *collision = NULL; f32 ground; struct geo *geo = NULL; - cd_collect_geo_for_cyl(pos, radius, rooms, CDTYPE_ALL, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, CHECKVERTICAL_NO, 0, 0, collisions, 20); - ground = cd_find_ground_from_list(collisions, pos, &sp72, radius); + cd_volume_collect(pos, radius, rooms, CDTYPE_ALL, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, CHECKVERTICAL_NO, 0, 0, collisions, 20); + ground = cd_find_ground_finalise(collisions, pos, &collision, radius); - if (sp72) { - geo = sp72->geo; + if (collision) { + geo = collision->geo; } if (floorcol) { @@ -2209,8 +2244,8 @@ f32 cd_find_ground_info_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u1 } if (floorroom) { - if (sp72) { - *floorroom = sp72->room; + if (collision) { + *floorroom = collision->room; } else { *floorroom = -1; } @@ -2219,7 +2254,7 @@ f32 cd_find_ground_info_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u1 if (inlift) { if (geo && geo->type == GEOTYPE_TILE_F && (geo->flags & GEOFLAG_LIFTFLOOR)) { *inlift = true; - *lift = sp72->prop; + *lift = collision->prop; if (*lift && (*lift)->obj->modelnum == MODEL_ESCA_STEP && floortype) { *floortype = FLOORTYPE_METAL; @@ -2234,10 +2269,10 @@ f32 cd_find_ground_info_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u1 } /** - * This function must come immediately after cd_find_ground_info_at_cyl. + * This function must come immediately after cd_find_ground_at_cyl_ctfril. * * A piracy check looks for this function, then backtracks two instructions to - * nop the jr ra at the end of cd_find_ground_info_at_cyl, causing it to flow into this + * nop the jr ra at the end of cd_find_ground_at_cyl_ctfril, causing it to flow into this * function and return 0. */ f32 cd_return_zero(void) @@ -2245,22 +2280,22 @@ f32 cd_return_zero(void) return 0; } -f32 cd_find_ground_at_cyl(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, u8 *floortype) +f32 cd_find_ground_at_cyl_ct(struct coord *pos, f32 radius, RoomNum *rooms, u16 *floorcol, u8 *floortype) { - return cd_find_ground_info_at_cyl(pos, radius, rooms, floorcol, floortype, NULL, NULL, NULL, NULL); + return cd_find_ground_at_cyl_ctfril(pos, radius, rooms, floorcol, floortype, NULL, NULL, NULL, NULL); } -f32 cd_find_floor_y_colour_type_at_pos(struct coord *pos, RoomNum *rooms, u16 *floorcol, u8 *floortype) +f32 cd_find_ground_at_pos_ct(struct coord *pos, RoomNum *rooms, u16 *floorcol, u8 *floortype) { struct geo *geo; - RoomNum sp30[2]; - f32 sp2c; - f32 result = -4294967296; + RoomNum room; + f32 y; + f32 ground = -4294967296; - cd_find_closest_vertical(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &sp30[1], &sp2c, NULL, SURFACE_FLOOR); + cd_find_y(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &y, NULL, SURFACE_FLOOR); if (geo) { - result = sp2c; + ground = y; } if (floorcol) { @@ -2271,34 +2306,34 @@ f32 cd_find_floor_y_colour_type_at_pos(struct coord *pos, RoomNum *rooms, u16 *f cd_get_floor_type(geo, floortype); } - return result; + return ground; } -s32 cd_find_floor_room_at_pos(struct coord *pos, RoomNum *nearrooms) +RoomNum cd_find_room_at_pos(struct coord *pos, RoomNum *nearrooms) { struct geo *geo; RoomNum room; - f32 sp2c; + f32 y; - cd_find_closest_vertical(pos, nearrooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &sp2c, 0, SURFACE_FLOOR); + cd_find_y(pos, nearrooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &y, 0, SURFACE_FLOOR); return room; } #if VERSION >= VERSION_NTSC_1_0 -RoomNum cd_find_floor_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr, u16 *flagsptr) +RoomNum cd_find_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *yptr, u16 *floorcolptr, u16 *flagsptr) #else -RoomNum cd_find_floor_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr) +RoomNum cd_find_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *yptr, u16 *floorcolptr) #endif { struct geo *geo; RoomNum room; - f32 sp2c; + f32 y; - cd_find_closest_vertical(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &sp2c, NULL, SURFACE_FLOOR); + cd_find_y(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &y, NULL, SURFACE_FLOOR); if (geo != NULL) { - *arg2 = sp2c; + *yptr = y; } if (floorcolptr != NULL) { @@ -2315,19 +2350,19 @@ RoomNum cd_find_floor_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *roo } #if VERSION >= VERSION_NTSC_1_0 -RoomNum cd_find_ceiling_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr, u16 *flagsptr) +RoomNum cd_find_ceiling_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *yptr, u16 *floorcolptr, u16 *flagsptr) #else -RoomNum cd_find_ceiling_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcolptr) +RoomNum cd_find_ceiling_room_at_pos_ycf(struct coord *pos, RoomNum *rooms, f32 *yptr, u16 *floorcolptr) #endif { struct geo *geo; - RoomNum sp32; - f32 sp2c; + RoomNum room; + f32 y; - cd_find_closest_vertical(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &sp32, &sp2c, NULL, SURFACE_CEILING); + cd_find_y(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &y, NULL, SURFACE_CEILING); if (geo != NULL) { - *arg2 = sp2c; + *yptr = y; } if (floorcolptr != NULL) { @@ -2340,19 +2375,19 @@ RoomNum cd_find_ceiling_room_y_colour_flags_at_pos(struct coord *pos, RoomNum *r } #endif - return sp32; + return room; } -RoomNum cd_find_floor_room_y_colour_normal_prop_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcol, struct coord *normal, struct prop **propptr) +RoomNum cd_find_room_at_pos_ycnp(struct coord *pos, RoomNum *rooms, f32 *yptr, u16 *floorcol, struct coord *normal, struct prop **propptr) { struct geo *geo; RoomNum room; - f32 sp2c; + f32 y; - cd_find_closest_vertical(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &sp2c, propptr, SURFACE_FLOOR); + cd_find_y(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &y, propptr, SURFACE_FLOOR); if (geo) { - *arg2 = sp2c; + *yptr = y; cd_get_geo_normal(geo, normal); } @@ -2363,16 +2398,16 @@ RoomNum cd_find_floor_room_y_colour_normal_prop_at_pos(struct coord *pos, RoomNu return room; } -RoomNum cd_find_ceiling_room_y_colour_flags_normal_at_pos(struct coord *pos, RoomNum *rooms, f32 *arg2, u16 *floorcol, u16 *flagsptr, struct coord *normal) +RoomNum cd_find_ceiling_room_at_pos_ycfn(struct coord *pos, RoomNum *rooms, f32 *yptr, u16 *floorcol, u16 *flagsptr, struct coord *normal) { struct geo *geo; - RoomNum sp32; - f32 sp2c; + RoomNum room; + f32 y; - cd_find_closest_vertical(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &sp32, &sp2c, NULL, SURFACE_CEILING); + cd_find_y(pos, rooms, GEOFLAG_FLOOR1 | GEOFLAG_FLOOR2, &geo, &room, &y, NULL, SURFACE_CEILING); if (geo) { - *arg2 = sp2c; + *yptr = y; cd_get_geo_normal(geo, normal); } @@ -2384,114 +2419,142 @@ RoomNum cd_find_ceiling_room_y_colour_flags_normal_at_pos(struct coord *pos, Roo *flagsptr = geo->flags; } - return sp32; + return room; } /** * Tests if a cylinder volume fits in the given position. */ -s32 cd_test_volume(struct coord *pos, f32 width, RoomNum *rooms, s32 types, bool checkvertical, f32 ymax, f32 ymin) +s32 cd_test_volume_simple(struct coord *pos, f32 radius, RoomNum *rooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) { struct collision collisions[2]; - bool result = true; + s32 result = CDRESULT_NOCOLLISION; - cd_collect_geo_for_cyl(pos, width, rooms, types, GEOFLAG_WALL, checkvertical, ymax, ymin, collisions, 1); + cd_volume_collect(pos, radius, rooms, types, GEOFLAG_WALL, checkvertical, ymax, ymin, collisions, 1); if (collisions[0].geo) { - result = false; + result = CDRESULT_COLLISION; cd_set_obstacle_prop(collisions[0].prop); } return result; } -s32 cd_exam_cyl_move01(struct coord *pos, struct coord *pos2, f32 radius, RoomNum *rooms, s32 types, bool checkvertical, f32 ymax, f32 ymin) +/** + * Do a volume test at topos. If there are any collisions, + * find the edge closest to topos. Unless the collision is with a cylinder, + * in which case the edge facing frompos is used. + * + * Saves the obstacle's edge vertices and prop. + * + * The function stops once any collision is found, so it's possible that there + * could be a closer obstacle than the returned edge. + * + * Used by: + * - Chrs being pushed + * - Chrs navigating around obstacles + * - Hoverbikes + * - Player movement with a grabbed object + */ +s32 cd_test_volume_closestedge(struct coord *frompos, struct coord *topos, f32 radius, RoomNum *rooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) { struct collision collisions[2]; - s32 cdresult; - struct coord sp70; - struct coord sp64; + s32 result; + struct coord edgevtx1; + struct coord edgevtx2; - cdresult = CDRESULT_NOCOLLISION; + result = CDRESULT_NOCOLLISION; - cd_collect_geo_for_cyl(pos2, radius, rooms, types, GEOFLAG_WALL, checkvertical, ymax, ymin, collisions, 1); + cd_volume_collect(topos, radius, rooms, types, GEOFLAG_WALL, checkvertical, ymax, ymin, collisions, 1); if (collisions[0].geo != NULL) { - cdresult = CDRESULT_COLLISION; + result = CDRESULT_COLLISION; if (collisions[0].geo->type == GEOTYPE_TILE_I) { struct geotilei *tile = (struct geotilei *) collisions[0].geo; s32 this = collisions[0].vertexindex; s32 next = (this + 1) % tile->header.numvertices; - sp70.x = tile->vertices[this][0]; - sp70.y = tile->vertices[this][1]; - sp70.z = tile->vertices[this][2]; + edgevtx1.x = tile->vertices[this][0]; + edgevtx1.y = tile->vertices[this][1]; + edgevtx1.z = tile->vertices[this][2]; - sp64.x = tile->vertices[next][0]; - sp64.y = tile->vertices[next][1]; - sp64.z = tile->vertices[next][2]; + edgevtx2.x = tile->vertices[next][0]; + edgevtx2.y = tile->vertices[next][1]; + edgevtx2.z = tile->vertices[next][2]; } else if (collisions[0].geo->type == GEOTYPE_TILE_F) { struct geotilef *tile = (struct geotilef *) collisions[0].geo; s32 this = collisions[0].vertexindex; s32 next = (this + 1) % tile->header.numvertices; - sp70.x = tile->vertices[this].x; - sp70.y = tile->vertices[this].y; - sp70.z = tile->vertices[this].z; + edgevtx1.x = tile->vertices[this].x; + edgevtx1.y = tile->vertices[this].y; + edgevtx1.z = tile->vertices[this].z; - sp64.x = tile->vertices[next].x; - sp64.y = tile->vertices[next].y; - sp64.z = tile->vertices[next].z; + edgevtx2.x = tile->vertices[next].x; + edgevtx2.y = tile->vertices[next].y; + edgevtx2.z = tile->vertices[next].z; } else if (collisions[0].geo->type == GEOTYPE_BLOCK) { struct geoblock *block = (struct geoblock *) collisions[0].geo; s32 this = collisions[0].vertexindex; s32 next = (this + 1) % block->header.numvertices; - sp70.x = block->vertices[this][0]; - sp70.y = pos->y; - sp70.z = block->vertices[this][1]; + edgevtx1.x = block->vertices[this][0]; + edgevtx1.y = frompos->y; + edgevtx1.z = block->vertices[this][1]; - sp64.x = block->vertices[next][0]; - sp64.y = pos->y; - sp64.z = block->vertices[next][1]; + edgevtx2.x = block->vertices[next][0]; + edgevtx2.y = frompos->y; + edgevtx2.z = block->vertices[next][1]; } else if (collisions[0].geo->type == GEOTYPE_CYL) { struct geocyl *cyl = (struct geocyl *) collisions[0].geo; - cd_00025848(cyl->x, cyl->z, cyl->radius, pos->x, pos->z, &sp70.x, &sp70.z, &sp64.x, &sp64.z); + cd_pos_get_cyl_edge(cyl->x, cyl->z, cyl->radius, frompos->x, frompos->z, &edgevtx1.x, &edgevtx1.z, &edgevtx2.x, &edgevtx2.z); - sp70.y = pos->y; - sp64.y = pos->y; + edgevtx1.y = frompos->y; + edgevtx2.y = frompos->y; } - cd_set_obstacle_vtx_prop(&sp70, &sp64, collisions[0].prop); - } - - return cdresult; -} - -s32 cd_exam_cyl_move02(struct coord *origpos, struct coord *dstpos, f32 width, RoomNum *dstrooms, s32 types, bool checkvertical, f32 ymax, f32 ymin) -{ - struct collision collisions[21]; - struct coord dist; - s32 result = CDRESULT_NOCOLLISION; - - cd_collect_geo_for_cyl_move(dstpos, width, dstrooms, types, GEOFLAG_WALL, checkvertical, ymax, ymin, collisions, 20); - - if (collisions[0].geo) { - result = CDRESULT_COLLISION; - - dist.x = dstpos->x - origpos->x; - dist.y = dstpos->y - origpos->y; - dist.z = dstpos->z - origpos->z; - - cd_0002901c(origpos, &dist, width, collisions); + cd_set_obstacle_edge_prop(&edgevtx1, &edgevtx2, collisions[0].prop); } return result; } -bool cd_0002aac0_int_tile(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct geotilei *tile, struct coord *arg4, struct coord *arg5) +/** + * Do a volume test at topos. If there are any collisions, + * find the edge of the closest object in the direction of frompos. + * + * Saves the obstacle's edge vertices, prop and distance. + * + * Used by: + * - Player movement when walking + * - Player movement when on hoverbike + * - Player movement when using eyespy + * - Projectiles + */ +s32 cd_test_volume_fromdir(struct coord *frompos, struct coord *topos, f32 radius, RoomNum *dstrooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) +{ + struct collision collisions[21]; + struct coord dist; + s32 result = CDRESULT_NOCOLLISION; + + cd_volumefromdir_collect(topos, radius, dstrooms, types, GEOFLAG_WALL, checkvertical, ymax, ymin, collisions, 20); + + if (collisions[0].geo) { + result = CDRESULT_COLLISION; + + dist.x = topos->x - frompos->x; + dist.y = topos->y - frompos->y; + dist.z = topos->z - frompos->z; + + cd_volumefromdir_finalise(frompos, &dist, radius, collisions); + } + + return result; +} + +bool cd_is_line_intersecting_tilei(struct coord *frompos, struct coord *topos, struct coord *dist, struct geotilei *tile, struct coord *endpos, struct coord *arg5) { s32 i; u8 numvertices = tile->header.numvertices; @@ -2500,7 +2563,7 @@ bool cd_0002aac0_int_tile(struct coord *arg0, struct coord *arg1, struct coord * if (func0002f490((struct vec3s16 *)&tile->vertices[0][0], (struct vec3s16 *)&tile->vertices[i - 1][0], (struct vec3s16 *)&tile->vertices[i][0], - NULL, arg0, arg1, arg2, arg4, arg5)) { + NULL, frompos, topos, dist, endpos, arg5)) { return true; } } @@ -2508,14 +2571,14 @@ bool cd_0002aac0_int_tile(struct coord *arg0, struct coord *arg1, struct coord * return false; } -bool cd_0002ab98_flt_tile(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct geotilef *tile, struct coord *arg4, struct coord *arg5) +bool cd_is_line_intersecting_tilef(struct coord *frompos, struct coord *topos, struct coord *dist, struct geotilef *tile, struct coord *endpos, struct coord *arg5) { s32 i; u8 numvertices = tile->header.numvertices; for (i = 2; i < numvertices; i++) { if (func0002f560(&tile->vertices[0], &tile->vertices[i - 1], &tile->vertices[i], - NULL, arg0, arg1, arg2, arg4, arg5)) { + NULL, frompos, topos, dist, endpos, arg5)) { return true; } } @@ -2523,89 +2586,89 @@ bool cd_0002ab98_flt_tile(struct coord *arg0, struct coord *arg1, struct coord * return false; } -bool cd_0002ac70_int_tile(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct geotilei *tile, - struct coord *arg4, struct coord *arg5, struct coord *arg6, bool arg7, f32 arg8, f32 arg9) +bool cd_is_cylpath_intersecting_tilei(struct coord *frompos, struct coord *topos, struct coord *dist, struct geotilei *tile, + struct coord *endpos, struct coord *edgevtx1, struct coord *edgevtx2, bool checkvertical, f32 cylymax, f32 cylymin) { bool result = false; s32 i; - f32 f0; + f32 distfrac; s32 numvertices = tile->header.numvertices; s32 next; - s32 spb8 = 1; - f32 f22 = 1.0f; - s32 spb0; - f32 spac; - f32 spa8; - f32 ymax = *(s16 *)(tile->ymax + (uintptr_t)tile); - f32 ymin = *(s16 *)(tile->ymin + (uintptr_t)tile); - f32 spa0[2]; - f32 sp98[2]; - f32 sp90[2]; - f32 sp88[2]; + bool spb8 = true; + f32 bestdistfrac = 1.0f; + s32 bestvtx; + f32 y2; + f32 y1; + f32 tileymax = *(s16 *)(tile->ymax + (uintptr_t)tile); + f32 tileymin = *(s16 *)(tile->ymin + (uintptr_t)tile); + f32 fromxz[2]; + f32 toxz[2]; + f32 vtx1xz[2]; + f32 vtx2xz[2]; - if (!arg7 - || (arg0->y + arg8 >= ymin && arg1->y + arg9 <= ymax) - || (arg0->y + arg9 <= ymax && arg1->y + arg8 >= ymin)) { + if (!checkvertical + || (frompos->y + cylymax >= tileymin && topos->y + cylymin <= tileymax) + || (frompos->y + cylymin <= tileymax && topos->y + cylymax >= tileymin)) { for (i = 0; i < numvertices; i++) { next = (i + 1) % numvertices; - if (cd_000254d8(arg0, arg1, tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], &spb8)) { - spa0[0] = arg0->x; - spa0[1] = arg0->z; - sp98[0] = arg1->x; - sp98[1] = arg1->z; - sp90[0] = tile->vertices[i][0]; - sp90[1] = tile->vertices[i][2]; - sp88[0] = tile->vertices[next][0]; - sp88[1] = tile->vertices[next][2]; + if (cd_000254d8(frompos, topos, tile->vertices[i][0], tile->vertices[i][2], tile->vertices[next][0], tile->vertices[next][2], &spb8)) { + fromxz[0] = frompos->x; + fromxz[1] = frompos->z; + toxz[0] = topos->x; + toxz[1] = topos->z; + vtx1xz[0] = tile->vertices[i][0]; + vtx1xz[1] = tile->vertices[i][2]; + vtx2xz[0] = tile->vertices[next][0]; + vtx2xz[1] = tile->vertices[next][2]; - f0 = func0f1577f0(spa0, sp98, sp90, sp88); + distfrac = func0f1577f0(fromxz, toxz, vtx1xz, vtx2xz); - if (f0 < f22) { - if (arg7) { - spa8 = (arg1->y - arg0->y) * f0 + arg0->y; - spac = spa8 + arg8; - spa8 = spa8 + arg9; + if (distfrac < bestdistfrac) { + if (checkvertical) { + y1 = frompos->f[1] + (topos->f[1] - frompos->f[1]) * distfrac; + y2 = y1 + cylymax; + y1 = y1 + cylymin; } - if (!arg7 || (!(spa8 >= ymax) && !(spac <= ymin))) { + if (!checkvertical || !(y1 >= tileymax || y2 <= tileymin)) { result = true; - f22 = f0; - spb0 = i; + bestdistfrac = distfrac; + bestvtx = i; } } } } if (result) { - arg4->x = arg0->x + arg2->f[0] * f22; - arg4->y = arg0->y + arg2->f[1] * f22; - arg4->z = arg0->z + arg2->f[2] * f22; + endpos->x = frompos->x + dist->f[0] * bestdistfrac; + endpos->y = frompos->y + dist->f[1] * bestdistfrac; + endpos->z = frompos->z + dist->f[2] * bestdistfrac; - if (arg5 != NULL && arg6 != NULL) { - arg5->x = tile->vertices[spb0][0]; - arg5->y = arg4->y; - arg5->z = tile->vertices[spb0][2]; + if (edgevtx1 != NULL && edgevtx2 != NULL) { + edgevtx1->x = tile->vertices[bestvtx][0]; + edgevtx1->y = endpos->y; + edgevtx1->z = tile->vertices[bestvtx][2]; - arg6->x = tile->vertices[(spb0 + 1) % numvertices][0]; - arg6->y = arg4->y; - arg6->z = tile->vertices[(spb0 + 1) % numvertices][2]; + edgevtx2->x = tile->vertices[(bestvtx + 1) % numvertices][0]; + edgevtx2->y = endpos->y; + edgevtx2->z = tile->vertices[(bestvtx + 1) % numvertices][2]; } } else if (!result && spb8) { result = true; - arg4->x = arg0->x; - arg4->y = arg0->y; - arg4->z = arg0->z; + endpos->x = frompos->x; + endpos->y = frompos->y; + endpos->z = frompos->z; - if (arg5 != NULL && arg6 != NULL) { - arg5->x = arg0->x; - arg5->y = arg0->y; - arg5->z = arg0->z; + if (edgevtx1 != NULL && edgevtx2 != NULL) { + edgevtx1->x = frompos->x; + edgevtx1->y = frompos->y; + edgevtx1->z = frompos->z; - arg6->x = arg0->x; - arg6->y = arg0->y; - arg6->z = arg0->z; + edgevtx2->x = frompos->x; + edgevtx2->y = frompos->y; + edgevtx2->z = frompos->z; } } } @@ -2613,89 +2676,89 @@ bool cd_0002ac70_int_tile(struct coord *arg0, struct coord *arg1, struct coord * return result; } -bool cd_0002b128_flt_tile(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct geotilef *tile, - struct coord *arg4, struct coord *arg5, struct coord *arg6, bool arg7, f32 arg8, f32 arg9) +bool cd_is_cylpath_intersecting_tilef(struct coord *frompos, struct coord *topos, struct coord *dist, struct geotilef *tile, + struct coord *endpos, struct coord *edgevtx1, struct coord *edgevtx2, bool checkvertical, f32 cylymax, f32 cylymin) { bool result = false; s32 i; - f32 f0; + f32 distfrac; s32 numvertices = tile->header.numvertices; s32 next; - s32 spb8 = 1; - f32 f22 = 1.0f; - s32 spb0; - f32 spac; - f32 spa8; - f32 ymax = tile->vertices[tile->max[1]].y; - f32 ymin = tile->vertices[tile->min[1]].y; - f32 spa0[2]; - f32 sp98[2]; - f32 sp90[2]; - f32 sp88[2]; + bool spb8 = true; + f32 bestdistfrac = 1.0f; + s32 bestvtx; + f32 y2; + f32 y1; + f32 tileymax = tile->vertices[tile->max[1]].y; + f32 tileymin = tile->vertices[tile->min[1]].y; + f32 fromxz[2]; + f32 toxz[2]; + f32 vtx1xz[2]; + f32 vtx2xz[2]; - if (!arg7 - || (arg0->y + arg8 >= ymin && arg1->y + arg9 <= ymax) - || (arg0->y + arg9 <= ymax && arg1->y + arg8 >= ymin)) { + if (!checkvertical + || (frompos->y + cylymax >= tileymin && topos->y + cylymin <= tileymax) + || (frompos->y + cylymin <= tileymax && topos->y + cylymax >= tileymin)) { for (i = 0; i < numvertices; i++) { next = (i + 1) % numvertices; - if (cd_000254d8(arg0, arg1, tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, &spb8)) { - spa0[0] = arg0->x; - spa0[1] = arg0->z; - sp98[0] = arg1->x; - sp98[1] = arg1->z; - sp90[0] = tile->vertices[i].x; - sp90[1] = tile->vertices[i].z; - sp88[0] = tile->vertices[next].x; - sp88[1] = tile->vertices[next].z; + if (cd_000254d8(frompos, topos, tile->vertices[i].x, tile->vertices[i].z, tile->vertices[next].x, tile->vertices[next].z, &spb8)) { + fromxz[0] = frompos->x; + fromxz[1] = frompos->z; + toxz[0] = topos->x; + toxz[1] = topos->z; + vtx1xz[0] = tile->vertices[i].x; + vtx1xz[1] = tile->vertices[i].z; + vtx2xz[0] = tile->vertices[next].x; + vtx2xz[1] = tile->vertices[next].z; - f0 = func0f1577f0(spa0, sp98, sp90, sp88); + distfrac = func0f1577f0(fromxz, toxz, vtx1xz, vtx2xz); - if (f0 < f22) { - if (arg7) { - spa8 = (arg1->y - arg0->y) * f0 + arg0->y; - spac = spa8 + arg8; - spa8 = spa8 + arg9; + if (distfrac < bestdistfrac) { + if (checkvertical) { + y1 = frompos->f[1] + (topos->f[1] - frompos->f[1]) * distfrac; + y2 = y1 + cylymax; + y1 = y1 + cylymin; } - if (!arg7 || (!(spa8 >= ymax) && !(spac <= ymin))) { + if (!checkvertical || !(y1 >= tileymax || y2 <= tileymin)) { result = true; - f22 = f0; - spb0 = i; + bestdistfrac = distfrac; + bestvtx = i; } } } } if (result) { - arg4->x = arg0->x + arg2->f[0] * f22; - arg4->y = arg0->y + arg2->f[1] * f22; - arg4->z = arg0->z + arg2->f[2] * f22; + endpos->x = frompos->x + dist->f[0] * bestdistfrac; + endpos->y = frompos->y + dist->f[1] * bestdistfrac; + endpos->z = frompos->z + dist->f[2] * bestdistfrac; - if (arg5 != NULL && arg6 != NULL) { - arg5->x = tile->vertices[spb0].x; - arg5->y = arg4->y; - arg5->z = tile->vertices[spb0].z; + if (edgevtx1 != NULL && edgevtx2 != NULL) { + edgevtx1->x = tile->vertices[bestvtx].x; + edgevtx1->y = endpos->y; + edgevtx1->z = tile->vertices[bestvtx].z; - arg6->x = tile->vertices[(spb0 + 1) % numvertices].x; - arg6->y = arg4->y; - arg6->z = tile->vertices[(spb0 + 1) % numvertices].z; + edgevtx2->x = tile->vertices[(bestvtx + 1) % numvertices].x; + edgevtx2->y = endpos->y; + edgevtx2->z = tile->vertices[(bestvtx + 1) % numvertices].z; } } else if (!result && spb8) { result = true; - arg4->x = arg0->x; - arg4->y = arg0->y; - arg4->z = arg0->z; + endpos->x = frompos->x; + endpos->y = frompos->y; + endpos->z = frompos->z; - if (arg5 != NULL && arg6 != NULL) { - arg5->x = arg0->x; - arg5->y = arg0->y; - arg5->z = arg0->z; + if (edgevtx1 != NULL && edgevtx2 != NULL) { + edgevtx1->x = frompos->x; + edgevtx1->y = frompos->y; + edgevtx1->z = frompos->z; - arg6->x = arg0->x; - arg6->y = arg0->y; - arg6->z = arg0->z; + edgevtx2->x = frompos->x; + edgevtx2->y = frompos->y; + edgevtx2->z = frompos->z; } } } @@ -2703,87 +2766,87 @@ bool cd_0002b128_flt_tile(struct coord *arg0, struct coord *arg1, struct coord * return result; } -bool cd_0002b560_block(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct geoblock *block, - struct coord *arg4, struct coord *arg5, struct coord *arg6, bool arg7, f32 arg8, f32 arg9) +bool cd_is_cylpath_intersecting_block(struct coord *frompos, struct coord *topos, struct coord *dist, struct geoblock *block, + struct coord *endpos, struct coord *edgevtx1, struct coord *edgevtx2, bool checkvertical, f32 cylymax, f32 cylymin) { bool result = false; s32 i; - f32 f0; + f32 distfrac; s32 numvertices = block->header.numvertices; s32 next; - s32 spb8 = 1; - f32 f22 = 1.0f; - s32 spb0; - f32 spac; - f32 spa8; - f32 spa0[2]; - f32 sp98[2]; - f32 sp90[2]; - f32 sp88[2]; + bool spb8 = true; + f32 bestdistfrac = 1.0f; + s32 bestvtx; + f32 y2; + f32 y1; + f32 fromxz[2]; + f32 toxz[2]; + f32 vtx1xz[2]; + f32 vtx2xz[2]; - if (!arg7 - || (arg0->y + arg8 >= block->ymin && arg1->y + arg9 <= block->ymax) - || (arg0->y + arg9 <= block->ymax && arg1->y + arg8 >= block->ymin)) { + if (!checkvertical + || (frompos->y + cylymax >= block->ymin && topos->y + cylymin <= block->ymax) + || (frompos->y + cylymin <= block->ymax && topos->y + cylymax >= block->ymin)) { for (i = 0; i < numvertices; i++) { next = (i + 1) % numvertices; - if (cd_000254d8(arg0, arg1, block->vertices[i][0], block->vertices[i][1], block->vertices[next][0], block->vertices[next][1], &spb8)) { - spa0[0] = arg0->x; - spa0[1] = arg0->z; - sp98[0] = arg1->x; - sp98[1] = arg1->z; - sp90[0] = block->vertices[i][0]; - sp90[1] = block->vertices[i][1]; - sp88[0] = block->vertices[next][0]; - sp88[1] = block->vertices[next][1]; + if (cd_000254d8(frompos, topos, block->vertices[i][0], block->vertices[i][1], block->vertices[next][0], block->vertices[next][1], &spb8)) { + fromxz[0] = frompos->x; + fromxz[1] = frompos->z; + toxz[0] = topos->x; + toxz[1] = topos->z; + vtx1xz[0] = block->vertices[i][0]; + vtx1xz[1] = block->vertices[i][1]; + vtx2xz[0] = block->vertices[next][0]; + vtx2xz[1] = block->vertices[next][1]; - f0 = func0f1577f0(spa0, sp98, sp90, sp88); + distfrac = func0f1577f0(fromxz, toxz, vtx1xz, vtx2xz); - if (f0 < f22) { - if (arg7) { - spa8 = (arg1->y - arg0->y) * f0 + arg0->y; - spac = spa8 + arg8; - spa8 = spa8 + arg9; + if (distfrac < bestdistfrac) { + if (checkvertical) { + y1 = (topos->y - frompos->y) * distfrac + frompos->y; + y2 = y1 + cylymax; + y1 = y1 + cylymin; } - if (!arg7 || (!(spa8 >= block->ymax) && !(spac <= block->ymin))) { + if (!checkvertical || (!(y1 >= block->ymax) && !(y2 <= block->ymin))) { result = true; - f22 = f0; - spb0 = i; + bestdistfrac = distfrac; + bestvtx = i; } } } } if (result) { - arg4->x = arg0->x + arg2->f[0] * f22; - arg4->y = arg0->y + arg2->f[1] * f22; - arg4->z = arg0->z + arg2->f[2] * f22; + endpos->x = frompos->x + dist->f[0] * bestdistfrac; + endpos->y = frompos->y + dist->f[1] * bestdistfrac; + endpos->z = frompos->z + dist->f[2] * bestdistfrac; - if (arg5 != NULL && arg6 != NULL) { - arg5->x = block->vertices[spb0][0]; - arg5->y = arg4->y; - arg5->z = block->vertices[spb0][1]; + if (edgevtx1 != NULL && edgevtx2 != NULL) { + edgevtx1->x = block->vertices[bestvtx][0]; + edgevtx1->y = endpos->y; + edgevtx1->z = block->vertices[bestvtx][1]; - arg6->x = block->vertices[(spb0 + 1) % numvertices][0]; - arg6->y = arg4->y; - arg6->z = block->vertices[(spb0 + 1) % numvertices][1]; + edgevtx2->x = block->vertices[(bestvtx + 1) % numvertices][0]; + edgevtx2->y = endpos->y; + edgevtx2->z = block->vertices[(bestvtx + 1) % numvertices][1]; } } else if (!result && spb8) { result = true; - arg4->x = arg0->x; - arg4->y = arg0->y; - arg4->z = arg0->z; + endpos->x = frompos->x; + endpos->y = frompos->y; + endpos->z = frompos->z; - if (arg5 != NULL && arg6 != NULL) { - arg5->x = arg0->x; - arg5->y = arg0->y; - arg5->z = arg0->z; + if (edgevtx1 != NULL && edgevtx2 != NULL) { + edgevtx1->x = frompos->x; + edgevtx1->y = frompos->y; + edgevtx1->z = frompos->z; - arg6->x = arg0->x; - arg6->y = arg0->y; - arg6->z = arg0->z; + edgevtx2->x = frompos->x; + edgevtx2->y = frompos->y; + edgevtx2->z = frompos->z; } } } @@ -2791,8 +2854,8 @@ bool cd_0002b560_block(struct coord *arg0, struct coord *arg1, struct coord *arg return result; } -bool cd_0002b954_cyl(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct geocyl *cyl, - struct coord *arg4, struct coord *arg5, struct coord *arg6, bool arg7, f32 arg8, f32 arg9) +bool cd_is_cylpath_intersecting_cyl(struct coord *frompos, struct coord *topos, struct coord *dist, struct geocyl *cyl, + struct coord *endpos, struct coord *edgevtx1, struct coord *edgevtx2, bool checkvertical, f32 ymax, f32 ymin) { bool result = false; f32 mult; @@ -2801,23 +2864,23 @@ bool cd_0002b954_cyl(struct coord *arg0, struct coord *arg1, struct coord *arg2, f32 z = cyl->z; f32 radius = cyl->radius; - if (!arg7 - || (arg0->y + arg8 >= cyl->ymin && arg1->y + arg9 <= cyl->ymax) - || (arg0->y + arg9 <= cyl->ymax && arg1->y + arg8 >= cyl->ymin)) { - sp74 = cd_00025654(arg0->x, arg0->z, arg1->x, arg1->z, x, z); + if (!checkvertical + || (frompos->y + ymax >= cyl->ymin && topos->y + ymin <= cyl->ymax) + || (frompos->y + ymin <= cyl->ymax && topos->y + ymax >= cyl->ymin)) { + sp74 = cd_pos_get_dist_to_line(frompos->x, frompos->z, topos->x, topos->z, x, z); if (sp74 < 0.0f) { sp74 = -sp74; } if (sp74 < radius - && (cd_00025724(arg0->x, arg0->z, x, z) < radius - || cd_00025724(arg1->x, arg1->z, x, z) < radius - || cd_00025774(arg0->x, arg0->z, arg1->x, arg1->z, x, z))) { - f32 xdiff = arg1->x - arg0->x; - f32 zdiff = arg1->z - arg0->z; + && (cd_pos_get_dist_to_vtx(frompos->x, frompos->z, x, z) < radius + || cd_pos_get_dist_to_vtx(topos->x, topos->z, x, z) < radius + || cd_pos_get_side(frompos->x, frompos->z, topos->x, topos->z, x, z))) { + f32 xdiff = topos->x - frompos->x; + f32 zdiff = topos->z - frompos->z; f32 sqdist; - f32 dist; + f32 distance; u32 stack; f32 sp50; f32 sp4c; @@ -2826,41 +2889,41 @@ bool cd_0002b954_cyl(struct coord *arg0, struct coord *arg1, struct coord *arg2, sp50 = sqrtf(xdiff * xdiff + zdiff * zdiff); if (sp50 > 0.0f) { - xdiff = x - arg0->x; - zdiff = z - arg0->z; + xdiff = x - frompos->x; + zdiff = z - frompos->z; sqdist = xdiff * xdiff + zdiff * zdiff; if (sp74 * sp74 <= sqdist) { - dist = sqrtf(sqdist - sp74 * sp74) - sqrtf(radius * radius - sp74 * sp74); + distance = sqrtf(sqdist - sp74 * sp74) - sqrtf(radius * radius - sp74 * sp74); } else { - dist = 0.0f; + distance = 0.0f; } - mult = dist / sp50; + mult = distance / sp50; } else { mult = 0.0f; } if (mult < 1.0f) { - if (arg7) { - sp48 = (arg1->y - arg0->y) * mult + arg0->y; - sp4c = sp48 + arg8; - sp48 = sp48 + arg9; + if (checkvertical) { + sp48 = (topos->y - frompos->y) * mult + frompos->y; + sp4c = sp48 + ymax; + sp48 = sp48 + ymin; } - if (!arg7 || (!(sp48 >= cyl->ymax) && !(sp4c <= cyl->ymin))) { + if (!checkvertical || (!(sp48 >= cyl->ymax) && !(sp4c <= cyl->ymin))) { result = true; - arg4->x = arg0->x + arg2->f[0] * mult; - arg4->y = arg0->y + arg2->f[1] * mult; - arg4->z = arg0->z + arg2->f[2] * mult; + endpos->x = frompos->x + dist->f[0] * mult; + endpos->y = frompos->y + dist->f[1] * mult; + endpos->z = frompos->z + dist->f[2] * mult; - if (arg5 != NULL && arg6 != NULL) { - cd_00025848(x, z, radius, arg0->x, arg0->z, &arg5->x, &arg5->z, &arg6->x, &arg6->z); + if (edgevtx1 != NULL && edgevtx2 != NULL) { + cd_pos_get_cyl_edge(x, z, radius, frompos->x, frompos->z, &edgevtx1->x, &edgevtx1->z, &edgevtx2->x, &edgevtx2->z); - arg5->y = arg4->y; - arg6->y = arg4->y; + edgevtx1->y = endpos->y; + edgevtx2->y = endpos->y; } } } @@ -2870,7 +2933,7 @@ bool cd_0002b954_cyl(struct coord *arg0, struct coord *arg1, struct coord *arg2, return result; } -bool cd_test_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord *arg3, struct coord *arg4, u16 geoflags, bool checkvertical, s32 arg7, f32 arg8, f32 arg9) +bool cd_test_atobany_from_bytes(u8 *start, u8 *end, struct coord *frompos, struct coord *topos, struct coord *dist, u16 geoflags, bool islos, bool checkvertical, f32 ymax, f32 ymin) { struct geo *geo = (struct geo *) start; @@ -2879,35 +2942,37 @@ bool cd_test_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord struct geotilei *tile = (struct geotilei *) geo; struct coord min; struct coord max; - struct coord spc4; + struct coord endpos; struct coord spb8; if (tile->header.flags & geoflags) { min.x = *(s16 *)(tile->xmin + (uintptr_t)tile); - if ((!(arg2->x < min.x)) || !(arg3->x < min.x)) { + if ((!(frompos->x < min.x)) || !(topos->x < min.x)) { max.x = *(s16 *)(tile->xmax + (uintptr_t)tile); - if ((!(arg2->x > max.x)) || !(arg3->x > max.x)) { + if ((!(frompos->x > max.x)) || !(topos->x > max.x)) { min.z = *(s16 *)(tile->zmin + (uintptr_t)tile); - if ((!(arg2->z < min.z)) || !(arg3->z < min.z)) { + if ((!(frompos->z < min.z)) || !(topos->z < min.z)) { max.z = *(s16 *)(tile->zmax + (uintptr_t)tile); - if ((!(arg2->z > max.z)) || !(arg3->z > max.z)) { + if ((!(frompos->z > max.z)) || !(topos->z > max.z)) { if (1); - if (checkvertical) { + if (islos) { min.y = *(s16 *)(tile->ymin + (uintptr_t)tile); max.y = *(s16 *)(tile->ymax + (uintptr_t)tile); - if ((!(arg2->y < min.y) || !(arg3->y < min.y)) - && (!(arg2->y > max.y) || !(arg3->y > max.y)) - && bg_test_line_intersects_bbox(arg2, arg4, &min, &max) - && cd_0002aac0_int_tile(arg2, arg3, arg4, tile, &spc4, &spb8)) { + if ((!(frompos->y < min.y) || !(topos->y < min.y)) + && (!(frompos->y > max.y) || !(topos->y > max.y)) + && bg_test_line_intersects_bbox(frompos, dist, &min, &max) + && cd_is_line_intersecting_tilei(frompos, topos, dist, tile, &endpos, &spb8)) { + return false; + } + } else { + if (cd_is_cylpath_intersecting_tilei(frompos, topos, dist, tile, &endpos, NULL, NULL, checkvertical, ymax, ymin)) { return false; } - } else if (cd_0002ac70_int_tile(arg2, arg3, arg4, tile, &spc4, 0, 0, arg7, arg8, arg9)) { - return false; } } } @@ -2929,22 +2994,24 @@ bool cd_test_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord min.z = tile->vertices[tile->min[2]].z; max.z = tile->vertices[tile->max[2]].z; - if (((!(arg2->x < min.x)) || !(arg3->x < min.x)) - && (!(arg2->x > max.x) || !(arg3->x > max.x)) - && ((!(arg2->z < min.z)) || !(arg3->z < min.z)) - && (!(arg2->z > max.z) || !(arg3->z > max.z))) { - if (checkvertical) { + if (((!(frompos->x < min.x)) || !(topos->x < min.x)) + && (!(frompos->x > max.x) || !(topos->x > max.x)) + && ((!(frompos->z < min.z)) || !(topos->z < min.z)) + && (!(frompos->z > max.z) || !(topos->z > max.z))) { + if (islos) { min.y = tile->vertices[tile->min[1]].y; max.y = tile->vertices[tile->max[1]].y; - if ((!(arg2->y < min.y) || !(arg3->y < min.y)) - && (!(arg2->y > max.y) || !(arg3->y > max.y)) - && bg_test_line_intersects_bbox(arg2, arg4, &min, &max) - && cd_0002ab98_flt_tile(arg2, arg3, arg4, tile, &sp90, &sp84)) { + if ((!(frompos->y < min.y) || !(topos->y < min.y)) + && (!(frompos->y > max.y) || !(topos->y > max.y)) + && bg_test_line_intersects_bbox(frompos, dist, &min, &max) + && cd_is_line_intersecting_tilef(frompos, topos, dist, tile, &sp90, &sp84)) { + return false; + } + } else { + if (cd_is_cylpath_intersecting_tilef(frompos, topos, dist, tile, &sp90, 0, 0, checkvertical, ymax, ymin)) { return false; } - } else if (cd_0002b128_flt_tile(arg2, arg3, arg4, tile, &sp90, 0, 0, arg7, arg8, arg9)) { - return false; } } } @@ -2955,7 +3022,7 @@ bool cd_test_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord struct geoblock *block = (struct geoblock *) geo; if ((geoflags & (GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT)) - && cd_0002b560_block(arg2, arg3, arg4, block, &sp78, 0, 0, arg7, arg8, arg9)) { + && cd_is_cylpath_intersecting_block(frompos, topos, dist, block, &sp78, 0, 0, checkvertical, ymax, ymin)) { return false; } @@ -2965,7 +3032,7 @@ bool cd_test_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord struct geocyl *cyl = (struct geocyl *) geo; if ((geoflags & cyl->header.flags) - && cd_0002b954_cyl(arg2, arg3, arg4, cyl, &sp68, 0, 0, arg7, arg8, arg9)) { + && cd_is_cylpath_intersecting_cyl(frompos, topos, dist, cyl, &sp68, 0, 0, checkvertical, ymax, ymin)) { return false; } @@ -2976,7 +3043,7 @@ bool cd_test_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord return true; } -void cd_0002c328_int_tile(struct geotilei *tile, struct coord *arg1, struct coord *arg2, struct coord *arg3, struct coord *arg4) +void cd_test_atobclosest_findedge_tilei(struct geotilei *tile, struct coord *endpos, struct coord *arg2, struct coord *edgevtx1, struct coord *edgevtx2) { struct coord sp3c; u32 stack[2]; @@ -3010,8 +3077,8 @@ void cd_0002c328_int_tile(struct geotilei *tile, struct coord *arg1, struct coor numvertices = tile->header.numvertices; for (i = 0; i < numvertices; i++) { - f32 xdiff = tile->vertices[i][0] - arg1->x; - f32 zdiff = tile->vertices[i][2] - arg1->z; + f32 xdiff = tile->vertices[i][0] - endpos->x; + f32 zdiff = tile->vertices[i][2] - endpos->z; f32 f0 = xdiff * sp3c.f[0] + zdiff * sp3c.f[2]; if (f0 > max) { @@ -3021,16 +3088,16 @@ void cd_0002c328_int_tile(struct geotilei *tile, struct coord *arg1, struct coor } } - arg3->x = arg1->x + sp3c.f[0] * max; - arg3->y = arg1->y; - arg3->z = arg1->z + sp3c.f[2] * max; + edgevtx1->x = endpos->x + sp3c.f[0] * max; + edgevtx1->y = endpos->y; + edgevtx1->z = endpos->z + sp3c.f[2] * max; - arg4->x = arg1->x + sp3c.f[0] * min; - arg4->y = arg1->y; - arg4->z = arg1->z + sp3c.f[2] * min; + edgevtx2->x = endpos->x + sp3c.f[0] * min; + edgevtx2->y = endpos->y; + edgevtx2->z = endpos->z + sp3c.f[2] * min; } -void cd_0002c528_flt_tile(struct geotilef *tile, struct coord *arg1, struct coord *arg2, struct coord *arg3, struct coord *arg4) +void cd_test_atobclosest_findedge_tilef(struct geotilef *tile, struct coord *endpos, struct coord *arg2, struct coord *edgevtx1, struct coord *edgevtx2) { struct coord sp3c; u32 stack[2]; @@ -3064,8 +3131,8 @@ void cd_0002c528_flt_tile(struct geotilef *tile, struct coord *arg1, struct coor numvertices = tile->header.numvertices; for (i = 0; i < numvertices; i++) { - f32 xdiff = tile->vertices[i].x - arg1->x; - f32 zdiff = tile->vertices[i].z - arg1->z; + f32 xdiff = tile->vertices[i].x - endpos->x; + f32 zdiff = tile->vertices[i].z - endpos->z; f32 f0 = xdiff * sp3c.f[0] + zdiff * sp3c.f[2]; if (f0 > max) { @@ -3075,24 +3142,24 @@ void cd_0002c528_flt_tile(struct geotilef *tile, struct coord *arg1, struct coor } } - arg3->x = arg1->x + sp3c.f[0] * max; - arg3->y = arg1->y; - arg3->z = arg1->z + sp3c.f[2] * max; + edgevtx1->x = endpos->x + sp3c.f[0] * max; + edgevtx1->y = endpos->y; + edgevtx1->z = endpos->z + sp3c.f[2] * max; - arg4->x = arg1->x + sp3c.f[0] * min; - arg4->y = arg1->y; - arg4->z = arg1->z + sp3c.f[2] * min; + edgevtx2->x = endpos->x + sp3c.f[0] * min; + edgevtx2->y = endpos->y; + edgevtx2->z = endpos->z + sp3c.f[2] * min; } -bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord *arg3, struct coord *arg4, - u16 geoflags, bool checkvertical, s32 arg7, f32 ymax, f32 ymin, f32 *arg10, struct coord *arg11, - struct coord *arg12, struct coord *arg13, struct geo **geoptr, s32 roomnum) +bool cd_test_atobclosest_from_bytes(u8 *start, u8 *end, struct coord *frompos, struct coord *topos, struct coord *dist, + u16 geoflags, bool islos, bool checkvertical, f32 ymax, f32 ymin, f32 *closestsqdist, struct coord *closestendpos, + struct coord *closestedgevtx1, struct coord *closestedgevtx2, struct geo **closestgeo, s32 roomnum) { struct geo *geo; f32 x; f32 y; f32 z; - f32 sum; + f32 sqdist; bool ok; bool result = false; @@ -3103,13 +3170,13 @@ bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord struct geotilei *tile = (struct geotilei *) geo; struct coord min; struct coord max; - struct coord sp12c; + struct coord endpos; struct coord sp120; - struct coord sp114; - struct coord sp108; + struct coord edgevtx1; + struct coord edgevtx2; if (geo->flags & GEOFLAG_RAMPWALL) { - ok = cd_test_ramp_wall(tile, arg2, 0, arg2->y + ymin, arg2->y + ymax); + ok = cd_test_ramp_wall(tile, frompos, 0, frompos->y + ymin, frompos->y + ymax); } else { ok = true; } @@ -3117,67 +3184,67 @@ bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord if (ok && (geo->flags & geoflags)) { min.x = *(s16 *)(tile->xmin + (uintptr_t)tile); - if (!(arg2->x < min.x) || !(arg3->x < min.x)) { + if (!(frompos->x < min.x) || !(topos->x < min.x)) { max.x = *(s16 *)(tile->xmax + (uintptr_t)tile); - if (!(arg2->x > max.x) || !(arg3->x > max.x)) { + if (!(frompos->x > max.x) || !(topos->x > max.x)) { min.z = *(s16 *)(tile->zmin + (uintptr_t)tile); - if (!(arg2->z < min.z) || !(arg3->z < min.z)) { + if (!(frompos->z < min.z) || !(topos->z < min.z)) { max.z = *(s16 *)(tile->zmax + (uintptr_t)tile); - if (!(arg2->z > max.z) || !(arg3->z > max.z)) { - if (checkvertical) { + if (!(frompos->z > max.z) || !(topos->z > max.z)) { + if (islos) { min.y = *(s16 *)(tile->ymin + (uintptr_t)tile); max.y = *(s16 *)(tile->ymax + (uintptr_t)tile); - if ((!(arg2->y < min.y) || !(arg3->y < min.y)) - && (!(arg2->y > max.y) || !(arg3->y > max.y)) - && bg_test_line_intersects_bbox(arg2, arg4, &min, &max) - && cd_0002aac0_int_tile(arg2, arg3, arg4, tile, &sp12c, &sp120)) { - x = sp12c.x - arg2->x; - y = sp12c.y - arg2->y; - z = sp12c.z - arg2->z; + if ((!(frompos->y < min.y) || !(topos->y < min.y)) + && (!(frompos->y > max.y) || !(topos->y > max.y)) + && bg_test_line_intersects_bbox(frompos, dist, &min, &max) + && cd_is_line_intersecting_tilei(frompos, topos, dist, tile, &endpos, &sp120)) { + x = endpos.x - frompos->x; + y = endpos.y - frompos->y; + z = endpos.z - frompos->z; - sum = x * x + y * y + z * z; + sqdist = x * x + y * y + z * z; - if (sum < *arg10) { + if (sqdist < *closestsqdist) { result = true; - *arg10 = sum; + *closestsqdist = sqdist; - arg11->x = sp12c.x; - arg11->y = sp12c.y; - arg11->z = sp12c.z; + closestendpos->x = endpos.x; + closestendpos->y = endpos.y; + closestendpos->z = endpos.z; - cd_0002c328_int_tile(tile, &sp12c, &sp120, arg12, arg13); + cd_test_atobclosest_findedge_tilei(tile, &endpos, &sp120, closestedgevtx1, closestedgevtx2); - *geoptr = geo; + *closestgeo = geo; } } - } else if (cd_0002ac70_int_tile(arg2, arg3, arg4, tile, &sp12c, &sp114, &sp108, arg7, ymax, ymin)) { - x = sp12c.x - arg2->x; - y = sp12c.y - arg2->y; - z = sp12c.z - arg2->z; + } else if (cd_is_cylpath_intersecting_tilei(frompos, topos, dist, tile, &endpos, &edgevtx1, &edgevtx2, checkvertical, ymax, ymin)) { + x = endpos.x - frompos->x; + y = endpos.y - frompos->y; + z = endpos.z - frompos->z; - sum = x * x + y * y + z * z; + sqdist = x * x + y * y + z * z; - if (sum < *arg10) { + if (sqdist < *closestsqdist) { result = true; - *arg10 = sum; + *closestsqdist = sqdist; - arg11->x = sp12c.x; - arg11->y = sp12c.y; - arg11->z = sp12c.z; + closestendpos->x = endpos.x; + closestendpos->y = endpos.y; + closestendpos->z = endpos.z; - arg12->x = sp114.x; - arg12->y = sp114.y; - arg12->z = sp114.z; + closestedgevtx1->x = edgevtx1.x; + closestedgevtx1->y = edgevtx1.y; + closestedgevtx1->z = edgevtx1.z; - arg13->x = sp108.x; - arg13->y = sp108.y; - arg13->z = sp108.z; + closestedgevtx2->x = edgevtx2.x; + closestedgevtx2->y = edgevtx2.y; + closestedgevtx2->z = edgevtx2.z; - *geoptr = geo; + *closestgeo = geo; } } } @@ -3191,10 +3258,10 @@ bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord struct geotilef *tile = (struct geotilef *) geo; struct coord min; struct coord max; - struct coord spe0; + struct coord endpos; struct coord spd4; - struct coord spc8; - struct coord spbc; + struct coord edgevtx1; + struct coord edgevtx2; if (geo->flags & geoflags) { min.x = tile->vertices[tile->min[0]].x; @@ -3202,61 +3269,61 @@ bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord min.z = tile->vertices[tile->min[2]].z; max.z = tile->vertices[tile->max[2]].z; - if ((!(arg2->x < min.x) || !(arg3->x < min.x)) - && (!(arg2->x > max.x) || !(arg3->x > max.x)) - && (!(arg2->z < min.z) || !(arg3->z < min.z)) - && (!(arg2->z > max.z) || !(arg3->z > max.z))) { - if (checkvertical) { + if ((!(frompos->x < min.x) || !(topos->x < min.x)) + && (!(frompos->x > max.x) || !(topos->x > max.x)) + && (!(frompos->z < min.z) || !(topos->z < min.z)) + && (!(frompos->z > max.z) || !(topos->z > max.z))) { + if (islos) { min.y = tile->vertices[tile->min[1]].y; max.y = tile->vertices[tile->max[1]].y; - if ((!(arg2->y < min.y) || !(arg3->y < min.y)) - && (!(arg2->y > max.y) || !(arg3->y > max.y)) - && bg_test_line_intersects_bbox(arg2, arg4, &min, &max) - && cd_0002ab98_flt_tile(arg2, arg3, arg4, tile, &spe0, &spd4)) { - x = spe0.x - arg2->x; - y = spe0.y - arg2->y; - z = spe0.z - arg2->z; + if ((!(frompos->y < min.y) || !(topos->y < min.y)) + && (!(frompos->y > max.y) || !(topos->y > max.y)) + && bg_test_line_intersects_bbox(frompos, dist, &min, &max) + && cd_is_line_intersecting_tilef(frompos, topos, dist, tile, &endpos, &spd4)) { + x = endpos.x - frompos->x; + y = endpos.y - frompos->y; + z = endpos.z - frompos->z; - sum = x * x + y * y + z * z; + sqdist = x * x + y * y + z * z; - if (sum < *arg10) { + if (sqdist < *closestsqdist) { result = true; - *arg10 = sum; + *closestsqdist = sqdist; - arg11->x = spe0.x; - arg11->y = spe0.y; - arg11->z = spe0.z; + closestendpos->x = endpos.x; + closestendpos->y = endpos.y; + closestendpos->z = endpos.z; - cd_0002c528_flt_tile(tile, &spe0, &spd4, arg12, arg13); + cd_test_atobclosest_findedge_tilef(tile, &endpos, &spd4, closestedgevtx1, closestedgevtx2); - *geoptr = geo; + *closestgeo = geo; } } - } else if (cd_0002b128_flt_tile(arg2, arg3, arg4, tile, &spe0, &spc8, &spbc, arg7, ymax, ymin)) { - x = spe0.x - arg2->x; - y = spe0.y - arg2->y; - z = spe0.z - arg2->z; + } else if (cd_is_cylpath_intersecting_tilef(frompos, topos, dist, tile, &endpos, &edgevtx1, &edgevtx2, checkvertical, ymax, ymin)) { + x = endpos.x - frompos->x; + y = endpos.y - frompos->y; + z = endpos.z - frompos->z; - sum = x * x + y * y + z * z; + sqdist = x * x + y * y + z * z; - if (sum < *arg10) { + if (sqdist < *closestsqdist) { result = true; - *arg10 = sum; + *closestsqdist = sqdist; - arg11->x = spe0.x; - arg11->y = spe0.y; - arg11->z = spe0.z; + closestendpos->x = endpos.x; + closestendpos->y = endpos.y; + closestendpos->z = endpos.z; - arg12->x = spc8.x; - arg12->y = spc8.y; - arg12->z = spc8.z; + closestedgevtx1->x = edgevtx1.x; + closestedgevtx1->y = edgevtx1.y; + closestedgevtx1->z = edgevtx1.z; - arg13->x = spbc.x; - arg13->y = spbc.y; - arg13->z = spbc.z; + closestedgevtx2->x = edgevtx2.x; + closestedgevtx2->y = edgevtx2.y; + closestedgevtx2->z = edgevtx2.z; - *geoptr = geo; + *closestgeo = geo; } } } @@ -3264,70 +3331,70 @@ bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord geo = (struct geo *)((uintptr_t)geo + GEOTILEF_SIZE(tile)); } else if (geo->type == GEOTYPE_BLOCK) { - struct coord spb0; - struct coord spa4; - struct coord sp98; + struct coord endpos; + struct coord edgevtx1; + struct coord edgevtx2; if ((geoflags & (GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT)) - && (cd_0002b560_block(arg2, arg3, arg4, (struct geoblock *)geo, &spb0, &spa4, &sp98, arg7, ymax, ymin))) { - x = spb0.x - arg2->x; - y = spb0.y - arg2->y; - z = spb0.z - arg2->z; + && (cd_is_cylpath_intersecting_block(frompos, topos, dist, (struct geoblock *)geo, &endpos, &edgevtx1, &edgevtx2, checkvertical, ymax, ymin))) { + x = endpos.x - frompos->x; + y = endpos.y - frompos->y; + z = endpos.z - frompos->z; - sum = x * x + y * y + z * z; + sqdist = x * x + y * y + z * z; - if (sum < *arg10) { + if (sqdist < *closestsqdist) { result = true; - *arg10 = sum; + *closestsqdist = sqdist; - arg11->x = spb0.x; - arg11->y = spb0.y; - arg11->z = spb0.z; + closestendpos->x = endpos.x; + closestendpos->y = endpos.y; + closestendpos->z = endpos.z; - arg12->x = spa4.x; - arg12->y = spa4.y; - arg12->z = spa4.z; + closestedgevtx1->x = edgevtx1.x; + closestedgevtx1->y = edgevtx1.y; + closestedgevtx1->z = edgevtx1.z; - arg13->x = sp98.x; - arg13->y = sp98.y; - arg13->z = sp98.z; + closestedgevtx2->x = edgevtx2.x; + closestedgevtx2->y = edgevtx2.y; + closestedgevtx2->z = edgevtx2.z; - *geoptr = geo; + *closestgeo = geo; } } geo = (struct geo *)((uintptr_t)geo + GEOBLOCK_SIZE(geo)); } else if (geo->type == GEOTYPE_CYL) { struct geocyl *cyl = (struct geocyl *) geo; - struct coord sp88; - struct coord sp7c; - struct coord sp70; + struct coord endpos; + struct coord edgevtx1; + struct coord edgevtx2; if ((geoflags & geo->flags) - && cd_0002b954_cyl(arg2, arg3, arg4, cyl, &sp88, &sp7c, &sp70, arg7, ymax, ymin)) { - x = sp88.x - arg2->x; - y = sp88.y - arg2->y; - z = sp88.z - arg2->z; + && cd_is_cylpath_intersecting_cyl(frompos, topos, dist, cyl, &endpos, &edgevtx1, &edgevtx2, checkvertical, ymax, ymin)) { + x = endpos.x - frompos->x; + y = endpos.y - frompos->y; + z = endpos.z - frompos->z; - sum = x * x + y * y + z * z; + sqdist = x * x + y * y + z * z; - if (sum < *arg10) { + if (sqdist < *closestsqdist) { result = true; - *arg10 = sum; + *closestsqdist = sqdist; - arg11->x = sp88.x; - arg11->y = sp88.y; - arg11->z = sp88.z; + closestendpos->x = endpos.x; + closestendpos->y = endpos.y; + closestendpos->z = endpos.z; - arg12->x = sp7c.x; - arg12->y = sp7c.y; - arg12->z = sp7c.z; + closestedgevtx1->x = edgevtx1.x; + closestedgevtx1->y = edgevtx1.y; + closestedgevtx1->z = edgevtx1.z; - arg13->x = sp70.x; - arg13->y = sp70.y; - arg13->z = sp70.z; + closestedgevtx2->x = edgevtx2.x; + closestedgevtx2->y = edgevtx2.y; + closestedgevtx2->z = edgevtx2.z; - *geoptr = geo; + *closestgeo = geo; } } @@ -3338,30 +3405,42 @@ bool cd_exam_a_to_b_geolist(u8 *start, u8 *end, struct coord *arg2, struct coord return !result; } -bool cd_test_a_to_b(struct coord *pos, struct coord *coord2, RoomNum *rooms, u32 types, u16 geoflags, bool checkvertical, s32 arg6, f32 ymax, f32 ymin) +/** + * Do an A to B test, stopping once any obstacle is found. The obstacle may not + * be the closest one. + * + * If islos is true, the test is a line of sight test which means the checkvertical, + * ymax and ymin arguments will be ignored (LOS tests always check vertical). + * + * If islos is false, the test is a cylinder move test. The cylinder radius not + * checked or even passed to this function, so the radius is effectively almost 0. + * The caller may set checkvertical to true if they want Y values compared. + */ +bool cd_test_atobany(struct coord *frompos, struct coord *topos, RoomNum *throughrooms, u32 types, u16 geoflags, bool islos, bool checkvertical, f32 ymax, f32 ymin) { s32 roomnum; RoomNum *roomptr; u8 *start; u8 *end; - struct coord sp27c; + struct coord dist; s16 *propnumptr; s16 propnums[256]; - sp27c.x = coord2->x - pos->x; - sp27c.y = coord2->y - pos->y; - sp27c.z = coord2->z - pos->z; + dist.x = topos->x - frompos->x; + dist.y = topos->y - frompos->y; + dist.z = topos->z - frompos->z; + // Check BG if (types & CDTYPE_BG) { - roomptr = rooms; - roomnum = rooms[0]; + roomptr = throughrooms; + roomnum = throughrooms[0]; while (roomnum != -1) { if (roomnum < g_TileNumRooms) { start = g_TileFileData.u8 + g_TileRooms[roomnum]; end = g_TileFileData.u8 + g_TileRooms[roomnum + 1]; - if (cd_test_a_to_b_geolist(start, end, pos, coord2, &sp27c, geoflags, checkvertical, arg6, ymax, ymin) == 0) { + if (cd_test_atobany_from_bytes(start, end, frompos, topos, &dist, geoflags, islos, checkvertical, ymax, ymin) == 0) { cd_set_obstacle_prop(NULL); return false; } @@ -3372,7 +3451,8 @@ bool cd_test_a_to_b(struct coord *pos, struct coord *coord2, RoomNum *rooms, u32 } } - room_get_props(rooms, propnums, 256); + // Check props + room_get_props(throughrooms, propnums, 256); propnumptr = propnums; @@ -3381,7 +3461,7 @@ bool cd_test_a_to_b(struct coord *pos, struct coord *coord2, RoomNum *rooms, u32 if (prop_is_of_cd_type(prop, types) && prop_get_geometry(prop, &start, &end) - && cd_test_a_to_b_geolist(start, end, pos, coord2, &sp27c, geoflags, checkvertical, arg6, ymax, ymin) == 0) { + && cd_test_atobany_from_bytes(start, end, frompos, topos, &dist, geoflags, islos, checkvertical, ymax, ymin) == 0) { cd_set_obstacle_prop(prop); return false; } @@ -3392,26 +3472,38 @@ bool cd_test_a_to_b(struct coord *pos, struct coord *coord2, RoomNum *rooms, u32 return true; } -s32 cd_exam_a_to_b(struct coord *arg0, struct coord *arg1, RoomNum *rooms, s32 types, u16 geoflags, bool checkvertical, s32 arg6, f32 ymax, f32 ymin) +/** + * Do an A to B test, finding the closest obstacle and information about it so + * the caller can query it afterwards. + * + * If islos is true, the test is a line of sight test which means the checkvertical, + * ymax and ymin arguments will be ignored (LOS tests always check vertical). + * + * If islos is false, the test is a cylinder move test. The cylinder radius not + * checked or even passed to this function, so the radius is effectively almost 0. + * The caller may set checkvertical to true if they want Y values compared. + */ +s32 cd_test_atobclosest(struct coord *frompos, struct coord *topos, RoomNum *rooms, u32 types, u16 geoflags, bool islos, bool checkvertical, f32 ymax, f32 ymin) { s32 roomnum; RoomNum *roomptr; u8 *start; u8 *end; - struct coord sp2c4; - bool sp2c0 = false; - struct coord sp2b4; - struct coord sp2a8; - struct coord sp29c; - f32 sp298 = 4294967296; - struct geo *sp294; + struct coord dist; + bool result = false; + struct coord endpos; + struct coord edgevtx1; + struct coord edgevtx2; + f32 sqdist = 4294967296; + struct geo *geo; s16 *propnumptr; s16 propnums[256]; - sp2c4.x = arg1->x - arg0->x; - sp2c4.y = arg1->y - arg0->y; - sp2c4.z = arg1->z - arg0->z; + dist.x = topos->x - frompos->x; + dist.y = topos->y - frompos->y; + dist.z = topos->z - frompos->z; + // Check BG if (types & CDTYPE_BG) { roomptr = rooms; roomnum = rooms[0]; @@ -3422,9 +3514,10 @@ s32 cd_exam_a_to_b(struct coord *arg0, struct coord *arg1, RoomNum *rooms, s32 t start = g_TileFileData.u8 + ptr[0]; end = g_TileFileData.u8 + ptr[1]; - if (!cd_exam_a_to_b_geolist(start, end, arg0, arg1, &sp2c4, geoflags, checkvertical, arg6, ymax, ymin, &sp298, &sp2b4, &sp2a8, &sp29c, &sp294, roomnum)) { - sp2c0 = true; - cd_set_obstacle_vtx_col_prop_flt_geo(&sp2a8, &sp29c, &sp2b4, NULL, sp298, sp294); + if (!cd_test_atobclosest_from_bytes(start, end, frompos, topos, &dist, geoflags, islos, checkvertical, ymax, ymin, + &sqdist, &endpos, &edgevtx1, &edgevtx2, &geo, roomnum)) { + result = true; + cd_set_obstacle_edge_pos_prop_sqdist_geo(&edgevtx1, &edgevtx2, &endpos, NULL, sqdist, geo); } } @@ -3433,6 +3526,7 @@ s32 cd_exam_a_to_b(struct coord *arg0, struct coord *arg1, RoomNum *rooms, s32 t } } + // Check props room_get_props(rooms, propnums, 256); propnumptr = propnums; @@ -3441,37 +3535,64 @@ s32 cd_exam_a_to_b(struct coord *arg0, struct coord *arg1, RoomNum *rooms, s32 t if (prop_is_of_cd_type(prop, types) && prop_get_geometry(prop, &start, &end) - && !cd_exam_a_to_b_geolist(start, end, arg0, arg1, &sp2c4, geoflags, checkvertical, arg6, ymax, ymin, &sp298, &sp2b4, &sp2a8, &sp29c, &sp294, -999)) { - sp2c0 = true; - cd_set_obstacle_vtx_col_prop_flt_geo(&sp2a8, &sp29c, &sp2b4, prop, sp298, sp294); + && !cd_test_atobclosest_from_bytes(start, end, frompos, topos, &dist, geoflags, islos, checkvertical, ymax, ymin, + &sqdist, &endpos, &edgevtx1, &edgevtx2, &geo, -999)) { + result = true; + cd_set_obstacle_edge_pos_prop_sqdist_geo(&edgevtx1, &edgevtx2, &endpos, prop, sqdist, geo); } propnumptr++; } - return !sp2c0; + return !result; } -bool cd_test_cyl_move01(struct coord *pos, RoomNum *rooms, struct coord *targetpos, u32 types, u32 arg4, f32 ymax, f32 ymin) +/** + * Naming conventions for cylmove and los functions: + * + * oobok/oobfail: + * - Denotes what the function does if topos is out of bounds + * and no collisions were found matching the criteria. + * If oobok, the function will return CDRESULT_NOCOLLISION. + * If oobfail, the function will return CDRESULT_COLLISION. + * + * findclosest: + * - The function will examines all collisions and find the closest one, + * instead of stopping once any collision is found. + * + * getfinalroom: + * - The function has a finalrooms pointer argument which will be populated + * with the final rooms that topos is in. Usually just one room and a -1 terminator. + * + * finddist: + * - The function will find the distance to the obstacle and save it, + * allowing the caller to read it by calling cd_get_distance(). + * + * autoflags: + * - The collision system will use the flags GEOFLAG_WALL, GEOFLAG_BLOCK_SHOOT + * and GEOFLAG_BLOCK_SIGHT instead of having the caller pass a flags argument. + */ + +s32 cd_test_cylmove_oobok(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, bool checkvertical, f32 ymax, f32 ymin) { - RoomNum sp44[21]; - RoomNum sp34[8]; + RoomNum throughrooms[21]; + RoomNum finalrooms[8]; - portal_find_rooms(pos, targetpos, rooms, sp34, sp44, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - return cd_test_a_to_b(pos, targetpos, sp44, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg4, ymax, ymin); + return cd_test_atobany(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); } -s32 cd_test_cyl_move02(struct coord *pos, RoomNum *rooms, struct coord *coord2, RoomNum *rooms2, u32 types, s32 arg5, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobfail(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) { s32 result; - RoomNum sp44[20]; - RoomNum sp34[8]; + RoomNum throughrooms[20]; + RoomNum finalrooms[8]; - los_find_intersecting_rooms_properly(pos, rooms, coord2, sp34, sp44, 20); + los_find_intersecting_rooms_properly(frompos, fromrooms, topos, finalrooms, throughrooms, 20); - if (array_intersects(sp34, rooms2)) { - result = cd_test_a_to_b(pos, coord2, sp44, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg5, ymax, ymin); + if (array_intersects(finalrooms, torooms)) { + result = cd_test_atobany(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); } else { result = CDRESULT_COLLISION; } @@ -3479,36 +3600,36 @@ s32 cd_test_cyl_move02(struct coord *pos, RoomNum *rooms, struct coord *coord2, return result; } -s32 cd_exam_cyl_move03(struct coord *pos, RoomNum *rooms, struct coord *arg2, u32 types, u32 arg4, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobok_findclosest(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, bool checkvertical, f32 ymax, f32 ymin) { - RoomNum sp44[21]; - RoomNum sp34[8]; + RoomNum throughrooms[21]; + RoomNum finalrooms[8]; - portal_find_rooms(pos, arg2, rooms, sp34, sp44, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - return cd_exam_a_to_b(pos, arg2, sp44, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg4, ymax, ymin); + return cd_test_atobclosest(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); } -s32 cd_test_cyl_move04(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types, s32 arg5, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobok_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) { RoomNum rooms[21]; - portal_find_rooms(arg0, arg2, arg1, arg3, rooms, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, rooms, 20); - return cd_test_a_to_b(arg0, arg2, rooms, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg5, ymax, ymin); + return cd_test_atobany(frompos, topos, rooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); } -s32 cd_exam_cyl_move05(struct coord *pos, RoomNum *rooms, struct coord *pos2, RoomNum *rooms2, s32 types, bool arg5, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobfail_findclosest(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) { - RoomNum sp44[21]; - RoomNum sp34[8]; + RoomNum throughrooms[21]; + RoomNum finalrooms[8]; s32 result; - los_find_intersecting_rooms_properly(pos, rooms, pos2, sp34, sp44, 20); + los_find_intersecting_rooms_properly(frompos, fromrooms, topos, finalrooms, throughrooms, 20); - result = cd_exam_a_to_b(pos, pos2, sp44, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg5, ymax, ymin); + result = cd_test_atobclosest(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); - if (result != CDRESULT_COLLISION && !array_intersects(sp34, rooms2)) { + if (result != CDRESULT_COLLISION && !array_intersects(finalrooms, torooms)) { cd_clear_results(); result = CDRESULT_ERROR; } @@ -3516,24 +3637,24 @@ s32 cd_exam_cyl_move05(struct coord *pos, RoomNum *rooms, struct coord *pos2, Ro return result; } -s32 cd_exam_cyl_move06(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, f32 width, s32 types, s32 arg6, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobfail_findclosest_finddist(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, f32 radius, u32 types, bool checkvertical, f32 ymax, f32 ymin) { - RoomNum sp5c[21]; - RoomNum sp4c[8]; - struct coord sp40; + RoomNum throughrooms[21]; + RoomNum finalrooms[8]; + struct coord dist; s32 result; - los_find_intersecting_rooms_properly(arg0, arg1, arg2, sp4c, sp5c, 20); + los_find_intersecting_rooms_properly(frompos, fromrooms, topos, finalrooms, throughrooms, 20); - result = cd_exam_a_to_b(arg0, arg2, sp5c, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg6, ymax, ymin); + result = cd_test_atobclosest(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); if (result == CDRESULT_COLLISION) { - sp40.x = arg2->x - arg0->x; - sp40.y = arg2->y - arg0->y; - sp40.z = arg2->z - arg0->z; + dist.x = topos->x - frompos->x; + dist.y = topos->y - frompos->y; + dist.z = topos->z - frompos->z; - cd_000250cc(arg0, &sp40, width); - } else if (!array_intersects(sp4c, arg3)) { + cd_set_obstacle_distance(frompos, &dist, radius); + } else if (!array_intersects(finalrooms, torooms)) { cd_clear_results(); result = CDRESULT_ERROR; } @@ -3541,123 +3662,123 @@ s32 cd_exam_cyl_move06(struct coord *arg0, RoomNum *arg1, struct coord *arg2, Ro return result; } -s32 cd_exam_cyl_move07(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types, s32 arg5, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobok_findclosest_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types, bool checkvertical, f32 ymax, f32 ymin) { - RoomNum rooms[21]; + RoomNum throughrooms[21]; - portal_find_rooms(arg0, arg2, arg1, arg3, rooms, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - return cd_exam_a_to_b(arg0, arg2, rooms, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg5, ymax, ymin); + return cd_test_atobclosest(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); } -s32 cd_exam_cyl_move08(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, f32 width, u32 types, s32 arg6, f32 ymax, f32 ymin) +s32 cd_test_cylmove_oobok_findclosest_getfinalroom_finddist(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, f32 radius, u32 types, bool checkvertical, f32 ymax, f32 ymin) { - RoomNum rooms[21]; - struct coord sp40; + RoomNum throughrooms[21]; + struct coord diff; s32 result; - portal_find_rooms(arg0, arg2, arg1, arg3, rooms, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - result = cd_exam_a_to_b(arg0, arg2, rooms, types, GEOFLAG_WALL, CHECKVERTICAL_NO, arg6, ymax, ymin); + result = cd_test_atobclosest(frompos, topos, throughrooms, types, GEOFLAG_WALL, ATOBTYPE_CYL, checkvertical, ymax, ymin); if (result == CDRESULT_COLLISION) { - sp40.x = arg2->x - arg0->x; - sp40.y = arg2->y - arg0->y; - sp40.z = arg2->z - arg0->z; + diff.x = topos->x - frompos->x; + diff.y = topos->y - frompos->y; + diff.z = topos->z - frompos->z; - cd_000250cc(arg0, &sp40, width); + cd_set_obstacle_distance(frompos, &diff, radius); } return result; } -bool cd_test_los03(struct coord *viewpos, RoomNum *rooms, struct coord *targetpos, u32 types, u16 geoflags) +s32 cd_test_los_oobok(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, u16 geoflags) { - RoomNum sp44[21]; - RoomNum sp34[8]; + RoomNum throughrooms[21]; + RoomNum finalrooms[8]; - portal_find_rooms(viewpos, targetpos, rooms, sp34, sp44, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - return cd_test_a_to_b(viewpos, targetpos, sp44, types, geoflags, CHECKVERTICAL_YES, 1, 0, 0); + return cd_test_atobany(frompos, topos, throughrooms, types, geoflags, ATOBTYPE_LOS, CHECKVERTICAL_YES, 0, 0); } -bool cd_test_los04(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, s32 types) +s32 cd_test_los_oobok_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types) { - return cd_test_los03(frompos, fromrooms, topos, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); + return cd_test_los_oobok(frompos, fromrooms, topos, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); } -bool cd_test_los05(struct coord *coord, RoomNum *rooms, struct coord *coord2, RoomNum *rooms2, s32 types, u16 geoflags) +s32 cd_test_los_oobfail(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types, u16 geoflags) { bool result; - RoomNum sp44[20]; - RoomNum sp34[8]; + RoomNum throughrooms[20]; + RoomNum finalrooms[8]; - los_find_intersecting_rooms_properly(coord, rooms, coord2, sp34, sp44, 20); + los_find_intersecting_rooms_properly(frompos, fromrooms, topos, finalrooms, throughrooms, 20); - if (array_intersects(sp34, rooms2)) { - result = cd_test_a_to_b(coord, coord2, sp44, types, geoflags, CHECKVERTICAL_YES, 1, 0, 0); + if (array_intersects(finalrooms, torooms)) { + result = cd_test_atobany(frompos, topos, throughrooms, types, geoflags, ATOBTYPE_LOS, CHECKVERTICAL_YES, 0, 0); } else { - result = false; + result = CDRESULT_COLLISION; } return result; } -bool cd_test_los06(struct coord *arg0, RoomNum *rooms1, struct coord *arg2, RoomNum *rooms2, u32 types) +s32 cd_test_los_oobtail_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, u32 types) { - return cd_test_los05(arg0, rooms1, arg2, rooms2, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); + return cd_test_los_oobfail(frompos, fromrooms, topos, torooms, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); } -bool cd_test_los07(struct coord *pos, RoomNum *rooms, struct coord *pos2, RoomNum *rooms2, RoomNum *rooms3, u32 types, u16 geoflags) +s32 cd_test_los_oobfail_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *torooms, RoomNum *finalrooms, u32 types, u16 geoflags) { bool result; - RoomNum sp34[20]; + RoomNum throughrooms[20]; - los_find_intersecting_rooms_properly(pos, rooms, pos2, rooms3, sp34, 20); + los_find_intersecting_rooms_properly(frompos, fromrooms, topos, finalrooms, throughrooms, 20); - if (array_intersects(rooms3, rooms2)) { - result = cd_test_a_to_b(pos, pos2, sp34, types, geoflags, CHECKVERTICAL_YES, 1, 0, 0); + if (array_intersects(finalrooms, torooms)) { + result = cd_test_atobany(frompos, topos, throughrooms, types, geoflags, ATOBTYPE_LOS, CHECKVERTICAL_YES, 0, 0); } else { - result = false; + result = CDRESULT_COLLISION; } return result; } -s32 cd_exam_los08(struct coord *pos, RoomNum *rooms, struct coord *pos2, u32 types, u16 geoflags) +s32 cd_test_los_oobok_findclosest(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types, u16 geoflags) { - RoomNum sp44[21]; - RoomNum sp34[8]; + RoomNum throughrooms[21]; + RoomNum finalrooms[8]; - portal_find_rooms(pos, pos2, rooms, sp34, sp44, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - return cd_exam_a_to_b(pos, pos2, sp44, types, geoflags, CHECKVERTICAL_YES, 1, 0, 0); + return cd_test_atobclosest(frompos, topos, throughrooms, types, geoflags, ATOBTYPE_LOS, CHECKVERTICAL_YES, 0, 0); } -s32 cd_exam_los09(struct coord *pos, RoomNum *rooms, struct coord *pos2, u32 types) +s32 cd_test_los_oobok_findclosest_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, u32 types) { - return cd_exam_los08(pos, rooms, pos2, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); + return cd_test_los_oobok_findclosest(frompos, fromrooms, topos, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); } -s32 cd_test_los10(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types, u16 geoflags) +s32 cd_test_los_oobok_getfinalroom(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types, u16 geoflags) { - RoomNum rooms[21]; + RoomNum throughrooms[21]; - portal_find_rooms(arg0, arg2, arg1, arg3, rooms, 20); + portal_find_rooms(frompos, topos, fromrooms, finalrooms, throughrooms, 20); - return cd_test_a_to_b(arg0, arg2, rooms, types, geoflags, CHECKVERTICAL_YES, 1, 0, 0); + return cd_test_atobany(frompos, topos, throughrooms, types, geoflags, ATOBTYPE_LOS, CHECKVERTICAL_YES, 0, 0); } -s32 cd_test_los11(struct coord *arg0, RoomNum *arg1, struct coord *arg2, RoomNum *arg3, u32 types) +s32 cd_test_los_oobok_getfinalroom_autoflags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, RoomNum *finalrooms, u32 types) { - return cd_test_los10(arg0, arg1, arg2, arg3, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); + return cd_test_los_oobok_getfinalroom(frompos, fromrooms, topos, finalrooms, types, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT); } -bool cd_0002ded8(struct coord *arg0, struct coord *arg1, struct prop *prop) +bool cd_test_line_intersects_prop(struct coord *frompos, struct coord *topos, struct prop *prop) { u8 *start; u8 *end; - struct coord sp7c; + struct coord dist; bool result = false; struct coord sp6c; struct coord sp60; @@ -3665,16 +3786,16 @@ bool cd_0002ded8(struct coord *arg0, struct coord *arg1, struct prop *prop) f32 sp50 = 4294967296; struct geo *geo; - sp7c.x = arg1->x - arg0->x; - sp7c.y = arg1->y - arg0->y; - sp7c.z = arg1->z - arg0->z; + dist.x = topos->x - frompos->x; + dist.y = topos->y - frompos->y; + dist.z = topos->z - frompos->z; if (prop_get_geometry(prop, &start, &end)) { - if (!cd_exam_a_to_b_geolist(start, end, arg0, arg1, &sp7c, + if (!cd_test_atobclosest_from_bytes(start, end, frompos, topos, &dist, GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT, - CHECKVERTICAL_YES, 1, 0, 0, &sp50, &sp6c, &sp60, &sp54, &geo, -999)) { + ATOBTYPE_LOS, CHECKVERTICAL_YES, 0, 0, &sp50, &sp6c, &sp60, &sp54, &geo, -999)) { result = true; - cd_set_obstacle_vtx_col_prop_flt_geo(&sp60, &sp54, &sp6c, prop, sp50, geo); + cd_set_obstacle_edge_pos_prop_sqdist_geo(&sp60, &sp54, &sp6c, prop, sp50, geo); } } @@ -3684,7 +3805,7 @@ bool cd_0002ded8(struct coord *arg0, struct coord *arg1, struct prop *prop) /** * Return true if both blocks are not intersecting on the X/Z plane. */ -bool cd_block_excludes_block_laterally(struct geoblock *block1, struct geoblock *block2) +bool cd_block_collides_with_block_laterally(struct geoblock *block1, struct geoblock *block2) { u32 stack[4]; f32 zero = 0.0f; @@ -3701,7 +3822,7 @@ bool cd_block_excludes_block_laterally(struct geoblock *block1, struct geoblock diff2 = block1->vertices[i][0] - (f64)block1->vertices[next][0]; if (diff1 == zero && diff2 == zero) { - if (cd_is_2d_point_in_block(block2, block1->vertices[i][0], block1->vertices[i][1])) { + if (cd_is_xz_in_block(block2, block1->vertices[i][0], block1->vertices[i][1])) { return false; } } else { @@ -3745,7 +3866,7 @@ bool cd_block_excludes_block_laterally(struct geoblock *block1, struct geoblock return false; } -s32 cd_test_block_overlaps_geolist(u8 *start, u8 *end, struct geoblock *block, u16 geoflags) +s32 cd_test_blockvolume_from_bytes(u8 *start, u8 *end, struct geoblock *block, u16 geoflags) { struct geo *geo = (struct geo *) start; @@ -3766,20 +3887,18 @@ s32 cd_test_block_overlaps_geolist(u8 *start, u8 *end, struct geoblock *block, u s32 i; for (i = 0; i < block->header.numvertices; i++) { - if (cd_is_2d_point_in_block(thisblock, block->vertices[i][0], block->vertices[i][1])) { + if (cd_is_xz_in_block(thisblock, block->vertices[i][0], block->vertices[i][1])) { return CDRESULT_COLLISION; } } for (i = 0; i < thisblock->header.numvertices; i++) { - if (cd_is_2d_point_in_block(block, thisblock->vertices[i][0], thisblock->vertices[i][1])) { + if (cd_is_xz_in_block(block, thisblock->vertices[i][0], thisblock->vertices[i][1])) { return CDRESULT_COLLISION; } } - // This is a bit wasteful... - // If A excludes B, there's no point checking if B excludes A. - if (!cd_block_excludes_block_laterally(block, thisblock) && !cd_block_excludes_block_laterally(thisblock, block)) { + if (!cd_block_collides_with_block_laterally(block, thisblock) && !cd_block_collides_with_block_laterally(thisblock, block)) { return CDRESULT_COLLISION; } } @@ -3791,7 +3910,7 @@ s32 cd_test_block_overlaps_geolist(u8 *start, u8 *end, struct geoblock *block, u if ((geoflags & geo->flags) && cyl->ymax >= block->ymin && cyl->ymin <= block->ymax - && cd_000274e0_block(block, cyl->x, cyl->z, cyl->radius, NULL, NULL)) { + && cd_block_collides_with_cyl_laterally(block, cyl->x, cyl->z, cyl->radius, NULL, NULL)) { return CDRESULT_COLLISION; } @@ -3805,14 +3924,14 @@ s32 cd_test_block_overlaps_geolist(u8 *start, u8 *end, struct geoblock *block, u /** * Test if the given block overlaps any prop. Set the saved obstacle prop if so. * - * The BG tests are pointless and not used, as cd_test_block_overlaps_geolist only + * The BG tests are pointless and not used, as cd_test_blockvolume_from_bytes only * tests blocks and cylinders. * * The function is used to check if a door is being blocked by another prop, * and is also used in a sanity check to make sure a moved object hasn't moved * into the player's position. */ -s32 cd_test_block_overlaps_any_prop(struct geoblock *geo, RoomNum *rooms, u32 types) +s32 cd_test_blockvolume(struct geoblock *block, RoomNum *rooms, u32 types) { s32 result = CDRESULT_NOCOLLISION; s32 roomnum; @@ -3832,7 +3951,7 @@ s32 cd_test_block_overlaps_any_prop(struct geoblock *geo, RoomNum *rooms, u32 ty start = g_TileFileData.u8 + g_TileRooms[roomnum]; end = g_TileFileData.u8 + g_TileRooms[roomnum + 1]; - result = cd_test_block_overlaps_geolist(start, end, geo, GEOFLAG_WALL); + result = cd_test_blockvolume_from_bytes(start, end, block, GEOFLAG_WALL); if (result == CDRESULT_COLLISION) { cd_set_obstacle_prop(NULL); @@ -3854,7 +3973,7 @@ s32 cd_test_block_overlaps_any_prop(struct geoblock *geo, RoomNum *rooms, u32 ty struct prop *prop = &g_Vars.props[*propnumptr]; if (prop_is_of_cd_type(prop, types) && prop_get_geometry(prop, &start, &end)) { - result = cd_test_block_overlaps_geolist(start, end, geo, GEOFLAG_WALL); + result = cd_test_blockvolume_from_bytes(start, end, block, GEOFLAG_WALL); if (result == CDRESULT_COLLISION) { cd_set_obstacle_prop(prop); @@ -3869,7 +3988,7 @@ s32 cd_test_block_overlaps_any_prop(struct geoblock *geo, RoomNum *rooms, u32 ty return result; } -bool cd_0002e680_int_tile(struct geotilei *tile, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) +bool cd_test_blockmove_tilei(struct geotilei *tile, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) { bool result = false; s32 i; @@ -3880,7 +3999,7 @@ bool cd_0002e680_int_tile(struct geotilei *tile, s32 numvertices, struct coord * struct coord sp6c; for (i = 0; i < numvertices; i++) { - if (var8005f030) { + if (g_CdReverseVertices) { s32 remaining = numvertices - i; next = (remaining + numvertices - 2) % numvertices; curr = remaining - 1; @@ -3889,13 +4008,13 @@ bool cd_0002e680_int_tile(struct geotilei *tile, s32 numvertices, struct coord * curr = i; } - if (cd_0002ac70_int_tile((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), + if (cd_is_cylpath_intersecting_tilei((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord)), (struct coord *)((uintptr_t)diffs + curr * sizeof(struct coord)), tile, &sp6c, &sp84, &sp78, 0, 0.0f, 0.0f)) { - cd_set_obstacle_vtx_col_prop(&sp84, &sp78, &sp6c, prop); - cd_set_saved_pos((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); - cd_set_saved_block(block); + cd_set_obstacle_edge_pos_prop(&sp84, &sp78, &sp6c, prop); + cd_set_block_edge((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); + cd_set_block(block); result = true; break; } @@ -3904,7 +4023,7 @@ bool cd_0002e680_int_tile(struct geotilei *tile, s32 numvertices, struct coord * return result; } -bool cd_0002e82c_int_tile(struct geotilef *tile, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) +bool cd_test_blockmove_tilef(struct geotilef *tile, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) { bool result = false; s32 i; @@ -3915,7 +4034,7 @@ bool cd_0002e82c_int_tile(struct geotilef *tile, s32 numvertices, struct coord * struct coord sp6c; for (i = 0; i < numvertices; i++) { - if (var8005f030) { + if (g_CdReverseVertices) { s32 remaining = numvertices - i; next = (remaining + numvertices - 2) % numvertices; curr = remaining - 1; @@ -3924,13 +4043,13 @@ bool cd_0002e82c_int_tile(struct geotilef *tile, s32 numvertices, struct coord * curr = i; } - if (cd_0002b128_flt_tile((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), + if (cd_is_cylpath_intersecting_tilef((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord)), (struct coord *)((uintptr_t)diffs + curr * sizeof(struct coord)), tile, &sp6c, &sp84, &sp78, 0, 0.0f, 0.0f)) { - cd_set_obstacle_vtx_col_prop(&sp84, &sp78, &sp6c, prop); - cd_set_saved_pos((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); - cd_set_saved_block(block); + cd_set_obstacle_edge_pos_prop(&sp84, &sp78, &sp6c, prop); + cd_set_block_edge((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); + cd_set_block(block); result = true; break; } @@ -3939,7 +4058,7 @@ bool cd_0002e82c_int_tile(struct geotilef *tile, s32 numvertices, struct coord * return result; } -bool cd_0002e9d8_block(struct geoblock *thisblock, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) +bool cd_test_blockmove_block(struct geoblock *thisblock, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) { bool result = false; s32 i; @@ -3950,7 +4069,7 @@ bool cd_0002e9d8_block(struct geoblock *thisblock, s32 numvertices, struct coord struct coord sp6c; for (i = 0; i < numvertices; i++) { - if (var8005f030) { + if (g_CdReverseVertices) { s32 remaining = numvertices - i; next = (remaining + numvertices - 2) % numvertices; curr = remaining - 1; @@ -3959,13 +4078,13 @@ bool cd_0002e9d8_block(struct geoblock *thisblock, s32 numvertices, struct coord curr = i; } - if (cd_0002b560_block((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), + if (cd_is_cylpath_intersecting_block((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord)), (struct coord *)((uintptr_t)diffs + curr * sizeof(struct coord)), thisblock, &sp6c, &sp84, &sp78, 0, 0.0f, 0.0f)) { - cd_set_obstacle_vtx_col_prop(&sp84, &sp78, &sp6c, prop); - cd_set_saved_pos((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); - cd_set_saved_block(block); + cd_set_obstacle_edge_pos_prop(&sp84, &sp78, &sp6c, prop); + cd_set_block_edge((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); + cd_set_block(block); result = true; break; } @@ -3974,7 +4093,7 @@ bool cd_0002e9d8_block(struct geoblock *thisblock, s32 numvertices, struct coord return result; } -bool cd_0002eb84_cyl(struct geocyl *cyl, s32 numvertices, struct coord *arg2, struct coord *arg3, struct prop *prop, struct geoblock *block) +bool cd_test_blockmove_cyl(struct geocyl *cyl, s32 numvertices, struct coord *verts, struct coord *diffs, struct prop *prop, struct geoblock *block) { bool result = false; s32 i; @@ -3985,7 +4104,7 @@ bool cd_0002eb84_cyl(struct geocyl *cyl, s32 numvertices, struct coord *arg2, st struct coord sp6c; for (i = 0; i < numvertices; i++) { - if (var8005f030) { + if (g_CdReverseVertices) { s32 remaining = numvertices - i; next = (remaining + numvertices - 2) % numvertices; curr = remaining - 1; @@ -3994,13 +4113,13 @@ bool cd_0002eb84_cyl(struct geocyl *cyl, s32 numvertices, struct coord *arg2, st curr = i; } - if (cd_0002b954_cyl((struct coord *)((uintptr_t)arg2 + curr * sizeof(struct coord)), - (struct coord *)((uintptr_t)arg2 + next * sizeof(struct coord)), - (struct coord *)((uintptr_t)arg3 + curr * sizeof(struct coord)), + if (cd_is_cylpath_intersecting_cyl((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), + (struct coord *)((uintptr_t)verts + next * sizeof(struct coord)), + (struct coord *)((uintptr_t)diffs + curr * sizeof(struct coord)), cyl, &sp6c, &sp84, &sp78, 0, 0.0f, 0.0f)) { - cd_set_obstacle_vtx_col_prop(&sp84, &sp78, &sp6c, prop); - cd_set_saved_pos((struct coord *)((uintptr_t)arg2 + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)arg2 + next * sizeof(struct coord))); - cd_set_saved_block(block); + cd_set_obstacle_edge_pos_prop(&sp84, &sp78, &sp6c, prop); + cd_set_block_edge((struct coord *)((uintptr_t)verts + curr * sizeof(struct coord)), (struct coord *)((uintptr_t)verts + next * sizeof(struct coord))); + cd_set_block(block); result = true; break; } @@ -4009,7 +4128,7 @@ bool cd_0002eb84_cyl(struct geocyl *cyl, s32 numvertices, struct coord *arg2, st return result; } -bool cd_0002ed30(u8 *start, u8 *end, struct geoblock *block, s32 numvertices, struct coord *verts, struct coord *diffs, u16 geoflags, struct prop *prop) +s32 cd_test_blockmove_from_bytes(u8 *start, u8 *end, struct geoblock *block, s32 numvertices, struct coord *verts, struct coord *diffs, u16 geoflags, struct prop *prop) { struct geo *geo = (struct geo *) start; @@ -4022,8 +4141,8 @@ bool cd_0002ed30(u8 *start, u8 *end, struct geoblock *block, s32 numvertices, st if ((geoflags & geo->flags) && *(s16 *)(tile->ymax + (uintptr_t)tile) >= block->ymin && *(s16 *)(tile->ymin + (uintptr_t)tile) <= block->ymax - && cd_0002e680_int_tile(tile, numvertices, verts, diffs, prop, block)) { - return false; + && cd_test_blockmove_tilei(tile, numvertices, verts, diffs, prop, block)) { + return CDRESULT_COLLISION; } geo = (struct geo *)((uintptr_t)geo + GEOTILEI_SIZE(tile)); @@ -4033,8 +4152,8 @@ bool cd_0002ed30(u8 *start, u8 *end, struct geoblock *block, s32 numvertices, st if ((geoflags & geo->flags) && tile->vertices[tile->max[1]].y >= block->ymin && tile->vertices[tile->min[1]].y <= block->ymax - && cd_0002e82c_int_tile(tile, numvertices, verts, diffs, prop, block)) { - return false; + && cd_test_blockmove_tilef(tile, numvertices, verts, diffs, prop, block)) { + return CDRESULT_COLLISION; } geo = (struct geo *)((uintptr_t)geo + GEOTILEF_SIZE(tile)); @@ -4044,8 +4163,8 @@ bool cd_0002ed30(u8 *start, u8 *end, struct geoblock *block, s32 numvertices, st if ((geoflags & (GEOFLAG_WALL | GEOFLAG_BLOCK_SIGHT | GEOFLAG_BLOCK_SHOOT)) && block2->ymax >= block->ymin && block2->ymin <= block->ymax - && cd_0002e9d8_block(block2, numvertices, verts, diffs, prop, block)) { - return false; + && cd_test_blockmove_block(block2, numvertices, verts, diffs, prop, block)) { + return CDRESULT_COLLISION; } geo = (struct geo *)((uintptr_t)geo + GEOBLOCK_SIZE(block2)); @@ -4055,18 +4174,21 @@ bool cd_0002ed30(u8 *start, u8 *end, struct geoblock *block, s32 numvertices, st if ((geoflags & geo->flags) && cyl->ymax >= block->ymin && cyl->ymin <= block->ymax - && cd_0002eb84_cyl(cyl, numvertices, verts, diffs, prop, block)) { - return false; + && cd_test_blockmove_cyl(cyl, numvertices, verts, diffs, prop, block)) { + return CDRESULT_COLLISION; } geo = (struct geo *)((uintptr_t)geo + GEOCYL_SIZE(cyl)); } } - return true; + return CDRESULT_NOCOLLISION; } -bool cd_0002f02c(struct geoblock *block, RoomNum *rooms, s32 types) +/** + * Test a block moving horizontally into other geometry. + */ +bool cd_test_blockmove(struct geoblock *block, RoomNum *rooms, u32 types) { s32 numvertices = block->header.numvertices; s32 i; @@ -4093,6 +4215,7 @@ bool cd_0002f02c(struct geoblock *block, RoomNum *rooms, s32 types) diffs[i].z = verts[next].z - verts[i].z; } + // Check BG if (types & CDTYPE_BG) { RoomNum *roomsptr = rooms; s32 roomnum = *roomsptr; @@ -4102,9 +4225,9 @@ bool cd_0002f02c(struct geoblock *block, RoomNum *rooms, s32 types) start = g_TileFileData.u8 + g_TileRooms[roomnum]; end = g_TileFileData.u8 + g_TileRooms[roomnum + 1]; - result = cd_0002ed30(start, end, block, numvertices, verts, diffs, GEOFLAG_WALL, NULL); + result = cd_test_blockmove_from_bytes(start, end, block, numvertices, verts, diffs, GEOFLAG_WALL, NULL); - if (!result) { + if (result == CDRESULT_COLLISION) { break; } } @@ -4114,7 +4237,8 @@ bool cd_0002f02c(struct geoblock *block, RoomNum *rooms, s32 types) } } - if (result) { + if (result != CDRESULT_COLLISION) { + // Check props room_get_props(rooms, propnums, 256); propnumptr = propnums; @@ -4124,9 +4248,9 @@ bool cd_0002f02c(struct geoblock *block, RoomNum *rooms, s32 types) if (prop_is_of_cd_type(prop, types)) { if (prop_get_geometry(prop, &start, &end)) { - result = cd_0002ed30(start, end, block, numvertices, verts, diffs, GEOFLAG_WALL, prop); + result = cd_test_blockmove_from_bytes(start, end, block, numvertices, verts, diffs, GEOFLAG_WALL, prop); - if (!result) { + if (result == CDRESULT_COLLISION) { break; } } @@ -4228,51 +4352,55 @@ Gfx *cd_render(Gfx *gdl, u32 arg1, u32 arg2, u32 arg3) return gdl; } -void cd_0002f2fc(u32 arg0, u32 arg1) +void cd_stub(u32 arg0, u32 arg1) { // empty } -bool cd_is_nearly_in_sight_with_flags(struct coord *viewpos, RoomNum *rooms, struct coord *targetpos, f32 distance, s32 types, u16 geoflags) +/** + * Check direct line of sight, then check positions left and right of topos + * using the distance argument. + */ +bool cd_is_nearly_in_sight_with_flags(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, f32 distance, u32 types, u16 geoflags) { struct coord diff; f32 x; f32 z; struct coord vector; - if (cd_test_los03(viewpos, rooms, targetpos, types, geoflags)) { + if (cd_test_los_oobok(frompos, fromrooms, topos, types, geoflags)) { return true; } - vector.x = targetpos->x - viewpos->x; + vector.x = topos->x - frompos->x; vector.y = 0; - vector.z = targetpos->z - viewpos->z; + vector.z = topos->z - frompos->z; guNormalize(&vector.x, &vector.y, &vector.z); x = vector.f[0] * distance; z = vector.f[2] * distance; - diff.x = targetpos->x - z; - diff.y = targetpos->y; - diff.z = targetpos->z + x; + diff.x = topos->x - z; + diff.y = topos->y; + diff.z = topos->z + x; - if (cd_test_los03(viewpos, rooms, &diff, types, geoflags)) { + if (cd_test_los_oobok(frompos, fromrooms, &diff, types, geoflags)) { return true; } - diff.x = targetpos->x + z; - diff.y = targetpos->y; - diff.z = targetpos->z - x; + diff.x = topos->x + z; + diff.y = topos->y; + diff.z = topos->z - x; - if (cd_test_los03(viewpos, rooms, &diff, types, geoflags)) { + if (cd_test_los_oobok(frompos, fromrooms, &diff, types, geoflags)) { return true; } return false; } -bool cd_is_nearly_in_sight(struct coord *viewpos, RoomNum *rooms, struct coord *targetpos, f32 distance, s32 types) +bool cd_is_nearly_in_sight(struct coord *frompos, RoomNum *fromrooms, struct coord *topos, f32 distance, u32 types) { - return cd_is_nearly_in_sight_with_flags(viewpos, rooms, targetpos, distance, types, GEOFLAG_BLOCK_SIGHT); + return cd_is_nearly_in_sight_with_flags(frompos, fromrooms, topos, distance, types, GEOFLAG_BLOCK_SIGHT); } diff --git a/src/lib/portal.c b/src/lib/portal.c index 813b0058a..2f93baa80 100644 --- a/src/lib/portal.c +++ b/src/lib/portal.c @@ -173,10 +173,10 @@ s32 portal_calculate_intersection(s32 portalnum, struct coord *pos1, struct coor * Given frompos, fromrooms and a topos, * use portals to figure out the new rooms list. * - * The final rooms are written to results1, + * The final rooms are written to finalrooms, * which should only ever have 0 or 1 room in it. * - * The caller may optionally pass results2 and its length, + * The caller may optionally pass intersecting and its length, * which will be populated with all traversed rooms. * * This is overengineered. It allows a room to have multiple