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 (12)
Showing
with 336 additions and 355 deletions
......@@ -21,6 +21,7 @@
*+ - Added support for voice chat. Audio is encoded and decoded using Opus, allowing it to be transmitted over the network with minimal bandwidth usage and decent quality. Any unwanted noise in the audio is also removed with RNNoise before it's sent to the server. [AKMDM]
*+ - Generalized the medal system and added the new MEDALDEF lump to define custom medals. Players can be awarded medals using the ACS and DECORATE functions: "GivePlayerMedal" and "A_GivePlayerMedal". [AKMDM]
*+ - Added support for loading multiple banlists (and exemption lists). Server hosts can load extra files by separating the filenames with semi-colons. [AKMDM]
*+ - Reworked the domination gamemode to allow contesting of control points. [Trillster]
+ - Added the +NOMORPHLIMITATIONS flag, allowing morphs to switch weapons, play sounds, and be affected by speed powerups. [geNia, Binary]
+ - Added CVars: "con_interpolate" and "con_speed" which interpolates and controls how fast the console moves. Based on featues from ZCC. [AKMDM]
+ - Added ACS functions: "GetMapPosition", "GetEventResult", "GetActorSectorLocation", and "ChangeTeamScore". [AKMDM]
......@@ -76,6 +77,9 @@
+ - Added new SBARINFO top level "AppendStatusBar" to allow for adding extra SBARINFO code onto existing custom SBARINFO definitions. [Binary]
+ - Added the CVar "sv_dominationscorerate" to allow customizing how often points are obtained in the Domination gamemode. [Trillster]
+ - Added the CVar "cl_noswitchonfire", preventing players from automatically switching to the weapon they picked up if they're pressing +attack or +altattack. [AKMDM]
+ - Added ACS functions: "GetControlPointInfo" and "SetControlPointInfo", to get and set different types of info about any domination points which exist on the level. [Trillster]
+ - Added event GAMEEVENT_DOMINATION_PRECONTROL, which executes just before a domination point is captured, allowing the capture to be denied. [Trillster]
+ - Added event GAMEEVENT_DOMINATION_CONTEST, which executes whenever a player is contesting a domination point. Note that for performance reasons, this event is disabled by default so modders have to enable it by themselves. [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]
......@@ -218,6 +222,7 @@
- - Fixed: it was possible to set chat_sound or privatechat_sound to "Doom 2" in Doom 1, which didn't work because Doom 1 only has one chat sound. Also fixed these settings for other non-Doom IWADs. [AKMDM]
- - 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]
! - 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]
......@@ -271,6 +276,7 @@
! - Players now earn medals while cl_medals is disabled, but the medals themselves still remain unseen. [AKMDM]
! - Removed the hardcoded spawning behaviour that was used specifically for Team LMS, in favour of using sv_spawnfarthest. [AKMDM]
! - Adding -NOTDMATCH to WhiteFlag inheriting actors now allows them to spawn in non-1FCTF gamemodes. [Trillster]
! - NetIDs are now unsigned, doubling the maximum NetID possible from 32767 to 65535. [AKMDM, Sean]
3.1
......
......@@ -377,8 +377,9 @@
{
BuildNetCommand().sendCommandToClients( playerExtra, flags );
}
};
''')
};''')
self.writeline('')
# For each server command, create a class to represent it.
for command in self.getcommands('GameServerToClient'):
......
......@@ -234,7 +234,8 @@
# Write the code to read in the netid
writer.declare('int', netid)
writer.writeline('{netid} = bytestream->ReadShort();'.format(**locals()))
# [SB] NetIDs are ushorts now, so ensure they are interpreted as such.
writer.writeline('{netid} = static_cast<unsigned short>(bytestream->ReadShort());'.format(**locals()))
def writereadchecks(self, writer, command, reference, **args):
netid = self.readnetid
......@@ -250,7 +251,7 @@
allownull=('nullallowed' in self.attributes) and 'true' or 'false', **locals()))
def writesend(self, writer, command, reference, **args):
writer.writeline('command.addShort( this->{reference} ? this->{reference}->NetID : -1 );'.format(**locals()))
writer.writeline('command.addShort( this->{reference} ? this->{reference}->NetID : 0 );'.format(**locals()))
# ----------------------------------------------------------------------------------------------------------------------
......@@ -561,3 +562,31 @@
def writesend(self, writer, command, reference, **args):
writer.writeline('command.addName( this->{reference} );'.format(**locals()))
# ----------------------------------------------------------------------------------------------------------------------
class NetidParameter(ShortParameter):
def writeread(self, writer, command, reference):
readfunction = 'Read' + self.methodname()
casttype = self.cxxtypename
writer.writeline('command.{reference} = static_cast<{casttype}>(bytestream->{readfunction}());'.format(**locals()))
@property
def cxxtypename(self):
return 'unsigned short'
# ----------------------------------------------------------------------------------------------------------------------
class BufferParameter(SpecParameter):
def __init__(self, **args):
super().__init__(**args)
self.cxxtypename = 'BufferParameter'
def writeread(self, writer, command, reference, **args):
writer.writeline('command.{reference}( bytestream );'.format(**locals()))
def writesend(self, writer, command, reference, **args):
writer.writecontext('''
command.addShort( this->{reference}.size );
command.addBuffer( this->{reference}.data, this->{reference}.size );'''.format(**locals()))
......@@ -79,3 +79,9 @@
Command CloseMenu
ExtendedCommand
EndCommand
Command SetDominationPointOwner
Byte point
Byte team
Bool broadcast
EndCommand
......@@ -6,7 +6,7 @@
Bool isSpectating
Bool isDeadSpectator
Bool isMorphed
Short netid
NetID netid
Angle angle
Fixed x
Fixed y
......@@ -290,6 +290,13 @@
String message
EndCommand
Command PlayerVoIPAudioPacket
UnreliableCommand
Byte playerNumber
Long frame
Buffer audio
EndCommand
Command PlayerTaunt
Player player with MoTest
EndCommand
......
......@@ -3,7 +3,7 @@
AproxFixed y
AproxFixed z
Class type
Short id
NetID id
EndCommand
Command SpawnThingNoNetID
......@@ -18,7 +18,7 @@
Fixed y
Fixed z
Class type
Short id
NetID id
EndCommand
Command SpawnThingExactNoNetID
......@@ -34,7 +34,7 @@
AproxFixed y
AproxFixed z
Class type
Short id
NetID id
EndCommand
Command LevelSpawnThingNoNetID
......@@ -370,7 +370,7 @@
AproxFixed y
AproxFixed z
Class pufftype
Short id
NetID id
EndCommand
Command SpawnPuffNoNetID
......
......@@ -6,8 +6,8 @@
Fixed velY
Fixed velZ
Class<AActor> missileType
Short netID
Short targetNetID
NetID netID
NetID targetNetID
EndCommand
Command SpawnMissileExact
......@@ -18,8 +18,8 @@
Fixed velY
Fixed velZ
Class<AActor> missileType
Short netID
Short targetNetID
NetID netID
NetID targetNetID
EndCommand
Command MissileExplode
......
......@@ -40,6 +40,9 @@
#include "memarena.h"
#include "g_level.h"
// [AK] Needed for std::numeric_limits in the IDList class.
#include <limits>
struct subsector_t;
//
// NOTES: AActor
......@@ -1152,7 +1155,7 @@
int FixedColormap;
// ID used to identify this actor over network games.
int NetID;
unsigned short NetID;
// Pointer to the pickup spot this item was spawned from.
ABaseMonsterInvasionSpot *pMonsterSpot;
......@@ -1370,9 +1373,6 @@
template <typename T>
class IDList
{
public:
const static int MAX_NETID = 32768;
private:
// List of all possible network ID's for an actor. Slot is true if it available for use.
typedef struct
......@@ -1385,6 +1385,6 @@
} IDNODE_t;
IDNODE_t _entries[MAX_NETID];
ULONG _firstFreeID;
IDNODE_t _entries[ static_cast<unsigned int>(( std::numeric_limits<unsigned short>::max )( )) + 1];
unsigned short _firstFreeID;
......@@ -1390,3 +1390,3 @@
inline bool isIndexValid ( const LONG lNetID ) const
inline bool isIndexValid ( const unsigned short netID ) const
{
......@@ -1392,5 +1392,5 @@
{
return ( lNetID >= 0 ) && ( lNetID < MAX_NETID );
return ( netID > 0 );
}
public:
void clear ( );
......@@ -1403,5 +1403,5 @@
clear ( );
}
void useID ( const LONG lNetID, T *pActor );
void useID ( const unsigned short netID, T *actor );
......@@ -1407,3 +1407,3 @@
void freeID ( const LONG lNetID )
void freeID ( const unsigned short netID )
{
......@@ -1409,3 +1409,3 @@
{
if ( isIndexValid ( lNetID ) )
if ( isIndexValid ( netID ) )
{
......@@ -1411,6 +1411,6 @@
{
_entries[lNetID].bFree = true;
_entries[lNetID].pActor = NULL;
_entries[netID].bFree = true;
_entries[netID].pActor = NULL;
}
}
......@@ -1414,5 +1414,5 @@
}
}
ULONG getNewID ( );
unsigned short getNewID ( );
......@@ -1418,3 +1418,3 @@
T* findPointerByID ( const LONG lNetID ) const
T* findPointerByID ( const unsigned short netID ) const
{
......@@ -1420,4 +1420,4 @@
{
if ( isIndexValid ( lNetID ) == false )
if ( isIndexValid ( netID ) == false )
return ( NULL );
......@@ -1422,7 +1422,7 @@
return ( NULL );
if (( _entries[lNetID].bFree == false ) && ( _entries[lNetID].pActor ))
return ( _entries[lNetID].pActor );
if (( _entries[netID].bFree == false ) && ( _entries[netID].pActor ))
return ( _entries[netID].pActor );
return ( NULL );
}
......
......@@ -788,5 +788,5 @@
//*****************************************************************************
//
bool BOTCMD_IgnoreItem( CSkullBot *pBot, LONG lIdx, bool bVisibilityCheck )
bool BOTCMD_IgnoreItem( CSkullBot *pBot, unsigned short netID, bool bVisibilityCheck )
{
......@@ -792,5 +792,5 @@
{
AActor *pActor = g_ActorNetIDList.findPointerByID ( lIdx );
AActor *pActor = g_ActorNetIDList.findPointerByID ( netID );
if (( pActor == NULL ) ||
(( pActor->flags & MF_SPECIAL ) == false ) ||
( bVisibilityCheck && ( BOTS_IsVisible( pBot->GetPlayer( )->mo, pActor ) == false )))
......@@ -824,5 +824,5 @@
//*****************************************************************************
//
void botcmd_ValidateItemNetID( const LONG lNetID, const char *pszFunctionName )
void botcmd_ValidateItemNetID( const unsigned short netID, const char *pszFunctionName )
{
......@@ -828,5 +828,5 @@
{
botcmd_CheckIfInputIsValid( lNetID, IDList<AActor>::MAX_NETID, pszFunctionName, "Illegal item index" );
botcmd_CheckIfInputIsValid( netID, static_cast<LONG>(( std::numeric_limits<unsigned short>::max )( )) + 1, pszFunctionName, "Illegal item index" );
}
//*****************************************************************************
......@@ -918,9 +918,6 @@
template <typename T>
int botcmd_LookForItemType( CSkullBot *pBot, const char *FunctionName )
{
LONG lIdx;
bool bVisibilityCheck;
bVisibilityCheck = !!pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
bool visibilityCheck = !!pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
pBot->PopStack( );
......@@ -925,5 +922,5 @@
pBot->PopStack( );
lIdx = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -928,7 +925,7 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lIdx, FunctionName );
while (( BOTCMD_IgnoreItem( pBot, lIdx, bVisibilityCheck )) ||
( g_ActorNetIDList.findPointerByID ( lIdx )->GetClass( )->IsDescendantOf( RUNTIME_CLASS( T )) == false ))
botcmd_ValidateItemNetID( netID, FunctionName );
while (( BOTCMD_IgnoreItem( pBot, netID, visibilityCheck )) ||
( g_ActorNetIDList.findPointerByID( netID )->GetClass( )->IsDescendantOf( RUNTIME_CLASS( T )) == false ))
{
......@@ -934,5 +931,7 @@
{
if ( ++lIdx == IDList<AActor>::MAX_NETID )
break;
if ( netID == ( std::numeric_limits<unsigned short>::max )( ))
return -1;
netID++;
}
......@@ -937,9 +936,6 @@
}
if ( lIdx == IDList<AActor>::MAX_NETID )
return g_iReturnInt = -1;
else
return g_iReturnInt = lIdx;
return netID;
}
//*****************************************************************************
......@@ -967,9 +963,6 @@
// [BB] Helperfunction to reduce code duplication.
int botcmd_LookForItemWithFlag( CSkullBot *pBot, const int Flag, const char *FunctionName )
{
LONG lIdx;
bool bVisibilityCheck;
bVisibilityCheck = !!pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
bool visibilityCheck = !!pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
pBot->PopStack( );
......@@ -974,5 +967,5 @@
pBot->PopStack( );
lIdx = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -977,7 +970,7 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lIdx, FunctionName );
while (( BOTCMD_IgnoreItem( pBot, lIdx, bVisibilityCheck )) ||
(( g_ActorNetIDList.findPointerByID ( lIdx )->STFlags & Flag ) == false ))
botcmd_ValidateItemNetID( netID, FunctionName );
while (( BOTCMD_IgnoreItem( pBot, netID, visibilityCheck )) ||
(( g_ActorNetIDList.findPointerByID( netID )->STFlags & Flag ) == false ))
{
......@@ -983,5 +976,7 @@
{
if ( ++lIdx == IDList<AActor>::MAX_NETID )
break;
if ( netID == ( std::numeric_limits<unsigned short>::max )( ))
return -1;
netID++;
}
......@@ -986,9 +981,6 @@
}
if ( lIdx == IDList<AActor>::MAX_NETID )
return -1;
else
return lIdx;
return netID;
}
//*****************************************************************************
......@@ -1632,10 +1624,6 @@
//
static void botcmd_GetPathingCostToItem( CSkullBot *pBot )
{
LONG lItem;
POS_t GoalPos;
ASTARRETURNSTRUCT_t ReturnVal;
lItem = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -1640,11 +1628,11 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lItem, "botcmd_GetPathingCostToItem" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lItem );
botcmd_ValidateItemNetID( netID, "botcmd_GetPathingCostToItem" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor == NULL )
{
g_iReturnInt = -1;
return;
}
......@@ -1645,11 +1633,12 @@
if ( pActor == NULL )
{
g_iReturnInt = -1;
return;
}
POS_t GoalPos;
GoalPos.x = pActor->x;
GoalPos.y = pActor->y;
ASTAR_ClearPath(( pBot->GetPlayer( ) - players ) + MAXPLAYERS );
......@@ -1651,9 +1640,9 @@
GoalPos.x = pActor->x;
GoalPos.y = pActor->y;
ASTAR_ClearPath(( pBot->GetPlayer( ) - players ) + MAXPLAYERS );
ReturnVal = ASTAR_Path(( pBot->GetPlayer( ) - players ) + MAXPLAYERS, GoalPos, 0, static_cast<LONG> ( botdebug_maxgiveupnodes ) );
ASTARRETURNSTRUCT_t ReturnVal = ASTAR_Path(( pBot->GetPlayer( ) - players ) + MAXPLAYERS, GoalPos, 0, static_cast<LONG> ( botdebug_maxgiveupnodes ) );
if ( ReturnVal.ulFlags & PF_COMPLETE )
{
// If it wasn't possible to create a path to the goal, try again next tick.
......@@ -1670,8 +1659,6 @@
//
static void botcmd_GetDistanceToItem( CSkullBot *pBot )
{
LONG lItem;
lItem = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -1676,8 +1663,8 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lItem, "botcmd_GetDistanceToItem" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lItem );
botcmd_ValidateItemNetID( netID, "botcmd_GetDistanceToItem" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor )
{
g_iReturnInt = abs( P_AproxDistance( pActor->x - pBot->GetPlayer( )->mo->x,
......@@ -1691,8 +1678,6 @@
//
static void botcmd_GetItemName( CSkullBot *pBot )
{
LONG lItem;
lItem = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -1697,8 +1682,8 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lItem, "botcmd_GetItemName" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lItem );
botcmd_ValidateItemNetID( netID, "botcmd_GetItemName" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor )
{
if ( strlen( pActor->GetClass( )->TypeName.GetChars( )) < BOTCMD_RETURNSTRING_SIZE )
......@@ -1714,8 +1699,6 @@
//
static void botcmd_IsItemVisible( CSkullBot *pBot )
{
LONG lIdx;
lIdx = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -1720,8 +1703,8 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lIdx, "botcmd_IsItemVisible" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lIdx );
botcmd_ValidateItemNetID( netID, "botcmd_IsItemVisible" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor )
{
......@@ -1759,8 +1742,6 @@
//
static void botcmd_SetGoal( CSkullBot *pBot )
{
LONG lIdx;
lIdx = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -1765,11 +1746,11 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lIdx, "botcmd_SetGoal" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lIdx );
botcmd_ValidateItemNetID( netID, "botcmd_SetGoal" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor )
{
pBot->m_pGoalActor = pActor;
pBot->m_ulPathType = BOTPATHTYPE_NONE;
}
else
......@@ -1770,10 +1751,10 @@
if ( pActor )
{
pBot->m_pGoalActor = pActor;
pBot->m_ulPathType = BOTPATHTYPE_NONE;
}
else
Printf( "botcmd_SetGoal: WARNING! Tried to set goal to bad item ID, %d!\n", static_cast<int> (lIdx) );
Printf( "botcmd_SetGoal: WARNING! Tried to set goal to bad item ID, %u!\n", netID );
}
//*****************************************************************************
......@@ -1992,8 +1973,6 @@
//
static void botcmd_GetWeaponFromItem( CSkullBot *pBot )
{
LONG lItem;
lItem = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -1998,8 +1977,8 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lItem, "botcmd_GetWeaponFromItem" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lItem );
botcmd_ValidateItemNetID( netID, "botcmd_GetWeaponFromItem" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor )
{
if ( pActor->GetClass( )->IsDescendantOf( RUNTIME_CLASS( AWeapon )) == false )
......@@ -2020,8 +1999,6 @@
//
static void botcmd_IsWeaponOwned( CSkullBot *pBot )
{
LONG lItem;
lItem = pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1];
unsigned short netID = static_cast<unsigned short>( pBot->m_ScriptData.alStack[pBot->m_ScriptData.lStackPosition - 1] );
pBot->PopStack( );
......@@ -2026,8 +2003,8 @@
pBot->PopStack( );
botcmd_ValidateItemNetID( lItem, "botcmd_IsWeaponOwned" );
AActor *pActor = g_ActorNetIDList.findPointerByID ( lItem );
botcmd_ValidateItemNetID( netID, "botcmd_IsWeaponOwned" );
AActor *pActor = g_ActorNetIDList.findPointerByID( netID );
if ( pActor )
{
if ( pActor->GetClass( )->IsDescendantOf( RUNTIME_CLASS( AWeapon )) == false )
......
......@@ -279,6 +279,6 @@
void BOTCMD_SetLastChatPlayer( const char *pszString );
void BOTCMD_SetLastJoinedPlayer( const char *pszString );
void BOTCMD_DoChatStringSubstitutions( CSkullBot *pBot, FString &Input );
bool BOTCMD_IgnoreItem( CSkullBot *pBot, LONG lIdx, bool bVisibilityCheck );
bool BOTCMD_IgnoreItem( CSkullBot *pBot, unsigned short netID, bool bVisibilityCheck );
#endif // __BOTCOMMANDS_H__
......@@ -602,8 +602,9 @@
PLAYER_ResetCustomValues( ulPlayerIdx );
// [BB] Morphed bots need to be unmorphed before disconnecting.
if (players[ulPlayerIdx].morphTics)
P_UndoPlayerMorph (&players[ulPlayerIdx], &players[ulPlayerIdx]);
// [AK] Using MORPH_UNDOBYTIMEOUT ensures this succeeds when they're invulnerable.
if ( players[ulPlayerIdx].morphTics )
P_UndoPlayerMorphWithoutFlash( &players[ulPlayerIdx], &players[ulPlayerIdx], MORPH_UNDOBYTIMEOUT, true );
// [RK] Stop the runing scripts for the bot.
FBehavior::StaticStopMyScripts (players[ulPlayerIdx].mo);
......
......@@ -1272,7 +1272,7 @@
if (linetarget)
{
// [TP] If we're the client, ask the server for information about the linetarget.
if ( NETWORK_GetState() == NETSTATE_CLIENT && linetarget->NetID != -1 )
if ( NETWORK_GetState() == NETSTATE_CLIENT && linetarget->NetID != 0 )
{
CLIENTCOMMANDS_InfoCheat( linetarget, false );
return;
......@@ -1298,7 +1298,7 @@
if (linetarget)
{
// [TP] If we're the client, ask the server for information about the linetarget.
if ( NETWORK_GetState() == NETSTATE_CLIENT && linetarget->NetID != -1 )
if ( NETWORK_GetState() == NETSTATE_CLIENT && linetarget->NetID != 0 )
{
CLIENTCOMMANDS_InfoCheat( linetarget, true );
return;
......
......@@ -813,7 +813,7 @@
// [Dusk]
void CLIENTCOMMANDS_InfoCheat( AActor* mobj, bool extended )
{
if ( mobj == NULL || mobj->NetID == -1 )
if ( mobj == NULL || mobj->NetID == 0 )
return;
CLIENT_GetLocalBuffer( )->ByteStream.WriteByte( CLC_INFOCHEAT );
......
......@@ -216,7 +216,6 @@
// Player functions.
// [BB] Does not work with the latest ZDoom changes. Check if it's still necessary.
//static void client_SetPlayerPieces( BYTESTREAM_s *pByteStream );
static void client_PlayerVoIPAudioPacket( BYTESTREAM_s *byteStream );
// Game commands.
static void client_SetGameMode( BYTESTREAM_s *pByteStream );
......@@ -236,8 +235,6 @@
static void client_DoGameModeFight( BYTESTREAM_s *pByteStream );
static void client_DoGameModeCountdown( BYTESTREAM_s *pByteStream );
static void client_DoGameModeWinSequence( BYTESTREAM_s *pByteStream );
static void client_SetDominationState( BYTESTREAM_s *pByteStream );
static void client_SetDominationPointOwnership( BYTESTREAM_s *pByteStream );
// Team commands.
static void client_SetTeamScore( BYTESTREAM_s *pByteStream );
......@@ -1682,14 +1679,6 @@
client_DoGameModeWinSequence( pByteStream );
break;
case SVC_SETDOMINATIONSTATE:
client_SetDominationState( pByteStream );
break;
case SVC_SETDOMINATIONPOINTOWNER:
client_SetDominationPointOwnership( pByteStream );
break;
case SVC_SETTEAMSCORE:
client_SetTeamScore( pByteStream );
......@@ -1925,11 +1914,6 @@
client_AdjustPusher( pByteStream );
break;
case SVC_PLAYERVOIPAUDIOPACKET:
client_PlayerVoIPAudioPacket( pByteStream );
break;
case SVC_EXTENDEDCOMMAND:
{
const LONG lExtCommand = pByteStream->ReadByte();
......@@ -2005,5 +1989,5 @@
case SVC2_SETTHINGREACTIONTIME:
{
const LONG lID = pByteStream->ReadShort();
const unsigned short netID = pByteStream->ReadShort();
const LONG lReactionTime = pByteStream->ReadShort();
......@@ -2009,5 +1993,5 @@
const LONG lReactionTime = pByteStream->ReadShort();
AActor *pActor = CLIENT_FindThingByNetID( lID );
AActor *pActor = CLIENT_FindThingByNetID( netID );
if ( pActor == NULL )
{
......@@ -2011,7 +1995,7 @@
if ( pActor == NULL )
{
CLIENT_PrintWarning( "SETTHINGREACTIONTIME: Couldn't find thing: %ld\n", lID );
CLIENT_PrintWarning( "SETTHINGREACTIONTIME: Couldn't find thing: %u\n", netID );
break;
}
pActor->reactiontime = lReactionTime;
......@@ -2021,5 +2005,5 @@
// [Dusk]
case SVC2_SETFASTCHASESTRAFECOUNT:
{
const LONG lID = pByteStream->ReadShort();
const unsigned short netID = pByteStream->ReadShort();
const LONG lStrafeCount = pByteStream->ReadByte();
......@@ -2025,5 +2009,5 @@
const LONG lStrafeCount = pByteStream->ReadByte();
AActor *pActor = CLIENT_FindThingByNetID( lID );
AActor *pActor = CLIENT_FindThingByNetID( netID );
if ( pActor == NULL )
{
......@@ -2027,7 +2011,7 @@
if ( pActor == NULL )
{
CLIENT_PrintWarning( "SETFASTCHASESTRAFECOUNT: Couldn't find thing: %ld\n", lID );
CLIENT_PrintWarning( "SETFASTCHASESTRAFECOUNT: Couldn't find thing: %u\n", netID );
break;
}
pActor->FastChaseStrafeCount = lStrafeCount;
......@@ -2116,5 +2100,5 @@
case SVC2_SETTHINGSPECIAL:
{
const LONG lID = pByteStream->ReadShort();
const unsigned short netID = pByteStream->ReadShort();
const LONG lSpecial = pByteStream->ReadShort();
......@@ -2120,5 +2104,5 @@
const LONG lSpecial = pByteStream->ReadShort();
AActor *pActor = CLIENT_FindThingByNetID( lID );
AActor *pActor = CLIENT_FindThingByNetID( netID );
if ( pActor == NULL )
{
......@@ -2122,7 +2106,7 @@
if ( pActor == NULL )
{
CLIENT_PrintWarning( "SVC2_SETTHINGSPECIAL: Couldn't find thing: %ld\n", lID );
CLIENT_PrintWarning( "SVC2_SETTHINGSPECIAL: Couldn't find thing: %u\n", netID );
break;
}
pActor->special = lSpecial;
......@@ -2156,5 +2140,5 @@
case SVC2_SETTHINGHEALTH:
{
const LONG lID = pByteStream->ReadShort();
const unsigned short netID = pByteStream->ReadShort();
const int health = pByteStream->ReadByte();
......@@ -2160,5 +2144,5 @@
const int health = pByteStream->ReadByte();
AActor* mo = CLIENT_FindThingByNetID( lID );
AActor* mo = CLIENT_FindThingByNetID( netID );
if ( mo == NULL )
{
......@@ -2162,7 +2146,7 @@
if ( mo == NULL )
{
CLIENT_PrintWarning( "SVC2_SETTHINGSPECIAL: Couldn't find thing: %ld\n", lID );
CLIENT_PrintWarning( "SVC2_SETTHINGSPECIAL: Couldn't find thing: %u\n", netID );
break;
}
......@@ -2226,8 +2210,8 @@
case SVC2_SETDEFAULTSKYBOX:
{
int mobjNetID = pByteStream->ReadShort();
if ( mobjNetID == -1 )
unsigned short mobjNetID = pByteStream->ReadShort();
if ( mobjNetID == 0 )
level.DefaultSkybox = NULL;
else
{
......@@ -2654,7 +2638,7 @@
//*****************************************************************************
//
AActor *CLIENT_SpawnThing( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, LONG lNetID, BYTE spawnFlags )
AActor *CLIENT_SpawnThing( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, unsigned short netID, BYTE spawnFlags )
{
AActor *pActor;
......@@ -2667,6 +2651,6 @@
// Potentially print the name, position, and network ID of the thing spawning.
if ( cl_showspawnnames )
Printf( "Name: %s: (%d, %d, %d), %d\n", pType->TypeName.GetChars( ), X >> FRACBITS, Y >> FRACBITS, Z >> FRACBITS, static_cast<int> (lNetID) );
Printf( "Name: %s: (%d, %d, %d), %u\n", pType->TypeName.GetChars( ), X >> FRACBITS, Y >> FRACBITS, Z >> FRACBITS, netID );
// If there's already an actor with the network ID of the thing we're spawning, kill it!
......@@ -2671,8 +2655,8 @@
// If there's already an actor with the network ID of the thing we're spawning, kill it!
pActor = CLIENT_FindThingByNetID( lNetID );
pActor = CLIENT_FindThingByNetID( netID );
if ( pActor )
{
#ifdef _DEBUG
if ( pActor == players[consoleplayer].mo )
{
......@@ -2674,9 +2658,9 @@
if ( pActor )
{
#ifdef _DEBUG
if ( pActor == players[consoleplayer].mo )
{
Printf( "CLIENT_SpawnThing: WARNING! Tried to delete console player's body! lNetID = %ld\n", lNetID );
Printf( "CLIENT_SpawnThing: WARNING! Tried to delete console player's body! netID = %u\n", netID );
return NULL;
}
#endif
......@@ -2728,8 +2712,8 @@
}
}
pActor->NetID = lNetID;
g_ActorNetIDList.useID ( lNetID, pActor );
pActor->NetID = netID;
g_ActorNetIDList.useID( netID, pActor );
pActor->SpawnPoint[0] = X;
pActor->SpawnPoint[1] = Y;
......@@ -2758,10 +2742,10 @@
pActor->InvasionWave = INVASION_GetCurrentWave( );
}
else
CLIENT_PrintWarning( "CLIENT_SpawnThing: Failed to spawn actor %s with id %ld\n", pType->TypeName.GetChars( ), lNetID );
CLIENT_PrintWarning( "CLIENT_SpawnThing: Failed to spawn actor %s with id %u\n", pType->TypeName.GetChars( ), netID );
return ( pActor );
}
//*****************************************************************************
//
......@@ -2762,10 +2746,10 @@
return ( pActor );
}
//*****************************************************************************
//
void CLIENT_SpawnMissile( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, fixed_t VelX, fixed_t VelY, fixed_t VelZ, LONG lNetID, LONG lTargetNetID )
void CLIENT_SpawnMissile( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, fixed_t VelX, fixed_t VelY, fixed_t VelZ, unsigned short netID, unsigned short targetNetID )
{
AActor *pActor;
......@@ -2778,6 +2762,6 @@
// Potentially print the name, position, and network ID of the thing spawning.
if ( cl_showspawnnames )
Printf( "Name: %s: (%d, %d, %d), %d\n", pType->TypeName.GetChars( ), X >> FRACBITS, Y >> FRACBITS, Z >> FRACBITS, static_cast<int> (lNetID) );
Printf( "Name: %s: (%d, %d, %d), %u\n", pType->TypeName.GetChars( ), X >> FRACBITS, Y >> FRACBITS, Z >> FRACBITS, netID );
// If there's already an actor with the network ID of the thing we're spawning, kill it!
......@@ -2782,6 +2766,6 @@
// If there's already an actor with the network ID of the thing we're spawning, kill it!
pActor = CLIENT_FindThingByNetID( lNetID );
pActor = CLIENT_FindThingByNetID( netID );
if ( pActor )
{
pActor->Destroy( );
......@@ -2791,7 +2775,7 @@
pActor = Spawn( pType, X, Y, Z, NO_REPLACE );
if ( pActor == NULL )
{
CLIENT_PrintWarning( "CLIENT_SpawnMissile: Failed to spawn missile: %ld\n", lNetID );
CLIENT_PrintWarning( "CLIENT_SpawnMissile: Failed to spawn missile: %u\n", netID );
return;
}
......@@ -2803,7 +2787,7 @@
// Derive the thing's angle from its velocity.
pActor->angle = R_PointToAngle2( 0, 0, VelX, VelY );
pActor->NetID = lNetID;
g_ActorNetIDList.useID ( lNetID, pActor );
pActor->NetID = netID;
g_ActorNetIDList.useID( netID, pActor );
// [RK] Moved this up since we need the target before we play the sound.
......@@ -2808,6 +2792,6 @@
// [RK] Moved this up since we need the target before we play the sound.
pActor->target = CLIENT_FindThingByNetID(lTargetNetID);
pActor->target = CLIENT_FindThingByNetID( targetNetID );
// Play the seesound if this missile has one.
// [RK] Play the sound at the target if the missile has MF_SPAWNSOUNDSOURCE.
......@@ -2900,9 +2884,9 @@
//*****************************************************************************
//
AActor *CLIENT_FindThingByNetID( LONG lNetID )
{
return ( g_ActorNetIDList.findPointerByID ( lNetID ) );
AActor *CLIENT_FindThingByNetID( unsigned short netID )
{
return ( g_ActorNetIDList.findPointerByID( netID ));
}
//*****************************************************************************
......@@ -3313,6 +3297,6 @@
//
// 'actor' MUST be either NULL or an instance of the provided subclass!
//
bool CLIENT_ReadActorFromNetID( int netid, const PClass *subclass, bool allowNull, AActor *&actor,
bool CLIENT_ReadActorFromNetID( unsigned short netID, const PClass *subclass, bool allowNull, AActor *&actor,
const char *commandName, const char *parameterName )
{
......@@ -3317,6 +3301,6 @@
const char *commandName, const char *parameterName )
{
actor = CLIENT_FindThingByNetID( netid );
actor = CLIENT_FindThingByNetID( netID );
if ( actor && ( actor->IsKindOf( subclass ) == false ))
{
......@@ -3331,7 +3315,7 @@
if (( actor == NULL ) && ( allowNull == false ))
{
CLIENT_PrintWarning( "%s: couldn't find %s: %d\n", commandName, parameterName, netid );
CLIENT_PrintWarning( "%s: couldn't find %s: %u\n", commandName, parameterName, netID );
return false;
}
......@@ -3492,7 +3476,7 @@
// [BB] Potentially print the player number, position, and network ID of the player spawning.
if ( cl_showspawnnames )
Printf( "Player %d body: (%d, %d, %d), %d\n", static_cast<int>(ulPlayer), x >> FRACBITS, y >> FRACBITS, z >> FRACBITS, static_cast<int> (netid) );
Printf( "Player %d body: (%d, %d, %d), %u\n", static_cast<int>(ulPlayer), x >> FRACBITS, y >> FRACBITS, z >> FRACBITS, netid );
// [BB] Remember if we were already ignoring WeaponSelect commands. If so, the server
// told us to ignore them and we need to continue to do so after spawning the player.
......@@ -4820,6 +4804,13 @@
//*****************************************************************************
//
void ServerCommands::PlayerVoIPAudioPacket::Execute()
{
VOIPController::GetInstance( ).ReceiveAudioPacket( playerNumber, frame, audio.data, audio.size );
}
//*****************************************************************************
//
void ServerCommands::PlayerTaunt::Execute()
{
// Don't taunt if we're not in a level!
......@@ -5046,7 +5037,7 @@
//
void ServerCommands::SpawnThingNoNetID::Execute()
{
CLIENT_SpawnThing( type, x, y, z, -1 );
CLIENT_SpawnThing( type, x, y, z, 0 );
}
//*****************************************************************************
......@@ -5060,7 +5051,7 @@
//
void ServerCommands::SpawnThingExactNoNetID::Execute()
{
CLIENT_SpawnThing( type, x, y, z, -1 );
CLIENT_SpawnThing( type, x, y, z, 0 );
}
//*****************************************************************************
......@@ -5074,7 +5065,7 @@
//
void ServerCommands::LevelSpawnThingNoNetID::Execute()
{
CLIENT_SpawnThing( type, x, y, z, -1, SPAWNFLAG_LEVELTHING );
CLIENT_SpawnThing( type, x, y, z, 0, SPAWNFLAG_LEVELTHING );
}
//*****************************************************************************
......@@ -5828,7 +5819,7 @@
//
void ServerCommands::SpawnPuffNoNetID::Execute()
{
AActor *puff = CLIENT_SpawnThing( pufftype, x, y, z, -1, SPAWNFLAG_PUFF );
AActor *puff = CLIENT_SpawnThing( pufftype, x, y, z, 0, SPAWNFLAG_PUFF );
if ( puff == NULL )
return;
......@@ -6372,45 +6363,6 @@
//*****************************************************************************
//
static void client_SetDominationState( BYTESTREAM_s *pByteStream )
{
unsigned int NumPoints = pByteStream->ReadLong();
// [BB] It's impossible that the server sends us this many points
// in a single packet, so something must be wrong. Just parse
// what the server has claimed to have send, but don't try to store
// it or allocate memory for it.
if ( NumPoints > MAX_UDP_PACKET )
{
for ( unsigned int i = 0; i < NumPoints; ++i )
pByteStream->ReadByte();
return;
}
unsigned int *PointOwners = new unsigned int[NumPoints];
for(unsigned int i = 0;i < NumPoints;i++)
{
PointOwners[i] = pByteStream->ReadByte();
}
DOMINATION_LoadInit(NumPoints, PointOwners);
}
//*****************************************************************************
//
static void client_SetDominationPointOwnership( BYTESTREAM_s *pByteStream )
{
unsigned int ulPoint = pByteStream->ReadByte();
unsigned int ulPlayer = pByteStream->ReadByte();
// If this is an invalid player, break out.
if ( PLAYER_IsValidPlayer( ulPlayer ) == false )
return;
DOMINATION_SetOwnership(ulPoint, &players[ulPlayer]);
}
//*****************************************************************************
//
static void client_SetTeamScore( BYTESTREAM_s *pByteStream )
{
// Read in the team having its score updated.
......@@ -9133,9 +9085,8 @@
static void client_EarthQuake( BYTESTREAM_s *pByteStream )
{
AActor *pCenter;
LONG lID;
LONG lIntensity;
LONG lDuration;
LONG lTremorRadius;
// Read in the center's network ID.
......@@ -9137,9 +9088,9 @@
LONG lIntensity;
LONG lDuration;
LONG lTremorRadius;
// Read in the center's network ID.
lID = pByteStream->ReadShort();
unsigned short netID = pByteStream->ReadShort();
// Read in the intensity of the quake.
lIntensity = pByteStream->ReadByte();
......@@ -9155,7 +9106,7 @@
// Find the actor that represents the center of the quake based on the network
// ID sent. If we can't find the actor, then the quake has no center.
pCenter = CLIENT_FindThingByNetID( lID );
pCenter = CLIENT_FindThingByNetID( netID );
if ( pCenter == NULL )
return;
......@@ -9328,10 +9279,9 @@
//
static void client_SetCameraToTexture( BYTESTREAM_s *pByteStream )
{
LONG lID;
const char *pszTexture;
LONG lFOV;
AActor *pCamera;
FTextureID picNum;
// Read in the ID of the camera.
......@@ -9332,10 +9282,10 @@
const char *pszTexture;
LONG lFOV;
AActor *pCamera;
FTextureID picNum;
// Read in the ID of the camera.
lID = pByteStream->ReadShort();
unsigned short netID = pByteStream->ReadShort();
// Read in the name of the texture.
pszTexture = pByteStream->ReadString();
......@@ -9345,7 +9295,7 @@
// Find the actor that represents the camera. If we can't find the actor, then
// break out.
pCamera = CLIENT_FindThingByNetID( lID );
pCamera = CLIENT_FindThingByNetID( netID );
if ( pCamera == NULL )
return;
......@@ -9438,23 +9388,9 @@
//*****************************************************************************
//
static void client_PlayerVoIPAudioPacket( BYTESTREAM_s *byteStream )
{
const unsigned int player = byteStream->ReadByte( );
const unsigned int frame = byteStream->ReadLong( );
const unsigned int length = byteStream->ReadShort( );
unsigned char *data = new unsigned char[length];
byteStream->ReadBuffer( data, length );
VOIPController::GetInstance( ).ReceiveAudioPacket( player, frame, data, length );
delete[] data;
}
//*****************************************************************************
//
static void client_DoPusher( BYTESTREAM_s *pByteStream )
{
const ULONG ulType = pByteStream->ReadByte();
const int iLineNum = pByteStream->ReadShort();
const int iMagnitude = pByteStream->ReadLong();
const int iAngle = pByteStream->ReadLong();
......@@ -9455,10 +9391,10 @@
static void client_DoPusher( BYTESTREAM_s *pByteStream )
{
const ULONG ulType = pByteStream->ReadByte();
const int iLineNum = pByteStream->ReadShort();
const int iMagnitude = pByteStream->ReadLong();
const int iAngle = pByteStream->ReadLong();
const LONG lSourceNetID = pByteStream->ReadShort();
const unsigned short sourceNetID = pByteStream->ReadShort();
const int iAffectee = pByteStream->ReadShort();
line_t *pLine = ( iLineNum >= 0 && iLineNum < numlines ) ? &lines[iLineNum] : NULL;
......@@ -9462,7 +9398,7 @@
const int iAffectee = pByteStream->ReadShort();
line_t *pLine = ( iLineNum >= 0 && iLineNum < numlines ) ? &lines[iLineNum] : NULL;
new DPusher ( static_cast<DPusher::EPusher> ( ulType ), pLine, iMagnitude, iAngle, CLIENT_FindThingByNetID( lSourceNetID ), iAffectee );
new DPusher ( static_cast<DPusher::EPusher> ( ulType ), pLine, iMagnitude, iAngle, CLIENT_FindThingByNetID( sourceNetID ), iAffectee );
}
//*****************************************************************************
......@@ -9488,9 +9424,9 @@
//
void APathFollower::InitFromStream ( BYTESTREAM_s *pByteStream )
{
APathFollower *pPathFollower = static_cast<APathFollower*> ( CLIENT_FindThingByNetID( pByteStream->ReadShort() ) );
const int currNodeId = pByteStream->ReadShort();
const int prevNodeId = pByteStream->ReadShort();
APathFollower *pPathFollower = static_cast<APathFollower*> ( CLIENT_FindThingByNetID( static_cast<unsigned short>( pByteStream->ReadShort() ) ) );
const unsigned short currNodeId = static_cast<unsigned short>(pByteStream->ReadShort());
const unsigned short prevNodeId = static_cast<unsigned short>(pByteStream->ReadShort());
const float serverTime = pByteStream->ReadFloat();
if ( pPathFollower )
......@@ -9609,6 +9545,13 @@
}
//*****************************************************************************
// [TRSR]
void ServerCommands::SetDominationPointOwner::Execute()
{
DOMINATION_SetOwnership( point, team, broadcast );
}
//*****************************************************************************
//
void STACK_ARGS CLIENT_PrintWarning( const char* format, ... )
{
......
......@@ -172,6 +172,6 @@
// Support functions to make things work more smoothly.
void CLIENT_AuthenticateLevel( const char *pszMapName );
AActor *CLIENT_SpawnThing( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, LONG lNetID, BYTE spawnFlags = 0 );
void CLIENT_SpawnMissile( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, fixed_t VelX, fixed_t VelY, fixed_t VelZ, LONG lNetID, LONG lTargetNetID );
AActor *CLIENT_SpawnThing( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, unsigned short netID, BYTE spawnFlags = 0 );
void CLIENT_SpawnMissile( const PClass *pType, fixed_t X, fixed_t Y, fixed_t Z, fixed_t VelX, fixed_t VelY, fixed_t zelZ, unsigned short netID, unsigned short targetNetID );
void CLIENT_MoveThing( AActor *pActor, fixed_t X, fixed_t Y, fixed_t Z );
......@@ -177,5 +177,5 @@
void CLIENT_MoveThing( AActor *pActor, fixed_t X, fixed_t Y, fixed_t Z );
AActor *CLIENT_FindThingByNetID( LONG lID );
AActor *CLIENT_FindThingByNetID( unsigned short netID );
void CLIENT_RestoreSpecialPosition( AActor *pActor );
void CLIENT_RestoreSpecialDoomThing( AActor *pActor, bool bFog );
AInventory *CLIENT_FindPlayerInventory( ULONG ulPlayer, const PClass *pType );
......@@ -197,7 +197,7 @@
void CLIENT_LimitProtectedCVARs( void );
bool CLIENT_CanClipMovement( AActor *pActor );
void STACK_ARGS CLIENT_PrintWarning( const char* format, ... ) GCCPRINTF( 1, 2 );
bool CLIENT_ReadActorFromNetID( int netid, const PClass *subclass, bool allowNull, AActor *&actor,
bool CLIENT_ReadActorFromNetID( unsigned short netID, const PClass *subclass, bool allowNull, AActor *&actor,
const char *commandName = "CLIENT_ReadActorFromNetID",
const char *parameterName = "actor" );
bool CLIENT_HasRCONAccess();
......
......@@ -197,7 +197,7 @@
// [BB] The clients will not spawn the doll, so mark it accordingly and free it's network ID.
pDoll->NetworkFlags |= NETFL_SERVERSIDEONLY;
g_ActorNetIDList.freeID ( pDoll->NetID );
pDoll->NetID = -1;
pDoll->NetID = 0;
// [BB] If we would just set the player pointer to NULL, a lot of things wouldn't work
// at all for the voodoo dolls (e.g. floor scrollers), so we set it do a pointer to a
......
......@@ -67,6 +67,10 @@
#include "sectinfo.h"
#include "cl_demo.h"
#include "p_acs.h"
#include "gi.h"
// [TRSR] Private helper function(s)
static void domination_SetControlPointColor( unsigned int point );
CUSTOM_CVAR(Int, sv_dominationscorerate, 3, CVAR_SERVERINFO | CVAR_GAMEPLAYSETTING)
{
......@@ -83,8 +87,5 @@
//CREATE_GAMEMODE(domination, DOMINATION, "Domination", "DOM", "F1_DOM", GMF_TEAMGAME|GMF_PLAYERSEARNPOINTS|GMF_PLAYERSONTEAMS)
unsigned int *PointOwners;
unsigned int NumPoints;
bool finished;
......@@ -89,39 +90,7 @@
bool finished;
unsigned int DOMINATION_NumPoints(void) { return NumPoints; }
unsigned int* DOMINATION_PointOwners(void) { return PointOwners; }
void DOMINATION_LoadInit(unsigned int numpoints, unsigned int* pointowners)
{
if(!domination)
return;
finished = false;
NumPoints = numpoints;
if ( PointOwners )
delete[] PointOwners;
PointOwners = pointowners;
}
void DOMINATION_SendState(ULONG ulPlayerExtra)
{
if(!domination)
return;
if(SERVER_IsValidClient(ulPlayerExtra) == false)
return;
SERVER_CheckClientBuffer(ulPlayerExtra, NumPoints + 4, true);
SERVER_GetClient(ulPlayerExtra)->PacketBuffer.ByteStream.WriteLong(NumPoints);
for(unsigned int i = 0;i < NumPoints;i++)
{
//one byte should be enough to hold the value of the team.
SERVER_GetClient( ulPlayerExtra )->PacketBuffer.ByteStream.WriteByte(PointOwners[i]);
}
}
void DOMINATION_Reset(void)
{
if(!domination)
return;
......@@ -123,7 +92,9 @@
void DOMINATION_Reset(void)
{
if(!domination)
return;
finished = false;
for(unsigned int i = 0;i < level.info->SectorInfo.Points.Size();i++)
{
......@@ -128,11 +99,7 @@
for(unsigned int i = 0;i < level.info->SectorInfo.Points.Size();i++)
{
PointOwners[i] = 255;
for(unsigned int j = 0;j < level.info->SectorInfo.Points[i]->Size();j++)
{
if(j < static_cast<unsigned> (numsectors))
sectors[(*level.info->SectorInfo.Points[i])[0]].SetFade(POINT_DEFAULT_R, POINT_DEFAULT_G, POINT_DEFAULT_B);
}
level.info->SectorInfo.Points[i].owner = TEAM_None;
domination_SetControlPointColor( i );
}
}
......@@ -142,10 +109,6 @@
return;
finished = false;
if(PointOwners != NULL)
delete[] PointOwners;
PointOwners = new unsigned int[level.info->SectorInfo.Points.Size()];
NumPoints = level.info->SectorInfo.Points.Size();
DOMINATION_Reset();
}
......@@ -159,6 +122,7 @@
return;
// [BB] Scoring is server-side.
// [TRSR] Control point management is also server-side.
if ( NETWORK_InClientMode() )
return;
......@@ -162,5 +126,55 @@
if ( NETWORK_InClientMode() )
return;
for( unsigned int i = 0; i < level.info->SectorInfo.Points.Size(); i++ )
{
unsigned int teamPlayers[MAX_TEAMS] = { 0 };
// [TRSR] Count number of players per team on the point.
for ( unsigned int p = 0; p < MAXPLAYERS; p++ ) {
if ( !level.info->SectorInfo.Points[i].PlayerInsidePoint( p ) )
continue;
if( !players[p].bOnTeam )
continue;
// [TRSR] Call event script to allow modders to say whether this player's contesting status counts.
// For example, if player is too high up or above 3D floor, a modder may not want them to be able to contest.
if (( !gameinfo.bAllowDominationContestScripts ) || ( GAMEMODE_HandleEvent( GAMEEVENT_DOMINATION_CONTEST, players[p].mo, i, 0, true ) != 0 ))
teamPlayers[players[p].Team]++;
}
// [TRSR] If the point is owned and one of that team's players is contesting, don't let the point swap.
if( level.info->SectorInfo.Points[i].owner != TEAM_None && teamPlayers[level.info->SectorInfo.Points[i].owner] > 0 )
continue;
// [TRSR] Figure out which team has the most contesters. Point will swap to them.
unsigned int winner = TEAM_None;
unsigned int max = 0;
for ( int team = 0; team < MAX_TEAMS; team++ )
{
if( teamPlayers[team] > max )
{
max = teamPlayers[team];
winner = team;
}
// [TRSR] If two teams are tied, neither gets the point.
// A bit awkward, but it gives a resolution to priority issues.
else if ( teamPlayers[team] == max )
{
winner = TEAM_None;
}
}
if( winner == TEAM_None )
continue;
// [TRSR] Trigger an event to allow denying of the capture.
if ( GAMEMODE_HandleEvent( GAMEEVENT_DOMINATION_PRECONTROL, nullptr, winner, i, true ) == 0 )
continue;
DOMINATION_SetOwnership( i, winner );
}
if(!(level.maptime % (sv_dominationscorerate * TICRATE)))
{
......@@ -165,4 +179,4 @@
if(!(level.maptime % (sv_dominationscorerate * TICRATE)))
{
for(unsigned int i = 0;i < NumPoints;i++)
for(unsigned int i = 0;i < level.info->SectorInfo.Points.Size();i++)
{
......@@ -168,6 +182,6 @@
{
if(PointOwners[i] != 255)
if(level.info->SectorInfo.Points[i].owner != TEAM_None)
{
// [AK] Trigger an event script when this team gets a point from a point sector.
// The first argument is the team that owns the sector and the second argument is the name
// of the sector. Don't let event scripts change the result value to anything less than zero.
......@@ -170,7 +184,7 @@
{
// [AK] Trigger an event script when this team gets a point from a point sector.
// The first argument is the team that owns the sector and the second argument is the name
// of the sector. Don't let event scripts change the result value to anything less than zero.
LONG lResult = MAX<LONG>( GAMEMODE_HandleEvent( GAMEEVENT_DOMINATION_POINT, NULL, PointOwners[i], ACS_PushAndReturnDynamicString( level.info->SectorInfo.PointNames[i]->GetChars( )), true ), 0 );
LONG lResult = MAX<LONG>( GAMEMODE_HandleEvent( GAMEEVENT_DOMINATION_POINT, NULL, level.info->SectorInfo.Points[i].owner, i, true ), 0 );
if ( lResult != 0 )
......@@ -175,4 +189,7 @@
if ( lResult != 0 )
TEAM_SetPointCount( PointOwners[i], TEAM_GetPointCount( PointOwners[i] ) + lResult, false );
TEAM_SetPointCount( level.info->SectorInfo.Points[i].owner, TEAM_GetPointCount( level.info->SectorInfo.Points[i].owner ) + lResult, false );
}
}
}
......@@ -178,9 +195,13 @@
if( pointlimit && (TEAM_GetPointCount(PointOwners[i]) >= pointlimit) )
{
DOMINATION_WinSequence(0);
break;
}
// [TRSR] Check this every tick in case a modder gives score via non-control point means.
if( pointlimit )
{
for( int team = 0; team < MAX_TEAMS; team++ )
{
if( TEAM_GetPointCount( team ) >= pointlimit )
{
DOMINATION_WinSequence(0);
break;
}
}
}
......@@ -194,32 +215,8 @@
finished = true;
}
void DOMINATION_SetOwnership(unsigned int point, player_t *toucher)
{
if(!domination)
return;
if(point >= NumPoints)
return;
if(!toucher->bOnTeam) //The toucher must be on a team
return;
unsigned int team = toucher->Team;
PointOwners[point] = team;
Printf ( "%s has taken control of %s.\n", toucher->userinfo.GetName(), (*level.info->SectorInfo.PointNames[point]).GetChars() );
for(unsigned int i = 0;i < level.info->SectorInfo.Points[point]->Size();i++)
{
unsigned int secnum = (*level.info->SectorInfo.Points[point])[i];
int color = TEAM_GetColor ( team );
sectors[secnum].SetFade( RPART(color), GPART(color), BPART(color) );
}
}
void DOMINATION_EnterSector(player_t *toucher)
void DOMINATION_SetOwnership(unsigned int point, unsigned int team, bool broadcast)
{
if(!domination)
return;
......@@ -222,8 +219,9 @@
{
if(!domination)
return;
// [BB] This is server side.
if ( NETWORK_InClientMode() )
{
if(point >= level.info->SectorInfo.Points.Size())
return;
if ( !TEAM_CheckIfValid( team ) && team != TEAM_None )
return;
......@@ -229,3 +227,2 @@
return;
}
......@@ -231,4 +228,6 @@
if(!toucher->bOnTeam) //The toucher must be on a team
// [TRSR] Need to save previous team for event script below.
int prevTeam = level.info->SectorInfo.Points[point].owner;
if( team == prevTeam )
return;
......@@ -233,10 +232,21 @@
return;
assert(PointOwners != NULL);
for(unsigned int point = 0;point < level.info->SectorInfo.Points.Size();point++)
{
for(unsigned int i = 0;i < level.info->SectorInfo.Points[point]->Size();i++)
{
if(toucher->mo->Sector->sectornum != static_cast<signed> ((*level.info->SectorInfo.Points[point])[i]))
continue;
if ( broadcast ) {
if( team != TEAM_None ) {
Printf( "\034%s%s" TEXTCOLOR_NORMAL " has taken control of %s.\n", TEAM_GetTextColorName( team ), TEAM_GetName( team ), level.info->SectorInfo.Points[point].name.GetChars() );
} else {
Printf( "\034%s%s" TEXTCOLOR_NORMAL " has lost control of %s.\n", TEAM_GetTextColorName( prevTeam ), TEAM_GetName( prevTeam ), level.info->SectorInfo.Points[point].name.GetChars() );
}
}
level.info->SectorInfo.Points[point].owner = team;
domination_SetControlPointColor( point );
// [TRSR] Trigger an event script when a team takes ownership of a point sector.
GAMEMODE_HandleEvent( GAMEEVENT_DOMINATION_CONTROL, nullptr, prevTeam, point );
// [TRSR] Let clients know about the change in management too.
if ( NETWORK_GetState() == NETSTATE_SERVER )
SERVERCOMMANDS_SetDominationPointOwner ( point, team, broadcast );
}
......@@ -242,5 +252,10 @@
// [BB] The team already owns the point, nothing to do.
if ( toucher->Team == PointOwners[point] )
continue;
static void domination_SetControlPointColor( unsigned int point )
{
if (( !domination ) || ( point >= level.info->SectorInfo.Points.Size( )))
return;
for ( unsigned int i = 0; i < level.info->SectorInfo.Points[point].sectors.Size(); i++ )
{
unsigned int secnum = level.info->SectorInfo.Points[point].sectors[i];
......@@ -246,6 +261,4 @@
// [AK] Trigger an event script when the player takes ownership of a point sector. This
// must be called before DOMINATION_SetOwnership so that the original owner of the sector
// is sent as the first argument. The second argument is the name of the sector.
GAMEMODE_HandleEvent( GAMEEVENT_DOMINATION_CONTROL, toucher->mo, PointOwners[point], ACS_PushAndReturnDynamicString( level.info->SectorInfo.PointNames[point]->GetChars( )));
if ( secnum >= static_cast<unsigned>( numsectors ))
continue;
......@@ -251,9 +264,12 @@
DOMINATION_SetOwnership(point, toucher);
// [BB] Let the clients know about the point ownership change.
if( NETWORK_GetState() == NETSTATE_SERVER )
SERVERCOMMANDS_SetDominationPointOwnership ( point, static_cast<ULONG> ( toucher - players ) );
if ( level.info->SectorInfo.Points[point].owner != TEAM_None )
{
int color = TEAM_GetColor( level.info->SectorInfo.Points[point].owner );
sectors[secnum].SetFade( RPART( color ), GPART( color ), BPART( color ));
}
else
{
sectors[secnum].SetFade( POINT_DEFAULT_R, POINT_DEFAULT_G, POINT_DEFAULT_B );
}
}
}
......
......@@ -67,6 +67,5 @@
#include "team.h"
#include "sectinfo.h"
void DOMINATION_LoadInit(unsigned int numpoints, unsigned int* pointowners);
void DOMINATION_WinSequence(unsigned int winner);
void DOMINATION_Tick(void);
......@@ -71,5 +70,4 @@
void DOMINATION_WinSequence(unsigned int winner);
void DOMINATION_Tick(void);
void DOMINATION_SetOwnership(unsigned int point, player_t *toucher);
void DOMINATION_EnterSector(player_t *toucher);
void DOMINATION_SetOwnership(unsigned int point, unsigned int team, bool broadcast = true);
void DOMINATION_Init(void);
......@@ -75,6 +73,4 @@
void DOMINATION_Init(void);
unsigned int DOMINATION_NumPoints(void);
unsigned int* DOMINATION_PointOwners(void);
void DOMINATION_Reset(void);
#endif // __DOMINATION_H__
......@@ -404,7 +404,7 @@
// [CK] This is executed both server and clientside, resulting in
// clientside clouds with no netID, but the server does have a netID.
// Clearing of clouds therefore fail because the client's poisoncloud
// netID is -1.
// netID is 0.
// This is run on both the server and client, so since we can safely
// assume this is clientside only, we can ensure proper cleanup by
// setting NETFL_CLIENTSIDEONLY, resulting in proper removal when
......
......@@ -1862,9 +1862,8 @@
TThinkerIterator<APlayerPawn> it (STAT_TRAVELLING);
APlayerPawn *pawn, *pawndup, *oldpawn, *next;
AInventory *inv;
// [BC]
LONG lSavedNetID;
bool doSweep = false; // [RK] Do a GC sweep
unsigned short savedNetID = 0; // [BC]
bool doSweep = false; // [RK] Do a GC sweep
next = it.Next ();
while ( (pawn = next) != NULL)
......@@ -1899,7 +1898,7 @@
G_CooperativeSpawnPlayer( pawn->player - players, false, true );
// [BC]
lSavedNetID = pawndup->NetID;
savedNetID = pawndup->NetID;
pawndup = pawn->player->mo;
if (!(changeflags & CHANGELEVEL_KEEPFACING))
{
......@@ -1937,7 +1936,7 @@
pawn->player->SendPitchLimits();
// [BC]
pawn->NetID = lSavedNetID;
pawn->NetID = savedNetID;
g_ActorNetIDList.useID ( pawn->NetID, pawn );
// [RK] Since the player wasn't spawned in during level load, the thinker GC sweep called in G_UnSnapshot
......