mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-08-18 13:13:11 -04:00
1783 lines
52 KiB
C
1783 lines
52 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/bondmove.h"
|
|
#include "game/bondwalk.h"
|
|
#include "game/cheats.h"
|
|
#include "game/chraction.h"
|
|
#include "game/debug.h"
|
|
#include "game/game_006900.h"
|
|
#include "game/chr.h"
|
|
#include "game/prop.h"
|
|
#include "game/propsnd.h"
|
|
#include "game/objectives.h"
|
|
#include "game/bondgun.h"
|
|
#include "game/player.h"
|
|
#include "game/inv.h"
|
|
#include "game/bondhead.h"
|
|
#include "game/playermgr.h"
|
|
#include "game/propobj.h"
|
|
#include "bss.h"
|
|
#include "lib/snd.h"
|
|
#include "lib/rng.h"
|
|
#include "lib/mtx.h"
|
|
#include "lib/anim.h"
|
|
#include "lib/collision.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
void bwalkInit(void)
|
|
{
|
|
u32 prevmode = g_Vars.currentplayer->bondmovemode;
|
|
s32 i;
|
|
|
|
g_Vars.currentplayer->bondmovemode = MOVEMODE_WALK;
|
|
g_Vars.currentplayer->bondonground = 0;
|
|
g_Vars.currentplayer->tank = NULL;
|
|
g_Vars.currentplayer->unk1af0 = NULL;
|
|
g_Vars.currentplayer->bondonturret = false;
|
|
|
|
g_Vars.currentplayer->swaypos = 0;
|
|
g_Vars.currentplayer->swayoffset = 0;
|
|
g_Vars.currentplayer->swaytarget = 0;
|
|
g_Vars.currentplayer->swayoffset0 = 0;
|
|
g_Vars.currentplayer->swayoffset2 = 0;
|
|
|
|
g_Vars.currentplayer->bdeltapos.x = 0;
|
|
g_Vars.currentplayer->bdeltapos.y = -0.0001f;
|
|
g_Vars.currentplayer->bdeltapos.z = 0;
|
|
|
|
g_Vars.currentplayer->isfalling = false;
|
|
g_Vars.currentplayer->fallstart = 0;
|
|
|
|
g_Vars.currentplayer->gunextraaimx = 0;
|
|
g_Vars.currentplayer->gunextraaimy = 0;
|
|
|
|
g_Vars.currentplayer->bondforcespeed.x = 0;
|
|
g_Vars.currentplayer->bondforcespeed.y = 0;
|
|
g_Vars.currentplayer->bondforcespeed.z = 0;
|
|
|
|
if (prevmode != MOVEMODE_WALK && prevmode != MOVEMODE_CUTSCENE) {
|
|
g_Vars.currentplayer->sumcrouch = 0;
|
|
g_Vars.currentplayer->crouchheight = 0;
|
|
g_Vars.currentplayer->crouchtime240 = 0;
|
|
g_Vars.currentplayer->crouchfall = 0;
|
|
g_Vars.currentplayer->crouchpos = CROUCHPOS_STAND;
|
|
g_Vars.currentplayer->autocrouchpos = CROUCHPOS_STAND;
|
|
g_Vars.currentplayer->crouchspeed = 0;
|
|
g_Vars.currentplayer->crouchoffset = 0;
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
bwalkUpdateCrouchOffsetReal();
|
|
#endif
|
|
|
|
g_Vars.currentplayer->guncloseroffset = 0;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
bwalkUpdateCrouchOffsetReal();
|
|
#endif
|
|
|
|
if (prevmode != MOVEMODE_GRAB && prevmode != MOVEMODE_WALK) {
|
|
for (i = 0; i != 3; i++) {
|
|
g_Vars.currentplayer->bondshotspeed.f[i] = 0;
|
|
}
|
|
|
|
g_Vars.currentplayer->speedsideways = 0;
|
|
g_Vars.currentplayer->speedstrafe = 0;
|
|
g_Vars.currentplayer->speedgo = 0;
|
|
g_Vars.currentplayer->speedboost = 1;
|
|
g_Vars.currentplayer->speedmaxtime60 = 0;
|
|
g_Vars.currentplayer->speedforwards = 0;
|
|
g_Vars.currentplayer->speedtheta = 0;
|
|
g_Vars.currentplayer->speedthetacontrol = 0;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->walkinitmove) {
|
|
struct coord delta;
|
|
mtx00016b58(&g_Vars.currentplayer->walkinitmtx,
|
|
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->walkinitt = 0;
|
|
g_Vars.currentplayer->walkinitt2 = 0;
|
|
g_Vars.currentplayer->walkinitstart.x = g_Vars.currentplayer->prop->pos.x;
|
|
g_Vars.currentplayer->walkinitstart.y = g_Vars.currentplayer->prop->pos.y;
|
|
g_Vars.currentplayer->walkinitstart.z = g_Vars.currentplayer->prop->pos.z;
|
|
|
|
delta.x = g_Vars.currentplayer->walkinitpos.x - g_Vars.currentplayer->prop->pos.x;
|
|
delta.y = 0;
|
|
delta.z = g_Vars.currentplayer->walkinitpos.z - g_Vars.currentplayer->prop->pos.z;
|
|
|
|
propSetPerimEnabled(g_Vars.currentplayer->hoverbike, false);
|
|
bwalkCalculateNewPositionWithPush(&delta, 0, true, 0, CDTYPE_ALL);
|
|
propSetPerimEnabled(g_Vars.currentplayer->hoverbike, true);
|
|
} else if (prevmode != MOVEMODE_GRAB && prevmode != MOVEMODE_WALK) {
|
|
g_Vars.currentplayer->moveinitspeed.x = 0;
|
|
g_Vars.currentplayer->moveinitspeed.y = 0;
|
|
g_Vars.currentplayer->moveinitspeed.z = 0;
|
|
}
|
|
}
|
|
|
|
void bwalkSetSwayTarget(s32 value)
|
|
{
|
|
g_Vars.currentplayer->swaytarget = value * 75.0f;
|
|
}
|
|
|
|
void bwalkAdjustCrouchPos(s32 value)
|
|
{
|
|
g_Vars.currentplayer->crouchpos += value;
|
|
|
|
if (g_Vars.currentplayer->crouchpos < CROUCHPOS_SQUAT) {
|
|
g_Vars.currentplayer->crouchpos = CROUCHPOS_SQUAT;
|
|
} else if (g_Vars.currentplayer->crouchpos > CROUCHPOS_STAND) {
|
|
g_Vars.currentplayer->crouchpos = CROUCHPOS_STAND;
|
|
}
|
|
}
|
|
|
|
void bwalk0f0c3b38(struct coord *reltarget, struct defaultobj *obj)
|
|
{
|
|
struct coord posunk;
|
|
struct coord vector;
|
|
struct coord tween;
|
|
struct coord globalthinga;
|
|
struct coord globalthingb;
|
|
struct coord abstarget;
|
|
|
|
abstarget.x = reltarget->x + g_Vars.currentplayer->prop->pos.x;
|
|
abstarget.y = g_Vars.currentplayer->prop->pos.y;
|
|
abstarget.z = reltarget->z + g_Vars.currentplayer->prop->pos.z;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&globalthinga, &globalthingb, 223, "bondwalk.c");
|
|
#else
|
|
cd00024e4c(&globalthinga, &globalthingb, 221, "bondwalk.c");
|
|
#endif
|
|
|
|
vector.x = globalthingb.z - globalthinga.z;
|
|
vector.y = 0;
|
|
vector.z = globalthinga.x - globalthingb.x;
|
|
|
|
if (vector.f[0] != 0 || vector.f[2] != 0) {
|
|
guNormalize(&vector.x, &vector.y, &vector.z);
|
|
} else {
|
|
vector.z = 1;
|
|
}
|
|
|
|
func0f02e3dc(&globalthinga, &globalthingb, &abstarget, &vector, &posunk);
|
|
|
|
tween.x = (abstarget.x - g_Vars.currentplayer->prop->pos.x) / g_Vars.lvupdate240freal;
|
|
tween.y = 0;
|
|
tween.z = (abstarget.z - g_Vars.currentplayer->prop->pos.z) / g_Vars.lvupdate240freal;
|
|
|
|
func0f082e84(obj, &posunk, &vector, &tween, false);
|
|
}
|
|
|
|
/**
|
|
* Attempt to move the current player up vertically by the given amount.
|
|
*
|
|
* Collision checks are done for the new location, and if successful the
|
|
* player's positional values are updated.
|
|
*
|
|
* The function is called with amount = 0 when attempting to stand up from a
|
|
* crouch, after increasing the player's bbox to the standing size.
|
|
*/
|
|
s32 bwalkTryMoveUpwards(f32 amount)
|
|
{
|
|
bool result;
|
|
struct coord newpos;
|
|
s16 rooms[8];
|
|
u32 stack;
|
|
u32 types;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
|
|
if (g_Vars.currentplayer->floorflags & GEOFLAG_0100) {
|
|
g_Vars.enableslopes = false;
|
|
} else {
|
|
g_Vars.enableslopes = true;
|
|
}
|
|
|
|
newpos.x = g_Vars.currentplayer->prop->pos.x;
|
|
newpos.y = g_Vars.currentplayer->prop->pos.y + amount;
|
|
newpos.z = g_Vars.currentplayer->prop->pos.z;
|
|
|
|
types = g_Vars.bondcollisions ? CDTYPE_ALL : CDTYPE_BG;
|
|
|
|
playerGetBbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin);
|
|
func0f065e74(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &newpos, rooms);
|
|
bmoveFindEnteredRoomsByPos(g_Vars.currentplayer, &newpos, rooms);
|
|
propSetPerimEnabled(g_Vars.currentplayer->prop, false);
|
|
|
|
ymin -= 0.1f;
|
|
|
|
result = cdTestVolume(&newpos, radius, rooms, types, 1,
|
|
ymax - g_Vars.currentplayer->prop->pos.y,
|
|
ymin - g_Vars.currentplayer->prop->pos.y);
|
|
|
|
propSetPerimEnabled(g_Vars.currentplayer->prop, true);
|
|
|
|
if (result == CDRESULT_NOCOLLISION) {
|
|
g_Vars.currentplayer->prop->pos.y = newpos.y;
|
|
propDeregisterRooms(g_Vars.currentplayer->prop);
|
|
roomsCopy(rooms, g_Vars.currentplayer->prop->rooms);
|
|
}
|
|
|
|
g_Vars.enableslopes = true;
|
|
|
|
return result;
|
|
}
|
|
|
|
bool bwalkCalculateNewPosition(struct coord *vel, f32 rotateamount, bool apply, f32 extrawidth, s32 checktypes)
|
|
{
|
|
s32 result = CDRESULT_NOCOLLISION;
|
|
f32 halfradius;
|
|
struct coord dstpos;
|
|
s16 dstrooms[8];
|
|
bool copyrooms = false;
|
|
s16 sp64[22];
|
|
s32 types;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
s32 i;
|
|
|
|
if (g_Vars.currentplayer->floorflags & GEOFLAG_0100) {
|
|
g_Vars.enableslopes = false;
|
|
} else {
|
|
g_Vars.enableslopes = true;
|
|
}
|
|
|
|
dstpos.x = g_Vars.currentplayer->prop->pos.x;
|
|
dstpos.y = g_Vars.currentplayer->prop->pos.y;
|
|
dstpos.z = g_Vars.currentplayer->prop->pos.z;
|
|
|
|
if (vel->x || vel->y || vel->z) {
|
|
if (g_Vars.currentplayer->tank) {
|
|
propSetPerimEnabled(g_Vars.currentplayer->tank, false);
|
|
}
|
|
|
|
propSetPerimEnabled(g_Vars.currentplayer->prop, false);
|
|
|
|
dstpos.x += vel->x;
|
|
dstpos.y += vel->y;
|
|
dstpos.z += vel->z;
|
|
|
|
types = g_Vars.bondcollisions ? checktypes : CDTYPE_BG;
|
|
|
|
playerGetBbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin);
|
|
radius += extrawidth;
|
|
|
|
func0f065dfc(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms,
|
|
&dstpos, dstrooms, sp64, 20);
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
for (i = 0; dstrooms[i] != -1; i++) {
|
|
if (dstrooms[i] == g_Vars.currentplayer->floorroom) {
|
|
dstrooms[0] = g_Vars.currentplayer->floorroom;
|
|
dstrooms[1] = -1;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
bmoveFindEnteredRoomsByPos(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?
|
|
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 = cdTestAToB3(&g_Vars.currentplayer->prop->pos,
|
|
g_Vars.currentplayer->prop->rooms,
|
|
&dstpos, dstrooms, radius, types, 1,
|
|
ymax - g_Vars.currentplayer->prop->pos.y,
|
|
ymin - g_Vars.currentplayer->prop->pos.y);
|
|
|
|
if (result == CDRESULT_NOCOLLISION) {
|
|
result = cdTestAToB1(&g_Vars.currentplayer->prop->pos,
|
|
&dstpos, radius, dstrooms, types, 1,
|
|
ymax - g_Vars.currentplayer->prop->pos.y,
|
|
ymin - g_Vars.currentplayer->prop->pos.y);
|
|
}
|
|
} else {
|
|
result = cdTestAToB1(&g_Vars.currentplayer->prop->pos,
|
|
&dstpos, radius, sp64, types, 1,
|
|
ymax - g_Vars.currentplayer->prop->pos.y,
|
|
ymin - g_Vars.currentplayer->prop->pos.y);
|
|
}
|
|
|
|
propSetPerimEnabled(g_Vars.currentplayer->prop, true);
|
|
|
|
if (g_Vars.currentplayer->tank) {
|
|
propSetPerimEnabled(g_Vars.currentplayer->tank, true);
|
|
}
|
|
}
|
|
|
|
if (result == CDRESULT_NOCOLLISION && apply) {
|
|
f32 angle = g_Vars.currentplayer->vv_theta + (rotateamount * 360) / M_BADTAU;
|
|
|
|
while (angle < 0) {
|
|
angle += 360;
|
|
}
|
|
|
|
while (angle >= 360) {
|
|
angle -= 360;
|
|
}
|
|
|
|
g_Vars.currentplayer->vv_theta = angle;
|
|
|
|
g_Vars.currentplayer->prop->pos.x = dstpos.x;
|
|
g_Vars.currentplayer->prop->pos.y = dstpos.y;
|
|
g_Vars.currentplayer->prop->pos.z = dstpos.z;
|
|
|
|
if (copyrooms) {
|
|
propDeregisterRooms(g_Vars.currentplayer->prop);
|
|
roomsCopy(dstrooms, g_Vars.currentplayer->prop->rooms);
|
|
}
|
|
}
|
|
|
|
g_Vars.enableslopes = true;
|
|
|
|
return result;
|
|
}
|
|
|
|
bool bwalkCalculateNewPositionWithPush(struct coord *delta, f32 rotateamount, bool apply, f32 extrawidth, s32 types)
|
|
{
|
|
s32 result = bwalkCalculateNewPosition(delta, rotateamount, apply, extrawidth, types);
|
|
|
|
if (result != CDRESULT_NOCOLLISION) {
|
|
struct prop *obstacle = cdGetObstacle();
|
|
|
|
if (obstacle && g_Vars.lvupdate240 > 0) {
|
|
if (obstacle->type == PROPTYPE_DOOR) {
|
|
struct doorobj *door = obstacle->door;
|
|
struct coord sp90;
|
|
struct coord sp84;
|
|
struct coord sp78;
|
|
|
|
if (door->doorflags & DOORFLAG_DAMAGEONCONTACT) {
|
|
if (!g_Vars.currentplayer->isdead) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&sp84, &sp78, 465, "bondwalk.c");
|
|
#else
|
|
cd00024e4c(&sp84, &sp78, 460, "bondwalk.c");
|
|
#endif
|
|
|
|
sp90.x = sp78.f[2] - sp84.f[2];
|
|
sp90.y = 0;
|
|
sp90.z = sp84.f[0] - sp78.f[0];
|
|
|
|
if (sp90.f[0] || sp90.f[2]) {
|
|
guNormalize(&sp90.x, &sp90.y, &sp90.z);
|
|
} else {
|
|
sp90.z = 1;
|
|
}
|
|
|
|
chrDamageByLaser(g_Vars.currentplayer->prop->chr, 0.4f, &sp90, 0, g_Vars.currentplayer->prop);
|
|
|
|
// Laser zap sound
|
|
sndStart(var80095200, SFX_PICKUP_LASER, 0, -1, -1, -1, -1, -1);
|
|
}
|
|
}
|
|
} else if (obstacle->type == PROPTYPE_CHR) {
|
|
struct chrdata *chr = obstacle->chr;
|
|
struct coord newpos;
|
|
s16 newrooms[8];
|
|
f32 movingdist;
|
|
f32 xdist;
|
|
f32 zdist;
|
|
f32 disttochr;
|
|
bool canpush = false;
|
|
|
|
if (g_Vars.normmplayerisrunning) {
|
|
if (chrCompareTeams(g_Vars.currentplayer->prop->chr, chr, COMPARE_FRIENDS)) {
|
|
// AI bot on same team
|
|
canpush = true;
|
|
}
|
|
} else if (chr->chrflags & CHRCFLAG_PUSHABLE) {
|
|
if (g_Vars.antiplayernum < 0
|
|
|| g_Vars.currentplayer != g_Vars.anti
|
|
|| (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE) == 0) {
|
|
canpush = true;
|
|
}
|
|
}
|
|
|
|
if (canpush) {
|
|
movingdist = sqrtf(delta->f[0] * delta->f[0] + delta->f[2] * delta->f[2]) / LVUPDATE240FREAL();
|
|
|
|
xdist = obstacle->pos.x - g_Vars.currentplayer->prop->pos.x;
|
|
zdist = obstacle->pos.z - g_Vars.currentplayer->prop->pos.z;
|
|
|
|
if (xdist || zdist) {
|
|
disttochr = sqrtf(xdist * xdist + zdist * zdist);
|
|
|
|
if (disttochr > 0) {
|
|
disttochr = movingdist / disttochr;
|
|
|
|
xdist *= disttochr;
|
|
zdist *= disttochr;
|
|
|
|
chr->pushspeed[0] = 0.5f * xdist;
|
|
chr->pushspeed[1] = 0.5f * zdist;
|
|
|
|
newpos.x = obstacle->pos.x + chr->pushspeed[0] * LVUPDATE240FREAL();
|
|
newpos.y = obstacle->pos.y;
|
|
newpos.z = obstacle->pos.z + chr->pushspeed[1] * LVUPDATE240FREAL();
|
|
|
|
chrCalculatePushPos(chr, &newpos, newrooms, false);
|
|
|
|
obstacle->pos.x = newpos.x;
|
|
obstacle->pos.y = newpos.y;
|
|
obstacle->pos.z = newpos.z;
|
|
|
|
propDeregisterRooms(obstacle);
|
|
roomsCopy(newrooms, obstacle->rooms);
|
|
chr0f0220ac(chr);
|
|
modelSetRootPosition(chr->model, &newpos);
|
|
|
|
result = bwalkCalculateNewPosition(delta, rotateamount, apply, extrawidth, types);
|
|
}
|
|
}
|
|
}
|
|
} else if (obstacle->type == PROPTYPE_PLAYER) {
|
|
// empty
|
|
} else if (obstacle->type == PROPTYPE_OBJ) {
|
|
struct defaultobj *obj = obstacle->obj;
|
|
bool dothething;
|
|
|
|
if ((obj->hidden & OBJHFLAG_MOUNTED) == 0 && (obj->hidden & OBJHFLAG_GRABBED) == 0) {
|
|
if (g_Vars.currentplayer->unk1af0 == 0 && obj->type == OBJTYPE_TANK) {
|
|
g_Vars.currentplayer->tank = obstacle;
|
|
} else if (obj->flags3 & OBJFLAG3_PUSHABLE) {
|
|
g_Vars.currentplayer->speedmaxtime60 = 0;
|
|
dothething = true;
|
|
|
|
if ((obj->hidden & OBJHFLAG_PROJECTILE) &&
|
|
(obj->projectile->flags & PROJECTILEFLAG_00001000)) {
|
|
dothething = false;
|
|
}
|
|
|
|
if (dothething) {
|
|
bwalk0f0c3b38(delta, obj);
|
|
|
|
if (obj->hidden & OBJHFLAG_PROJECTILE && (obj->projectile->flags & PROJECTILEFLAG_SLIDING)) {
|
|
bool 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 = bwalkCalculateNewPosition(delta, rotateamount, apply, extrawidth, types);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
s32 bwalk0f0c4764(struct coord *delta, struct coord *arg1, struct coord *arg2, s32 types)
|
|
{
|
|
s32 result = bwalkCalculateNewPositionWithPush(delta, 0, true, 0, types);
|
|
|
|
if (result == CDRESULT_COLLISION) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(arg1, arg2, 607, "bondwalk.c");
|
|
#else
|
|
cd00024e4c(arg1, arg2, 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)
|
|
{
|
|
struct coord quarter;
|
|
bool result;
|
|
|
|
if (cd00024ea4()) {
|
|
f32 mult = cd00024e98();
|
|
quarter.x = a->x * mult * 0.25f;
|
|
quarter.y = a->y * mult * 0.25f;
|
|
quarter.z = a->z * mult * 0.25f;
|
|
result = bwalkCalculateNewPositionWithPush(&quarter, 0, true, 0, types);
|
|
|
|
if (result == CDRESULT_NOCOLLISION) {
|
|
return CDRESULT_NOCOLLISION;
|
|
}
|
|
|
|
if (result == CDRESULT_COLLISION) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(d, e, 635, "bondwalk.c");
|
|
#else
|
|
cd00024e4c(d, e, 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) {
|
|
return CDRESULT_COLLISION;
|
|
}
|
|
}
|
|
}
|
|
|
|
return CDRESULT_ERROR;
|
|
}
|
|
|
|
s32 bwalk0f0c494c(struct coord *a, struct coord *b, struct coord *c, s32 types)
|
|
{
|
|
if (b->f[0] != c->f[0] || b->f[2] != c->f[2]) {
|
|
f32 tmp;
|
|
struct coord sp38;
|
|
struct coord sp2c;
|
|
|
|
sp38.x = c->x - b->x;
|
|
sp38.y = 0;
|
|
sp38.z = c->z - b->z;
|
|
|
|
tmp = sqrtf(sp38.f[0] * sp38.f[0] + sp38.f[2] * sp38.f[2]);
|
|
|
|
sp38.x *= 1.0f / tmp;
|
|
sp38.z *= 1.0f / tmp;
|
|
|
|
tmp = a->f[0] * sp38.f[0] + a->f[2] * sp38.f[2];
|
|
|
|
sp2c.x = sp38.x * tmp;
|
|
sp2c.y = 0;
|
|
sp2c.z = sp38.z * tmp;
|
|
|
|
return bwalkCalculateNewPositionWithPush(&sp2c, 0, true, 0, types);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
s32 bwalk0f0c4a5c(struct coord *arg0, struct coord *arg1, struct coord *arg2, s32 types)
|
|
{
|
|
struct coord sp34;
|
|
struct coord sp28;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 tmp;
|
|
f32 radius;
|
|
|
|
playerGetBbox(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]);
|
|
|
|
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);
|
|
sp34.y = 0;
|
|
sp34.z = arg1->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];
|
|
|
|
sp34.x = sp34.x * tmp;
|
|
sp34.z = sp34.z * tmp;
|
|
|
|
sp28.x = sp34.x;
|
|
sp28.y = 0;
|
|
sp28.z = sp34.z;
|
|
|
|
if (bwalkCalculateNewPositionWithPush(&sp28, 0, true, 0, types) == CDRESULT_NOCOLLISION) {
|
|
return true;
|
|
}
|
|
}
|
|
} 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]);
|
|
|
|
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);
|
|
sp34.y = 0;
|
|
sp34.z = arg2->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];
|
|
|
|
sp34.x = sp34.x * tmp;
|
|
sp34.z = sp34.z * tmp;
|
|
|
|
sp28.x = sp34.x;
|
|
sp28.y = 0;
|
|
sp28.z = sp34.z;
|
|
|
|
if (bwalkCalculateNewPositionWithPush(&sp28, 0, true, 0, types) == CDRESULT_NOCOLLISION) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void bwalk0f0c4d98(void)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
void bwalkUpdateSpeedSideways(f32 targetspeed, f32 accelspeed, s32 mult)
|
|
{
|
|
if (g_Vars.normmplayerisrunning) {
|
|
targetspeed = (g_PlayerConfigsArray[g_Vars.currentplayerstats->mpindex].base.unk1c + 25.0f) / 100 * targetspeed;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->speedstrafe > targetspeed) {
|
|
g_Vars.currentplayer->speedstrafe -= PALUPF(accelspeed * mult);
|
|
|
|
if (g_Vars.currentplayer->speedstrafe < targetspeed) {
|
|
g_Vars.currentplayer->speedstrafe = targetspeed;
|
|
}
|
|
} else if (g_Vars.currentplayer->speedstrafe < targetspeed) {
|
|
g_Vars.currentplayer->speedstrafe += PALUPF(accelspeed * mult);
|
|
|
|
if (g_Vars.currentplayer->speedstrafe > targetspeed) {
|
|
g_Vars.currentplayer->speedstrafe = targetspeed;
|
|
}
|
|
}
|
|
|
|
g_Vars.currentplayer->speedsideways = g_Vars.currentplayer->speedstrafe;
|
|
}
|
|
|
|
void bwalkUpdateSpeedForwards(f32 targetspeed, f32 accelspeed)
|
|
{
|
|
if (g_Vars.normmplayerisrunning) {
|
|
targetspeed = (g_PlayerConfigsArray[g_Vars.currentplayerstats->mpindex].base.unk1c + 25.0f) / 100 * targetspeed;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->speedgo < targetspeed) {
|
|
g_Vars.currentplayer->speedgo += accelspeed * g_Vars.lvupdate240freal;
|
|
|
|
if (g_Vars.currentplayer->speedgo > targetspeed) {
|
|
g_Vars.currentplayer->speedgo = targetspeed;
|
|
}
|
|
} else if (g_Vars.currentplayer->speedgo > targetspeed) {
|
|
g_Vars.currentplayer->speedgo -= accelspeed * g_Vars.lvupdate240freal;
|
|
|
|
if (g_Vars.currentplayer->speedgo < targetspeed) {
|
|
g_Vars.currentplayer->speedgo = targetspeed;
|
|
}
|
|
}
|
|
|
|
g_Vars.currentplayer->speedforwards = g_Vars.currentplayer->speedgo;
|
|
}
|
|
|
|
void bwalkUpdateVertical(void)
|
|
{
|
|
s32 i;
|
|
f32 newfallspeed;
|
|
f32 radius;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 ground;
|
|
bool onladder;
|
|
bool onladder2 = false;
|
|
s16 rooms[8];
|
|
struct coord testpos;
|
|
struct coord newpos;
|
|
s16 newrooms[8];
|
|
s32 newinlift;
|
|
struct prop *lift = NULL;
|
|
f32 sumground;
|
|
f32 moveamount;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
f32 limit;
|
|
f32 amount;
|
|
struct prop *prop;
|
|
#endif
|
|
f32 newmanground;
|
|
f32 fallspeed;
|
|
f32 eyeheight;
|
|
f32 multiplier;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
struct defaultobj *obj;
|
|
#endif
|
|
|
|
playerGetBbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
// Maybe reset counter-op's radius - not sure why
|
|
// Maybe it gets set to 0 when they die?
|
|
if (g_Vars.antiplayernum >= 0
|
|
&& g_Vars.currentplayer == g_Vars.anti
|
|
&& g_Vars.currentplayer->bond2.radius != 30
|
|
&& cdTestVolume(&g_Vars.currentplayer->prop->pos, 30, g_Vars.currentplayer->prop->rooms, CDTYPE_ALL, 1, 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;
|
|
}
|
|
#endif
|
|
|
|
// Determine if player is on a ladder
|
|
// If this comes up false, a second check is done... maybe checking if the
|
|
// player is touching a ladder from a room which shares the same coordinate
|
|
// space?
|
|
onladder = cd00029ffc(&g_Vars.currentplayer->prop->pos,
|
|
radius * 1.2f, ymax - g_Vars.currentplayer->prop->pos.y,
|
|
g_Vars.currentplayer->vv_manground - g_Vars.currentplayer->prop->pos.y + 1,
|
|
g_Vars.currentplayer->prop->rooms, 0x8040, &g_Vars.currentplayer->laddernormal);
|
|
|
|
if (!onladder) {
|
|
testpos.x = g_Vars.currentplayer->prop->pos.x;
|
|
testpos.y = g_Vars.currentplayer->prop->pos.y - 10;
|
|
testpos.z = g_Vars.currentplayer->prop->pos.z;
|
|
roomsCopy(g_Vars.currentplayer->prop->rooms, rooms);
|
|
bmoveFindEnteredRoomsByPos(g_Vars.currentplayer, &testpos, rooms);
|
|
onladder2 = cd00029ffc(&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 - 10,
|
|
rooms, 0x8040, &g_Vars.currentplayer->laddernormal);
|
|
}
|
|
|
|
testpos.x = g_Vars.currentplayer->prop->pos.x;
|
|
testpos.y = g_Vars.currentplayer->prop->pos.y;
|
|
testpos.z = g_Vars.currentplayer->prop->pos.z;
|
|
|
|
if (g_Vars.currentplayer->inlift) {
|
|
testpos.y -= g_Vars.currentplayer->crouchheight + g_Vars.currentplayer->crouchoffsetrealsmall;
|
|
}
|
|
|
|
roomsCopy(g_Vars.currentplayer->prop->rooms, rooms);
|
|
bmoveFindEnteredRoomsByPos(g_Vars.currentplayer, &testpos, rooms);
|
|
ground = cdFindGroundY(&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);
|
|
ground += g_Vars.currentplayer->bondonground;
|
|
|
|
if (ground < -30000) {
|
|
ground = -30000;
|
|
}
|
|
|
|
#if PIRACYCHECKS
|
|
if (g_Vars.currentplayer->inlift && newinlift == false) {
|
|
// Exiting a lift
|
|
piracyRestore();
|
|
}
|
|
#endif
|
|
|
|
if (g_Vars.currentplayer->inlift && newinlift && g_Vars.currentplayer->onladder == false) {
|
|
// Remaining in a lift
|
|
moveamount = ground - g_Vars.currentplayer->vv_ground;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (moveamount != 0)
|
|
#endif
|
|
{
|
|
// The lift is moving
|
|
if (g_Vars.currentplayer->isfalling == false && lift == g_Vars.currentplayer->lift) {
|
|
if (g_Vars.currentplayer->liftground - g_Vars.currentplayer->vv_manground < 1.0f
|
|
&& g_Vars.currentplayer->liftground - g_Vars.currentplayer->vv_manground > -1.0f) {
|
|
// It's actually moving, and not a floating point precision issue
|
|
g_Vars.currentplayer->vv_ground += moveamount;
|
|
|
|
if (moveamount > 0
|
|
|| lift == NULL
|
|
|| lift->obj == NULL
|
|
|| (lift->obj->flags & OBJFLAG_CHOPPER_INACTIVE) == 0
|
|
|| bwalkTryMoveUpwards(moveamount) == CDRESULT_NOCOLLISION) {
|
|
// Going up
|
|
g_Vars.currentplayer->vv_manground += moveamount;
|
|
g_Vars.currentplayer->sumground = g_Vars.currentplayer->vv_manground / (PAL ? 0.054400026798248f : 0.045499980449677f);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (g_Vars.currentplayer->walkinitmove) {
|
|
g_Vars.currentplayer->walkinitstart.y += moveamount;
|
|
}
|
|
}
|
|
} else {
|
|
lift = NULL;
|
|
}
|
|
|
|
g_Vars.currentplayer->inlift = newinlift;
|
|
|
|
if (newinlift) {
|
|
g_Vars.currentplayer->liftground = ground;
|
|
}
|
|
|
|
g_Vars.currentplayer->lift = lift;
|
|
|
|
// Ladders
|
|
if (g_Vars.currentplayer->onladder) {
|
|
if (g_Vars.currentplayer->ladderupdown >= 0 ||
|
|
(ground <= g_Vars.currentplayer->vv_manground &&
|
|
ground <= g_Vars.currentplayer->vv_manground + g_Vars.currentplayer->ladderupdown)) {
|
|
// Still on ladder
|
|
if (bwalkTryMoveUpwards(g_Vars.currentplayer->ladderupdown) == CDRESULT_NOCOLLISION) {
|
|
g_Vars.currentplayer->vv_manground += g_Vars.currentplayer->ladderupdown;
|
|
}
|
|
} else {
|
|
if (bwalkTryMoveUpwards(ground - g_Vars.currentplayer->vv_manground) == CDRESULT_NOCOLLISION) {
|
|
g_Vars.currentplayer->vv_manground = ground;
|
|
onladder = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
g_Vars.currentplayer->onladder = onladder;
|
|
|
|
if (g_Vars.currentplayer->onladder) {
|
|
g_Vars.currentplayer->vv_ground = g_Vars.currentplayer->vv_manground;
|
|
} else if (onladder2 == false) {
|
|
g_Vars.currentplayer->vv_ground = ground;
|
|
}
|
|
|
|
// Standing on flat ground, or going up stairs, ledges or ramps
|
|
// In other words, not falling
|
|
if (g_Vars.currentplayer->bdeltapos.y >= 0.0f
|
|
|| g_Vars.currentplayer->vv_ground > g_Vars.currentplayer->vv_manground) {
|
|
g_Vars.currentplayer->sumground = g_Vars.currentplayer->vv_manground / (PAL ? 0.054400026798248f : 0.045499980449677f);
|
|
|
|
for (i = 0; i < g_Vars.lvupdate240; i++) {
|
|
g_Vars.currentplayer->sumground =
|
|
g_Vars.currentplayer->sumground * (PAL ? 0.94559997320175f : 0.9545f) + g_Vars.currentplayer->vv_ground;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->vv_manground < g_Vars.currentplayer->vv_ground) {
|
|
// Feet are lower than the ground
|
|
sumground = g_Vars.currentplayer->sumground * (PAL ? 0.054400026798248f : 0.045499980449677f);
|
|
|
|
if (sumground < g_Vars.currentplayer->vv_ground - 50) {
|
|
sumground = g_Vars.currentplayer->vv_ground - 50;
|
|
}
|
|
|
|
if (bwalkTryMoveUpwards(sumground - g_Vars.currentplayer->vv_manground) == CDRESULT_NOCOLLISION) {
|
|
g_Vars.currentplayer->vv_manground = sumground;
|
|
}
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
else {
|
|
// Not enough room above. If on a hoverbike, blow it up
|
|
prop = cdGetObstacle();
|
|
|
|
if (prop
|
|
&& g_Vars.currentplayer->prop->pos.y < prop->pos.y
|
|
&& prop->type == PROPTYPE_OBJ) {
|
|
obj = prop->obj;
|
|
|
|
if (obj->modelnum == MODEL_HOVBIKE) {
|
|
amount = (obj->maxdamage - obj->damage + 1) / 250.0f;
|
|
obj->flags &= ~OBJFLAG_INVINCIBLE;
|
|
objDamage(obj, amount, &obj->prop->pos, WEAPON_REMOTEMINE, -1);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// Kill player if standing on tile with GEOFLAG_DIE
|
|
if ((g_Vars.currentplayer->floorflags & GEOFLAG_DIE)
|
|
&& g_Vars.currentplayer->vv_manground - 20.0f < g_Vars.currentplayer->vv_ground
|
|
&& g_Vars.currentplayer->onladder == false
|
|
&& onladder2 == false) {
|
|
playerDie(true);
|
|
}
|
|
}
|
|
|
|
if (g_Vars.currentplayer->vv_manground > g_Vars.currentplayer->vv_ground) {
|
|
// Not standing on ground - probably falling, or on an object of some sort
|
|
fallspeed = g_Vars.currentplayer->bdeltapos.y;
|
|
newmanground = g_Vars.currentplayer->vv_manground;
|
|
|
|
if (debugIsTurboModeEnabled()
|
|
&& g_Vars.currentplayer->bondforcespeed.x == 0
|
|
&& g_Vars.currentplayer->bondforcespeed.z == 0) {
|
|
multiplier = 0.277777777f * 5;
|
|
} else {
|
|
multiplier = 0.277777777f;
|
|
}
|
|
|
|
newfallspeed = fallspeed - g_Vars.lvupdate240freal * multiplier;
|
|
newmanground += g_Vars.lvupdate240freal * (fallspeed + newfallspeed) * 0.5f;
|
|
fallspeed = newfallspeed;
|
|
|
|
if (newmanground < g_Vars.currentplayer->vv_ground) {
|
|
newfallspeed = g_Vars.currentplayer->vv_manground - g_Vars.currentplayer->vv_ground;
|
|
newmanground = g_Vars.currentplayer->vv_ground;
|
|
|
|
fallspeed = sqrtf(g_Vars.currentplayer->bdeltapos.y *
|
|
g_Vars.currentplayer->bdeltapos.y +
|
|
(((newfallspeed + newfallspeed) * 0.277777777f) / 60.0f) * 60.0f);
|
|
fallspeed = -fallspeed;
|
|
}
|
|
|
|
if (bwalkTryMoveUpwards(newmanground - g_Vars.currentplayer->vv_manground) == CDRESULT_NOCOLLISION) {
|
|
// Falling
|
|
g_Vars.currentplayer->vv_manground = newmanground;
|
|
g_Vars.currentplayer->bdeltapos.y = fallspeed;
|
|
|
|
if (g_Vars.currentplayer->isfalling == false) {
|
|
// Just started falling
|
|
g_Vars.currentplayer->isfalling = true;
|
|
g_Vars.currentplayer->fallstart = g_Vars.lvframe60;
|
|
} else {
|
|
if (g_Vars.lvframe60 - g_Vars.currentplayer->fallstart > TICKS(240)) {
|
|
// Have been falling for 4 seconds
|
|
playerDie(true);
|
|
}
|
|
}
|
|
} else {
|
|
// Not falling
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_Vars.normmplayerisrunning == false
|
|
&& g_Vars.currentplayer->vv_ground < g_Vars.currentplayer->vv_manground - 30) {
|
|
// Not falling - but still at least 30 units off the ground.
|
|
// Must be something in the way...
|
|
prop = cdGetObstacle();
|
|
|
|
if (prop) {
|
|
if (prop->type == PROPTYPE_CHR) {
|
|
// Landed on top of a chr
|
|
if (prop->chr->inlift) {
|
|
chrYeetFromPos(prop->chr, &g_Vars.currentplayer->prop->pos, 0);
|
|
}
|
|
} else if (prop->type == PROPTYPE_PLAYER) {
|
|
// Landed on top of a player
|
|
u32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(prop));
|
|
|
|
if (g_Vars.currentplayer->inlift) {
|
|
playerDieByShooter(prevplayernum, true);
|
|
}
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
g_Vars.currentplayer->bdeltapos.y = VERSION >= VERSION_NTSC_1_0 ? 0.0f : 0;
|
|
|
|
if (g_Vars.currentplayer->isfalling) {
|
|
g_Vars.currentplayer->isfalling = false;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->vv_manground <= -30000) {
|
|
playerDie(true);
|
|
}
|
|
}
|
|
} else {
|
|
// Not falling
|
|
if (g_Vars.currentplayer->isfalling) {
|
|
g_Vars.currentplayer->isfalling = false;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->vv_manground <= -30000) {
|
|
playerDie(true);
|
|
}
|
|
}
|
|
|
|
if (g_Vars.currentplayer->bdeltapos.y < 0 &&
|
|
g_Vars.currentplayer->vv_manground <= g_Vars.currentplayer->vv_ground) {
|
|
// Landing after a fall
|
|
if (g_Vars.currentplayer->isfalling) {
|
|
g_Vars.currentplayer->isfalling = false;
|
|
}
|
|
|
|
// I suspect these crouch fields are related to the recovery during
|
|
// landing. Eg. The faster the fall speed, the longer Jo will take to
|
|
// stand back to full height again.
|
|
if (g_Vars.currentplayer->bdeltapos.y < -13.333333f) {
|
|
g_Vars.currentplayer->crouchtime240 = TICKS(60);
|
|
g_Vars.currentplayer->crouchfall = -90;
|
|
} else if (g_Vars.currentplayer->bdeltapos.y < -5.0f) {
|
|
g_Vars.currentplayer->crouchtime240 = TICKS(60);
|
|
g_Vars.currentplayer->crouchfall =
|
|
(-5.0f - g_Vars.currentplayer->bdeltapos.y) * -90.0f / 8.333333f;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->bdeltapos.y < -6.0f) {
|
|
// Play footstep sounds
|
|
s32 sound;
|
|
struct chrdata *chr = g_Vars.currentplayer->prop->chr;
|
|
chr->floortype = g_Vars.currentplayer->floortype;
|
|
chr->footstep = 1;
|
|
|
|
sound = footstepChooseSound(chr, true);
|
|
|
|
if (sound != -1) {
|
|
if (sound != -1) {
|
|
propsnd0f0939f8(NULL, g_Vars.currentplayer->prop, sound,
|
|
-1, -1, 0x8400, 0, 0, 0, -1, NULL, -1, -1, -1, -1);
|
|
}
|
|
|
|
chr->footstep = 2;
|
|
sound = footstepChooseSound(chr, true);
|
|
|
|
if (sound != -1) {
|
|
propsnd0f0939f8(NULL, g_Vars.currentplayer->prop, sound,
|
|
-1, -1, 0x8400, 0, 0, 0, -1, NULL, -1, -1, -1, -1);
|
|
}
|
|
}
|
|
|
|
if (g_Vars.mplayerisrunning == false
|
|
&& (chr->headnum == HEAD_DARK_COMBAT || chr->headnum == HEAD_DARK_FROCK)
|
|
&& g_Vars.lvframe60 - g_Vars.currentplayer->fallstart > TICKS(40)) {
|
|
// Play Jo landing grunt
|
|
s32 sounds[] = {
|
|
SFX_JO_LANDING_046F,
|
|
SFX_JO_LANDING_05B6,
|
|
SFX_JO_LANDING_05B7
|
|
};
|
|
|
|
propsnd0f0939f8(NULL, g_Vars.currentplayer->prop, sounds[random() % 3],
|
|
-1, -1, 0x8400, 0, 0, 0, -1, NULL, -1, -1, -1, -1);
|
|
}
|
|
}
|
|
|
|
g_Vars.currentplayer->bdeltapos.y = 0;
|
|
}
|
|
|
|
// Decrease crouchtime240 for this tick.
|
|
// If reached 0 and crouchfall is negative, start increasing
|
|
// crouchfall over the next several ticks until it reaches 0.
|
|
for (i = 0; i < g_Vars.lvupdate240; i++) {
|
|
if (g_Vars.currentplayer->crouchtime240 > 0) {
|
|
g_Vars.currentplayer->sumcrouch =
|
|
g_Vars.currentplayer->sumcrouch * (PAL ? 0.93540000915527f : 0.9456f) + g_Vars.currentplayer->crouchfall;
|
|
g_Vars.currentplayer->crouchtime240--;
|
|
} else {
|
|
if (g_Vars.currentplayer->crouchfall < 0) {
|
|
g_Vars.currentplayer->crouchfall -= (PAL ? -1.3636363744736f : -1.125f);
|
|
|
|
if (g_Vars.currentplayer->crouchfall >= 0) {
|
|
g_Vars.currentplayer->crouchfall = 0;
|
|
}
|
|
}
|
|
|
|
g_Vars.currentplayer->sumcrouch =
|
|
g_Vars.currentplayer->sumcrouch * (PAL ? 0.93540000915527f : 0.9456f) + g_Vars.currentplayer->crouchfall;
|
|
}
|
|
}
|
|
|
|
{
|
|
g_Vars.currentplayer->crouchheight = g_Vars.currentplayer->sumcrouch * (PAL ? 0.064599990844727f : 0.054400026798248f);
|
|
g_Vars.currentplayer->vv_height =
|
|
(g_Vars.currentplayer->headpos.y / g_Vars.currentplayer->standheight)
|
|
* g_Vars.currentplayer->vv_eyeheight;
|
|
|
|
eyeheight = g_Vars.currentplayer->vv_height +
|
|
g_Vars.currentplayer->crouchoffsetrealsmall +
|
|
g_Vars.currentplayer->crouchheight *
|
|
g_Vars.currentplayer->vv_eyeheight * 0.0062893079593778f;
|
|
|
|
if (eyeheight < 30) {
|
|
eyeheight = 30;
|
|
}
|
|
|
|
newpos.x = g_Vars.currentplayer->prop->pos.x;
|
|
newpos.y = g_Vars.currentplayer->vv_manground + eyeheight;
|
|
newpos.z = g_Vars.currentplayer->prop->pos.z;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (newpos.y < g_Vars.currentplayer->vv_ground + 10) {
|
|
newpos.y = g_Vars.currentplayer->vv_ground + 10;
|
|
}
|
|
#endif
|
|
|
|
if (newpos.x != g_Vars.currentplayer->prop->pos.x
|
|
|| newpos.y != g_Vars.currentplayer->prop->pos.y
|
|
|| newpos.z != g_Vars.currentplayer->prop->pos.z) {
|
|
func0f065e74(&g_Vars.currentplayer->prop->pos, g_Vars.currentplayer->prop->rooms, &newpos, newrooms);
|
|
|
|
g_Vars.currentplayer->prop->pos.x = newpos.x;
|
|
g_Vars.currentplayer->prop->pos.y = newpos.y;
|
|
g_Vars.currentplayer->prop->pos.z = newpos.z;
|
|
|
|
propDeregisterRooms(g_Vars.currentplayer->prop);
|
|
roomsCopy(newrooms, g_Vars.currentplayer->prop->rooms);
|
|
}
|
|
}
|
|
|
|
void bwalkApplyCrouchSpeed(void)
|
|
{
|
|
if (bmoveGetCrouchPos() == CROUCHPOS_DUCK) {
|
|
g_Vars.currentplayer->speedforwards *= 0.5f;
|
|
g_Vars.currentplayer->speedsideways *= 0.5f;
|
|
} else if (bmoveGetCrouchPos() == CROUCHPOS_SQUAT) {
|
|
g_Vars.currentplayer->speedforwards *= 0.35f;
|
|
g_Vars.currentplayer->speedsideways *= 0.35f;
|
|
}
|
|
}
|
|
|
|
void bwalkUpdateCrouchOffsetReal(void)
|
|
{
|
|
if (g_Vars.currentplayer->vv_eyeheight + -90.0f * g_Vars.currentplayer->vv_eyeheight * (1.0f / 159.0f) < 69.0f) {
|
|
g_Vars.currentplayer->crouchoffsetreal = g_Vars.currentplayer->crouchoffset * ((69.0f - g_Vars.currentplayer->vv_eyeheight) / -90.0f);
|
|
} else {
|
|
g_Vars.currentplayer->crouchoffsetreal = g_Vars.currentplayer->crouchoffset * g_Vars.currentplayer->vv_eyeheight * (1.0f / 159.0f);
|
|
}
|
|
|
|
if (cheatIsActive(CHEAT_SMALLJO)) {
|
|
g_Vars.currentplayer->crouchoffsetsmall = 69.0f - g_Vars.currentplayer->vv_eyeheight;
|
|
g_Vars.currentplayer->crouchoffsetrealsmall = 69.0f - g_Vars.currentplayer->vv_eyeheight;
|
|
} else {
|
|
g_Vars.currentplayer->crouchoffsetsmall = g_Vars.currentplayer->crouchoffset;
|
|
g_Vars.currentplayer->crouchoffsetrealsmall = g_Vars.currentplayer->crouchoffsetreal;
|
|
}
|
|
}
|
|
|
|
void bwalkUpdateCrouchOffset(void)
|
|
{
|
|
f32 targetoffset = 0;
|
|
|
|
if (bmoveGetCrouchPos() == CROUCHPOS_SQUAT) {
|
|
targetoffset = -90;
|
|
} else if (bmoveGetCrouchPos() == CROUCHPOS_DUCK) {
|
|
targetoffset = -45;
|
|
} else if (bmoveGetCrouchPos() == CROUCHPOS_STAND) {
|
|
// empty
|
|
}
|
|
|
|
if (targetoffset != g_Vars.currentplayer->crouchoffset) {
|
|
f32 prevcrouchoffset = g_Vars.currentplayer->crouchoffset;
|
|
f32 prevcrouchoffsetreal = g_Vars.currentplayer->crouchoffsetreal;
|
|
f32 prevcrouchoffsetsmall = g_Vars.currentplayer->crouchoffsetsmall;
|
|
f32 prevcrouchoffsetrealsmall = g_Vars.currentplayer->crouchoffsetrealsmall;
|
|
|
|
// f32 *frac, f32 maxfrac, f32 *fracspeed, f32 accel, f32 decel, f32 maxspeed
|
|
applySpeed(&g_Vars.currentplayer->crouchoffset, targetoffset,
|
|
&g_Vars.currentplayer->crouchspeed, PALUPF(0.5f), PALUPF(0.5f), PALUPF(5.0f));
|
|
|
|
bwalkUpdateCrouchOffsetReal();
|
|
|
|
if (bwalkTryMoveUpwards(0) == CDRESULT_COLLISION) {
|
|
// Crouch adjustment is blocked by ceiling
|
|
g_Vars.currentplayer->crouchoffset = prevcrouchoffset;
|
|
g_Vars.currentplayer->crouchoffsetreal = prevcrouchoffsetreal;
|
|
g_Vars.currentplayer->crouchoffsetsmall = prevcrouchoffsetsmall;
|
|
g_Vars.currentplayer->crouchoffsetrealsmall = prevcrouchoffsetrealsmall;
|
|
g_Vars.currentplayer->crouchspeed = 0;
|
|
bwalkAdjustCrouchPos(-1);
|
|
}
|
|
}
|
|
|
|
if (targetoffset == g_Vars.currentplayer->crouchoffset) {
|
|
g_Vars.currentplayer->crouchspeed = 0;
|
|
}
|
|
|
|
g_Vars.currentplayer->guncloseroffset = g_Vars.currentplayer->crouchoffset / -90;
|
|
}
|
|
|
|
void bwalkUpdateTheta(void)
|
|
{
|
|
f32 mult;
|
|
f32 rotateamount;
|
|
struct coord delta = {0, 0, 0};
|
|
|
|
// Turn speed is calculated from the chr's height
|
|
mult = 159.0f / g_Vars.currentplayer->vv_eyeheight;
|
|
rotateamount = g_Vars.currentplayer->speedtheta * mult
|
|
* g_Vars.lvupdate240freal * 0.0174505133f * 3.5f;
|
|
|
|
bwalkCalculateNewPositionWithPush(&delta, rotateamount, true, 0, CDTYPE_ALL);
|
|
}
|
|
|
|
void bwalk0f0c63bc(struct coord *arg0, u32 arg1, s32 types)
|
|
{
|
|
struct coord sp100;
|
|
struct coord sp88;
|
|
|
|
g_Vars.currentplayer->bondonturret = false;
|
|
g_Vars.currentplayer->autocrouchpos = CROUCHPOS_STAND;
|
|
|
|
bwalk0f0c4d98();
|
|
|
|
if (bwalk0f0c4764(arg0, &sp100, &sp88, types) == CDRESULT_COLLISION) {
|
|
struct coord sp76;
|
|
struct coord sp64;
|
|
|
|
s32 result = bwalk0f0c47d0(arg0, &sp100, &sp88, &sp76, &sp64, types);
|
|
|
|
if (result >= CDRESULT_NOCOLLISION || result <= CDRESULT_ERROR) {
|
|
if (result >= CDRESULT_NOCOLLISION) {
|
|
bwalk0f0c4d98();
|
|
}
|
|
|
|
if (arg1
|
|
&& bwalk0f0c494c(arg0, &sp100, &sp88, types) <= CDRESULT_COLLISION
|
|
&& bwalk0f0c4a5c(arg0, &sp100, &sp88, types) <= CDRESULT_COLLISION) {
|
|
// empty
|
|
}
|
|
} else if (result == CDRESULT_COLLISION) {
|
|
struct coord sp48;
|
|
struct coord sp36;
|
|
|
|
if (bwalk0f0c47d0(arg0, &sp76, &sp64, &sp48, &sp36, types) >= CDRESULT_NOCOLLISION) {
|
|
bwalk0f0c4d98();
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
bwalk0f0c4d98();
|
|
}
|
|
|
|
void bwalkUpdatePrevPos(void)
|
|
{
|
|
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;
|
|
|
|
roomsCopy(g_Vars.currentplayer->prop->rooms, g_Vars.currentplayer->bondprevrooms);
|
|
}
|
|
|
|
void bwalkHandleActivate(void)
|
|
{
|
|
if (g_Vars.currentplayer->walkinitmove) {
|
|
g_Vars.currentplayer->bondactivateorreload = 0;
|
|
}
|
|
}
|
|
|
|
void bwalkApplyMoveData(struct movedata *data)
|
|
{
|
|
if (g_Vars.currentplayer->walkinitmove == false) {
|
|
// Sideways
|
|
if (data->digitalstepleft) {
|
|
bwalkUpdateSpeedSideways(-1, 0.2f, data->digitalstepleft);
|
|
} else if (data->digitalstepright) {
|
|
bwalkUpdateSpeedSideways(1, 0.2f, data->digitalstepright);
|
|
} else if (data->unk14 == false) {
|
|
bwalkUpdateSpeedSideways(0, 0.2f, g_Vars.lvupdate240_60);
|
|
}
|
|
|
|
if (data->unk14) {
|
|
bwalkUpdateSpeedSideways(data->analogstrafe * 0.014285714365542f, 0.2f, g_Vars.lvupdate240_60);
|
|
}
|
|
|
|
// Forward/back
|
|
if (data->digitalstepforward) {
|
|
bwalkUpdateSpeedForwards(1, 1);
|
|
g_Vars.currentplayer->speedmaxtime60 += g_Vars.lvupdate240_60;
|
|
} else if (data->digitalstepback) {
|
|
bwalkUpdateSpeedForwards(-1, 1);
|
|
} else if (data->canlookahead == false) {
|
|
bwalkUpdateSpeedForwards(0, 1);
|
|
}
|
|
|
|
if (data->canlookahead) {
|
|
bwalkUpdateSpeedForwards(data->analogwalk * 0.014285714365542f, 1);
|
|
|
|
if (data->analogwalk > 60) {
|
|
g_Vars.currentplayer->speedmaxtime60 += g_Vars.lvupdate240_60;
|
|
} else {
|
|
g_Vars.currentplayer->speedmaxtime60 = 0;
|
|
}
|
|
}
|
|
|
|
// Force speeds to range -1 to 1
|
|
if (g_Vars.currentplayer->speedforwards > 1) {
|
|
g_Vars.currentplayer->speedforwards = 1;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->speedforwards < -1) {
|
|
g_Vars.currentplayer->speedforwards = -1;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->speedsideways > 1) {
|
|
g_Vars.currentplayer->speedsideways = 1;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->speedsideways < -1) {
|
|
g_Vars.currentplayer->speedsideways = -1;
|
|
}
|
|
|
|
g_Vars.currentplayer->speedforwards *= 1.08f;
|
|
g_Vars.currentplayer->speedforwards *= g_Vars.currentplayer->speedboost;
|
|
|
|
if ((data->canlookahead == false && data->digitalstepforward == false) ||
|
|
bmoveGetCrouchPos() != CROUCHPOS_STAND) {
|
|
g_Vars.currentplayer->speedmaxtime60 = 0;
|
|
}
|
|
|
|
if (data->rleanleft) {
|
|
bwalkSetSwayTarget(-1);
|
|
} else if (data->rleanright) {
|
|
bwalkSetSwayTarget(1);
|
|
} else {
|
|
bwalkSetSwayTarget(0);
|
|
}
|
|
|
|
while (data->crouchdown-- > 0) {
|
|
bwalkAdjustCrouchPos(-1);
|
|
}
|
|
|
|
while (data->crouchup-- > 0) {
|
|
bwalkAdjustCrouchPos(1);
|
|
}
|
|
|
|
g_Vars.currentplayer->eyesshut = data->eyesshut;
|
|
}
|
|
}
|
|
|
|
void bwalkUpdateSpeedTheta(void)
|
|
{
|
|
if (bmoveGetCrouchPos() == CROUCHPOS_SQUAT) {
|
|
g_Vars.currentplayer->speedtheta *= 0.5f;
|
|
} else if (bmoveGetCrouchPos() == CROUCHPOS_DUCK) {
|
|
g_Vars.currentplayer->speedtheta *= 0.75f;
|
|
}
|
|
}
|
|
|
|
void bwalk0f0c69b8(void)
|
|
{
|
|
s32 i;
|
|
f32 spe0;
|
|
f32 spdc;
|
|
f32 spd8;
|
|
struct coord spcc = {0, 0, 0};
|
|
f32 spc8;
|
|
f32 spc4;
|
|
f32 spc0;
|
|
f32 tmp1;
|
|
f32 tmp2;
|
|
f32 spb4;
|
|
f32 spb0;
|
|
f32 dist;
|
|
f32 spa8;
|
|
f32 mult;
|
|
f32 f0;
|
|
f32 lvupdate240f;
|
|
s32 lvupdate240;
|
|
s32 cdresult;
|
|
struct escalatorobj *esc;
|
|
f32 sp8c;
|
|
f32 sp88;
|
|
f32 speedforwards;
|
|
f32 speedsideways;
|
|
f32 speedtheta;
|
|
f32 maxspeed;
|
|
f32 sp74;
|
|
f32 radius;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
f32 xdelta;
|
|
f32 zdelta;
|
|
f32 sp54;
|
|
f32 sp50;
|
|
f32 sp4c;
|
|
f32 sp48;
|
|
f32 sp44;
|
|
f32 sp40;
|
|
f32 sp3c;
|
|
f32 breathing;
|
|
|
|
spc0 = g_Vars.currentplayer->vv_eyeheight - 159;
|
|
|
|
if (invHasBriefcase() && ((g_MpSetup.scenario == MPSCENARIO_HOLDTHEBRIEFCASE || g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE))) {
|
|
spc0 = -63.600006f;
|
|
}
|
|
|
|
spc0 = spc0 / 353.33331298828f + 1.0f;
|
|
|
|
if (g_Vars.normmplayerisrunning && (g_MpSetup.options & MPOPTION_FASTMOVEMENT)) {
|
|
spc0 *= 1.25f;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (cheatIsActive(CHEAT_SMALLJO)) {
|
|
spc0 *= 0.4f;
|
|
}
|
|
#endif
|
|
|
|
if (g_Vars.currentplayer->walkinitmove) {
|
|
g_Vars.currentplayer->walkinitt += g_Vars.lvupdate240freal * (1.0f / 60.0f);
|
|
|
|
if (g_Vars.currentplayer->walkinitt >= 1.0f) {
|
|
g_Vars.currentplayer->walkinitt = 1.0f;
|
|
g_Vars.currentplayer->walkinitmove = false;
|
|
}
|
|
|
|
g_Vars.currentplayer->walkinitt2 = 1.0f - (cosf(g_Vars.currentplayer->walkinitt * M_BADPI) + 1.0f) * 0.5f;
|
|
|
|
bmoveUpdateHead(0.0f, 0.0f, 0.0f, &g_Vars.currentplayer->walkinitmtx, 1.0f - g_Vars.currentplayer->walkinitt2);
|
|
|
|
g_Vars.currentplayer->gunspeed = 0.0f;
|
|
|
|
bmoveUpdateMoveInitSpeed(&spcc);
|
|
bwalkCalculateNewPositionWithPush(&spcc, 0.0f, true, 0.0f, CDTYPE_ALL);
|
|
} else {
|
|
bwalkApplyCrouchSpeed();
|
|
bwalkUpdateCrouchOffset();
|
|
|
|
bmove0f0cba88(&spc8, &spc4,
|
|
&g_Vars.currentplayer->bondshotspeed,
|
|
g_Vars.currentplayer->vv_sintheta, g_Vars.currentplayer->vv_costheta);
|
|
|
|
tmp1 = -g_Vars.currentplayer->swaytarget * g_Vars.currentplayer->bond2.unk00.f[2];
|
|
tmp2 = g_Vars.currentplayer->swaytarget * g_Vars.currentplayer->bond2.unk00.f[0];
|
|
tmp1 *= spc0;
|
|
tmp2 *= spc0;
|
|
spa8 = 0.0f;
|
|
|
|
if (g_Vars.currentplayer->crouchoffset < -45.0f) {
|
|
tmp1 *= 0.35f;
|
|
tmp2 *= 0.35f;
|
|
} else if (g_Vars.currentplayer->crouchoffset < 0.0f) {
|
|
tmp1 *= 0.5f;
|
|
tmp2 *= 0.5f;
|
|
}
|
|
|
|
spb4 = tmp1 - g_Vars.currentplayer->swayoffset0;
|
|
spb0 = tmp2 - g_Vars.currentplayer->swayoffset2;
|
|
|
|
dist = sqrtf(spb4 * spb4 + spb0 * spb0);
|
|
|
|
if (g_Vars.lvupdate240freal > PALUPF(4)) {
|
|
lvupdate240f = PALUPF(4);
|
|
lvupdate240 = 4;
|
|
} else {
|
|
lvupdate240f = g_Vars.lvupdate240freal;
|
|
lvupdate240 = g_Vars.lvupdate240_60;
|
|
}
|
|
|
|
for (i = 0; i < lvupdate240; i++) {
|
|
spa8 += (dist - spa8) * PALUPF(0.1f);
|
|
}
|
|
|
|
spa8 += 3.75f * lvupdate240f;
|
|
|
|
if (g_Vars.currentplayer->crouchoffset < -45.0f) {
|
|
spa8 *= 0.35f;
|
|
} else if (g_Vars.currentplayer->crouchoffset < 0.0f) {
|
|
spa8 *= 0.5f;
|
|
}
|
|
|
|
if (spa8 < dist) {
|
|
spa8 /= dist;
|
|
spb4 *= spa8;
|
|
spb0 *= spa8;
|
|
}
|
|
|
|
speedsideways = (g_Vars.currentplayer->speedsideways + spc4) * 0.8f;
|
|
speedforwards = g_Vars.currentplayer->speedforwards + spc8;
|
|
speedtheta = g_Vars.currentplayer->speedtheta * 0.8f;
|
|
|
|
if (speedsideways < 0.0f) {
|
|
speedsideways = -speedsideways;
|
|
}
|
|
|
|
if (speedforwards < 0.0f) {
|
|
speedforwards = -speedforwards;
|
|
}
|
|
|
|
if (speedtheta < 0.0f) {
|
|
speedtheta = -speedtheta;
|
|
}
|
|
|
|
maxspeed = speedforwards;
|
|
|
|
if (speedsideways > maxspeed) {
|
|
maxspeed = speedsideways;
|
|
}
|
|
|
|
if (speedtheta > maxspeed) {
|
|
maxspeed = speedtheta;
|
|
}
|
|
|
|
if (dist >= 0.1f && maxspeed < 0.8f) {
|
|
maxspeed = 0.8f;
|
|
}
|
|
|
|
if (maxspeed >= 0.75f) {
|
|
g_Vars.currentplayer->bondbreathing += (maxspeed - 0.75f) * g_Vars.lvupdate240freal / 900;
|
|
} else {
|
|
g_Vars.currentplayer->bondbreathing -= (0.75f - maxspeed) * g_Vars.lvupdate240freal / 2700;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->bondbreathing < 0.0f) {
|
|
g_Vars.currentplayer->bondbreathing = 0.0f;
|
|
} else if (g_Vars.currentplayer->bondbreathing > 1.0f) {
|
|
g_Vars.currentplayer->bondbreathing = 1.0f;
|
|
}
|
|
|
|
mult = var80075c00[1].unk0c * 0.5f * g_Vars.lvupdate240freal;
|
|
spe0 = (g_Vars.currentplayer->speedsideways * spc0 + spc4) * mult;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (cheatIsActive(CHEAT_SMALLJO)) {
|
|
spe0 /= 0.4f;
|
|
}
|
|
#endif
|
|
|
|
bmove0f0cc654(maxspeed, g_Vars.currentplayer->speedforwards * spc0 + spc8, spe0);
|
|
|
|
g_Vars.currentplayer->gunspeed = maxspeed;
|
|
|
|
spdc = g_Vars.currentplayer->headpos.x;
|
|
spd8 = g_Vars.currentplayer->headpos.z;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (cheatIsActive(CHEAT_SMALLJO)) {
|
|
spdc *= 0.4f;
|
|
}
|
|
#endif
|
|
|
|
spcc.f[0] += (spd8 * g_Vars.currentplayer->bond2.unk00.f[0] - spdc * g_Vars.currentplayer->bond2.unk00.f[2]) * g_Vars.lvupdate240freal;
|
|
spcc.f[2] += (spd8 * g_Vars.currentplayer->bond2.unk00.f[2] + spdc * g_Vars.currentplayer->bond2.unk00.f[0]) * g_Vars.lvupdate240freal;
|
|
spcc.f[0] += spb4;
|
|
spcc.f[2] += spb0;
|
|
|
|
bmoveUpdateMoveInitSpeed(&spcc);
|
|
|
|
if (debugIsTurboModeEnabled()) {
|
|
spcc.f[0] += (g_Vars.currentplayer->bond2.unk00.f[0] * g_Vars.currentplayer->speedforwards - g_Vars.currentplayer->bond2.unk00.f[2] * g_Vars.currentplayer->speedsideways) * g_Vars.lvupdate240freal * 10.0f;
|
|
spcc.f[2] += (g_Vars.currentplayer->bond2.unk00.f[2] * g_Vars.currentplayer->speedforwards + g_Vars.currentplayer->bond2.unk00.f[0] * g_Vars.currentplayer->speedsideways) * g_Vars.lvupdate240freal * 10.0f;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->bondforcespeed.f[0] != 0.0f || g_Vars.currentplayer->bondforcespeed.f[2] != 0.0f) {
|
|
spcc.f[0] += g_Vars.currentplayer->bondforcespeed.f[0] * g_Vars.lvupdate240freal;
|
|
spcc.f[2] += g_Vars.currentplayer->bondforcespeed.f[2] * g_Vars.lvupdate240freal;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->onladder) {
|
|
guNormalize(&g_Vars.currentplayer->laddernormal.x, &g_Vars.currentplayer->laddernormal.y, &g_Vars.currentplayer->laddernormal.z);
|
|
|
|
sp74 = -(spcc.f[0] * g_Vars.currentplayer->laddernormal.f[0] + spcc.f[2] * g_Vars.currentplayer->laddernormal.f[2]);
|
|
|
|
if (-4.0f * g_Vars.lvupdate240freal < sp74) {
|
|
if (sp74 < 0.0f) {
|
|
spcc.f[0] += sp74 * g_Vars.currentplayer->laddernormal.f[0];
|
|
spcc.f[2] += sp74 * g_Vars.currentplayer->laddernormal.f[2];
|
|
g_Vars.currentplayer->ladderupdown = sp74 * 0.3f;
|
|
} else {
|
|
playerGetBbox(g_Vars.currentplayer->prop, &radius, &ymax, &ymin);
|
|
|
|
cdresult = cd0002a13c(&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, 0x8040);
|
|
|
|
if (cdresult == CDRESULT_COLLISION) {
|
|
g_Vars.currentplayer->ladderupdown = 0.0f;
|
|
} else {
|
|
spcc.f[0] += sp74 * g_Vars.currentplayer->laddernormal.f[0];
|
|
spcc.f[2] += sp74 * g_Vars.currentplayer->laddernormal.f[2];
|
|
g_Vars.currentplayer->ladderupdown = sp74 * 0.3f;
|
|
}
|
|
}
|
|
|
|
spcc.x *= 0.3f;
|
|
spcc.z *= 0.3f;
|
|
} else {
|
|
g_Vars.currentplayer->ladderupdown = 0.0f;
|
|
}
|
|
}
|
|
|
|
if (g_Vars.currentplayer->lift) {
|
|
esc = (struct escalatorobj *) g_Vars.currentplayer->lift->obj;
|
|
|
|
if (esc->base.type == OBJTYPE_ESCASTEP) {
|
|
spcc.x += esc->base.prop->pos.x - esc->prevpos.x;
|
|
spcc.z += esc->base.prop->pos.z - esc->prevpos.z;
|
|
}
|
|
}
|
|
|
|
sp8c = g_Vars.currentplayer->prop->pos.x;
|
|
sp88 = g_Vars.currentplayer->prop->pos.z;
|
|
|
|
bwalk0f0c63bc(&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;
|
|
|
|
sp54 = -xdelta * g_Vars.currentplayer->bond2.unk00.f[2] + zdelta * g_Vars.currentplayer->bond2.unk00.f[0];
|
|
sp50 = xdelta * g_Vars.currentplayer->bond2.unk00.f[0] + zdelta * g_Vars.currentplayer->bond2.unk00.f[2];
|
|
|
|
sp4c = -spcc.f[0] * g_Vars.currentplayer->bond2.unk00.f[2] + spcc.f[2] * g_Vars.currentplayer->bond2.unk00.f[0];
|
|
sp48 = spcc.f[0] * g_Vars.currentplayer->bond2.unk00.f[0] + spcc.f[2] * g_Vars.currentplayer->bond2.unk00.f[2];
|
|
|
|
if (xdelta >= 0.0f) {
|
|
if (g_Vars.currentplayer->bondshotspeed.f[0] > 0.0f) {
|
|
if (spcc.f[0] >= 0.0f && xdelta < spcc.f[0]) {
|
|
g_Vars.currentplayer->bondshotspeed.f[0] *= xdelta / spcc.f[0];
|
|
}
|
|
} else {
|
|
if (spcc.f[0] < 0.0f) {
|
|
g_Vars.currentplayer->bondshotspeed.f[0] = 0.0f;
|
|
}
|
|
}
|
|
} else {
|
|
if (g_Vars.currentplayer->bondshotspeed.f[0] < 0.0f) {
|
|
if (spcc.f[0] <= 0.0f && spcc.f[0] < xdelta) {
|
|
g_Vars.currentplayer->bondshotspeed.f[0] *= xdelta / spcc.f[0];
|
|
}
|
|
} else {
|
|
if (spcc.f[0] > 0.0f) {
|
|
g_Vars.currentplayer->bondshotspeed.f[0] = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (zdelta >= 0.0f) {
|
|
if (g_Vars.currentplayer->bondshotspeed.f[2] > 0.0f) {
|
|
if (spcc.f[2] >= 0.0f && zdelta < spcc.f[2]) {
|
|
g_Vars.currentplayer->bondshotspeed.f[2] *= zdelta / spcc.f[2];
|
|
}
|
|
} else {
|
|
if (spcc.f[2] < 0.0f) {
|
|
g_Vars.currentplayer->bondshotspeed.f[2] = 0.0f;
|
|
}
|
|
}
|
|
} else {
|
|
if (g_Vars.currentplayer->bondshotspeed.f[2] < 0.0f) {
|
|
if (spcc.f[2] <= 0.0f && spcc.f[2] < zdelta) {
|
|
g_Vars.currentplayer->bondshotspeed.f[2] *= zdelta / spcc.f[2];
|
|
}
|
|
} else {
|
|
if (spcc.f[2] > 0.0f) {
|
|
g_Vars.currentplayer->bondshotspeed.f[2] = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sp4c != 0.0f && g_Vars.currentplayer->speedstrafe * sp4c > 0.0f) {
|
|
sp54 /= sp4c;
|
|
|
|
if (sp54 <= 0.0f) {
|
|
g_Vars.currentplayer->speedstrafe = 0.0f;
|
|
} else if (sp54 < 1.0f) {
|
|
g_Vars.currentplayer->speedstrafe *= sp54;
|
|
}
|
|
}
|
|
|
|
if (sp48 != 0.0f) {
|
|
if (g_Vars.currentplayer->speedgo * sp48 > 0.0f) {
|
|
sp50 /= sp48;
|
|
|
|
if (sp50 <= 0.0f) {
|
|
g_Vars.currentplayer->speedgo = 0.0f;
|
|
} else if (sp50 < 1.0f) {
|
|
g_Vars.currentplayer->speedgo *= sp50;
|
|
}
|
|
}
|
|
}
|
|
|
|
xdiff = g_Vars.currentplayer->prop->pos.x - sp8c;
|
|
zdiff = g_Vars.currentplayer->prop->pos.z - sp88;
|
|
f0 = spcc.f[0] * spcc.f[0] + spcc.f[2] * spcc.f[2];
|
|
|
|
if (f0 != 0.0f) {
|
|
f0 = (xdiff * xdiff + zdiff * zdiff) / f0;
|
|
}
|
|
|
|
f0 = sqrtf(f0);
|
|
g_Vars.currentplayer->swayoffset0 += f0 * spb4;
|
|
g_Vars.currentplayer->swayoffset2 += f0 * spb0;
|
|
}
|
|
|
|
sp44 = g_Vars.currentplayer->speedtheta;
|
|
sp40 = g_Vars.currentplayer->speedverta / 0.7f + g_Vars.currentplayer->crouchspeed / PALUPF(5.0f);
|
|
sp3c = g_Vars.currentplayer->gunspeed;
|
|
|
|
breathing = bheadGetBreathingValue();
|
|
|
|
if (sp40 > 1.0f) {
|
|
sp40 = 1.0f;
|
|
} else if (sp40 < -1.0f) {
|
|
sp40 = -1.0f;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->headanim == 1) {
|
|
breathing *= 1.2f;
|
|
}
|
|
|
|
bgun0f09d8dc(breathing, sp3c, sp40, sp44, 0.0f);
|
|
bgunSetAdjustPos(g_Vars.currentplayer->vv_verta360 * 0.017450513318181f);
|
|
}
|
|
|
|
void bwalkTick(void)
|
|
{
|
|
bwalkUpdatePrevPos();
|
|
bwalkUpdateTheta();
|
|
bmoveUpdateVerta();
|
|
bwalk0f0c69b8();
|
|
bwalkUpdateVertical();
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; g_Vars.currentplayer->prop->rooms[i] != -1; i++) {
|
|
if (g_Vars.currentplayer->floorroom == g_Vars.currentplayer->prop->rooms[i]) {
|
|
propDeregisterRooms(g_Vars.currentplayer->prop);
|
|
g_Vars.currentplayer->prop->rooms[0] = g_Vars.currentplayer->floorroom;
|
|
g_Vars.currentplayer->prop->rooms[1] = -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
bmoveUpdateRooms(g_Vars.currentplayer);
|
|
objectiveCheckRoomEntered(g_Vars.currentplayer->prop->rooms[0]);
|
|
|
|
if (g_Vars.currentplayer->walkinitmove) {
|
|
struct coord coord;
|
|
coord.x = (g_Vars.currentplayer->walkinitstart.x - g_Vars.currentplayer->walkinitpos.x)
|
|
* (1.0f - g_Vars.currentplayer->walkinitt2) + g_Vars.currentplayer->prop->pos.x;
|
|
|
|
coord.y = (g_Vars.currentplayer->walkinitstart.y - g_Vars.currentplayer->prop->pos.y)
|
|
* (1.0f - g_Vars.currentplayer->walkinitt2) + g_Vars.currentplayer->prop->pos.y;
|
|
|
|
coord.z = (g_Vars.currentplayer->walkinitstart.z - g_Vars.currentplayer->walkinitpos.z)
|
|
* (1.0f - g_Vars.currentplayer->walkinitt2) + g_Vars.currentplayer->prop->pos.z;
|
|
|
|
bmove0f0cc19c(&coord);
|
|
} else {
|
|
bmove0f0cc19c(&g_Vars.currentplayer->prop->pos);
|
|
}
|
|
|
|
playerUpdatePerimInfo();
|
|
doorsCheckAutomatic();
|
|
}
|