- In conjunction with all the below changes, attempt to fix A_CheckSightOrRange and A_CheckSight
for multiplayer: They now always check through the eyes of every player. For players whose cameras are not players, they also check through the eyes of those cameras. - Using spynext/spyprev to switch from a non-player to a player now writes a command to the network stream and lets Net_DoCommand() take care of it later. The logic here is that if a player is viewing from something that isn't another player, then every player needs to know about it for sync purposes. Consequently, when they stop viewing from a non-player and switch to a player, everybody needs to know about that too. But if they are viewing from a player, it doesn't matter which player it is, so they can spynext/spyprev all they want without letting the other players know about it (and without potentially breaking demos--due to the above-mentioned two codepointers--while doing it during demo playback). - Replaced the instances of checking players[consoleplayer].camera for a valid pointer to ones that do it for every player. - Fixed: Upon changing levels, all players but the consoleplayer would have their cameras NULLed. - Fixed: player_t::FixPointers() needs to bypass the read barriers, or it won't be able to do substitutions of old objects that are pending deletion. SVN r3448 (trunk)
This commit is contained in:
parent
07118147d8
commit
77c663a9b8
8 changed files with 109 additions and 54 deletions
|
|
@ -2253,7 +2253,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
|
|||
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && P_CheckSight(players[i].camera, self, SF_IGNOREVISIBILITY)) return;
|
||||
if (playeringame[i])
|
||||
{
|
||||
// Always check sight from each player.
|
||||
if (P_CheckSight(players[i].mo, self, SF_IGNOREVISIBILITY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If a player is viewing from a non-player, then check that too.
|
||||
if (players[i].camera != NULL && players[i].camera->player == NULL &&
|
||||
P_CheckSight(players[i].camera, self, SF_IGNOREVISIBILITY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACTION_JUMP(jump);
|
||||
|
|
@ -2266,6 +2279,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
|
|||
// Useful for maps with many multi-actor special effects.
|
||||
//
|
||||
//===========================================================================
|
||||
static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range)
|
||||
{
|
||||
if (camera == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Check distance first, since it's cheaper than checking sight.
|
||||
double dx = self->x - camera->x;
|
||||
double dy = self->y - camera->y;
|
||||
double dz;
|
||||
fixed_t eyez = (camera->z + camera->height - (camera->height>>2)); // same eye height as P_CheckSight
|
||||
if (eyez > self->z + self->height)
|
||||
{
|
||||
dz = self->z + self->height - eyez;
|
||||
}
|
||||
else if (eyez < self->z)
|
||||
{
|
||||
dz = self->z - eyez;
|
||||
}
|
||||
else
|
||||
{
|
||||
dz = 0;
|
||||
}
|
||||
if ((dx*dx) + (dy*dy) + (dz*dz) <= range)
|
||||
{ // Within range
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now check LOS.
|
||||
if (P_CheckSight(camera, self, SF_IGNOREVISIBILITY))
|
||||
{ // Visible
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange)
|
||||
{
|
||||
ACTION_PARAM_START(2);
|
||||
|
|
@ -2279,33 +2328,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange)
|
|||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
AActor *camera = players[i].camera;
|
||||
|
||||
// Check distance first, since it's cheaper than checking sight.
|
||||
double dx = self->x - camera->x;
|
||||
double dy = self->y - camera->y;
|
||||
double dz;
|
||||
fixed_t eyez = (camera->z + camera->height - (camera->height>>2)); // same eye height as P_CheckSight
|
||||
if (eyez > self->z + self->height)
|
||||
// Always check from each player.
|
||||
if (DoCheckSightOrRange(self, players[i].mo, range))
|
||||
{
|
||||
dz = self->z + self->height - eyez;
|
||||
}
|
||||
else if (eyez < self->z)
|
||||
{
|
||||
dz = self->z - eyez;
|
||||
}
|
||||
else
|
||||
{
|
||||
dz = 0;
|
||||
}
|
||||
if ((dx*dx) + (dy*dy) + (dz*dz) <= range)
|
||||
{ // Within range
|
||||
return;
|
||||
}
|
||||
|
||||
// Now check LOS.
|
||||
if (P_CheckSight(camera, self, SF_IGNOREVISIBILITY))
|
||||
{ // Visible
|
||||
// If a player is viewing from a non-player, check that too.
|
||||
if (players[i].camera != NULL && players[i].camera->player == NULL &&
|
||||
DoCheckSightOrRange(self, players[i].camera, range))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue