mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-09-05 02:25:48 -04:00
Reinstate cctv
This commit is contained in:
+228
-1
@@ -108,6 +108,8 @@ s32 g_EmbedHitPart = 0;
|
||||
u32 g_EmbedSide = 0x00000000;
|
||||
s16 var8006993c[3] = {0};
|
||||
u32 var80069944 = 0x00000000;
|
||||
f32 g_CctvWaitScale = 1;
|
||||
f32 g_CctvDamageRxScale = 1;
|
||||
f32 g_AutogunAccuracyScale = 1;
|
||||
f32 g_AutogunDamageTxScale = 1;
|
||||
f32 g_AutogunDamageRxScale = 1;
|
||||
@@ -7681,6 +7683,227 @@ void escastepTick(struct prop *prop)
|
||||
}
|
||||
}
|
||||
|
||||
void cctvTick(struct prop *camprop)
|
||||
{
|
||||
struct cctvobj *camera = (struct cctvobj *)camprop->obj;
|
||||
struct defaultobj *obj = camprop->obj;
|
||||
f32 yaw;
|
||||
struct prop *playerprop;
|
||||
f32 xdist;
|
||||
f32 ydist;
|
||||
f32 zdist;
|
||||
bool canseeplayer = true;
|
||||
|
||||
// If playing in coop mode, cycle between players in alternating frames
|
||||
if (g_Vars.coopplayernum >= 0) {
|
||||
if (g_Vars.lvframenum & 1) {
|
||||
playerprop = g_Vars.bond->prop;
|
||||
} else {
|
||||
playerprop = g_Vars.coop->prop;
|
||||
}
|
||||
} else {
|
||||
playerprop = g_Vars.bond->prop;
|
||||
}
|
||||
|
||||
// Check distance
|
||||
xdist = playerprop->pos.x - camprop->pos.x;
|
||||
ydist = playerprop->pos.y - camprop->pos.y;
|
||||
zdist = playerprop->pos.z - camprop->pos.z;
|
||||
|
||||
yaw = camera->toleft ? camera->yleft : camera->yright;
|
||||
|
||||
if (camera->maxdist > 0) {
|
||||
if (xdist * xdist + ydist * ydist + zdist * zdist > camera->maxdist * camera->maxdist) {
|
||||
canseeplayer = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Vars.bondvisible == false
|
||||
|| (obj->flags & OBJFLAG_CAMERA_DISABLED)
|
||||
|| (playerprop->chr->hidden & CHRHFLAG_CLOAKED)) {
|
||||
canseeplayer = false;
|
||||
}
|
||||
|
||||
// Check horizontal angle
|
||||
if (canseeplayer) {
|
||||
f32 angle = atan2f(xdist, zdist);
|
||||
f32 yrot = camera->yrot;
|
||||
f32 finalangle;
|
||||
|
||||
if (yrot < 0) {
|
||||
yrot += M_BADTAU;
|
||||
} else if (yrot >= M_BADTAU) {
|
||||
yrot -= M_BADTAU;
|
||||
}
|
||||
|
||||
yrot += camera->yzero;
|
||||
|
||||
if (yrot >= M_BADTAU) {
|
||||
yrot -= M_BADTAU;
|
||||
}
|
||||
|
||||
finalangle = angle - yrot;
|
||||
|
||||
if (angle < yrot) {
|
||||
finalangle += M_BADTAU;
|
||||
}
|
||||
|
||||
finalangle -= M_BADPI;
|
||||
|
||||
if (finalangle < 0) {
|
||||
finalangle += M_BADTAU;
|
||||
}
|
||||
|
||||
if (finalangle > M_BADPI) {
|
||||
finalangle -= M_BADTAU;
|
||||
}
|
||||
|
||||
if (finalangle > 0.7852731347084f || finalangle < -0.7852731347084f) {
|
||||
canseeplayer = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check vertical angle
|
||||
if (canseeplayer) {
|
||||
f32 angle = atan2f(ydist, sqrtf(xdist * xdist + zdist * zdist));
|
||||
f32 finalangle = angle - camera->xzero;
|
||||
|
||||
if (angle < camera->xzero) {
|
||||
finalangle = angle - camera->xzero + M_BADTAU;
|
||||
}
|
||||
|
||||
if (finalangle > M_BADTAU) {
|
||||
finalangle -= M_BADTAU;
|
||||
}
|
||||
|
||||
if (finalangle > M_BADPI) {
|
||||
finalangle -= M_BADTAU;
|
||||
}
|
||||
|
||||
if (finalangle);
|
||||
|
||||
if (finalangle > 0.7852731347084f || finalangle < -0.7852731347084f) {
|
||||
canseeplayer = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check line of sight
|
||||
if (canseeplayer) {
|
||||
playerSetPerimEnabled(playerprop, false);
|
||||
|
||||
if (!cdTestLos05(&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;
|
||||
}
|
||||
|
||||
playerSetPerimEnabled(playerprop, true);
|
||||
}
|
||||
|
||||
if (canseeplayer) {
|
||||
obj->flags |= OBJFLAG_CAMERA_BONDINVIEW;
|
||||
camera->seebondtime60 += g_Vars.lvupdate60;
|
||||
|
||||
if (g_Vars.coopplayernum >= 0) {
|
||||
camera->seebondtime60 += g_Vars.lvupdate60;
|
||||
}
|
||||
|
||||
if (camera->seebondtime60 >= (s32)(TICKS(300) * g_CctvWaitScale)) {
|
||||
alarmActivate();
|
||||
camera->seebondtime60 = 0;
|
||||
}
|
||||
} else {
|
||||
obj->flags &= ~OBJFLAG_CAMERA_BONDINVIEW;
|
||||
}
|
||||
|
||||
// Update yaw
|
||||
if (camera->yrot < yaw) {
|
||||
f32 tmp = camera->yspeed * camera->yspeed * 764.06536865234f;
|
||||
|
||||
if (camera->yrot >= yaw - tmp) {
|
||||
camera->yspeed -= 0.00065439427271485f * g_Vars.lvupdate60freal;
|
||||
|
||||
if (camera->yspeed < 0.00065439427271485f) {
|
||||
camera->yspeed = 0.00065439427271485f;
|
||||
}
|
||||
} else if (camera->yspeed < camera->ymaxspeed) {
|
||||
f32 newspeed = camera->yspeed + 0.00065439427271485f * g_Vars.lvupdate60freal;
|
||||
|
||||
if (newspeed > camera->ymaxspeed) {
|
||||
newspeed = camera->ymaxspeed;
|
||||
}
|
||||
|
||||
if (camera->yrot < yaw - newspeed * newspeed * 764.06536865234f) {
|
||||
camera->yspeed = newspeed;
|
||||
}
|
||||
}
|
||||
|
||||
camera->yrot += camera->yspeed * g_Vars.lvupdate60freal;
|
||||
|
||||
if (camera->yrot >= yaw) {
|
||||
camera->yrot = yaw;
|
||||
camera->toleft = false;
|
||||
camera->yspeed = 0;
|
||||
}
|
||||
} else {
|
||||
f32 tmp = camera->yspeed * camera->yspeed * 764.06536865234f;
|
||||
|
||||
if (camera->yrot <= yaw + tmp) {
|
||||
camera->yspeed -= 0.00065439427271485f * g_Vars.lvupdate60freal;
|
||||
|
||||
if (camera->yspeed < 0.00065439427271485f) {
|
||||
camera->yspeed = 0.00065439427271485f;
|
||||
}
|
||||
} else if (camera->yspeed < camera->ymaxspeed) {
|
||||
f32 newspeed = camera->yspeed + 0.00065439427271485f * g_Vars.lvupdate60freal;
|
||||
|
||||
if (newspeed > camera->ymaxspeed) {
|
||||
newspeed = camera->ymaxspeed;
|
||||
}
|
||||
|
||||
if (camera->yrot > yaw + newspeed * newspeed * 764.06536865234f) {
|
||||
camera->yspeed = newspeed;
|
||||
}
|
||||
}
|
||||
|
||||
camera->yrot -= camera->yspeed * g_Vars.lvupdate60freal;
|
||||
|
||||
if (camera->yrot <= yaw) {
|
||||
camera->yrot = yaw;
|
||||
camera->toleft = true;
|
||||
camera->yspeed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cctvInitMatrices(struct prop *prop, Mtxf *mtx)
|
||||
{
|
||||
struct cctvobj *cctv = (struct cctvobj *)prop->obj;
|
||||
struct model *model = cctv->base.model;
|
||||
Mtxf *matrices = model->matrices;
|
||||
union modelrodata *rodata = modelGetPartRodata(model->filedata, MODELPART_CCTV_CASING);
|
||||
struct coord sp64;
|
||||
Mtxf sp24;
|
||||
f32 yrot = cctv->yrot;
|
||||
|
||||
if (yrot < 0) {
|
||||
yrot += M_BADTAU;
|
||||
} else if (yrot >= M_BADTAU) {
|
||||
yrot -= M_BADTAU;
|
||||
}
|
||||
|
||||
mtx4LoadYRotation(yrot, &sp24);
|
||||
mtx4MultMtx4(&sp24, &cctv->camrotm, &matrices[1]);
|
||||
|
||||
sp64.x = rodata->position.pos.x;
|
||||
sp64.y = rodata->position.pos.y;
|
||||
sp64.z = rodata->position.pos.z;
|
||||
|
||||
mtx4TransformVecInPlace(mtx, &sp64);
|
||||
mtx4SetTranslation(&sp64, &matrices[1]);
|
||||
mtx00015be0(camGetWorldToScreenMtxf(), &matrices[1]);
|
||||
}
|
||||
|
||||
void fanTick(struct prop *prop)
|
||||
{
|
||||
struct defaultobj *obj = (struct defaultobj *)prop->obj;
|
||||
@@ -9990,7 +10213,9 @@ void objInitMatrices(struct prop *prop)
|
||||
mtx4SetTranslation(&prop->pos, &mtx);
|
||||
mtx00015be4(camGetWorldToScreenMtxf(), &mtx, obj->model->matrices);
|
||||
|
||||
if (obj->type == OBJTYPE_AUTOGUN) {
|
||||
if (obj->type == OBJTYPE_CCTV) {
|
||||
cctvInitMatrices(prop, &mtx);
|
||||
} else if (obj->type == OBJTYPE_AUTOGUN) {
|
||||
autogunInitMatrices(prop, &mtx);
|
||||
} else if (obj->type == OBJTYPE_CHOPPER) {
|
||||
chopperInitMatrices(prop);
|
||||
@@ -10376,6 +10601,8 @@ s32 objTickPlayer(struct prop *prop)
|
||||
|
||||
if (obj->type == OBJTYPE_DOOR) {
|
||||
doorTick(prop);
|
||||
} else if (obj->type == OBJTYPE_CCTV && (obj->flags & OBJFLAG_DEACTIVATED) == 0) {
|
||||
cctvTick(prop);
|
||||
} else if (obj->type == OBJTYPE_FAN) {
|
||||
fanTick(prop);
|
||||
} else if (obj->type == OBJTYPE_AUTOGUN && (obj->flags & OBJFLAG_DEACTIVATED) == 0) {
|
||||
|
||||
@@ -272,6 +272,8 @@ void propsReset(void)
|
||||
|
||||
g_EmbedProp = NULL;
|
||||
g_EmbedHitPart = -1;
|
||||
g_CctvWaitScale = 1;
|
||||
g_CctvDamageRxScale = 1;
|
||||
g_AutogunAccuracyScale = 1;
|
||||
g_AutogunDamageTxScale = 1;
|
||||
g_AutogunDamageRxScale = 1;
|
||||
@@ -719,6 +721,60 @@ void setupCreateMine(struct mineobj *mine, s32 cmdindex)
|
||||
}
|
||||
}
|
||||
|
||||
void setupCreateCctv(struct cctvobj *cctv, s32 cmdindex)
|
||||
{
|
||||
struct defaultobj *obj = &cctv->base;
|
||||
|
||||
setupCreateObject(obj, cmdindex);
|
||||
|
||||
if (cctv->lookatpadnum >= 0) {
|
||||
struct coord lenspos;
|
||||
union modelrodata *lens = modelGetPartRodata(obj->model->filedata, MODELPART_CCTV_CASING);
|
||||
struct pad *pad;
|
||||
f32 xdiff;
|
||||
f32 ydiff;
|
||||
f32 zdiff;
|
||||
|
||||
pad = &g_Pads[cctv->lookatpadnum];
|
||||
|
||||
lenspos = lens->position.pos;
|
||||
|
||||
mtx00016208(obj->realrot, &lenspos);
|
||||
|
||||
lenspos.x += obj->prop->pos.x;
|
||||
lenspos.y += obj->prop->pos.y;
|
||||
lenspos.z += obj->prop->pos.z;
|
||||
|
||||
xdiff = lenspos.x - pad->pos.x;
|
||||
ydiff = lenspos.y - pad->pos.y;
|
||||
zdiff = lenspos.z - pad->pos.z;
|
||||
|
||||
if (ydiff) {
|
||||
// empty
|
||||
}
|
||||
|
||||
mtx00016d58(&cctv->camrotm, 0.0f, 0.0f, 0.0f, xdiff, ydiff, zdiff, 0.0f, 1.0f, 0.0f);
|
||||
mtx00015f04(obj->model->scale, &cctv->camrotm);
|
||||
|
||||
cctv->toleft = 0;
|
||||
cctv->yleft = *(s32 *)&cctv->yleft * M_BADTAU / 65536.0f;
|
||||
cctv->yright = *(s32 *)&cctv->yright * M_BADTAU / 65536.0f;
|
||||
cctv->yspeed = 0.0f;
|
||||
cctv->ymaxspeed = *(s32 *)&cctv->ymaxspeed * M_BADTAU / 65536.0f;
|
||||
cctv->maxdist = *(s32 *)&cctv->maxdist;
|
||||
cctv->yrot = cctv->yleft;
|
||||
|
||||
cctv->yzero = atan2f(xdiff, zdiff);
|
||||
cctv->xzero = M_BADTAU - atan2f(ydiff, sqrtf(xdiff * xdiff + zdiff * zdiff));
|
||||
|
||||
if (xdiff || zdiff) {
|
||||
// empty
|
||||
}
|
||||
|
||||
cctv->seebondtime60 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setupCreateAutogun(struct autogunobj *autogun, s32 cmdindex)
|
||||
{
|
||||
setupCreateObject(&autogun->base, cmdindex);
|
||||
@@ -1434,6 +1490,11 @@ void setupCreateProps(s32 stagenum)
|
||||
setupCreateKey((struct keyobj *)obj, index);
|
||||
}
|
||||
break;
|
||||
case OBJTYPE_CCTV:
|
||||
if (withobjs && (obj->flags2 & diffflag) == 0) {
|
||||
setupCreateCctv((struct cctvobj *)obj, index);
|
||||
}
|
||||
break;
|
||||
case OBJTYPE_AUTOGUN:
|
||||
if (withobjs && (obj->flags2 & diffflag) == 0) {
|
||||
setupCreateAutogun((struct autogunobj *)obj, index);
|
||||
|
||||
@@ -262,6 +262,8 @@ extern struct linksceneryobj *g_LinkedScenery;
|
||||
extern struct blockedpathobj *g_BlockedPaths;
|
||||
extern struct prop *g_EmbedProp;
|
||||
extern s32 g_EmbedHitPart;
|
||||
extern f32 g_CctvWaitScale;
|
||||
extern f32 g_CctvDamageRxScale;
|
||||
extern f32 g_AutogunAccuracyScale;
|
||||
extern f32 g_AutogunDamageTxScale;
|
||||
extern f32 g_AutogunDamageRxScale;
|
||||
|
||||
Reference in New Issue
Block a user