Files
perfect_dark/src/game/bondbike.c
T
fgsfds 600dae58e2 port: allow using N64 control schemes
change from Ext to another control scheme to activate

note that this will require rebinding keys, as the default config is for the Ext scheme
2023-11-26 18:07:35 +01:00

1033 lines
29 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "game/bondbike.h"
#include "game/bondmove.h"
#include "game/camera.h"
#include "game/chraction.h"
#include "game/prop.h"
#include "game/setuputils.h"
#include "game/propsnd.h"
#include "game/objectives.h"
#include "game/quaternion.h"
#include "game/bondgun.h"
#include "game/tex.h"
#include "game/player.h"
#include "game/bondhead.h"
#include "game/lv.h"
#include "game/objectives.h"
#include "game/options.h"
#include "game/propobj.h"
#include "bss.h"
#include "lib/mtx.h"
#include "lib/anim.h"
#include "lib/collision.h"
#include "lib/joy.h"
#include "data.h"
#include "types.h"
void bbikeInit(void)
{
struct hoverbikeobj *hoverbike = (struct hoverbikeobj *)g_Vars.currentplayer->hoverbike->obj;
Mtxf matrix;
g_Vars.currentplayer->bondmovemode = MOVEMODE_BIKE;
g_Vars.currentplayer->bondvehiclemode = 0;
g_Vars.currentplayer->guncloseroffset = 0;
g_Vars.currentplayer->gunextraaimx = 0;
g_Vars.currentplayer->gunextraaimy = 0;
bbikeUpdateVehicleOffset();
g_Vars.currentplayer->bondentert = 0;
g_Vars.currentplayer->bondentert2 = 1;
g_Vars.currentplayer->bondenterpos.x = g_Vars.currentplayer->prop->pos.x;
g_Vars.currentplayer->bondenterpos.y = g_Vars.currentplayer->prop->pos.y;
g_Vars.currentplayer->bondenterpos.z = g_Vars.currentplayer->prop->pos.z;
mtx3ToMtx4(hoverbike->base.realrot, &matrix);
mtx4SetTranslation(&hoverbike->base.prop->pos, &matrix);
mtx4TransformVec(&matrix, &g_Vars.currentplayer->bondvehicleoffset, &g_Vars.currentplayer->bondenteraim);
mtx00016b58(&g_Vars.currentplayer->bondentermtx,
0, 0, 0,
-g_Vars.currentplayer->bond2.unk1c.x, -g_Vars.currentplayer->bond2.unk1c.y, -g_Vars.currentplayer->bond2.unk1c.z,
g_Vars.currentplayer->bond2.unk28.x, g_Vars.currentplayer->bond2.unk28.y, g_Vars.currentplayer->bond2.unk28.z);
g_Vars.currentplayer->speedtheta = 0;
g_Vars.currentplayer->speedthetacontrol = 0;
g_Vars.currentplayer->speedforwards = 0;
g_Vars.currentplayer->speedsideways = 0;
if (hoverbike->base.hidden & OBJHFLAG_PROJECTILE) {
struct projectile *projectile = hoverbike->base.projectile;
hoverbike->speed[0] = projectile->speed.x;
hoverbike->speed[1] = projectile->speed.z;
hoverbike->w = projectile->unk0dc;
}
objFreeEmbedmentOrProjectile(g_Vars.currentplayer->hoverbike);
hoverbike->base.hidden |= OBJHFLAG_MOUNTED;
}
void bbikeExit(void)
{
struct defaultobj *obj = g_Vars.currentplayer->hoverbike->obj;
struct hoverbikeobj *bikeobj = (struct hoverbikeobj *)g_Vars.currentplayer->hoverbike->obj;
struct coord speed;
f32 rotation;
obj->hidden &= ~OBJHFLAG_MOUNTED;
speed.x = bikeobj->speed[0];
speed.y = 0;
speed.z = bikeobj->speed[1];
rotation = bikeobj->w;
objApplyMomentum(obj, &speed, rotation, false, false);
psStopSound(g_Vars.currentplayer->hoverbike, PSTYPE_GENERAL, 0xffff);
psStopSound(g_Vars.currentplayer->prop, PSTYPE_GENERAL, 0xffff);
psCreate(NULL, g_Vars.currentplayer->hoverbike, SFX_BIKE_PULSE, -1,
-1, 0, 0, PSTYPE_NONE, 0, -1, 0, -1, -1, -1, -1);
obj->flags |= OBJFLAG_HOVERBIKE_MOVINGWHILEEMPTY;
}
void bbikeUpdateVehicleOffset(void)
{
struct defaultobj *hoverbike = g_Vars.currentplayer->hoverbike->obj;
g_Vars.currentplayer->bondvehicleoffset.x = 0.0f / hoverbike->model->scale;
g_Vars.currentplayer->bondvehicleoffset.y = 80.0f / hoverbike->model->scale;
g_Vars.currentplayer->bondvehicleoffset.z = -50.0f / hoverbike->model->scale;
}
void bbikeTryDismountAngle(f32 relativeangle, f32 distance)
{
u32 stack;
struct hoverbikeobj *bike;
f32 angle;
struct coord pos;
RoomNum rooms[8];
s32 result;
f32 ymax;
f32 ymin;
f32 radius;
if (g_Vars.currentplayer->walkinitmove == 0) {
bike = (struct hoverbikeobj *)g_Vars.currentplayer->hoverbike->obj;
angle = hoverpropGetTurnAngle(&bike->base);
playerGetBbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin);
distance += radius + 10;
angle += relativeangle;
if (angle >= M_BADTAU) {
angle -= M_BADTAU;
}
pos.x = g_Vars.currentplayer->hoverbike->pos.x + sinf(angle) * distance;
pos.y = g_Vars.currentplayer->hoverbike->pos.y;
pos.z = g_Vars.currentplayer->hoverbike->pos.z + cosf(angle) * distance;
propSetPerimEnabled(g_Vars.currentplayer->hoverbike, false);
propSetPerimEnabled(g_Vars.currentplayer->prop, false);
func0f065e74(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &pos, rooms);
bmoveFindEnteredRoomsByPos(g_Vars.currentplayer, &pos, rooms);
result = cdTestCylMove02(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms,
&pos, rooms, CDTYPE_ALL, true,
ymax - g_Vars.currentplayer->prop->pos.y,
ymin - g_Vars.currentplayer->prop->pos.y);
propSetPerimEnabled(g_Vars.currentplayer->hoverbike, true);
if (result == CDRESULT_NOCOLLISION) {
result = cdTestVolume(&pos, radius, rooms, CDTYPE_ALL, CHECKVERTICAL_YES,
ymax - g_Vars.currentplayer->prop->pos.y,
ymin - g_Vars.currentplayer->prop->pos.y);
}
if (result == CDRESULT_NOCOLLISION) {
g_Vars.currentplayer->walkinitmove = true;
g_Vars.currentplayer->walkinitpos.x = pos.x;
g_Vars.currentplayer->walkinitpos.y = pos.y;
g_Vars.currentplayer->walkinitpos.z = pos.z;
g_Vars.currentplayer->moveinitspeed.x = bike->speed[0];
g_Vars.currentplayer->moveinitspeed.y = 0;
g_Vars.currentplayer->moveinitspeed.z = bike->speed[1];
}
propSetPerimEnabled(g_Vars.currentplayer->prop, true);
}
}
void bbikeHandleActivate(void)
{
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_RUNNING
&& g_Vars.lvframe60 - g_Vars.currentplayer->activatetimelast < TICKS(25)) {
struct hoverbikeobj *bike = (struct hoverbikeobj *)g_Vars.currentplayer->hoverbike->obj;
struct modelrodata_bbox *bbox = objFindBboxRodata(&bike->base);
f32 sidedist = bbox->xmax * bike->base.model->scale;
f32 frontdist = bbox->zmax * bike->base.model->scale;
f32 diagdist = sqrtf(sidedist * sidedist + frontdist * frontdist);
g_Vars.currentplayer->walkinitmove = false;
bbikeTryDismountAngle(1.5705462694168f, sidedist); // 90 - left
bbikeTryDismountAngle(4.7116389274597f, sidedist); // 270 - right
bbikeTryDismountAngle(0.7852731347084f, diagdist); // 45 - front left
bbikeTryDismountAngle(5.4969120025635f, diagdist); // 315 - front right
bbikeTryDismountAngle(2.3558194637299f, diagdist); // 135 - back left
bbikeTryDismountAngle(3.9263656139374f, diagdist); // 225 - back right
bbikeTryDismountAngle(0, frontdist); // 0 - front
bbikeTryDismountAngle(3.1410925388336f, frontdist); // 180 - back
if (g_Vars.currentplayer->walkinitmove) {
bmoveSetMode(MOVEMODE_WALK);
}
g_Vars.currentplayer->bondactivateorreload = 0;
}
}
void bbikeApplyMoveData(struct movedata *data)
{
struct hoverbikeobj *bike = (struct hoverbikeobj *)g_Vars.currentplayer->hoverbike->obj;
s8 contnum = optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex);
f32 value1;
f32 tmp;
s32 contmode = optionsGetControlMode(g_Vars.currentplayerstats->mpindex);
if ((contmode == CONTROLMODE_12
|| contmode == CONTROLMODE_14
|| contmode == CONTROLMODE_13
|| contmode == CONTROLMODE_11
|| contmode == CONTROLMODE_PC)
&& !lvIsPaused()) {
u32 lmask, rmask;
if (contmode == CONTROLMODE_PC) {
lmask = L_CBUTTONS;
rmask = R_CBUTTONS;
} else {
lmask = L_JPAD | L_CBUTTONS;
rmask = R_JPAD | R_CBUTTONS;
}
data->digitalstepleft = joyCountButtonsOnSpecificSamples(0, contnum, lmask);
data->digitalstepright = joyCountButtonsOnSpecificSamples(0, contnum, rmask);
}
// Forward/back
if (data->digitalstepforward) {
value1 = 1.0f - g_Vars.currentplayer->speedforwards;
if (value1 > 0.1f * g_Vars.lvupdate60freal) {
value1 = 0.1f * g_Vars.lvupdate60freal;
}
g_Vars.currentplayer->speedforwards += value1;
} else if (data->digitalstepback) {
value1 = -1.0f - g_Vars.currentplayer->speedforwards;
if (value1 < -0.1f * g_Vars.lvupdate60freal) {
value1 = -0.1f * g_Vars.lvupdate60freal;
}
g_Vars.currentplayer->speedforwards += value1;
} else if (data->canlookahead) {
g_Vars.currentplayer->speedforwards = data->analogwalk / 70.0f;
if (g_Vars.currentplayer->speedforwards > 1.0f) {
g_Vars.currentplayer->speedforwards = 1.0f;
} else if (g_Vars.currentplayer->speedforwards < -1.0f) {
g_Vars.currentplayer->speedforwards = -1.0f;
}
} else {
g_Vars.currentplayer->speedforwards = 0;
}
// Sideways
if (data->digitalstepleft) {
f32 value2 = -1.0f - g_Vars.currentplayer->speedsideways;
f32 tmp = data->digitalstepleft * PALUPF(-0.1f);
if (value2 < tmp) {
value2 = tmp;
}
g_Vars.currentplayer->speedsideways += value2;
} else if (data->digitalstepright) {
f32 value2 = 1.0f - g_Vars.currentplayer->speedsideways;
f32 tmp = data->digitalstepright * PALUPF(0.1f);
if (value2 > tmp) {
value2 = tmp;
}
g_Vars.currentplayer->speedsideways += value2;
} else if (data->unk14) {
g_Vars.currentplayer->speedsideways = data->analogstrafe / 70.0f;
if (g_Vars.currentplayer->speedsideways > 1.0f) {
g_Vars.currentplayer->speedsideways = 1.0f;
}
if (g_Vars.currentplayer->speedsideways < -1.0f) {
g_Vars.currentplayer->speedsideways = -1.0f;
}
} else {
g_Vars.currentplayer->speedsideways = 0;
}
{
f32 sp3c;
struct coord sp30;
f32 sp28[2];
sp3c = -bike->exreal;
if (bike->hov.bobpitchcur < M_PI) {
sp3c += -bike->hov.bobpitchcur * 0.8f;
} else {
sp3c += (M_BADTAU - bike->hov.bobpitchcur) * 0.8f;
}
if (sp3c < 0) {
sp3c += M_BADTAU;
} else if (sp3c >= M_BADTAU) {
sp3c -= M_BADTAU;
}
sp30.f[0] = 0;
sp30.f[1] = -sinf(sp3c);
sp30.f[2] = cosf(sp3c);
cam0f0b4d04(&sp30, sp28);
g_Vars.currentplayer->gunextraaimy = -((sp28[1] - camGetScreenTop()) * 2.0f / camGetScreenHeight() - 1.0f) * 0.75f;
}
}
void bbike0f0d2b40(struct defaultobj *bike, struct coord *arg1, f32 arg2, struct defaultobj *obstacle)
{
struct coord sp9c;
struct coord sp90;
struct coord sp84 = {0, 0, 0};
struct coord sp78;
struct coord sp6c;
struct coord sp60;
struct coord sp54;
cdGetEdge(&sp78, &sp6c, 333, "bondbike.c");
sp60.x = bike->prop->pos.x;
sp60.y = bike->prop->pos.y;
sp60.z = bike->prop->pos.z;
sp54.x = obstacle->prop->pos.x - bike->prop->pos.x;
sp54.y = obstacle->prop->pos.y - bike->prop->pos.y;
sp54.z = obstacle->prop->pos.z - bike->prop->pos.z;
func0f02e3dc(&sp78, &sp6c, &sp60, &sp54, &sp9c);
sp90.x = arg1->f[0];
sp90.y = 0;
sp90.z = arg1->f[2];
if (sp90.f[0] || sp90.f[2]) {
guNormalize(&sp90.x, &sp90.y, &sp90.z);
} else {
sp90.z = 1;
}
if (arg1->x) {
sp84.x += arg1->x / g_Vars.lvupdate60freal;
}
if (arg1->z) {
sp84.z += arg1->z / g_Vars.lvupdate60freal;
}
func0f082e84(obstacle, &sp9c, &sp90, &sp84, false);
if (arg2) {
f32 xdiff = sp9c.x - bike->prop->pos.x;
f32 zdiff = sp9c.z - bike->prop->pos.z;
f32 rotation = 0;
struct coord speed = {0, 0, 0};
f32 tmp = 1 / sqrtf(xdiff * xdiff + zdiff * zdiff);
xdiff *= tmp;
zdiff *= tmp;
arg2 = arg2 / g_Vars.lvupdate60freal;
speed.x += -zdiff * arg2 * 40;
speed.z += xdiff * arg2 * 40;
rotation += arg2 * 0.1f;
objApplyMomentum(obstacle, &speed, rotation, true, true);
}
}
s32 bbikeCalculateNewPosition(struct coord *vel, f32 angledelta)
{
s32 result = CDRESULT_NOCOLLISION;
struct coord dstpos;
RoomNum dstrooms[8];
struct hov hov;
bool hasvel = false;
struct hoverbikeobj *bike = (struct hoverbikeobj *) g_Vars.currentplayer->hoverbike->obj;
RoomNum spa8[20];
f32 xdiff;
f32 zdiff;
f32 ymax;
f32 ymin;
f32 radius;
f32 halfradius;
dstpos.x = g_Vars.currentplayer->hoverbike->pos.x;
dstpos.y = g_Vars.currentplayer->hoverbike->pos.y;
dstpos.z = g_Vars.currentplayer->hoverbike->pos.z;
if (vel->x || vel->y || vel->z) {
propSetPerimEnabled(g_Vars.currentplayer->prop, false);
propSetPerimEnabled(g_Vars.currentplayer->hoverbike, false);
dstpos.x += vel->x;
dstpos.z += vel->z;
objGetBbox(g_Vars.currentplayer->hoverbike, &radius, &ymax, &ymin);
func0f065dfc(&g_Vars.currentplayer->hoverbike->pos,
g_Vars.currentplayer->hoverbike->rooms,
&dstpos, dstrooms, spa8, 20);
setup0f09233c(&bike->base, &dstpos, bike->base.realrot, dstrooms);
hasvel = true;
hov = bike->hov;
hovUpdateGround(&bike->base, &hov, &dstpos, dstrooms, bike->base.realrot);
dstpos.y += hov.ground - bike->hov.ground;
halfradius = radius * 0.5f;
xdiff = dstpos.x - g_Vars.currentplayer->hoverbike->pos.x;
zdiff = dstpos.z - g_Vars.currentplayer->hoverbike->pos.z;
if (xdiff > halfradius || zdiff > halfradius || xdiff < -halfradius || zdiff < -halfradius) {
result = cdExamCylMove06(&g_Vars.currentplayer->hoverbike->pos,
g_Vars.currentplayer->hoverbike->rooms,
&dstpos, dstrooms, radius, CDTYPE_ALL, 1,
ymax - g_Vars.currentplayer->hoverbike->pos.y,
ymin - g_Vars.currentplayer->hoverbike->pos.y);
if (result == CDRESULT_NOCOLLISION) {
result = cdExamCylMove02(&g_Vars.currentplayer->hoverbike->pos,
&dstpos, radius, dstrooms, CDTYPE_ALL, true,
ymax - g_Vars.currentplayer->hoverbike->pos.y,
ymin - g_Vars.currentplayer->hoverbike->pos.y);
}
} else {
result = cdExamCylMove02(&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);
}
propSetPerimEnabled(g_Vars.currentplayer->prop, true);
propSetPerimEnabled(g_Vars.currentplayer->hoverbike, true);
}
if (angledelta) {
u32 stack[2];
f32 newangle = hoverpropGetTurnAngle(&bike->base) - angledelta;
Mtxf sp44;
if (newangle >= M_BADTAU) {
newangle -= M_BADTAU;
} else if (newangle < 0.0f) {
newangle += M_BADTAU;
}
hoverpropSetTurnAngle(&bike->base, newangle);
mtx4LoadYRotation(newangle, &sp44);
mtx00015f04(bike->base.model->scale, &sp44);
mtx4ToMtx3(&sp44, bike->base.realrot);
}
if (result == CDRESULT_NOCOLLISION && hasvel) {
g_Vars.currentplayer->hoverbike->pos.x = dstpos.x;
g_Vars.currentplayer->hoverbike->pos.z = dstpos.z;
propDeregisterRooms(g_Vars.currentplayer->hoverbike);
roomsCopy(dstrooms, g_Vars.currentplayer->hoverbike->rooms);
bike->hov = hov;
}
return result;
}
s32 bbikeCalculateNewPositionWithPush(struct coord *arg0, f32 arg1)
{
s32 result = bbikeCalculateNewPosition(arg0, arg1);
if (result != CDRESULT_NOCOLLISION) {
struct prop *obstacle = cdGetObstacleProp();
if (obstacle && g_Vars.lvupdate240 > 0) {
if (obstacle->type == PROPTYPE_CHR) {
// empty
} else if (obstacle->type == PROPTYPE_PLAYER) {
// empty
} else if (obstacle->type == PROPTYPE_OBJ) {
struct defaultobj *obj = obstacle->obj;
if ((obj->hidden & OBJHFLAG_MOUNTED) == 0
&& (obj->hidden & OBJHFLAG_GRABBED) == 0
&& (obj->flags3 & OBJFLAG3_PUSHABLE)) {
bool pass = true;
struct defaultobj *bike = g_Vars.currentplayer->hoverbike->obj;
if ((obj->hidden & OBJHFLAG_PROJECTILE)
&& (obj->projectile->flags & PROJECTILEFLAG_00001000)) {
pass = false;
}
if (pass) {
bbike0f0d2b40(bike, arg0, arg1, obj);
if ((obj->hidden & OBJHFLAG_PROJECTILE)
&& (obj->projectile->flags & PROJECTILEFLAG_SLIDING)) {
s32 somevalue;
bool embedded = false;
somevalue = projectileTick(obj, &embedded);
if (obj->hidden & OBJHFLAG_PROJECTILE) {
obj->projectile->flags |= PROJECTILEFLAG_00001000;
if (somevalue) {
obj->projectile->flags |= PROJECTILEFLAG_00002000;
} else {
obj->projectile->flags &= ~PROJECTILEFLAG_00002000;
}
}
if (somevalue) {
result = bbikeCalculateNewPosition(arg0, arg1);
}
}
}
}
}
}
}
return result;
}
void bbikeUpdateVertical(struct coord *pos)
{
struct defaultobj *bike = g_Vars.currentplayer->hoverbike->obj;
f32 angle;
RoomNum newrooms[8];
bool newinlift;
struct prop *lift = NULL;
f32 ground;
angle = hoverpropGetTurnAngle(bike);
func0f065e74(&bike->prop->pos, bike->prop->rooms, pos, newrooms);
#if VERSION < VERSION_NTSC_1_0
{
s32 i;
for (i = 0; newrooms[i] != -1; i++) {
if (g_Vars.currentplayer->floorroom == newrooms[i]) {
newrooms[0] = g_Vars.currentplayer->floorroom;
newrooms[1] = -1;
break;
}
}
}
#endif
bmoveFindEnteredRoomsByPos(g_Vars.currentplayer, pos, newrooms);
propDeregisterRooms(g_Vars.currentplayer->prop);
roomsCopy(newrooms, g_Vars.currentplayer->prop->rooms);
g_Vars.currentplayer->vv_theta = (M_BADTAU - angle) * 360.0f / M_BADTAU;
g_Vars.currentplayer->prop->pos.x = pos->x;
g_Vars.currentplayer->prop->pos.y = pos->y;
g_Vars.currentplayer->prop->pos.z = pos->z;
ground = cdFindGroundInfoAtCyl(&g_Vars.currentplayer->prop->pos,
g_Vars.currentplayer->bond2.radius,
g_Vars.currentplayer->prop->rooms,
&g_Vars.currentplayer->floorcol,
&g_Vars.currentplayer->floortype,
&g_Vars.currentplayer->floorflags,
&g_Vars.currentplayer->floorroom,
&newinlift, &lift);
if (ground < -30000) {
ground = -30000;
}
if (g_Vars.currentplayer->inlift && newinlift) {
f32 diff = ground - g_Vars.currentplayer->vv_ground;
// If getting on the bike
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_OFF) {
g_Vars.currentplayer->bondenterpos.y += diff;
}
} else {
lift = NULL;
}
g_Vars.currentplayer->inlift = newinlift;
if (newinlift) {
g_Vars.currentplayer->liftground = ground;
}
g_Vars.currentplayer->lift = lift;
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;
g_Vars.currentplayer->vv_manground = g_Vars.currentplayer->prop->pos.y - g_Vars.currentplayer->vv_height;
if (g_Vars.currentplayer->floorflags & GEOFLAG_DIE) {
playerDie(true);
}
bmoveUpdateVerta();
}
s32 bbike0f0d363c(f32 arg0)
{
struct coord coord = {0, 0, 0};
return bbikeCalculateNewPositionWithPush(&coord, arg0);
}
s32 bbike0f0d3680(struct coord *arg0, struct coord *arg1, struct coord *arg2)
{
s32 result = bbikeCalculateNewPositionWithPush(arg0, 0);
if (!result) {
#if VERSION >= VERSION_NTSC_1_0
cdGetEdge(arg1, arg2, 659, "bondbike.c");
#else
cdGetEdge(arg1, arg2, 656, "bondbike.c");
#endif
}
return result;
}
s32 bbike0f0d36d4(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct coord *arg3, struct coord *arg4)
{
if (cd00024ea4()) {
struct coord sp24;
f32 somefloat = cd00024e98();
s32 someint;
sp24.x = arg0->x * somefloat * 0.25f;
sp24.y = arg0->y * somefloat * 0.25f;
sp24.z = arg0->z * somefloat * 0.25f;
someint = bbikeCalculateNewPositionWithPush(&sp24, 0);
if (someint == 1) {
return 1;
}
if (someint == 0) {
#if VERSION >= VERSION_NTSC_1_0
cdGetEdge(arg3, arg4, 685, "bondbike.c");
#else
cdGetEdge(arg3, arg4, 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;
}
}
}
return -1;
}
s32 bbike0f0d3840(struct coord *arg0, struct coord *arg1, struct coord *arg2)
{
s32 result;
if (arg1->f[0] != arg2->f[0] || arg1->f[2] != arg2->f[2]) {
struct coord sp30;
struct coord sp24;
f32 tmp;
sp30.x = arg2->x - arg1->x;
sp30.z = arg2->z - arg1->z;
tmp = sqrtf(sp30.f[0] * sp30.f[0] + sp30.f[2] * sp30.f[2]);
sp30.x *= 1.0f / tmp;
sp30.z *= 1.0f / tmp;
tmp = arg0->f[0] * sp30.f[0] + arg0->f[2] * sp30.f[2];
sp24.x = sp30.x * tmp;
sp24.y = 0;
sp24.z = sp30.z * tmp;
result = bbikeCalculateNewPositionWithPush(&sp24, 0);
} else {
result = -1;
}
return result;
}
s32 bbike0f0d3940(struct coord *arg0, struct coord *arg1, struct coord *arg2)
{
struct coord sp34;
struct coord sp28;
f32 ymax;
f32 ymin;
f32 tmp;
f32 radius;
objGetBbox(g_Vars.currentplayer->hoverbike, &radius, &ymax, &ymin);
sp34.x = arg1->x - (g_Vars.currentplayer->hoverbike->pos.x + arg0->f[0]);
sp34.z = arg1->z - (g_Vars.currentplayer->hoverbike->pos.z + arg0->f[2]);
if (sp34.f[0] * sp34.f[0] + sp34.f[2] * sp34.f[2] <= radius * radius) {
if (arg1->f[0] != g_Vars.currentplayer->hoverbike->pos.f[0] || arg1->f[2] != g_Vars.currentplayer->hoverbike->pos.f[2]) {
sp34.x = -(arg1->z - g_Vars.currentplayer->hoverbike->pos.z);
sp34.y = 0;
sp34.z = arg1->x - g_Vars.currentplayer->hoverbike->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];
sp34.x = sp34.x * tmp;
sp34.z = sp34.z * tmp;
sp28.x = sp34.x;
sp28.y = 0;
sp28.z = sp34.z;
if (bbikeCalculateNewPositionWithPush(&sp28, 0) == CDRESULT_NOCOLLISION) {
return true;
}
}
} else {
sp34.x = arg2->x - (g_Vars.currentplayer->hoverbike->pos.x + arg0->f[0]);
sp34.z = arg2->z - (g_Vars.currentplayer->hoverbike->pos.z + arg0->f[2]);
if (sp34.f[0] * sp34.f[0] + sp34.f[2] * sp34.f[2] <= radius * radius) {
if (arg2->f[0] != g_Vars.currentplayer->hoverbike->pos.f[0] || arg2->f[2] != g_Vars.currentplayer->hoverbike->pos.f[2]) {
sp34.x = -(arg2->z - g_Vars.currentplayer->hoverbike->pos.z);
sp34.y = 0;
sp34.z = arg2->x - g_Vars.currentplayer->hoverbike->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];
sp34.x = sp34.x * tmp;
sp34.z = sp34.z * tmp;
sp28.x = sp34.x;
sp28.y = 0;
sp28.z = sp34.z;
if (bbikeCalculateNewPositionWithPush(&sp28, 0) == CDRESULT_NOCOLLISION) {
return true;
}
}
}
}
return false;
}
void bbike0f0d3c60(struct coord *arg0)
{
struct coord sp64;
struct coord sp58;
struct coord sp4c;
struct coord sp40;
s32 value;
struct coord sp30;
struct coord sp24;
if (bbike0f0d3680(arg0, &sp64, &sp58) == 0) {
value = bbike0f0d36d4(arg0, &sp64, &sp58, &sp4c, &sp40);
if (value > 0 || value < 0) {
if (bbike0f0d3840(arg0, &sp64, &sp58) <= 0
&& bbike0f0d3940(arg0, &sp64, &sp58) <= 0) {
// empty
}
} else if (value == 0) {
bbike0f0d36d4(arg0, &sp4c, &sp40, &sp30, &sp24);
if (bbike0f0d3840(arg0, &sp4c, &sp40) <= 0
&& bbike0f0d3840(arg0, &sp64, &sp58) <= 0
&& bbike0f0d3940(arg0, &sp4c, &sp40) <= 0
&& bbike0f0d3940(arg0, &sp64, &sp58) <= 0) {
if (&arg0);
}
}
}
}
void bbikeTick(void)
{
struct defaultobj *obj = g_Vars.currentplayer->hoverbike->obj;
struct hoverbikeobj *bike = (struct hoverbikeobj *) g_Vars.currentplayer->hoverbike->obj;
struct coord sp20c;
struct prop *prop;
s32 i;
f32 sp200;
u32 stack;
f32 sp1f8;
f32 sp1f4;
struct coord sp1e8;
Mtxf sp1a8;
#if VERSION >= VERSION_NTSC_1_0
s32 j;
#endif
Mtxf sp164;
Mtxf sp124;
Mtxf spe4;
f32 spd4[4];
f32 spc4[4];
f32 spb4[4];
f32 spa4[4];
f32 sp94[4];
f32 sp84[4];
struct coord pos;
f32 breathing;
f32 sp70;
f32 sqdist;
static f32 var80070f04 = 0;
if (g_Vars.lvupdate240 > 0) {
g_Vars.currentplayer->bondprevpos.x = g_Vars.currentplayer->prop->pos.x;
g_Vars.currentplayer->bondprevpos.y = g_Vars.currentplayer->prop->pos.y;
g_Vars.currentplayer->bondprevpos.z = g_Vars.currentplayer->prop->pos.z;
g_Vars.currentplayer->bondbreathing -= (0.75f * g_Vars.lvupdate60freal) / 2700.0f;
if (g_Vars.currentplayer->bondbreathing < 0.0f) {
g_Vars.currentplayer->bondbreathing = 0.0f;
}
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_OFF) {
hoverbikeUpdateMovement(bike,
g_Vars.currentplayer->speedforwards,
g_Vars.currentplayer->speedsideways,
g_Vars.currentplayer->speedtheta);
} else {
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_ENGINESTART) {
g_Vars.currentplayer->bondvehiclemode = VEHICLEMODE_RUNNING;
}
hoverbikeUpdateMovement(bike,
g_Vars.currentplayer->speedforwards,
g_Vars.currentplayer->speedsideways,
g_Vars.currentplayer->speedtheta);
}
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_RUNNING) {
sqdist = g_Vars.currentplayer->speedforwards * g_Vars.currentplayer->speedforwards
+ g_Vars.currentplayer->speedsideways * g_Vars.currentplayer->speedsideways;
if (sqdist > 1.0f) {
sqdist = 1.0f;
}
for (i = 0; i < g_Vars.lvupdate240; i++) {
var80070f04 += (sqdist - var80070f04) * (PAL ? 0.003f : 0.0025f);
}
sp200 = 1.0f - (var80070f04 + var80070f04);
if (var80070f04 + var80070f04 > 1.0f) {
sp200 = 0.0f;
}
sp200 *= 300.0f;
psSetPitch(g_Vars.currentplayer->hoverbike, var80070f04, -1);
psSetVolume(g_Vars.currentplayer->hoverbike, var80070f04 * 300.0f);
psSetVolume(g_Vars.currentplayer->prop, sp200);
}
if (1);
bbike0f0d363c(bike->w * g_Vars.lvupdate60freal);
sp20c.x = bike->speed[0] * g_Vars.lvupdate60freal;
sp20c.y = 0.0f;
sp20c.z = bike->speed[1] * g_Vars.lvupdate60freal;
bike->prevpos[0] = bike->base.prop->pos.x;
bike->prevpos[1] = bike->base.prop->pos.z;
bbike0f0d3c60(&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;
if (sp1f8 != 0.0f || sp1f4 != 0.0f) {
f32 tmp = sp1f8 * sp1f8 + sp1f4 * sp1f4;
if (tmp > 0.0f) {
tmp = sqrtf((bike->speed[0] * bike->speed[0] + bike->speed[1] * bike->speed[1]) / tmp);
if (tmp < 1.0f) {
sp1f8 *= tmp;
sp1f4 *= tmp;
}
}
}
bike->speed[0] = sp1f8;
bike->speed[1] = sp1f4;
hovTick(obj, &bike->hov);
func0f069c70(obj, true, true);
mtx3ToMtx4(obj->realrot, &sp1a8);
mtx4SetTranslation(&obj->prop->pos, &sp1a8);
mtx4TransformVec(&sp1a8, &g_Vars.currentplayer->bondvehicleoffset, &sp1e8);
bbikeUpdateVertical(&sp1e8);
prop = g_Vars.currentplayer->prop;
#if VERSION >= VERSION_NTSC_1_0
for (j = 0; prop->rooms[j] != -1; j++) {
if (prop->rooms[j] == g_Vars.currentplayer->floorroom) {
propDeregisterRooms(prop);
g_Vars.currentplayer->prop->rooms[0] = g_Vars.currentplayer->floorroom;
g_Vars.currentplayer->prop->rooms[1] = -1;
break;
}
}
#endif
}
bheadAdjustAnimation(0);
bheadUpdate(0, 0);
mtx4LoadXRotation((360.0f - g_Vars.currentplayer->vv_verta360) * 0.017450513318181f, &sp164);
mtx00016d58(&sp124, 0.0f, 0.0f, 0.0f,
-g_Vars.currentplayer->headlook.x, -g_Vars.currentplayer->headlook.y, -g_Vars.currentplayer->headlook.z,
g_Vars.currentplayer->headup.x, g_Vars.currentplayer->headup.y, g_Vars.currentplayer->headup.z);
mtx4MultMtx4InPlace(&sp124, &sp164);
mtx3ToMtx4(obj->realrot, &sp124);
mtx00015f04(1.0f / obj->model->scale, &sp124);
mtx4LoadYRotation(hoverpropGetTurnAngle(obj), &spe4);
quaternion0f097044(&spe4, spd4);
quaternion0f097044(&sp124, spc4);
quaternion0f0976c0(spc4, spd4);
quaternionSlerp(spd4, spc4, 0.8f, spb4);
quaternionToMtx(spb4, &sp124);
mtx4MultMtx4InPlace(&sp124, &sp164);
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_OFF) {
g_Vars.currentplayer->bondentert += g_Vars.lvupdate60freal / 60.0f;
if (g_Vars.currentplayer->bondentert >= 1.0f) {
g_Vars.currentplayer->bondentert = 1.0f;
}
g_Vars.currentplayer->bondentert2 = (cosf(g_Vars.currentplayer->bondentert * M_BADTAU * 0.5f) + 1.0f) * 0.5f;
if (g_Vars.currentplayer->bondentert >= 1.0f) {
g_Vars.currentplayer->bondvehiclemode = VEHICLEMODE_ENGINESTART;
psStopSound(g_Vars.currentplayer->hoverbike, PSTYPE_GENERAL, 0xffff);
psCreate(NULL, g_Vars.currentplayer->prop, SFX_BIKE_TAKEOFF, -1,
-1, 0, 0, PSTYPE_NONE, NULL, -1, NULL, -1, -1, -1, -1);
psCreate(NULL, g_Vars.currentplayer->prop, SFX_BIKE_PULSE, -1,
-1, 0, 0, PSTYPE_NONE, NULL, -1, NULL, -1, -1, -1, -1);
psCreate(NULL, g_Vars.currentplayer->hoverbike, SFX_BIKE_ENGINE, -1,
-1, 0, 0, PSTYPE_NONE, NULL, -1, NULL, -1, -1, -1, -1);
}
quaternion0f097044(&g_Vars.currentplayer->bondentermtx, spa4);
quaternion0f097044(&sp164, sp94);
quaternion0f0976c0(sp94, spa4);
quaternionSlerp(spa4, sp94, 1.0f - g_Vars.currentplayer->bondentert2, sp84);
quaternionToMtx(sp84, &sp164);
}
g_Vars.currentplayer->bond2.unk1c.x = sp164.m[2][0];
g_Vars.currentplayer->bond2.unk1c.y = sp164.m[2][1];
g_Vars.currentplayer->bond2.unk1c.z = sp164.m[2][2];
g_Vars.currentplayer->bond2.unk28.x = sp164.m[1][0];
g_Vars.currentplayer->bond2.unk28.y = sp164.m[1][1];
g_Vars.currentplayer->bond2.unk28.z = sp164.m[1][2];
if (g_Vars.currentplayer->bondvehiclemode == VEHICLEMODE_OFF) {
pos.x = (g_Vars.currentplayer->bondenterpos.x - g_Vars.currentplayer->bondenteraim.x) * g_Vars.currentplayer->bondentert2 + g_Vars.currentplayer->prop->pos.x;
pos.y = (g_Vars.currentplayer->bondenterpos.y - g_Vars.currentplayer->prop->pos.y) * g_Vars.currentplayer->bondentert2 + g_Vars.currentplayer->prop->pos.y;
pos.z = (g_Vars.currentplayer->bondenterpos.z - g_Vars.currentplayer->bondenteraim.z) * g_Vars.currentplayer->bondentert2 + g_Vars.currentplayer->prop->pos.z;
bmove0f0cc19c(&pos);
} else {
bmove0f0cc19c(&g_Vars.currentplayer->prop->pos);
}
sp70 = g_Vars.currentplayer->speedverta / 0.7f;
breathing = bheadGetBreathingValue();
if (sp70 > 1.0f) {
sp70 = 1.0f;
} else if (sp70 < -1.0f) {
sp70 = -1.0f;
}
bgun0f09d8dc(breathing, 0, sp70, 0.0f, g_Vars.currentplayer->speedsideways);
bgunSetAdjustPos(g_Vars.currentplayer->vv_verta360 * 0.017450513318181f);
playerUpdatePerimInfo();
bmoveUpdateRooms(g_Vars.currentplayer);
objectiveCheckRoomEntered(g_Vars.currentplayer->prop->rooms[0]);
doorsCheckAutomatic();
}