Identify remaining door functions

This commit is contained in:
Ryan Dwyer 2024-08-31 14:36:19 +10:00
parent 42b4fd3789
commit 8a3b77a031
7 changed files with 185 additions and 181 deletions

View File

@ -40,7 +40,7 @@ The decomp project wraps all decompiled piracy checks in `#if PIRACYCHECKS` stat
**What It Checks:** Checks that the value of `osCicId` is 6105.
**Payload:** Rewrites the start of `func0f08f968` so it immediately returns false. This makes it impossible to open doors.
**Payload:** Rewrites the start of `door_test_interact_angle` so it immediately returns false. This makes it impossible to open doors.
### bot_pickup_prop

View File

@ -3010,7 +3010,7 @@ bool chr_find_onscreen_doors(struct chrdata *chr)
&& door->doortype != DOORTYPE_AZTECCHAIR
&& (obj->flags & (OBJFLAG_00000010 | OBJFLAG_AISEETHROUGH)) == 0
&& (obj->flags2 & OBJFLAG2_DOOR_ALTCOORDSYSTEM) == 0
&& !((door->doorflags & DOORFLAG_0080) == 0 && door->frac > 0)) {
&& !((door->doorflags & DOORFLAG_TRANSLATION) == 0 && door->frac > 0)) {
for (i = 0; i < g_ChrsNumOnscreenDoors; i++) {
if (g_ChrsOnscreenDoors[i].prop == prop) {
break;

View File

@ -641,7 +641,7 @@ void obj_populate_geoblock_from_modeldef(struct modelrodata_geo *georodata, stru
block->ymax = mtx->m[3][1] + obj_get_rotated_local_y_max_by_mtx4(bbox, mtx);
}
bool func0f0675c8(struct coord *pos, f32 arg1, struct modelrodata_bbox *bbox, Mtxf *mtx)
bool door_is_player_within_distance(struct coord *playerpos, f32 distance, struct modelrodata_bbox *doorbbox, Mtxf *doormtx)
{
Mtxf sp58;
struct coord sp4c;
@ -649,13 +649,13 @@ bool func0f0675c8(struct coord *pos, f32 arg1, struct modelrodata_bbox *bbox, Mt
struct coord sp34;
struct coord sp28;
sp34.f[0] = sp34.f[1] = sp34.f[2] = arg1;
sp34.f[0] = sp34.f[1] = sp34.f[2] = distance;
sp4c.x = pos->x - mtx->m[3][0];
sp4c.y = pos->y - mtx->m[3][1];
sp4c.z = pos->z - mtx->m[3][2];
sp4c.x = playerpos->x - doormtx->m[3][0];
sp4c.y = playerpos->y - doormtx->m[3][1];
sp4c.z = playerpos->z - doormtx->m[3][2];
mtx000170e4(mtx->m, sp58.m);
mtx000170e4(doormtx->m, sp58.m);
mtx4_rotate_vec(&sp58, &sp4c, &sp40);
mtx4_rotate_vec(&sp58, &sp34, &sp28);
@ -671,60 +671,60 @@ bool func0f0675c8(struct coord *pos, f32 arg1, struct modelrodata_bbox *bbox, Mt
sp28.z = -sp28.z;
}
return sp40.x - sp28.x <= bbox->xmax && sp28.x + sp40.x >= bbox->xmin
&& sp40.y - sp28.y <= bbox->ymax && sp28.y + sp40.y >= bbox->ymin
&& sp40.z - sp28.z <= bbox->zmax && sp28.z + sp40.z >= bbox->zmin;
return sp40.x - sp28.x <= doorbbox->xmax && sp28.x + sp40.x >= doorbbox->xmin
&& sp40.y - sp28.y <= doorbbox->ymax && sp28.y + sp40.y >= doorbbox->ymin
&& sp40.z - sp28.z <= doorbbox->zmax && sp28.z + sp40.z >= doorbbox->zmin;
}
bool func0f0677ac(struct coord *coord, struct coord *arg1, struct coord *pos,
struct coord *normal, struct coord *up, struct coord *look,
bool pos_is_within_padbbox(struct coord *playerpos, struct coord *padding, struct coord *padpos,
struct coord *padnormal, struct coord *padup, struct coord *padlook,
f32 xmin, f32 xmax, f32 ymin, f32 ymax, f32 zmin, f32 zmax)
{
f32 xdiff = coord->x - pos->x;
f32 ydiff = coord->y - pos->y;
f32 zdiff = coord->z - pos->z;
f32 xdiff = playerpos->x - padpos->x;
f32 ydiff = playerpos->y - padpos->y;
f32 zdiff = playerpos->z - padpos->z;
f32 f0;
f0 = xdiff * look->f[0] + ydiff * look->f[1] + zdiff * look->f[2];
f0 = xdiff * padlook->f[0] + ydiff * padlook->f[1] + zdiff * padlook->f[2];
if (f0 > arg1->z + zmax || f0 < zmin - arg1->z) {
if (f0 > padding->z + zmax || f0 < zmin - padding->z) {
return false;
}
f0 = xdiff * up->f[0] + ydiff * up->f[1] + zdiff * up->f[2];
f0 = xdiff * padup->f[0] + ydiff * padup->f[1] + zdiff * padup->f[2];
if (f0 > arg1->y + ymax || f0 < ymin - arg1->y) {
if (f0 > padding->y + ymax || f0 < ymin - padding->y) {
return false;
}
f0 = xdiff * normal->f[0] + ydiff * normal->f[1] + zdiff * normal->f[2];
f0 = xdiff * padnormal->f[0] + ydiff * padnormal->f[1] + zdiff * padnormal->f[2];
if (f0 > arg1->x + xmax || f0 < xmin - arg1->x) {
if (f0 > padding->x + xmax || f0 < xmin - padding->x) {
return false;
}
return true;
}
bool func0f0678f8(struct coord *coord, struct coord *arg1, s32 padnum)
bool pos_is_within_padding_of_padvol(struct coord *playerpos, struct coord *arg1, s32 padnum)
{
struct pad pad;
pad_unpack(padnum, PADFIELD_POS | PADFIELD_LOOK | PADFIELD_UP | PADFIELD_NORMAL | PADFIELD_BBOX, &pad);
return func0f0677ac(coord, arg1, &pad.pos, &pad.normal, &pad.up, &pad.look,
return pos_is_within_padbbox(playerpos, arg1, &pad.pos, &pad.normal, &pad.up, &pad.look,
pad.bbox.xmin, pad.bbox.xmax, pad.bbox.ymin, pad.bbox.ymax, pad.bbox.zmin, pad.bbox.zmax);
}
bool func0f06797c(struct coord *coord, f32 arg1, s32 padnum)
bool pos_is_within_dist_of_padvol(struct coord *playerpos, f32 dist, s32 padnum)
{
struct coord sp1c;
struct coord padding;
sp1c.x = arg1;
sp1c.y = arg1;
sp1c.z = arg1;
padding.x = dist;
padding.y = dist;
padding.z = dist;
return func0f0678f8(coord, &sp1c, padnum);
return pos_is_within_padding_of_padvol(playerpos, &padding, padnum);
}
bool func0f0679ac(struct model *model, f32 *max, f32 *min, f32 arg3[2], f32 arg4[2])
@ -1218,7 +1218,7 @@ s32 obj_get_destroyed_level(struct defaultobj *obj)
return (obj->damage >> 2) + 1;
}
struct modelnode *func0f0687e4(struct model *model)
struct modelnode *door_find_dl_node(struct model *model)
{
struct modeldef *modeldef = model->definition;
struct modelnode *node = modeldef->rootnode;
@ -1379,7 +1379,7 @@ s32 obj_get_average_brightness_in_rooms(RoomNum *rooms, s32 brightnesstype)
return 0;
}
s32 door0f068c04(struct prop *prop, s32 *arg1, s32 *arg2)
s32 door_calc_average_brightness(struct prop *prop, s32 *arg1, s32 *arg2)
{
struct doorobj *door = prop->door;
struct doorobj *sibling;
@ -1524,7 +1524,7 @@ s32 func0f068fc8(struct prop *prop, bool arg1)
actualptr = arg1 == 0 ? &actual : NULL;
extraptr = arg1 == 1 ? &extra : NULL;
door0f068c04(prop, actualptr, extraptr);
door_calc_average_brightness(prop, actualptr, extraptr);
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
if (g_Vars.currentplayernum == 1) {
@ -7748,7 +7748,7 @@ void door_init_matrices(struct prop *prop)
struct model *model = door->base.model;
Mtxf *matrices = model->matrices;
func0f08c424(door, matrices);
door_get_mtx(door, matrices);
mtx00015be0(cam_get_world_to_screen_mtxf(), matrices);
if (model->definition->skel == &g_Skel11) {
@ -13660,7 +13660,7 @@ Gfx *obj_render(struct prop *prop, Gfx *gdl, bool xlupass)
door = (struct doorobj *)obj;
if (door->doortype == DOORTYPE_LASER) {
node = func0f0687e4(obj->model);
node = door_find_dl_node(obj->model);
dldata1 = &node->rodata->dl;
dldata2 = (struct modelrwdata_dl *) model_get_node_rw_data(obj->model, node);
oldcolours = (Col *) ((((uintptr_t) &dldata1->vertices[dldata1->numvertices] + 7) | 7) ^ 7);
@ -15152,7 +15152,7 @@ void door_destroy_glass(struct doorobj *door)
}
}
func0f08c424(door, &matrix);
door_get_mtx(door, &matrix);
shards_create((struct coord *) &matrix.m[3][0], &matrix.m[0][0], &matrix.m[1][0], &matrix.m[2][0],
rodata->bbox.xmin, rodata->bbox.xmax, rodata->bbox.ymin, rodata->bbox.ymax,
SHARDTYPE_GLASS, prop);
@ -18884,7 +18884,7 @@ bool door_is_pos_in_range(struct doorobj *door, struct coord *pos, f32 distance,
if (door->doortype == DOORTYPE_VERTICAL
|| door->doortype == DOORTYPE_SLIDING
|| door->doortype == DOORTYPE_SWINGING) {
if (func0f0678f8(pos, &range, door->base.pad)) {
if (pos_is_within_padding_of_padvol(pos, &range, door->base.pad)) {
return true;
}
}
@ -19044,7 +19044,7 @@ void doors_check_automatic(void)
}
}
void func0f08c424(struct doorobj *door, Mtxf *matrix)
void door_get_mtx(struct doorobj *door, Mtxf *matrix)
{
mtx3_to_mtx4(door->base.realrot, matrix);
mtx4_set_translation(&door->base.prop->pos, matrix);
@ -19079,10 +19079,10 @@ void door_update_tiles(struct doorobj *door)
struct coord sp80;
struct pad pad;
if (door->doorflags & DOORFLAG_0080) {
door->base.prop->pos.x = door->unk98.x * door->frac + door->startpos.x;
door->base.prop->pos.y = door->unk98.y * door->frac + door->startpos.y;
door->base.prop->pos.z = door->unk98.z * door->frac + door->startpos.z;
if (door->doorflags & DOORFLAG_TRANSLATION) {
door->base.prop->pos.x = door->slidedist.x * door->frac + door->startpos.x;
door->base.prop->pos.y = door->slidedist.y * door->frac + door->startpos.y;
door->base.prop->pos.z = door->slidedist.z * door->frac + door->startpos.z;
} else if (door->doortype == DOORTYPE_SWINGING
|| door->doortype == DOORTYPE_AZTECCHAIR
|| door->doortype == DOORTYPE_HULL) {
@ -19118,7 +19118,7 @@ void door_update_tiles(struct doorobj *door)
sp80.y = door->startpos.y - sp8c.y;
sp80.z = door->startpos.z - sp8c.z;
mtx3_to_mtx4(door->mtx98, &spdc);
mtx3_to_mtx4(door->rotmtx, &spdc);
mtx4_load_translation(&sp80, &sp98);
mtx4_mult_mtx4_in_place(&sp98, &spdc);
@ -19154,6 +19154,7 @@ void door_update_tiles(struct doorobj *door)
door_get_bbox(door, &bbox);
// If the door is fully open then its geometry is removed
if (door->frac >= door->perimfrac) {
door->base.hidden |= OBJHFLAG_DOORPERIMDISABLED;
return;
@ -19162,12 +19163,14 @@ void door_update_tiles(struct doorobj *door)
geo = door->base.geoblock;
door->base.hidden &= ~OBJHFLAG_DOORPERIMDISABLED;
if ((door->doorflags & DOORFLAG_0020) == 0) {
func0f08c424(door, &spdc);
// Geometry is usually calculated on every frame.
// However, vertical doors calculate it once and reuse it.
if ((door->doorflags & DOORFLAG_REUSEGEO) == 0) {
door_get_mtx(door, &spdc);
obj_populate_geoblock_from_bbox_and_mtx(&bbox, &spdc, geo);
if (door->doortype == DOORTYPE_VERTICAL) {
door->doorflags |= DOORFLAG_0020;
door->doorflags |= DOORFLAG_REUSEGEO;
}
}
@ -19175,7 +19178,7 @@ void door_update_tiles(struct doorobj *door)
geo->ymin = door->startpos.y + obj_get_rotated_local_y_min_by_mtx3(&bbox, door->base.realrot);
} else if (door->doortype == DOORTYPE_FALLAWAY) {
geo->ymin = door->base.prop->pos.y - 10000;
} else if (door->doorflags & DOORFLAG_0001) {
} else if (door->doorflags & DOORFLAG_EXTENDEDY) {
geo->ymin -= 1000;
}
@ -19184,7 +19187,7 @@ void door_update_tiles(struct doorobj *door)
geo->ymax = geo->ymin + 50;
} else if (door->doortype == DOORTYPE_FALLAWAY) {
geo->ymax = door->base.prop->pos.y + 1000;
} else if (door->doorflags & DOORFLAG_0001) {
} else if (door->doorflags & DOORFLAG_EXTENDEDY) {
geo->ymax += 1000;
}
}
@ -19193,7 +19196,7 @@ void door_update_tiles(struct doorobj *door)
#define NEXT2() (j + 2) % 4
#define NEXT3() (j + 3) % 4
void door0f08cb20(struct doorobj *door, Vtx *src, Vtx *dst, s32 numvertices)
void door_calc_texturemap(struct doorobj *door, Vtx *src, Vtx *dst, s32 numvertices)
{
s32 i;
s32 j;
@ -19257,32 +19260,32 @@ void door0f08cb20(struct doorobj *door, Vtx *src, Vtx *dst, s32 numvertices)
}
}
void func0f08d3dc(struct doorobj *door)
void door_calc_vertices_without_cache(struct doorobj *door)
{
obj_update_extra_geo(&door->base);
if (door->doorflags & DOORFLAG_0004) {
struct modelnode *node = func0f0687e4(door->base.model);
struct modelnode *node = door_find_dl_node(door->base.model);
union modelrodata *rodata = node->rodata;
union modelrwdata *rwdata = model_get_node_rw_data(door->base.model, node);
rwdata->dl.vertices = gfx_allocate_vertices(rodata->dl.numvertices);
door0f08cb20(door, rodata->dl.vertices, rwdata->dl.vertices, rodata->dl.numvertices);
door_calc_texturemap(door, rodata->dl.vertices, rwdata->dl.vertices, rodata->dl.numvertices);
}
}
void func0f08d460(struct doorobj *door)
void door_calc_vertices_with_cache(struct doorobj *door)
{
if ((door->doorflags & (DOORFLAG_0004 | DOORFLAG_0080)) == (DOORFLAG_0004 | DOORFLAG_0080)) {
struct modelnode *node = func0f0687e4(door->base.model);
if ((door->doorflags & (DOORFLAG_0004 | DOORFLAG_TRANSLATION)) == (DOORFLAG_0004 | DOORFLAG_TRANSLATION)) {
struct modelnode *node = door_find_dl_node(door->base.model);
union modelrodata *rodata = node->rodata;
union modelrwdata *rwdata = model_get_node_rw_data(door->base.model, node);
if (rwdata->dl.vertices != door->unka4) {
door0f08cb20(door, rodata->dl.vertices, door->unka4, rodata->dl.numvertices);
if (rwdata->dl.vertices != door->vtxcache) {
door_calc_texturemap(door, rodata->dl.vertices, door->vtxcache, rodata->dl.numvertices);
}
rwdata->dl.vertices = door->unka4;
rwdata->dl.vertices = door->vtxcache;
}
}
@ -19300,11 +19303,11 @@ void door_deactivate_portal(struct doorobj *door)
}
}
struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomNum *rooms, struct coord *coord, struct coord *centre)
struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomNum *rooms, struct coord *slidedist, struct coord *centre)
{
struct prop *prop;
union modelrodata *rodata;
Mtxf sp38;
Mtxf rotmtx;
RoomNum sp28[8];
door->base.flags |= OBJFLAG_CORE_GEO_INUSE;
@ -19320,13 +19323,13 @@ struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomN
case DOORTYPE_VERTICAL:
case DOORTYPE_FALLAWAY:
case DOORTYPE_LASER:
door->doorflags |= DOORFLAG_0080;
door->doorflags |= DOORFLAG_TRANSLATION;
break;
}
mtx4_copy(mtx, &sp38);
mtx00015f04(g_ModelStates[door->base.modelnum].scale * (1.0f / 4096.0f), &sp38);
mtx4_to_mtx3(&sp38, door->base.realrot);
mtx4_copy(mtx, &rotmtx);
mtx00015f04(g_ModelStates[door->base.modelnum].scale * (1.0f / 4096.0f), &rotmtx);
mtx4_to_mtx3(&rotmtx, door->base.realrot);
door->frac = (door->base.flags & OBJFLAG_DOOR_KEEPOPEN) ? door->maxfrac : 0;
door->fracspeed = 0;
@ -19337,20 +19340,20 @@ struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomN
door->startpos.y = centre->y;
door->startpos.z = centre->z;
if (door->doorflags & DOORFLAG_0080) {
door->unk98.x = coord->x;
door->unk98.y = coord->y;
door->unk98.z = coord->z;
if (door->doorflags & DOORFLAG_TRANSLATION) {
door->slidedist.x = slidedist->x;
door->slidedist.y = slidedist->y;
door->slidedist.z = slidedist->z;
if (door->doorflags & DOORFLAG_0004) {
struct modelnode *node = func0f0687e4(door->base.model);
struct modelnode *node = door_find_dl_node(door->base.model);
rodata = node->rodata;
door->unka4 = memp_alloc(ALIGN16(rodata->dl.numvertices * sizeof(Vtx)), MEMPOOL_STAGE);
door->vtxcache = memp_alloc(ALIGN16(rodata->dl.numvertices * sizeof(Vtx)), MEMPOOL_STAGE);
} else {
door->unka4 = NULL;
door->vtxcache = NULL;
}
} else {
mtx4_to_mtx3(&sp38, door->mtx98);
mtx4_to_mtx3(&rotmtx, door->rotmtx);
}
los_find_final_room_exhaustive(pos, rooms, centre, sp28);
@ -19365,7 +19368,7 @@ struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomN
rooms_copy(sp28, prop->rooms);
door_update_tiles(door);
obj_onmoved(&door->base, false, true);
func0f08d3dc(door);
door_calc_vertices_without_cache(door);
door->base.shadecol[0] = door->base.nextcol[0];
door->base.shadecol[1] = door->base.nextcol[1];
@ -19731,7 +19734,7 @@ void door_finish_close(struct doorobj *door)
#if PIRACYCHECKS
if (osCicId != decode_xor_aaaaaaaa(PAL ? (6105 ^ 0x18743082) : (6105 ^ 0xaaaaaaaa))) {
u32 *ptr = (u32 *)func0f08f968;
u32 *ptr = (u32 *)door_test_interact_angle;
ptr[0] = 0x00001025; // li v0, 0
ptr[1] = 0x03e00008; // jr ra
ptr[2] = 0x00000000; // nop
@ -20240,8 +20243,8 @@ void doors_calc_frac(struct doorobj *door)
door_finish_open(loopdoor);
}
} else {
if (loopdoor->mode == DOORMODE_CLOSING && loopdoor->frac <= 0) {
} else if (loopdoor->mode == DOORMODE_CLOSING) {
if (loopdoor->frac <= 0) {
loopdoor->mode = DOORMODE_IDLE;
loopdoor->fracspeed = 0;
loopdoor->lastopen60 = 0;
@ -20251,7 +20254,7 @@ void doors_calc_frac(struct doorobj *door)
}
obj_onmoved(&loopdoor->base, false, false);
func0f08d3dc(loopdoor);
door_calc_vertices_without_cache(loopdoor);
} else {
// Door is blocked - restore the original frac
loopdoor->fracspeed = 0;
@ -20259,10 +20262,10 @@ void doors_calc_frac(struct doorobj *door)
door_update_tiles(loopdoor);
obj_detect_rooms(&loopdoor->base);
func0f08d460(loopdoor);
door_calc_vertices_with_cache(loopdoor);
}
} else {
func0f08d460(loopdoor);
door_calc_vertices_with_cache(loopdoor);
}
loopdoor->lastcalc60 = g_Vars.lvframe60;
@ -20303,7 +20306,7 @@ void doors_calc_frac(struct doorobj *door)
}
}
f32 func0f08f538(f32 x, f32 y)
f32 door_get_activation_angle(f32 x, f32 y)
{
f32 angle = atan2f(x, y);
@ -20328,24 +20331,28 @@ f32 func0f08f538(f32 x, f32 y)
}
/**
* Get some coordinates/distances related to activating doors.
* Calculate the angles of the left and right edges of the doorway, relative to
* the player's current direction, and write them to the home pointers.
*
* If the door pointers are included, do the same calculations for the door model
* itself and write the results to those pointers.
*/
void door0f08f604(struct doorobj *door, f32 *arg1, f32 *arg2, f32 *arg3, f32 *arg4, bool altcoordsystem)
void door_get_activation_angles(struct doorobj *door, f32 *homeminangle, f32 *homemaxangle, f32 *doorminangle, f32 *doormaxangle, bool altcoordsystem)
{
f32 value1;
f32 value2;
f32 value3;
f32 value4;
f32 x1;
f32 y1;
f32 z1;
f32 x2;
f32 y2;
f32 z2;
u32 stack[4];
struct prop *playerprop;
f32 spb0;
f32 spac;
f32 spa8;
f32 spa4;
f32 upx;
f32 upz;
f32 ymin;
f32 ymax;
struct coord playerpos;
struct pad pad;
f32 xfrac;
@ -20367,34 +20374,34 @@ void door0f08f604(struct doorobj *door, f32 *arg1, f32 *arg2, f32 *arg3, f32 *ar
playerpos.f[2] = playerprop->pos.z;
if (altcoordsystem) {
spa8 = pad.bbox.xmin;
spa4 = pad.bbox.xmax;
spb0 = pad.up.y * pad.look.z - pad.look.y * pad.up.z;
spac = pad.up.x * pad.look.y - pad.look.x * pad.up.y;
ymin = pad.bbox.xmin;
ymax = pad.bbox.xmax;
upx = pad.up.y * pad.look.z - pad.look.y * pad.up.z;
upz = pad.up.x * pad.look.y - pad.look.x * pad.up.y;
} else {
spa8 = pad.bbox.ymin;
spa4 = pad.bbox.ymax;
spb0 = pad.up.x;
spac = pad.up.z;
ymin = pad.bbox.ymin;
ymax = pad.bbox.ymax;
upx = pad.up.x;
upz = pad.up.z;
}
x1 = pad.pos.x + spb0 * spa8 - playerpos.f[0];
y1 = pad.pos.z + spac * spa8 - playerpos.f[2];
value1 = func0f08f538(x1, y1);
x1 = pad.pos.x + upx * ymin - playerpos.f[0];
z1 = pad.pos.z + upz * ymin - playerpos.f[2];
value1 = door_get_activation_angle(x1, z1);
x2 = pad.pos.x + spb0 * spa4 - playerpos.f[0];
y2 = pad.pos.z + spac * spa4 - playerpos.f[2];
value2 = func0f08f538(x2, y2);
x2 = pad.pos.x + upx * ymax - playerpos.f[0];
z2 = pad.pos.z + upz * ymax - playerpos.f[2];
value2 = door_get_activation_angle(x2, z2);
if (value1 < value2) {
*arg1 = value1;
*arg2 = value2;
*homeminangle = value1;
*homemaxangle = value2;
} else {
*arg1 = value2;
*arg2 = value1;
*homeminangle = value2;
*homemaxangle = value1;
}
if (arg3 != NULL && arg4 != NULL) {
if (doorminangle != NULL && doormaxangle != NULL) {
if (door->doortype == DOORTYPE_SWINGING) {
angle = door->frac * 0.017450513318181f;
value3 = value1;
@ -20406,47 +20413,47 @@ void door0f08f604(struct doorobj *door, f32 *arg1, f32 *arg2, f32 *arg3, f32 *ar
cosine = cosf(angle);
sine = sinf(angle);
x1 = pad.pos.x + (spb0 * spa8) - playerpos.f[0] + (spa4 - spa8) * (spb0 * cosine + spac * sine);
y1 = pad.pos.z + (spac * spa8) - playerpos.f[2] + (spa4 - spa8) * (-spb0 * sine + spac * cosine);
x1 = pad.pos.x + (upx * ymin) - playerpos.f[0] + (ymax - ymin) * (upx * cosine + upz * sine);
z1 = pad.pos.z + (upz * ymin) - playerpos.f[2] + (ymax - ymin) * (-upx * sine + upz * cosine);
value4 = func0f08f538(x1, y1);
value4 = door_get_activation_angle(x1, z1);
} else if (door->doortype == DOORTYPE_SLIDING
|| door->doortype == DOORTYPE_FLEXI1
|| door->doortype == DOORTYPE_FLEXI2
|| door->doortype == DOORTYPE_FLEXI3) {
xfrac = door->unk98.x * door->frac;
zfrac = door->unk98.z * door->frac;
xfrac = door->slidedist.x * door->frac;
zfrac = door->slidedist.z * door->frac;
value3 = func0f08f538(x1 + xfrac, y1 + zfrac);
value4 = func0f08f538(x2 + xfrac, y2 + zfrac);
value3 = door_get_activation_angle(x1 + xfrac, z1 + zfrac);
value4 = door_get_activation_angle(x2 + xfrac, z2 + zfrac);
} else {
value3 = value1;
value4 = value2;
}
if (value3 < value4) {
*arg3 = value3;
*arg4 = value4;
*doorminangle = value3;
*doormaxangle = value4;
} else {
*arg3 = value4;
*arg4 = value3;
*doorminangle = value4;
*doormaxangle = value3;
}
}
}
bool func0f08f968(struct doorobj *door, bool altcoordsystem)
bool door_test_interact_angle(struct doorobj *door, bool altcoordsystem)
{
bool checkmore = true;
f32 sp58;
f32 sp54;
f32 sp50;
f32 sp4c;
bool maybe;
f32 homeminangle;
f32 homemaxangle;
f32 doorminangle;
f32 doormaxangle;
bool includedoor;
struct prop *playerprop;
f32 limit = RAD(20, 0.34901028871536f);
if (g_InteractProp == NULL) {
maybe = false;
includedoor = false;
if (g_Vars.currentplayer->eyespy && g_Vars.currentplayer->eyespy->active) {
playerprop = g_Vars.currentplayer->eyespy->prop;
@ -20454,45 +20461,45 @@ bool func0f08f968(struct doorobj *door, bool altcoordsystem)
playerprop = g_Vars.currentplayer->prop;
}
if ((door->doorflags & (DOORFLAG_0080 | DOORFLAG_0100)) != DOORFLAG_0080) {
maybe = true;
} else if (func0f06797c(&playerprop->pos, 30, door->base.pad)) {
maybe = true;
if ((door->doorflags & (DOORFLAG_TRANSLATION | DOORFLAG_0100)) != DOORFLAG_TRANSLATION) {
includedoor = true;
} else if (pos_is_within_dist_of_padvol(&playerprop->pos, 30, door->base.pad)) {
includedoor = true;
}
if (maybe) {
door0f08f604(door, &sp58, &sp54, &sp50, &sp4c, altcoordsystem);
if (includedoor) {
door_get_activation_angles(door, &homeminangle, &homemaxangle, &doorminangle, &doormaxangle, altcoordsystem);
} else {
door0f08f604(door, &sp58, &sp54, NULL, NULL, altcoordsystem);
door_get_activation_angles(door, &homeminangle, &homemaxangle, NULL, NULL, altcoordsystem);
}
if (maybe && ((sp50 >= -limit && sp50 <= limit && sp4c >= -limit && sp4c <= limit)
|| (sp4c - sp50 < M_BADPI && sp50 < 0.0f && sp4c > 0.0f))) {
if (includedoor && ((doorminangle >= -limit && doorminangle <= limit && doormaxangle >= -limit && doormaxangle <= limit)
|| (doormaxangle - doorminangle < M_BADPI && doorminangle < 0.0f && doormaxangle > 0.0f))) {
g_InteractProp = door->base.prop;
checkmore = false;
} else if (sp58 >= -limit && sp58 <= limit && sp54 >= -limit && sp54 <= limit) {
} else if (homeminangle >= -limit && homeminangle <= limit && homemaxangle >= -limit && homemaxangle <= limit) {
g_InteractProp = door->base.prop;
checkmore = false;
} else {
struct doorobj *sibling = door->sibling;
f32 sp38;
f32 sp34;
f32 sibminangle;
f32 sibmaxangle;
while (sibling != NULL && sibling != door && (sp58 >= 0.0f || sp54 < 0.0f)) {
door0f08f604(sibling, &sp38, &sp34, NULL, NULL, altcoordsystem);
while (sibling != NULL && sibling != door && (homeminangle >= 0.0f || homemaxangle < 0.0f)) {
door_get_activation_angles(sibling, &sibminangle, &sibmaxangle, NULL, NULL, altcoordsystem);
if (sp58 >= 0.0f && sp38 < sp58) {
sp58 = sp38;
if (homeminangle >= 0.0f && homeminangle > sibminangle) {
homeminangle = sibminangle;
}
if (sp54 <= 0.0f && sp54 < sp34) {
sp54 = sp34;
if (homemaxangle <= 0.0f && homemaxangle < sibmaxangle) {
homemaxangle = sibmaxangle;
}
sibling = sibling->sibling;
}
if (sp54 - sp58 < M_BADPI && sp58 < 0.0f && sp54 > 0.0f) {
if (homemaxangle - homeminangle < M_BADPI && homeminangle < 0.0f && homemaxangle > 0.0f) {
g_InteractProp = door->base.prop;
checkmore = false;
}
@ -20529,20 +20536,20 @@ bool door_test_for_interact(struct prop *prop)
f32 ydiff = door->startpos.y - playerprop->pos.y;
f32 zdiff = door->startpos.z - playerprop->pos.z;
if (xdiff * xdiff + zdiff * zdiff < 40000 && ydiff < 200 && ydiff > -200) {
if (xdiff * xdiff + zdiff * zdiff < 200 * 200 && ydiff < 200 && ydiff > -200) {
maybe = true;
} else if (array_intersects(prop->rooms, playerprop->rooms)) {
if (func0f06797c(&playerprop->pos, 150, door->base.pad)) {
if (pos_is_within_dist_of_padvol(&playerprop->pos, 150, door->base.pad)) {
maybe = true;
} else if ((door->doorflags & (DOORFLAG_0080 | DOORFLAG_0100)) != DOORFLAG_0080) {
} else if ((door->doorflags & (DOORFLAG_TRANSLATION | DOORFLAG_0100)) != DOORFLAG_TRANSLATION) {
u32 stack;
struct modelrodata_bbox bbox;
Mtxf matrix;
door_get_bbox(door, &bbox);
func0f08c424(door, &matrix);
door_get_mtx(door, &matrix);
if (func0f0675c8(&playerprop->pos, 150, &bbox, &matrix)) {
if (door_is_player_within_distance(&playerprop->pos, 150, &bbox, &matrix)) {
maybe = true;
}
}
@ -20551,10 +20558,10 @@ 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)) {
checkmore = func0f08f968(door, false);
checkmore = door_test_interact_angle(door, false);
if (checkmore && (door->base.flags2 & OBJFLAG2_DOOR_ALTCOORDSYSTEM)) {
checkmore = func0f08f968(door, true);
checkmore = door_test_interact_angle(door, true);
}
}
}

View File

@ -1088,7 +1088,7 @@ void setup_create_door(struct doorobj *door, s32 cmdindex)
Mtxf finalmtx;
struct coord centre;
Mtxf zrotmtx;
struct coord sp54;
struct coord slidedist;
f32 xscale;
f32 yscale;
f32 zscale;
@ -1126,13 +1126,13 @@ void setup_create_door(struct doorobj *door, s32 cmdindex)
rooms[1] = -1;
if (door->doortype == DOORTYPE_VERTICAL || door->doortype == DOORTYPE_FALLAWAY) {
sp54.x = pad.look.f[0] * (pad.bbox.zmax - pad.bbox.zmin);
sp54.y = pad.look.f[1] * (pad.bbox.zmax - pad.bbox.zmin);
sp54.z = pad.look.f[2] * (pad.bbox.zmax - pad.bbox.zmin);
slidedist.x = pad.look.f[0] * (pad.bbox.zmax - pad.bbox.zmin);
slidedist.y = pad.look.f[1] * (pad.bbox.zmax - pad.bbox.zmin);
slidedist.z = pad.look.f[2] * (pad.bbox.zmax - pad.bbox.zmin);
} else {
sp54.x = pad.up.f[0] * (pad.bbox.ymin - pad.bbox.ymax);
sp54.y = pad.up.f[1] * (pad.bbox.ymin - pad.bbox.ymax);
sp54.z = pad.up.f[2] * (pad.bbox.ymin - pad.bbox.ymax);
slidedist.x = pad.up.f[0] * (pad.bbox.ymin - pad.bbox.ymax);
slidedist.y = pad.up.f[1] * (pad.bbox.ymin - pad.bbox.ymax);
slidedist.z = pad.up.f[2] * (pad.bbox.ymin - pad.bbox.ymax);
}
// These values are stored in the setup files as integers, but at
@ -1151,7 +1151,7 @@ void setup_create_door(struct doorobj *door, s32 cmdindex)
door->sibling = (struct doorobj *) setup_get_cmd_by_index(siblingcmdindex);
}
prop = door_init(door, &pos, &finalmtx, rooms, &sp54, &centre);
prop = door_init(door, &pos, &finalmtx, rooms, &slidedist, &centre);
if (door->base.flags & OBJFLAG_DOOR_HASPORTAL) {
door->portalnum = portalnum;

View File

@ -799,19 +799,19 @@
#define DIFFBIT_PA 0x04
#define DIFFBIT_PD 0x08
#define DOORFLAG_0001 0x0001
#define DOORFLAG_EXTENDEDY 0x0001 // GE bunker flexi door
#define DOORFLAG_WINDOWED 0x0002
#define DOORFLAG_0004 0x0004
#define DOORFLAG_FLIP 0x0008
#define DOORFLAG_AUTOMATIC 0x0010
#define DOORFLAG_0020 0x0020
#define DOORFLAG_REUSEGEO 0x0020
#define DOORFLAG_ROTATEDPAD 0x0040
#define DOORFLAG_0080 0x0080
#define DOORFLAG_TRANSLATION 0x0080 // Door opens using simple translation (no rotation)
#define DOORFLAG_0100 0x0100
#define DOORFLAG_LONGRANGE 0x0200
#define DOORFLAG_DAMAGEONCONTACT 0x0400 // Lasers
#define DOORFLAG_UNBLOCKABLEOPEN 0x0800 // Skip collision checks when opening
#define DOORFLAG_4000 0x4000 // Two Investigation vertical doors after lasers
#define DOORFLAG_4000 0x4000 // Unused. Two Investigation vertical doors after lasers
#define DOORMODE_IDLE 0
#define DOORMODE_OPENING 1

View File

@ -52,10 +52,9 @@ f32 obj_get_rotated_local_max(struct modelrodata_bbox *bbox, f32 arg1, f32 arg2,
s32 obj_populate_geoblock_vertices_from_bbox_and_mtx(f32 xmin, f32 xmax, f32 ymin, f32 ymax, f32 zmin, f32 zmax, Mtxf *mtx, struct geoblock *block);
void obj_populate_geoblock_from_bbox_and_mtx(struct modelrodata_bbox *bbox, Mtxf *mtx, struct geoblock *block);
void obj_populate_geoblock_from_modeldef(struct modelrodata_geo *georodata, struct modelrodata_bbox *bbox, Mtxf *mtx, struct geoblock *block);
bool func0f0675c8(struct coord *pos, f32 arg1, struct modelrodata_bbox *bbox, Mtxf *mtx);
bool func0f0677ac(struct coord *coord, struct coord *arg1, struct coord *pos, struct coord *normal, struct coord *up, struct coord *look, f32 xmin, f32 xmax, f32 ymin, f32 ymax, f32 zmin, f32 zmax);
bool func0f0678f8(struct coord *coord, struct coord *arg1, s32 padnum);
bool func0f06797c(struct coord *coord, f32 arg1, s32 padnum);
bool pos_is_within_padbbox(struct coord *coord, struct coord *arg1, struct coord *pos, struct coord *normal, struct coord *up, struct coord *look, f32 xmin, f32 xmax, f32 ymin, f32 ymax, f32 zmin, f32 zmax);
bool pos_is_within_padding_of_padvol(struct coord *coord, struct coord *arg1, s32 padnum);
bool pos_is_within_dist_of_padvol(struct coord *coord, f32 arg1, s32 padnum);
bool func0f0679ac(struct model *model, f32 *max, f32 *min, f32 arg3[2], f32 arg4[2]);
void model_get_screen_coords_by_axis(struct model *model, f32 *max, f32 *min, s32 axis);
void model_get_screen_coords3(struct model *model, f32 *xmax, f32 *xmin, f32 *ymax, f32 *ymin);
@ -74,7 +73,7 @@ void embedment_free(struct embedment *embedment);
struct embedment *embedment_allocate(void);
s32 obj_get_shots_taken(struct defaultobj *obj);
s32 obj_get_destroyed_level(struct defaultobj *obj);
struct modelnode *func0f0687e4(struct model *model);
struct modelnode *door_find_dl_node(struct model *model);
struct modelnode *modeldef_find_bbox_node(struct modeldef *modeldef);
struct modelrodata_bbox *modeldef_find_bbox_rodata(struct modeldef *modeldef);
struct modelnode *model_find_bbox_node(struct model *model);
@ -82,7 +81,7 @@ struct modelrodata_bbox *model_find_bbox_rodata(struct model *model);
struct modelnode *obj_find_bbox_node(struct defaultobj *obj);
struct modelrodata_bbox *obj_find_bbox_rodata(struct defaultobj *obj);
s32 obj_get_average_brightness_in_rooms(RoomNum *rooms, s32 arg1);
s32 door0f068c04(struct prop *prop, s32 *arg1, s32 *arg2);
s32 door_calc_average_brightness(struct prop *prop, s32 *arg1, s32 *arg2);
s32 func0f068fc8(struct prop *prop, bool arg1);
void prop_calculate_shade_colour(struct prop *prop, u8 *nextcol, u16 floorcol);
void prop_calculate_shade_info(struct prop *prop, u8 *nextcol, u16 floorcol);
@ -295,15 +294,15 @@ bool door_is_obj_in_range(struct doorobj *door, struct defaultobj *obj, bool isb
bool vector_is_in_front_of_door(struct doorobj *door, struct coord *vector);
bool door_is_range_empty(struct doorobj *door);
void doors_check_automatic(void);
void func0f08c424(struct doorobj *door, Mtxf *matrix);
void door_get_mtx(struct doorobj *door, Mtxf *matrix);
void door_get_bbox(struct doorobj *door, struct modelrodata_bbox *dst);
void door_update_tiles(struct doorobj *door);
void door0f08cb20(struct doorobj *door, Vtx *src, Vtx *dst, s32 numvertices);
void func0f08d3dc(struct doorobj *door);
void func0f08d460(struct doorobj *door);
void door_calc_texturemap(struct doorobj *door, Vtx *src, Vtx *dst, s32 numvertices);
void door_calc_vertices_without_cache(struct doorobj *door);
void door_calc_vertices_with_cache(struct doorobj *door);
void door_activate_portal(struct doorobj *door);
void door_deactivate_portal(struct doorobj *door);
struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomNum *rooms, struct coord *coord, struct coord *centre);
struct prop *door_init(struct doorobj *door, struct coord *pos, Mtxf *mtx, RoomNum *rooms, struct coord *slidedist, struct coord *centre);
void door_play_opening_sound(s32 soundtype, struct prop *prop);
void door_play_closing_sound(s32 soundtype, struct prop *prop);
void door_play_opened_sound(s32 soundtype, struct prop *prop);
@ -325,9 +324,7 @@ bool pos_is_in_draw_distance(struct coord *arg);
void door_create_sparks(struct doorobj *door);
bool door_calc_intended_frac(struct doorobj *door);
void doors_calc_frac(struct doorobj *door);
f32 func0f08f538(f32 x, f32 y);
void door0f08f604(struct doorobj *door, f32 *arg1, f32 *arg2, f32 *arg3, f32 *arg4, bool altcoordsystem);
bool func0f08f968(struct doorobj *door, bool altcoordsystem);
bool door_test_interact_angle(struct doorobj *door, bool altcoordsystem);
bool door_test_for_interact(struct prop *prop);
void doors_activate(struct prop *prop, bool allowliftclose);
bool pos_is_in_front_of_door(struct coord *pos, struct doorobj *door);

View File

@ -1473,10 +1473,10 @@ struct doorobj { // objtype 0x01
/*0x8c*/ struct coord startpos;
union {
struct {
/*0x98*/ struct coord unk98;
/*0xa4*/ Vtx *unka4;
/*0x98*/ struct coord slidedist;
/*0xa4*/ Vtx *vtxcache;
};
f32 mtx98[3][3];
f32 rotmtx[3][3];
};
/*0xbc*/ struct doorobj *sibling;
/*0xc0*/ s32 lastopen60;
@ -1485,7 +1485,7 @@ struct doorobj { // objtype 0x01
/*0xc7*/ s8 fadetime60; // counts down
/*0xc8*/ s32 lastcalc60;
/*0xcc*/ u8 laserfade;
/*0xcd*/ u8 unusedmaybe[3];
/*0xcd*/ u8 padding[3];
/*0xd0*/ u8 shadeinfo1[4]; // player 1
/*0xd4*/ u8 shadeinfo2[4]; // player 2
/*0xd8*/ u8 actual1;