mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-03 02:30:53 +00:00
* Updated to ZDoom r3450:
- Fix signed/unsigned mismatch warned by GCC. - Moved "Go away!" text into language.enu. - 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. - Revised the fix from r3442: Make the line a nonrepeatable Door_Open instead of completely clearing the line's special. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1315 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
908f2cd8c7
commit
c67c51614b
13 changed files with 124 additions and 64 deletions
|
@ -592,13 +592,16 @@ void PlayerIsGone (int netnode, int netconsole)
|
||||||
Printf ("%s left the game\n", players[netconsole].userinfo.netname);
|
Printf ("%s left the game\n", players[netconsole].userinfo.netname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Revert to your own view if spying through the player who left
|
// [RH] Revert each player to their own view if spying through the player who left
|
||||||
if (players[consoleplayer].camera == players[netconsole].mo)
|
for (int ii = 0; ii < MAXPLAYERS; ++ii)
|
||||||
{
|
{
|
||||||
players[consoleplayer].camera = players[consoleplayer].mo;
|
if (playeringame[ii] && players[ii].camera == players[netconsole].mo)
|
||||||
if (StatusBar != NULL)
|
|
||||||
{
|
{
|
||||||
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
players[ii].camera = players[ii].mo;
|
||||||
|
if (ii == consoleplayer && StatusBar != NULL)
|
||||||
|
{
|
||||||
|
StatusBar->AttachToPlayer (&players[ii]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2460,6 +2463,10 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
||||||
F_AdvanceIntermission();
|
F_AdvanceIntermission();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEM_REVERTCAMERA:
|
||||||
|
players[player].camera = players[player].mo;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
I_Error ("Unknown net command: %d", type);
|
I_Error ("Unknown net command: %d", type);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -162,6 +162,7 @@ enum EDemoCommand
|
||||||
DEM_SETPITCHLIMIT, // 63 Byte: Up limit, Byte: Down limit (in degrees)
|
DEM_SETPITCHLIMIT, // 63 Byte: Up limit, Byte: Down limit (in degrees)
|
||||||
DEM_ADVANCEINTER, // 64 Advance intermission screen state
|
DEM_ADVANCEINTER, // 64 Advance intermission screen state
|
||||||
DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int
|
DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int
|
||||||
|
DEM_REVERTCAMERA, // 66
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following are implemented by cht_DoCheat in m_cheat.cpp
|
// The following are implemented by cht_DoCheat in m_cheat.cpp
|
||||||
|
|
|
@ -831,7 +831,12 @@ static void ChangeSpy (bool forward)
|
||||||
// If not viewing through a player, return your eyes to your own head.
|
// If not viewing through a player, return your eyes to your own head.
|
||||||
if (players[consoleplayer].camera->player == NULL)
|
if (players[consoleplayer].camera->player == NULL)
|
||||||
{
|
{
|
||||||
players[consoleplayer].camera = players[consoleplayer].mo;
|
// When watching demos, you will just have to wait until your player
|
||||||
|
// has done this for you, since it could desync otherwise.
|
||||||
|
if (!demoplayback)
|
||||||
|
{
|
||||||
|
Net_WriteByte(DEM_REVERTCAMERA);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -920,10 +920,13 @@ void G_DoLoadLevel (int position, bool autosave)
|
||||||
level.starttime = gametic;
|
level.starttime = gametic;
|
||||||
G_UnSnapshotLevel (!savegamerestore); // [RH] Restore the state of the level.
|
G_UnSnapshotLevel (!savegamerestore); // [RH] Restore the state of the level.
|
||||||
G_FinishTravel ();
|
G_FinishTravel ();
|
||||||
if (players[consoleplayer].camera == NULL ||
|
// For each player, if they are viewing through a player, make sure it is themselves.
|
||||||
players[consoleplayer].camera->player != NULL)
|
for (int ii = 0; i < MAXPLAYERS; ++i)
|
||||||
{ // If we are viewing through a player, make sure it is us.
|
{
|
||||||
players[consoleplayer].camera = players[consoleplayer].mo;
|
if (playeringame[ii] && (players[ii].camera == NULL || players[ii].camera->player != NULL))
|
||||||
|
{
|
||||||
|
players[ii].camera = players[ii].mo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
||||||
P_DoDeferedScripts (); // [RH] Do script actions that were triggered on another map.
|
P_DoDeferedScripts (); // [RH] Do script actions that were triggered on another map.
|
||||||
|
@ -1143,6 +1146,7 @@ void G_FinishTravel ()
|
||||||
pawn->target = NULL;
|
pawn->target = NULL;
|
||||||
pawn->lastenemy = NULL;
|
pawn->lastenemy = NULL;
|
||||||
pawn->player->mo = pawn;
|
pawn->player->mo = pawn;
|
||||||
|
pawn->player->camera = pawn;
|
||||||
DObject::StaticPointerSubstitution (oldpawn, pawn);
|
DObject::StaticPointerSubstitution (oldpawn, pawn);
|
||||||
oldpawn->Destroy();
|
oldpawn->Destroy();
|
||||||
pawndup->Destroy ();
|
pawndup->Destroy ();
|
||||||
|
|
|
@ -5255,6 +5255,9 @@ int DLevelScript::RunScript ()
|
||||||
STACK(1) = !STACK(1);
|
STACK(1) = !STACK(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case PCD_NEGATEBINARY:
|
case PCD_NEGATEBINARY:
|
||||||
STACK(1) = ~STACK(1);
|
STACK(1) = ~STACK(1);
|
||||||
break;
|
break;
|
||||||
|
@ -7400,11 +7403,11 @@ static void addDefered (level_info_t *i, acsdefered_t::EType type, int script, c
|
||||||
def->next = i->defered;
|
def->next = i->defered;
|
||||||
def->type = type;
|
def->type = type;
|
||||||
def->script = script;
|
def->script = script;
|
||||||
for (j = 0; j < countof(def->args) && j < argcount; ++j)
|
for (j = 0; (size_t)j < countof(def->args) && j < argcount; ++j)
|
||||||
{
|
{
|
||||||
def->args[j] = args[j];
|
def->args[j] = args[j];
|
||||||
}
|
}
|
||||||
while (j < countof(def->args))
|
while ((size_t)j < countof(def->args))
|
||||||
{
|
{
|
||||||
def->args[j++] = 0;
|
def->args[j++] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -720,7 +720,7 @@ public:
|
||||||
toSay = GStrings[dlgtext];
|
toSay = GStrings[dlgtext];
|
||||||
if (toSay == NULL)
|
if (toSay == NULL)
|
||||||
{
|
{
|
||||||
toSay = "Go away!"; // Ok, it's lame - but it doesn't look like an error to the player. ;)
|
toSay = GStrings["TXT_GOAWAY"]; // Ok, it's lame - but it doesn't look like an error to the player. ;)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -4051,9 +4051,12 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
|
||||||
|
|
||||||
p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0.
|
p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0.
|
||||||
|
|
||||||
if (players[consoleplayer].camera == oldactor)
|
for (int ii = 0; ii < MAXPLAYERS; ++ii)
|
||||||
{
|
{
|
||||||
players[consoleplayer].camera = mobj;
|
if (playeringame[ii] && players[ii].camera == oldactor)
|
||||||
|
{
|
||||||
|
players[ii].camera = oldactor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] Allow chasecam for demo watching
|
// [RH] Allow chasecam for demo watching
|
||||||
|
|
|
@ -326,21 +326,25 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep)
|
||||||
{
|
{
|
||||||
APlayerPawn *replacement = static_cast<APlayerPawn *>(rep);
|
APlayerPawn *replacement = static_cast<APlayerPawn *>(rep);
|
||||||
size_t changed = 0;
|
size_t changed = 0;
|
||||||
if (mo == old) mo = replacement, changed++;
|
|
||||||
if (poisoner == old) poisoner = replacement, changed++;
|
// The construct *& is used in several of these to avoid the read barriers
|
||||||
if (attacker == old) attacker = replacement, changed++;
|
// that would turn the pointer we want to check to NULL if the old object
|
||||||
if (camera == old) camera = replacement, changed++;
|
// is pending deletion.
|
||||||
if (dest == old) dest = replacement, changed++;
|
if (mo == old) mo = replacement, changed++;
|
||||||
if (prev == old) prev = replacement, changed++;
|
if (*&poisoner == old) poisoner = replacement, changed++;
|
||||||
if (enemy == old) enemy = replacement, changed++;
|
if (*&attacker == old) attacker = replacement, changed++;
|
||||||
if (missile == old) missile = replacement, changed++;
|
if (*&camera == old) camera = replacement, changed++;
|
||||||
if (mate == old) mate = replacement, changed++;
|
if (*&dest == old) dest = replacement, changed++;
|
||||||
if (last_mate == old) last_mate = replacement, changed++;
|
if (*&prev == old) prev = replacement, changed++;
|
||||||
if (ReadyWeapon == old) ReadyWeapon = static_cast<AWeapon *>(rep), changed++;
|
if (*&enemy == old) enemy = replacement, changed++;
|
||||||
if (PendingWeapon == old) PendingWeapon = static_cast<AWeapon *>(rep), changed++;
|
if (*&missile == old) missile = replacement, changed++;
|
||||||
if (PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
|
if (*&mate == old) mate = replacement, changed++;
|
||||||
if (ConversationNPC == old) ConversationNPC = replacement, changed++;
|
if (*&last_mate == old) last_mate = replacement, changed++;
|
||||||
if (ConversationPC == old) ConversationPC = replacement, changed++;
|
if (ReadyWeapon == old) ReadyWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||||
|
if (PendingWeapon == old) PendingWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||||
|
if (*&PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||||
|
if (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
|
||||||
|
if (*&ConversationPC == old) ConversationPC = replacement, changed++;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
// This file was automatically generated by the
|
// This file was automatically generated by the
|
||||||
// updaterevision tool. Do not edit by hand.
|
// updaterevision tool. Do not edit by hand.
|
||||||
|
|
||||||
#define ZD_SVN_REVISION_STRING "3446"
|
#define ZD_SVN_REVISION_STRING "3450"
|
||||||
#define ZD_SVN_REVISION_NUMBER 3446
|
#define ZD_SVN_REVISION_NUMBER 3450
|
||||||
|
|
|
@ -2253,7 +2253,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
|
||||||
|
|
||||||
for (int i = 0; i < MAXPLAYERS; i++)
|
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);
|
ACTION_JUMP(jump);
|
||||||
|
@ -2266,6 +2279,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
|
||||||
// Useful for maps with many multi-actor special effects.
|
// 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)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange)
|
||||||
{
|
{
|
||||||
ACTION_PARAM_START(2);
|
ACTION_PARAM_START(2);
|
||||||
|
@ -2279,33 +2328,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
{
|
{
|
||||||
AActor *camera = players[i].camera;
|
// Always check from each player.
|
||||||
|
if (DoCheckSightOrRange(self, players[i].mo, range))
|
||||||
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
// If a player is viewing from a non-player, check that too.
|
||||||
// Now check LOS.
|
if (players[i].camera != NULL && players[i].camera->player == NULL &&
|
||||||
if (P_CheckSight(camera, self, SF_IGNOREVISIBILITY))
|
DoCheckSightOrRange(self, players[i].camera, range))
|
||||||
{ // Visible
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
// Version identifier for network games.
|
// Version identifier for network games.
|
||||||
// Bump it every time you do a release unless you're certain you
|
// Bump it every time you do a release unless you're certain you
|
||||||
// didn't change anything that will affect sync.
|
// didn't change anything that will affect sync.
|
||||||
#define NETGAMEVERSION 226
|
#define NETGAMEVERSION 227
|
||||||
|
|
||||||
// Version stored in the ini's [LastRun] section.
|
// Version stored in the ini's [LastRun] section.
|
||||||
// Bump it if you made some configuration change that you want to
|
// Bump it if you made some configuration change that you want to
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
// Protocol version used in demos.
|
// Protocol version used in demos.
|
||||||
// Bump it if you change existing DEM_ commands or add new ones.
|
// Bump it if you change existing DEM_ commands or add new ones.
|
||||||
// Otherwise, it should be safe to leave it alone.
|
// Otherwise, it should be safe to leave it alone.
|
||||||
#define DEMOGAMEVERSION 0x217
|
#define DEMOGAMEVERSION 0x218
|
||||||
|
|
||||||
// Minimum demo version we can play.
|
// Minimum demo version we can play.
|
||||||
// Bump it whenever you change or remove existing DEM_ commands.
|
// Bump it whenever you change or remove existing DEM_ commands.
|
||||||
|
|
|
@ -159,8 +159,9 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citidel, map54
|
||||||
|
|
||||||
2B65CB046EA40D2E44576949381769CA // Commercial Doom e3m4
|
2B65CB046EA40D2E44576949381769CA // Commercial Doom e3m4
|
||||||
{
|
{
|
||||||
// This line is erroneously flagged as a door that monsters can operate.
|
// This line is erroneously specified as Door_Raise that monsters
|
||||||
// If they do, they block you off from half the map. Since the attached
|
// can operate. If they do, they block you off from half the map. Change
|
||||||
// sector isn't a door, remove the special.
|
// this into a one-shot Door_Open so that it won't close.
|
||||||
clearlinespecial 1069
|
setlinespecial 1069 Door_Open 0 16 0 0 0
|
||||||
|
clearlineflags 1069 0x200
|
||||||
}
|
}
|
||||||
|
|
|
@ -1481,7 +1481,8 @@ TXT_RANDOM_PGUARD_10 = "If there is any honor inside that pathetic shell of a bo
|
||||||
TXT_RANDOMGOODBYE_1 = "Bye!";
|
TXT_RANDOMGOODBYE_1 = "Bye!";
|
||||||
TXT_RANDOMGOODBYE_2 = "Thanks, bye!";
|
TXT_RANDOMGOODBYE_2 = "Thanks, bye!";
|
||||||
TXT_RANDOMGOODBYE_3 = "See you later!";
|
TXT_RANDOMGOODBYE_3 = "See you later!";
|
||||||
TXT_HAVEENOUGH = "You seem to have enough!";
|
TXT_HAVEENOUGH = "You seem to have enough!";
|
||||||
|
TXT_GOAWAY = "Go away!";
|
||||||
|
|
||||||
// Skills:
|
// Skills:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue