Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • zandronum/zandronum-stable
1 result
Show changes
Commits on Source (36)
Showing with 526 additions and 915 deletions
......@@ -85,6 +85,8 @@
+ - Added ACS function: "IsPlayerContestingControlPoint", to determine if a player is currently contesting a given control point. [Trillster]
+ - Added the CVar flagset "sv_forbidvoteflags" which combines all native vote forbidding CVars. [Trillster]
+ - Added the CCMD "listvotetypes" to list all native and custom vote types. [Trillster]
+ - Added the WEAPON.ALLOW_WITH_RESPAWN_INVUL flag to basic weapons in Heretic, Hexen, and Strife [AKMDM]
+ - Backported the +INVENTORY.ALWAYSRESPAWN actor flag from ZDoom. [Trillster]
- - Fixed: clients didn't initialize a sector's friction properly in some cases due to a superfluous check that wasn't removed earlier. [AKMDM]
- - Fixed: the server wouldn't initialize compatflags and compatflags2 properly if entered as command line parameters. [AKMDM]
- - Fixed: serverinfo CVars entered on the command line were restored in reverse order. [AKMDM]
......@@ -228,6 +230,9 @@
- - Fixed: actors with the CLIENTSIDEONLY flag didn't create splashes in online games. [AKMDM]
- - Fixed: the server didn't destroy actors that were clientsided only and spawned from serversided ACS scripts, and clients didn't mark actors spawned from clientsided ACS scripts as clientsided only. [AKMDM]
- - Fixed: unmorphing a player before they disconnected, joined spectators, or respawned didn't always succeed, and could sometimes cause clients to spawn a player that no longer existed. Also prevented exit flashes from spawning when players unmorphed in these special cases. [AKMDM]
- - Fixed: voodoo dolls didn't work in multiplayer emulation (addresses 2510). [Sean]
- - Fixed: A_Raise sometimes failed to remove respawn invulnerability from a player if cl_respawninvuleffect was 0, and could remove an invulnerability powerup that a player had in their inventory instead of the actual respawn invulnerability. [AKMDM]
- - Fixed: Unloading Clientside scripts would crash out the clients online (addresses 2147). [Ru5tK1ng]
! - The result value of GAMEEVENT_MEDALS event scripts can now be used to determine whether or not the player receives the medal. [AKMDM]
! - GAMEMODE flags are now validated after all GAMEMODE lumps have been parsed instead of after each one. The internal game mode name (e.g. "TeamLMS") is now printed with the error message instead of the actual name. [AKMDM]
! - Added an extra check to ensure that game modes have a (short) name. [AKMDM]
......@@ -285,6 +290,8 @@
! - Custom properties in skins are no longer ignored and can now be used with "GetSkinProperty". [Trillster]
! - Adjusted the text alignment and placement of the control point list in Domination. [Trillster]
! - The ammo types of weapons that have the NOLMS flag are no longer given out in LMS/TEAMLMS. [Ru5tK1ng]
! - Domination control points are now displayed in the order that they're defined in SECTINFO. [Trillster]
! - The "held by" message for the white flag is now colorized the same way as it is when picking up a team's flag or skull. [AKMDM]
3.1
......
......@@ -301,10 +301,6 @@
Player player with MoTest
EndCommand
Command PlayerRespawnInvulnerability
Player player with MoTest
EndCommand
Command PlayerUseInventory
Player player with MoTest
Class<AInventory> itemType
......
......@@ -4833,36 +4833,6 @@
//*****************************************************************************
//
void ServerCommands::PlayerRespawnInvulnerability::Execute()
{
// Don't taunt if we're not in a level!
if ( gamestate != GS_LEVEL )
return;
// First, we need to adjust the blend color, so the player's screen doesn't go white.
APowerInvulnerable *invulnerability = player->mo->FindInventory<APowerInvulnerable>();
if ( invulnerability == NULL )
return;
invulnerability->BlendColor = 0;
// Apply respawn invulnerability effect.
switch ( cl_respawninvuleffect )
{
case 1:
player->mo->RenderStyle = STYLE_Translucent;
player->mo->effects |= FX_VISIBILITYFLICKER;
break;
case 2:
player->mo->effects |= FX_RESPAWNINVUL;
break;
}
}
//*****************************************************************************
//
void ServerCommands::PlayerUseInventory::Execute()
{
// Try to find this object within the player's personal inventory.
......
......@@ -163,7 +163,7 @@
void COOP_SpawnVoodooDollsForPlayerIfNecessary ( const ULONG ulPlayer, const bool bSpawnEvenIfPlayerIsNotIngame )
{
// [BB] Only the server spawns voodoo dolls.
if ( NETWORK_GetState() != NETSTATE_SERVER )
if ( NETWORK_GetState() != NETSTATE_SERVER && NETWORK_GetState() != NETSTATE_SINGLE_MULTIPLAYER )
return;
// [BB] The current game mode doesn't need voodoo dolls.
......
......@@ -69,8 +69,6 @@
// [RK] New include
#include "d_netinf.h"
EXTERN_CVAR( Int, cl_respawninvuleffect )
//*****************************************************************************
// VARIABLES
......
......@@ -749,7 +749,8 @@
// [RH] Give scripts a chance to do something
unloading = true;
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true);
// [RK] The clients will only run client side Unloading scripts.
FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true, NETWORK_InClientMode());
unloading = false;
// [BC] If we're the server, tell clients that the map has finished.
......
......@@ -392,7 +392,9 @@
void APowerInvulnerable::InitEffect ()
{
Super::InitEffect();
Owner->effects &= ~FX_RESPAWNINVUL;
// [AK] Only clear FX_RESPAWNINVUL if the owner has no respawn protection.
if (Owner->FindInventory(RUNTIME_CLASS(APowerRespawnInvulnerable)) == nullptr)
Owner->effects &= ~FX_RESPAWNINVUL;
Owner->flags2 |= MF2_INVULNERABLE;
if (Mode == NAME_None)
{
......@@ -475,22 +477,6 @@
Owner->flags2 &= ~MF2_INVULNERABLE;
Owner->effects &= ~FX_RESPAWNINVUL;
if ( Owner->effects & FX_VISIBILITYFLICKER )
{
Owner->effects &= ~FX_VISIBILITYFLICKER;
// [BC] If the owner is a spectating player, don't make him visible!
if (( Owner->player == NULL ) || ( Owner->player->bSpectating == false ))
{
// [BB] Restore the default alpha value and set RenderStyle accordingly.
Owner->alpha = Owner->GetDefault()->alpha;
if ( Owner->alpha == OPAQUE )
Owner->RenderStyle = STYLE_Normal;
else
Owner->RenderStyle = STYLE_Translucent;
}
else
Owner->RenderStyle = STYLE_None;
}
if (Mode == NAME_Ghost)
{
Owner->flags2 &= ~MF2_NONSHOOTABLE;
......@@ -2166,6 +2152,116 @@
Inventory->ModifyDamage( damage, damageType, newdamage, passive );
}
// [AK] Respawn Invulnerability artifact powerup ----------------------------
// [AK] Moved this definition out of p_effect.cpp.
CVAR (Int, cl_respawninvuleffect, 1, CVAR_ARCHIVE);
IMPLEMENT_CLASS (APowerRespawnInvulnerable)
//===========================================================================
//
// APowerRespawnInvulnerable :: InitEffect
//
//===========================================================================
void APowerRespawnInvulnerable::InitEffect ()
{
Super::InitEffect();
EffectTics = 3 * TICRATE;
BlendColor = 0; // Don't mess with the view.
ItemFlags |= IF_UNDROPPABLE; // Don't drop this.
// [AK] Make sure the owner is valid.
if (Owner == nullptr)
return;
// Apply respawn invulnerability effect.
switch (cl_respawninvuleffect)
{
case 1:
Owner->RenderStyle = STYLE_Translucent;
Owner->effects |= FX_VISIBILITYFLICKER;
break;
case 2:
Owner->effects |= FX_RESPAWNINVUL; // [RH] special effect
break;
}
}
//===========================================================================
//
// APowerRespawnInvulnerable :: DoEffect
//
//===========================================================================
void APowerRespawnInvulnerable::DoEffect ()
{
Super::DoEffect();
// [BC] Flicker this objects visibility... ala starman in SMB.
if ((Owner != nullptr) && (Owner->effects & FX_VISIBILITYFLICKER))
{
switch (M_Random() % 3)
{
case 0:
Owner->alpha = TRANSLUC25;
break;
case 1:
Owner->alpha = TRANSLUC50;
break;
case 2:
Owner->alpha = TRANSLUC75;
break;
}
}
}
//===========================================================================
//
// APowerRespawnInvulnerable :: EndEffect
//
//===========================================================================
void APowerRespawnInvulnerable::EndEffect ()
{
Super::EndEffect();
if (Owner != nullptr)
{
AInventory *otherInvul = Owner->FindInventory(RUNTIME_CLASS(APowerInvulnerable), true);
// [AK] Don't cancel out invulnerability from other similar powerups.
if ((otherInvul != nullptr) && (otherInvul != this))
Owner->flags2 |= MF2_INVULNERABLE;
if (Owner->effects & FX_VISIBILITYFLICKER)
{
Owner->effects &= ~FX_VISIBILITYFLICKER;
// [BC] If the owner is a spectating player, don't make him visible!
if ((Owner->player == nullptr) || (Owner->player->bSpectating == false))
{
// [BB] Restore the default alpha value and set RenderStyle accordingly.
Owner->alpha = Owner->GetDefault()->alpha;
if (Owner->alpha == OPAQUE)
Owner->RenderStyle = STYLE_Normal;
else
Owner->RenderStyle = STYLE_Translucent;
}
else
{
Owner->RenderStyle = STYLE_None;
}
}
}
}
// Translucency Powerup (Skulltag's version of invisibility) ----------------
IMPLEMENT_CLASS( APowerTranslucency )
......
......@@ -292,6 +292,15 @@
virtual void ModifyDamage( int damage, FName damageType, int &newdamage, bool passive );
};
class APowerRespawnInvulnerable : public APowerInvulnerable
{
DECLARE_CLASS( APowerRespawnInvulnerable, APowerInvulnerable )
protected:
virtual void InitEffect ();
virtual void DoEffect ();
virtual void EndEffect ();
};
class APowerTranslucency : public APowerInvisibility
{
DECLARE_CLASS (APowerTranslucency, APowerInvisibility)
......
This diff is collapsed.
......@@ -567,7 +567,7 @@
if ((ItemFlags & IF_BIGPOWERUP) && !(dmflags & DF_RESPAWN_SUPER)) return false;
if (ItemFlags & IF_NEVERRESPAWN) return false;
return !!(dmflags & DF_ITEMS_RESPAWN);
return !!((dmflags & DF_ITEMS_RESPAWN) || (ItemFlags & IF_ALWAYSRESPAWN));
}
//===========================================================================
......
......@@ -136,7 +136,8 @@
IF_NEVERRESPAWN = 1<<20, // Never, ever respawns
IF_NOSCREENFLASH = 1<<21, // No pickup flash on the player's screen
IF_TOSSED = 1<<22, // Was spawned by P_DropItem (i.e. as a monster drop)
IF_FORCERESPAWNINSURVIVAL = 1<<23, // [BB] Will be respawned in survival even without DF_ITEMS_RESPAWN.
IF_ALWAYSRESPAWN = 1<<23, // Always respawn, regardless of dmflag
IF_FORCERESPAWNINSURVIVAL = 1<<24, // [BB] Will be respawned in survival even without DF_ITEMS_RESPAWN.
};
......
......@@ -140,12 +140,12 @@
virtual bool ShouldRespawn( );
virtual bool TryPickup( AActor *&pToucher );
virtual bool HandlePickup( AInventory *pItem );
virtual LONG AllowFlagPickup( AActor *pToucher );
virtual void AnnounceFlagPickup( AActor *pToucher );
virtual void DisplayFlagTaken( AActor *pToucher );
virtual void ReturnFlag( AActor *pReturner );
virtual int AllowFlagPickup( AActor *toucher );
virtual void AnnounceFlagPickup( AActor *toucher );
virtual void DisplayFlagTaken( AActor *toucher );
virtual void ReturnFlag( AActor *returner );
virtual void AnnounceFlagReturn( void );
virtual void DisplayFlagReturn( void );
void MarkFlagTaken( bool bTaken );
void ResetReturnTicks( void );
......@@ -147,12 +147,13 @@
virtual void AnnounceFlagReturn( void );
virtual void DisplayFlagReturn( void );
void MarkFlagTaken( bool bTaken );
void ResetReturnTicks( void );
LONG lTick;
protected:
virtual const char *GetType( void ) { return "item"; }
};
class AFlag : public ATeamItem
{
DECLARE_CLASS( AFlag, ATeamItem )
public:
......@@ -153,14 +154,25 @@
};
class AFlag : public ATeamItem
{
DECLARE_CLASS( AFlag, ATeamItem )
public:
virtual bool HandlePickup( AInventory *pItem );
virtual LONG AllowFlagPickup( AActor *pToucher );
virtual void AnnounceFlagPickup( AActor *pToucher );
virtual void DisplayFlagTaken( AActor *pToucher );
virtual void ReturnFlag( AActor *pReturner );
virtual bool HandlePickup( AInventory *item );
virtual int AllowFlagPickup( AActor *toucher );
protected:
virtual const char *GetType( void ) { return "flag"; }
};
class AWhiteFlag : public AFlag
{
DECLARE_CLASS( AWhiteFlag, AFlag )
public:
virtual bool HandlePickup( AInventory *item );
virtual int AllowFlagPickup( AActor *toucher );
virtual void AnnounceFlagPickup( AActor *toucher );
virtual void DisplayFlagTaken( AActor *toucher );
virtual void ReturnFlag( AActor *returner );
virtual void AnnounceFlagReturn( void );
virtual void DisplayFlagReturn( void );
};
......@@ -168,5 +180,6 @@
class ASkull : public ATeamItem
{
DECLARE_CLASS( ASkull, ATeamItem )
protected:
public:
virtual int AllowFlagPickup( AActor *toucher );
......@@ -172,10 +185,6 @@
virtual LONG AllowFlagPickup( AActor *pToucher );
virtual void AnnounceFlagPickup( AActor *pToucher );
virtual void DisplayFlagTaken( AActor *pToucher );
virtual void ReturnFlag( AActor *pReturner );
virtual void AnnounceFlagReturn( void );
virtual void DisplayFlagReturn( void );
protected:
virtual const char *GetType( void ) { return "skull"; }
};
class AFloatyIcon : public AActor
......
......@@ -1021,7 +1021,7 @@
longestPointWidth += SmallFont->StringWidth( " " );
int currentPoint = 1;
for ( int i = level.info->SectorInfo.Points.Size() - 1; i >= 0; i-- )
for ( unsigned int i = 0; i < level.info->SectorInfo.Points.Size(); i++ )
{
if ( level.info->SectorInfo.Points[i].disabled )
continue;
......
......@@ -123,7 +123,6 @@
ENUM_ELEMENT ( SVC_PLAYERSAY ),
ENUM_ELEMENT ( SVC_PLAYERVOIPAUDIOPACKET ),
ENUM_ELEMENT ( SVC_PLAYERTAUNT ),
ENUM_ELEMENT ( SVC_PLAYERRESPAWNINVULNERABILITY ),
ENUM_ELEMENT ( SVC_PLAYERUSEINVENTORY ),
ENUM_ELEMENT ( SVC_PLAYERDROPINVENTORY ),
ENUM_ELEMENT ( SVC_SPAWNTHING ), // THING COMMANDS
......
......@@ -3401,7 +3401,9 @@
if (( NETWORK_GetState( ) == NETSTATE_SERVER ) &&
ACS_IsScriptClientSide( ptr ))
{
SERVERCOMMANDS_ACSScriptExecute( ptr->Number, activator, 0, 0, 0, arg, 3, always );
// [RK] If it's an unloading script, don't waste traffic since the clients will run it on their own in G_ChangeLevel
if( ptr->Type != SCRIPT_Unloading )
SERVERCOMMANDS_ACSScriptExecute( ptr->Number, activator, 0, 0, 0, arg, 3, always );
continue;
}
DLevelScript *runningScript = P_GetScriptGoing (activator, NULL, ptr->Number,
......
......@@ -63,7 +63,6 @@
CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
CVAR (Int, cl_grenadetrails, 1, CVAR_ARCHIVE);
CVAR (Int, cl_respawninvuleffect, 1, CVAR_ARCHIVE);
CVAR (Bool, cl_showspawns, false, CVAR_ARCHIVE); // [CK] Particle fountains at spawns
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
CVAR (Int, r_rail_spiralsparsity, 1, CVAR_ARCHIVE);
......
......@@ -33,7 +33,6 @@
#include "vectors.h"
#include "tables.h"
#include "c_cvars.h" // [BC] #include this so that we can't extern cl_respawninvuleffect.
#define FX_ROCKET 0x00000001
#define FX_GRENADE 0x00000002
......@@ -94,6 +93,3 @@
void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind);
void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind);
void P_DisconnectEffect (AActor *actor);
// [BC] Extern this here so we don't have to do it everywhere else.
EXTERN_CVAR (Int, cl_respawninvuleffect)
......@@ -4144,14 +4144,4 @@
}
}
// [BC] Flicker this objects visibility... ala starman in SMB.
if ( effects & FX_VISIBILITYFLICKER )
{
switch ( M_Random( ) % 3 )
{
case 0: alpha = TRANSLUC25; break;
case 1: alpha = TRANSLUC50; break;
case 2: alpha = TRANSLUC75; break;
}
}
// [RH] Pulse in and out of visibility
......@@ -4157,5 +4147,5 @@
// [RH] Pulse in and out of visibility
else if (effects & FX_VISIBILITYPULSE)
if (effects & FX_VISIBILITYPULSE)
{
if (visdir > 0)
{
......@@ -5422,7 +5412,6 @@
angle_t spawn_angle;
// [BC]
LONG lSkin;
AInventory *pInventory;
// not playing?
if ((unsigned)playernum >= (unsigned)MAXPLAYERS || !playeringame[playernum])
......@@ -5735,38 +5724,27 @@
// it above, but the other modes don't.
oldactor->DestroyAllInventory();
}
// [BC] Apply temporary invulnerability when respawned.
if (( NETWORK_InClientMode() == false ) &&
// [BB] Added PST_REBORNNOINVENTORY, PST_ENTERNOINVENTORY.
(state == PST_REBORN || state == PST_ENTER || state == PST_REBORNNOINVENTORY || state == PST_ENTERNOINVENTORY) &&
(( dmflags2 & DF2_NO_RESPAWN_INVUL ) == false ) &&
( deathmatch || teamgame || alwaysapplydmflags ) &&
( p->bSpectating == false ))
{
APowerup *invul = static_cast<APowerup*>(p->mo->GiveInventoryType (RUNTIME_CLASS(APowerInvulnerable)));
// [BB] It's possible that giving the powerup fails, e.g. in Cutman's Level Master.
if ( invul != NULL )
{
invul->EffectTics = 3*TICRATE;
invul->BlendColor = 0; // don't mess with the view
invul->ItemFlags |= IF_UNDROPPABLE; // Don't drop this
// [BB] The clients are informed about the powerup and these adjustments later.
// Apply respawn invulnerability effect.
switch ( cl_respawninvuleffect )
{
case 1:
p->mo->RenderStyle = STYLE_Translucent;
p->mo->effects |= FX_VISIBILITYFLICKER;
break;
case 2:
p->mo->effects |= FX_RESPAWNINVUL; // [RH] special effect
break;
}
}
// [BC] Handle temporary invulnerability when respawned
// [BB] Added PST_REBORNNOINVENTORY, PST_ENTERNOINVENTORY.
// [AK] multiplayer -> deathmatch || teamgame, and added NETWORK_InClientMode and spectator checks.
if ((state == PST_REBORN || state == PST_ENTER || state == PST_REBORNNOINVENTORY || state == PST_ENTERNOINVENTORY) &&
((dmflags2 & DF2_NO_RESPAWN_INVUL) == false) &&
(deathmatch || teamgame || alwaysapplydmflags) &&
(NETWORK_InClientMode() == false) &&
(p->bSpectating == false))
{
// [AK] Use APowerRespawnInvulnerable instead.
APowerup *invul = static_cast<APowerup*>(p->mo->GiveInventoryType (RUNTIME_CLASS(APowerRespawnInvulnerable)));
/* [AK] Zandronum handles this in APowerRespawnInvulnerable::InitEffect.
invul->EffectTics = 3*TICRATE;
invul->BlendColor = 0; // don't mess with the view
invul->ItemFlags |= IF_UNDROPPABLE; // Don't drop this
p->mo->effects |= FX_RESPAWNINVUL; // [RH] special effect
*/
// [AK] Tell clients about the respawning powerup.
if (NETWORK_GetState() == NETSTATE_SERVER)
SERVERCOMMANDS_GivePowerup (playernum, invul);
}
if (StatusBar != NULL && (playernum == consoleplayer || StatusBar->GetPlayer() == playernum))
......@@ -5802,19 +5780,10 @@
// [BB] Moved the exec.wad MAP01 "fix" up.
// Tell clients about the respawning player.
if ( NETWORK_GetState( ) == NETSTATE_SERVER )
{
// [BB] The clients start their reactiontime later on their end. Try to adjust for this.
SERVER_AdjustPlayersReactiontime ( playernum );
pInventory = mobj->FindInventory( RUNTIME_CLASS( APowerInvulnerable ));
if (( pInventory ) && ( p->bSpectating == false ))
{
SERVERCOMMANDS_GivePowerup( playernum, static_cast<APowerup *>( pInventory ));
SERVERCOMMANDS_PlayerRespawnInvulnerability( playernum );
}
}
// [BB] The clients start their reactiontime later on their end. Try to adjust for this.
if (NETWORK_GetState() == NETSTATE_SERVER)
SERVER_AdjustPlayersReactiontime (playernum);
// [BC] Do script stuff
if (!(flags & SPF_TEMPPLAYER))
{
......
......@@ -1157,6 +1157,5 @@
// [BC] If this player has respawn invulnerability, disable it if they're done raising
// a weapon that isn't the pistol or their fist.
if (( player->mo ) &&
( NETWORK_InClientMode() == false ))
if ((player->mo) && (NETWORK_InClientMode() == false))
{
......@@ -1162,3 +1161,3 @@
{
APowerInvulnerable *pInvulnerability;
APowerRespawnInvulnerable *invul = static_cast<APowerRespawnInvulnerable *>(player->mo->FindInventory (RUNTIME_CLASS(APowerRespawnInvulnerable)));
......@@ -1164,7 +1163,3 @@
pInvulnerability = static_cast<APowerInvulnerable *>( player->mo->FindInventory( RUNTIME_CLASS( APowerInvulnerable )));
if (( pInvulnerability ) &&
( player->ReadyWeapon ) &&
(( player->ReadyWeapon->WeaponFlags & WIF_ALLOW_WITH_RESPAWN_INVUL ) == false ) &&
(( player->mo->effects & FX_VISIBILITYFLICKER ) || ( player->mo->effects & FX_RESPAWNINVUL )))
if ((invul) && (player->ReadyWeapon) && ((player->ReadyWeapon->WeaponFlags & WIF_ALLOW_WITH_RESPAWN_INVUL) == false))
{
......@@ -1170,4 +1165,4 @@
{
pInvulnerability->Destroy( );
invul->Destroy();
// If we're the server, tell clients to take this player's powerup away.
......@@ -1172,7 +1167,7 @@
// If we're the server, tell clients to take this player's powerup away.
if ( NETWORK_GetState( ) == NETSTATE_SERVER )
SERVERCOMMANDS_TakeInventory( ULONG( player - players ), RUNTIME_CLASS( APowerInvulnerable ), 0 );
if (NETWORK_GetState() == NETSTATE_SERVER)
SERVERCOMMANDS_TakeInventory (static_cast<unsigned>(player - players), RUNTIME_CLASS(APowerRespawnInvulnerable), 0);
}
}
}
......
......@@ -1952,8 +1952,14 @@
// [BB] When we are using unassigned voodoo dolls, we have to enforce the spawning
// of all dolls for all players (even those who are not in the game) now.
COOP_SpawnVoodooDollsForPlayerIfNecessary ( i, sv_coopunassignedvoodoodolls );
if (playeringame[i] && players[i].mo != NULL)
P_PlayerStartStomp(players[i].mo);
// [SB] If we are in online or multiplayer emulation, at this point we will be spawning voodoo dolls,
// but the actual player mobjs will be spawned later. As such, handling spawn telefragging now will
// only result in telefragging the voodoo dolls, which can cause havoc on maps like Plutonia MAP06.
// Since the multiplayer spawning code also handles telefragging, skip it here.
if ( NETWORK_GetState() == NETSTATE_SINGLE )
if (playeringame[i] && players[i].mo != NULL)
P_PlayerStartStomp(players[i].mo);
}
// [BB] When initially spawning the voodoo dolls, we also need to clear the stored pickups
// of the unassigned dolls.
......