-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGame_local.h
1496 lines (1238 loc) · 59.7 KB
/
Game_local.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef __GAME_LOCAL_H__
#define __GAME_LOCAL_H__
// RAVEN BEGIN
// jsinger: attempt to eliminate cross-DLL allocation issues
#ifdef RV_UNIFIED_ALLOCATOR
inline void *operator new( size_t s ) { return Memory::Allocate(s); }
inline void operator delete( void *p ) { Memory::Free(p); }
inline void *operator new[]( size_t s ) { return Memory::Allocate(s); }
inline void operator delete[]( void *p ) { Memory::Free(p); }
#endif
// RAVEN END
/*
===============================================================================
Local implementation of the public game interface.
===============================================================================
*/
// if set to 1 the server sends the client PVS with snapshots and the client compares against what it sees
#ifndef ASYNC_WRITE_PVS
#define ASYNC_WRITE_PVS 0
#endif
extern idRenderWorld * gameRenderWorld;
// classes used by idGameLocal
class idEntity;
class idActor;
class idPlayer;
class idCamera;
class idWorldspawn;
class idTestModel;
class idAAS;
class idAI;
// RAVEN BEGIN
// bdube: not using id effects
//class idSmokeParticles;
//class idEntityFx;
// bdube: client side entities
class rvInstance;
class rvClientEntity;
class rvClientModel;
class rvCTFAssaultPlayerStart;
class idPlayerStart;
// RAVEN END
class idTypeInfo;
class idProgram;
class idThread;
class idEditEntities;
class idLocationEntity;
// RAVEN BEGIN
// dluetscher: reduced max clients for memory usage
#ifdef _XENON
#define MAX_CLIENTS 16
#else
// RAVEN END
#define MAX_CLIENTS 32
#endif
#define GENTITYNUM_BITS 12
#define MAX_GENTITIES (1<<GENTITYNUM_BITS)
#define ENTITYNUM_NONE (MAX_GENTITIES-1)
#define ENTITYNUM_WORLD (MAX_GENTITIES-2)
// RAVEN BEGIN
// bdube: dummy entity for client side physics
#define ENTITYNUM_CLIENT (MAX_GENTITIES-3)
#define ENTITYNUM_MAX_NORMAL (MAX_GENTITIES-3)
// RAVEN END
// RAVEN BEGIN
// bdube: client entities
#define CENTITYNUM_BITS 12
#define MAX_CENTITIES (1<<CENTITYNUM_BITS)
// shouchard: for ban lists and because I hate magic numbers
#define CLIENT_GUID_LENGTH 12
// RAVEN END
// RAVEN BEGIN
// abahr: helper macros
#define SAFE_DELETE_PTR(p) if(p) { delete (p); (p) = NULL; }
#define SAFE_REMOVE(p) if(p) { (p)->PostEventMS(&EV_Remove, 0); (p) = NULL; }
// RAVEN END
//============================================================================
void gameError( const char *fmt, ... );
//============================================================================
typedef enum {
CHANNEL_DEST_NONE,
CHANNEL_DEST_RELIABLE_SERVER,
CHANNEL_DEST_RELIABLE_REPEATER,
CHANNEL_DEST_COUNT
} channelDestType_t;
class idMessageSender {
public:
virtual channelDestType_t GetChannelType( void ) const = 0;
virtual void Send( const idBitMsg &msg ) const = 0;
};
class idNullMessageSender : public idMessageSender {
public:
virtual channelDestType_t GetChannelType( void ) const { return CHANNEL_DEST_NONE; }
virtual void Send( const idBitMsg &msg ) const { return; };
};
class idServerReliableMessageSender : public idMessageSender {
public:
virtual channelDestType_t GetChannelType( void ) const { return CHANNEL_DEST_RELIABLE_SERVER; }
virtual void Send( const idBitMsg &msg ) const {
if ( excludeClient != -1 ) {
networkSystem->ServerSendReliableMessageExcluding( excludeClient, msg, inhibitRepeater );
} else {
networkSystem->ServerSendReliableMessage( clientNum, msg, inhibitRepeater );
}
};
const idMessageSender &To( int _clientNum, bool _inhibitRepeater = false ) {
clientNum = _clientNum;
excludeClient = -1;
inhibitRepeater = _inhibitRepeater;
return *this;
}
const idMessageSender &NotTo( int _excludeClient, bool _inhibitRepeater = false ) {
clientNum = -1;
excludeClient = _excludeClient;
inhibitRepeater = _inhibitRepeater;
return *this;
}
private:
int clientNum;
int excludeClient;
bool inhibitRepeater;
};
class idRepeaterReliableMessageSender : public idMessageSender {
public:
virtual channelDestType_t GetChannelType( void ) const { return CHANNEL_DEST_RELIABLE_REPEATER; }
virtual void Send( const idBitMsg &msg ) const {
if ( excludeClient != -1 ) {
networkSystem->RepeaterSendReliableMessageExcluding( excludeClient, msg, inhibitHeader, repeaterClient );
} else {
networkSystem->RepeaterSendReliableMessage( repeaterClient, msg, inhibitHeader, clientNum );
}
};
const idMessageSender &To( int _clientNum, int asClient = -1, bool _inhibitHeader = false ) {
repeaterClient = _clientNum;
clientNum = asClient;
excludeClient = -1;
inhibitHeader = _inhibitHeader;
return *this;
}
const idMessageSender &ExcludingTo( int _excludeClient, int _clientNum, bool _inhibitHeader = false ) {
repeaterClient = _clientNum;
clientNum = -1;
excludeClient = _excludeClient;
inhibitHeader = _inhibitHeader;
return *this;
}
private:
int repeaterClient; // viewer number on repeater
int clientNum; // clientNum of real player to address exclusively to
int excludeClient; // clientNum of real player to exclude
bool inhibitHeader;
};
extern idNullMessageSender nullSender;
extern idServerReliableMessageSender serverReliableSender;
extern idRepeaterReliableMessageSender repeaterReliableSender;
//============================================================================
#include "gamesys/Event.h"
// RAVEN BEGIN
// bdube: added
#include "gamesys/State.h"
// RAVEN END
#include "gamesys/Class.h"
#include "gamesys/SysCvar.h"
#include "gamesys/SysCmds.h"
#include "gamesys/SaveGame.h"
#include "gamesys/DebugGraph.h"
#include "script/Script_Program.h"
#include "anim/Anim.h"
#include "ai/AAS.h"
#include "physics/Clip.h"
#include "physics/Push.h"
#include "Pvs.h"
#include "Lagometer.h"
//============================================================================
const int MAX_GAME_MESSAGE_SIZE = 8192;
const int MAX_ENTITY_STATE_SIZE = 512;
const int ENTITY_PVS_SIZE = ((MAX_GENTITIES+31)>>5);
// RAVEN BEGIN
// abahr: changed to NUM_PORTAL_ATTRIBUTES to take into account gravity
const int NUM_RENDER_PORTAL_BITS = NUM_PORTAL_ATTRIBUTES;
// RAVEN END
typedef struct entityState_s {
int entityNumber;
idBitMsg state;
byte stateBuf[MAX_ENTITY_STATE_SIZE];
struct entityState_s * next;
} entityState_t;
typedef struct snapshot_s {
int sequence;
entityState_t * firstEntityState;
int pvs[ENTITY_PVS_SIZE];
struct snapshot_s * next;
} snapshot_t;
const int MAX_EVENT_PARAM_SIZE = 128;
typedef struct entityNetEvent_s {
int spawnId;
int event;
int time;
int paramsSize;
byte paramsBuf[MAX_EVENT_PARAM_SIZE];
struct entityNetEvent_s *next;
struct entityNetEvent_s *prev;
} entityNetEvent_t;
enum {
GAME_RELIABLE_MESSAGE_SPAWN_PLAYER,
GAME_RELIABLE_MESSAGE_DELETE_ENT,
GAME_RELIABLE_MESSAGE_CHAT,
GAME_RELIABLE_MESSAGE_TCHAT,
GAME_RELIABLE_MESSAGE_DB,
GAME_RELIABLE_MESSAGE_KILL,
GAME_RELIABLE_MESSAGE_DROPWEAPON,
GAME_RELIABLE_MESSAGE_RESTART,
GAME_RELIABLE_MESSAGE_SERVERINFO,
GAME_RELIABLE_MESSAGE_CALLVOTE,
GAME_RELIABLE_MESSAGE_CASTVOTE,
GAME_RELIABLE_MESSAGE_STARTVOTE,
GAME_RELIABLE_MESSAGE_UPDATEVOTE,
GAME_RELIABLE_MESSAGE_PORTALSTATES,
GAME_RELIABLE_MESSAGE_PORTAL,
GAME_RELIABLE_MESSAGE_VCHAT,
GAME_RELIABLE_MESSAGE_STARTSTATE,
GAME_RELIABLE_MESSAGE_MENU,
GAME_RELIABLE_MESSAGE_EVENT,
GAME_RELIABLE_MESSAGE_ITEMACQUIRESOUND,
GAME_RELIABLE_MESSAGE_DEATH,
GAME_RELIABLE_MESSAGE_GAMESTATE,
GAME_RELIABLE_MESSAGE_STAT,
GAME_RELIABLE_MESSAGE_ALL_STATS,
GAME_RELIABLE_MESSAGE_INGAMEAWARD,
GAME_RELIABLE_MESSAGE_SET_INSTANCE,
GAME_RELIABLE_MESSAGE_VOICECHAT_MUTING,
GAME_RELIABLE_MESSAGE_SERVER_ADMIN,
GAME_RELIABLE_MESSAGE_CALLPACKEDVOTE,
GAME_RELIABLE_MESSAGE_STARTPACKEDVOTE,
GAME_RELIABLE_MESSAGE_GETADMINBANLIST,
GAME_RELIABLE_MESSAGE_PRINT,
GAME_RELIABLE_MESSAGE_VOICEDATA_CLIENT,
GAME_RELIABLE_MESSAGE_VOICEDATA_CLIENT_ECHO,
GAME_RELIABLE_MESSAGE_VOICEDATA_CLIENT_TEST,
GAME_RELIABLE_MESSAGE_VOICEDATA_CLIENT_ECHO_TEST,
GAME_RELIABLE_MESSAGE_GETVOTEMAPS,
// unreliable message sent over the reliable channel
// used as a debug solution when making sure some missing things are not due to packet drop
GAME_RELIABLE_MESSAGE_UNRELIABLE_MESSAGE,
// server acknowledges events from client, in response to specific GAME_RELIABLE_MESSAGE_EVENT situations
GAME_RELIABLE_MESSAGE_EVENT_ACK,
};
enum {
GAME_UNRELIABLE_MESSAGE_EVENT,
GAME_UNRELIABLE_MESSAGE_EFFECT,
GAME_UNRELIABLE_MESSAGE_HITSCAN,
GAME_UNRELIABLE_MESSAGE_VOICEDATA_SERVER
};
enum {
GAME_UNRELIABLE_RECORD_CLIENTNUM,
GAME_UNRELIABLE_RECORD_AREAS,
GAME_UNRELIABLE_RECORD_COUNT
};
typedef enum {
GAMESTATE_UNINITIALIZED, // prior to Init being called
GAMESTATE_NOMAP, // no map loaded
GAMESTATE_STARTUP, // inside InitFromNewMap(). spawning map entities.
GAMESTATE_RESTART, // spawning map entities from an instance restart, but not fully restarting
GAMESTATE_ACTIVE, // normal gameplay
GAMESTATE_SHUTDOWN // inside MapShutdown(). clearing memory.
} gameState_t;
typedef struct {
idPlayerStart *ent;
int dist;
} spawnSpot_t;
typedef struct {
bool connected;
bool active;
bool priv;
bool nopvs;
userOrigin_t origin;
int pvsArea;
idDict info;
} viewer_t;
//============================================================================
class idEventQueue {
public:
typedef enum {
OUTOFORDER_IGNORE,
OUTOFORDER_DROP,
OUTOFORDER_SORT
} outOfOrderBehaviour_t;
idEventQueue() : start( NULL ), end( NULL ) {}
entityNetEvent_t * Alloc();
void Free( entityNetEvent_t *event );
void Shutdown();
void Init();
void Enqueue( entityNetEvent_t* event, outOfOrderBehaviour_t oooBehaviour );
entityNetEvent_t * Dequeue( void );
entityNetEvent_t * RemoveLast( void );
entityNetEvent_t * Start( void ) { return start; }
private:
entityNetEvent_t * start;
entityNetEvent_t * end;
// RAVEN BEGIN
// jnewquist: Mark memory tags for idBlockAlloc
idBlockAlloc<entityNetEvent_t,32,MA_EVENT> eventAllocator;
// RAVEN END
};
//============================================================================
template< class type >
class idEntityPtr {
public:
idEntityPtr();
// save games
void Save( idSaveGame *savefile ) const; // archives object for save game file
void Restore( idRestoreGame *savefile ); // unarchives object from save game file
idEntityPtr<type> & operator=( type *ent );
// synchronize entity pointers over the network
int GetSpawnId( void ) const { return spawnId; }
bool SetSpawnId( int id );
bool UpdateSpawnId( void );
bool IsValid( void ) const;
type * GetEntity( void ) const;
int GetEntityNum( void ) const;
// RAVEN BEGIN
// bdube: overloaded operators
idEntityPtr( type* ent ) { *this = ent; }
idEntityPtr<type>& operator=( idEntityPtr<type>& ent ) { *this = ent.GetEntity(); return *this; }
type * operator->( void ) const;
operator type *( void ) const;
// RAVEN END
private:
int spawnId;
};
// RAVEN BEGIN
// abahr: forward declaration
class rvGravityArea;
// RAVEN END
//============================================================================
// ddynerman: moved MultiplayerGame.h down here, so it can use more stuff in Game_local (idEntityPtr)
#include "MultiplayerGame.h"
//============================================================================
class idGameLocal : public idGame {
public:
idDict serverInfo; // all the tunable parameters, like numclients, etc
idDict repeaterInfo; // serverInfo + repeater specific stuff
int numClients; // pulled from serverInfo and verified
idDict userInfo[MAX_CLIENTS]; // client specific settings
const usercmd_t *usercmds; // client input commands
idDict persistentPlayerInfo[MAX_CLIENTS];
idEntity * entities[MAX_GENTITIES];// index to entities
int spawnIds[MAX_GENTITIES];// for use in idEntityPtr
int firstFreeIndex; // first free index in the entities array
int minSpawnIndex; // when spawning multiple instances, so nothing pollutes in between the instances
int num_entities; // current number <= MAX_GENTITIES
idHashIndex entityHash; // hash table to quickly find entities by name
idWorldspawn * world; // world entity
idLinkList<idEntity> spawnedEntities; // all spawned entities
idLinkList<idEntity> activeEntities; // all thinking entities (idEntity::thinkFlags != 0)
int numEntitiesToDeactivate;// number of entities that became inactive in current frame
bool sortPushers; // true if active lists needs to be reordered to place pushers at the front
bool sortTeamMasters; // true if active lists needs to be reordered to place physics team masters before their slaves
idDict persistentLevelInfo; // contains args that are kept around between levels
// RAVEN BEGIN
// bdube: client entities
rvClientEntity * clientEntities[MAX_CENTITIES]; // index to client entities
int clientSpawnIds[MAX_CENTITIES]; // for use in idClientEntityPtr
idLinkList<rvClientEntity> clientSpawnedEntities; // all client side entities
int num_clientEntities; // current number of client entities
int firstFreeClientIndex; // first free index in the client entities array
int entityRegisterTime;
// RAVEN END
int maxViewers; // currently allocated
int maxViewer; // highest numbered active viewer + 1
viewer_t (*viewers);
// can be used to automatically effect every material in the world that references globalParms
float globalShaderParms[ MAX_GLOBAL_SHADER_PARMS ];
idRandom random; // random number generator used throughout the game
idProgram program; // currently loaded script and data space
idThread * frameCommandThread;
idPush push; // geometric pushing
idPVS pvs; // potential visible set
pvsHandle_t clientsPVS[MAX_CLIENTS];// PVS of multiplayer clients updated every frame
idTestModel * testmodel; // for development testing of models
// RAVEN BEGIN
// bdube: not using id effects
// idEntityFx * testFx; // for development testing of fx
// RAVEN END
// only set when an end level is activated, which will take over camera positioning
// and draw end-level guis, then
idStr sessionCommand; // a target_sessionCommand can set this to return something to the session
idMultiplayerGame mpGame; // handles rules for standard dm
idEditEntities * editEntities; // in game editing
int cinematicSkipTime; // don't allow skipping cinemetics until this time has passed so player doesn't skip out accidently from a firefight
int cinematicStopTime; // cinematics have several camera changes, so keep track of when we stop them so that we don't reset cinematicSkipTime unnecessarily
int cinematicMaxSkipTime; // time to end cinematic when skipping. there's a possibility of an infinite loop if the map isn't set up right.
bool inCinematic; // game is playing cinematic (player controls frozen)
bool skipCinematic;
// are kept up to date with changes to serverInfo
int framenum;
int previousTime; // time in msec of last frame
int time; // in msec
int msec; // time since last update in milliseconds
int mHz; // hertz
int vacuumAreaNum; // -1 if level doesn't have any outside areas
// RAVEN BEGIN
// abahr:
idList<rvGravityArea*> gravityInfo; // area num for each gravity zone
idList< idEntityPtr<idEntity> > scriptObjectProxies;
// RAVEN END
gameType_t gameType;
bool isMultiplayer; // set if the game is run in multiplayer mode
bool isServer; // set if the game is run for a dedicated or listen server
bool isClient; // set if the game is run for a client
// discriminates between the RunFrame path and the ClientPrediction path
// NOTE: on a listen server, isClient is false
bool isRepeater; // set if the game is repeating
bool isListenServer;
bool isTVClient;
int localClientNum; // number of the local client. MP: -1 on a dedicated, MAX_CLIENTS when playing a server demo
idLinkList<idEntity> snapshotEntities; // entities from the last snapshot
int realClientTime; // real client time
bool isNewFrame; // true if this is a new game frame, not a rerun due to prediction
int entityDefBits; // bits required to store an entity def number
int clientAckSequence; // holds frame number updated through GAME_RELIABLE_MESSAGE_EVENT_ACK server->client messages
static const char * sufaceTypeNames[ MAX_SURFACE_TYPES ]; // text names for surface types
idEntityPtr<idEntity> lastGUIEnt; // last entity with a GUI, used by Cmd_NextGUI_f
int lastGUI; // last GUI on the lastGUIEnt
int editors; // Mirrored editors flags from common determine which editors are running
bool isLastPredictFrame; // on an MP server or in SP game this means 'last catchup frame' rather than predict
// RAVEN BEGIN
// rjohnson: entity usage stats
idStr mapFileNameStripped; // name of the map, empty string if no map loaded, with path and extension removed. If entity filter, that is appended
idList<idDict> entityUsageList;
// ddynerman: the entity currently thinking, used to play effects/etc only in the appropriate instance
idEntity* currentThinkingEntity;
const static int INITIAL_SPAWN_COUNT = 1;
// RAVEN END
int filterMod;
idList<idStr> modList;
int nextLagoCheck;
// ---------------------- Public idGame Interface -------------------
idGameLocal();
// RAVEN BEGIN
// jsinger: attempt to eliminate cross-DLL allocation issues
#ifdef RV_UNIFIED_ALLOCATOR
virtual void Init( void *(*allocator)( size_t size ), void (*deallocator)( void *ptr ), size_t (*msize)( void *ptr ) );
#else
virtual void Init( void );
#endif
// RAVEN END
virtual void Shutdown( void );
virtual void SetLocalClient( int clientNum );
virtual void ThrottleUserInfo( void );
virtual const idDict * SetUserInfo( int clientNum, const idDict &userInfo, bool isClient );
virtual const idDict * GetUserInfo( int clientNum );
virtual bool IsClientActive( int clientNum );
virtual void SetServerInfo( const idDict &serverInfo );
virtual const idDict * RepeaterSetUserInfo( int clientNum, const idDict &userInfo );
virtual const idDict & GetPersistentPlayerInfo( int clientNum );
virtual void SetPersistentPlayerInfo( int clientNum, const idDict &playerInfo );
virtual void InitFromNewMap( const char *mapName, idRenderWorld *renderWorld, bool isServer, bool isClient, int randSeed );
virtual bool InitFromSaveGame( const char *mapName, idRenderWorld *renderWorld, idFile *saveGameFile );
// RAVEN BEGIN
// mekberg: added saveTypes
virtual void SaveGame( idFile *saveGameFile, saveType_t saveType = ST_REGULAR );
// RAVEN END
virtual void MapShutdown( void );
virtual void CacheDictionaryMedia( const idDict *dict );
virtual void SpawnPlayer( int clientNum );
virtual gameReturn_t RunFrame( const usercmd_t *clientCmds, int activeEditors, bool lastCatchupFrame, int serverGameFrame );
virtual void MenuFrame( void );
virtual void RepeaterFrame( const userOrigin_t *clientOrigins, bool lastCatchupFrame, int serverGameFrame );
virtual bool Draw( int clientNum );
virtual escReply_t HandleESC( idUserInterface **gui );
virtual idUserInterface *StartMenu( void );
virtual const char * HandleGuiCommands( const char *menuCommand );
virtual void HandleMainMenuCommands( const char *menuCommand, idUserInterface *gui );
virtual allowReply_t ServerAllowClient( int clientId, int numClients, const char *IP, const char *guid, const char *password, const char *privatePassword, char reason[MAX_STRING_CHARS] );
virtual void ServerClientConnect( int clientNum, const char *guid );
virtual void ServerClientBegin( int clientNum );
virtual void ServerClientDisconnect( int clientNum );
virtual void ServerWriteInitialReliableMessages( int clientNum );
virtual allowReply_t RepeaterAllowClient( int clientId, int numClients, const char *IP, const char *guid, bool repeater, const char *password, const char *privatePassword, char reason[MAX_STRING_CHARS] );
virtual void RepeaterClientConnect( int clientNum );
virtual void RepeaterClientBegin( int clientNum );
virtual void RepeaterClientDisconnect( int clientNum );
virtual void RepeaterWriteInitialReliableMessages( int clientNum );
virtual void WriteSnapshot( snapshot_t *&clientSnapshot, entityState_t *entityStates[MAX_GENTITIES], int PVS[ENTITY_PVS_SIZE], idMsgQueue &unreliable, int sequence, idBitMsg &msg, int transmitEntity, int transmitEntity2, int instance, bool doPVS, const idBounds &pvs_bounds, int lastSnapshotFrame );
virtual void ServerWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, dword *clientInPVS, int numPVSClients, int lastSnapshotFrame );
virtual bool ServerApplySnapshot( int clientNum, int sequence );
virtual void ServerProcessReliableMessage( int clientNum, const idBitMsg &msg );
virtual bool RepeaterApplySnapshot( int clientNum, int sequence );
virtual void RepeaterProcessReliableMessage( int clientNum, const idBitMsg &msg );
virtual void ClientReadSnapshot( int clientNum, int snapshotSequence, const int gameFrame, const int gameTime, const int dupeUsercmds, const int aheadOfServer, const idBitMsg &msg );
virtual bool ClientApplySnapshot( int clientNum, int sequence );
virtual void ClientProcessReliableMessage( int clientNum, const idBitMsg &msg );
virtual gameReturn_t ClientPrediction( int clientNum, const usercmd_t *clientCmds, bool lastPredictFrame = true, ClientStats_t *cs = NULL );
// RAVEN BEGIN
// ddynerman: client game frame
virtual void ClientRun( void );
virtual void ClientEndFrame( void );
// jshepard: rcon password check
virtual void ProcessRconReturn( bool success );
virtual void ResetRconGuiStatus( void );
// RAVEN END
virtual void GetClientStats( int clientNum, char *data, const int len );
virtual void SwitchTeam( int clientNum, int team );
virtual bool DownloadRequest( const char *IP, const char *guid, const char *paks, char urls[ MAX_STRING_CHARS ] );
virtual bool HTTPRequest( const char *IP, const char *file, bool isGamePak );
// RAVEN BEGIN
// bdube: client hitscan
virtual void ClientHitScan( const idBitMsg &msg );
// jscott: for effects system
virtual void StartViewEffect( int type, float time, float scale );
virtual void GetPlayerView( idVec3 &origin, idMat3 &axis );
virtual void Translation( trace_t &trace, idVec3 &source, idVec3 &dest, idTraceModel *trm, int clipMask );
virtual void SpawnClientMoveable ( const char* name, int lifetime, const idVec3& origin, const idMat3& axis, const idVec3& velocity, const idVec3& angular_velocity );
// bdube: added debug methods
virtual void DebugSetString ( const char* name, const char* value );
virtual void DebugSetFloat ( const char* name, float value );
virtual void DebugSetInt ( const char* name, int value );
virtual const char* DebugGetStatString ( const char* name );
virtual int DebugGetStatInt ( const char* name );
virtual float DebugGetStatFloat ( const char* name );
virtual bool IsDebugHudActive ( void ) const;
// rjohnson: for new note taking mechanism
virtual bool GetPlayerInfo( idVec3 &origin, idMat3 &axis, int PlayerNum = -1, idAngles *deltaViewAngles = NULL, int reqClientNum = -1 );
virtual void SetPlayerInfo( idVec3 &origin, idMat3 &axis, int PlayerNum = -1 );
virtual bool PlayerChatDisabled( int clientNum );
virtual void SetViewComments( const char *text = 0 );
// ddynerman: utility functions
virtual void GetPlayerName( int clientNum, char* name );
virtual void GetPlayerClan( int clientNum, char* clan );
virtual void SetFriend( int clientNum, bool isFriend );
static void Cmd_PrintMapEntityNumbers_f( const idCmdArgs& args );
static void Cmd_PrintSpawnIds_f( const idCmdArgs& args );
// abahr:
virtual int GetNumGravityAreas() const;
virtual const rvGravityArea* GetGravityInfo( int index ) const;
virtual void SetGravityInfo( int index, rvGravityArea* info );
virtual void AddUniqueGravityInfo( rvGravityArea* info );
virtual int GetCurrentGravityInfoIndex( const idVec3& origin ) const;
virtual bool InGravityArea( idEntity* entity ) const;
virtual int GetCurrentGravityInfoIndex( idEntity* entity ) const;
virtual const idVec3 GetCurrentGravity( idEntity* entity ) const;
virtual const idVec3 GetCurrentGravity( const idVec3& origin, const idMat3& axis ) const;
virtual bool InGravityArea( rvClientEntity* entity ) const;
virtual int GetCurrentGravityInfoIndex( rvClientEntity* entity ) const;
virtual const idVec3 GetCurrentGravity( rvClientEntity* entity ) const;
virtual idEntity* ReferenceScriptObjectProxy( const char* scriptObjectName );
virtual void ReleaseScriptObjectProxy( const char* proxyName );
// rjohnson: entity usage stats
virtual void ListEntityStats( const idCmdArgs &args );
// RAVEN END
virtual void SetDemoState( demoState_t state, bool serverDemo, bool timeDemo );
virtual void SetRepeaterState( bool isRepeater, bool serverIsRepeater );
virtual void WriteNetworkInfo( idFile* file, int clientNum );
virtual void ReadNetworkInfo( int gameTime, idFile* file, int clientNum );
virtual bool ValidateDemoProtocol( int minor_ref, int minor );
virtual void ServerWriteServerDemoSnapshot( int sequence, idBitMsg &msg, int lastSnapshotFrame );
virtual void ClientReadServerDemoSnapshot( int sequence, const int gameFrame, const int gameTime, const idBitMsg &msg );
virtual void RepeaterWriteSnapshot( int clientNum, int sequence, idBitMsg &msg, dword *clientInPVS, int numPVSClients, const userOrigin_t &pvs_origin, int lastSnapshotFrame );
virtual void RepeaterEndSnapshots( void );
virtual void ClientReadRepeaterSnapshot( int sequence, const int gameFrame, const int gameTime, const int aheadOfServer, const idBitMsg &msg );
virtual int GetDemoFollowClient( void ) { return IsServerDemoPlaying() ? followPlayer : -1; }
virtual void GetBotInput( int clientNum, usercmd_t &userCmd ) { Error( "Bot input requested\n" ); };
virtual const char * GetLoadingGui( const char *mapDeclName ) { return NULL; }
virtual void SetupLoadingGui( idUserInterface *gui ) {}
// ---------------------- Public idGameLocal Interface -------------------
void Printf( const char *fmt, ... ) const;
void DPrintf( const char *fmt, ... ) const;
void Warning( const char *fmt, ... ) const;
void DWarning( const char *fmt, ... ) const;
void Error( const char *fmt, ... ) const;
// Initializes all map variables common to both save games and spawned games
void LoadMap( const char *mapName, int randseed );
void LocalMapRestart( int instance = -1 );
void MapRestart( int instance = -1 );
static void VerifyServerSettings_f( const idCmdArgs &args );
static void MapRestart_f( const idCmdArgs &args );
bool NextMap( void ); // returns wether serverinfo settings have been modified
static void NextMap_f( const idCmdArgs &args );
idMapFile * GetLevelMap( void );
const char * GetMapName( void ) const;
int NumAAS( void ) const;
idAAS * GetAAS( int num ) const;
idAAS * GetAAS( const char *name ) const;
// RAVEN BEGIN
// jscott: added accessor for memory tracking
int GetNumAAS( void ) const { return( aasList.Num() ); }
// RAVEN END
void SetAASAreaState( const idBounds &bounds, const int areaContents, bool closed );
aasHandle_t AddAASObstacle( const idBounds &bounds );
void RemoveAASObstacle( const aasHandle_t handle );
void RemoveAllAASObstacles( void );
// RAVEN BEGIN
// mwhitlock: added entity memory usage stuff.
size_t GetEntityMemoryUsage ( void ) const;
// RAVEN END
bool CheatsOk( bool requirePlayer = true );
void SetSkill( int value );
gameState_t GameState( void ) const;
void SetGameState( gameState_t newState ) { gamestate = newState; }
idEntity * SpawnEntityType( const idTypeInfo &classdef, const idDict *args = NULL, bool bIsClientReadSnapshot = false );
bool SpawnEntityDef( const idDict &args, idEntity **ent = NULL, bool setDefaults = true );
bool SpawnClientEntityDef( const idDict &args, rvClientEntity **ent = NULL, bool setDefaults = true, const char* spawn = NULL );
// abahr:
idEntity* SpawnEntityDef( const char* entityDefName, const idDict* additionalArgs = NULL );
template< class type >
type* SpawnSafeEntityDef( const char* entityDefName, const idDict* additionalArgs = NULL );
int GetPreviousTime() const { return previousTime; }
// RAVEN END
int GetSpawnId( const idEntity *ent ) const;
const idDeclEntityDef * FindEntityDef( const char *name, bool makeDefault = true ) const;
const idDict * FindEntityDefDict( const char *name, bool makeDefault = true ) const;
void RegisterEntity( idEntity *ent );
void UnregisterEntity( idEntity *ent );
// used to skip one when registering entities, leaving an empty entity in the array
void SkipEntityIndex( void );
bool RequirementMet( idEntity *activator, const idStr &requires, int removeItem );
// RITUAL BEGIN
// squirrel: accessor for si_weaponStay checks
bool IsWeaponsStayOn( void );
// RITUAL END
// RAVEN BEGIN
// bdube: client entities
void RegisterClientEntity( rvClientEntity *cent );
void UnregisterClientEntity( rvClientEntity *cent );
// RAVEN END
void AlertAI( idEntity *ent );
// RAVEN BEGIN
// bdube: added get alert actor
idActor * GetAlertActor( void );
idEntity * GetAlertEntity( void );
// RAVEN END
bool InPlayerPVS( idEntity *ent ) const;
bool InPlayerConnectedArea( idEntity *ent ) const;
void SetCamera( idCamera *cam );
idCamera * GetCamera( void ) const;
bool SkipCinematic( void );
// RAVEN BEGIN
// jscott: for portal skies
idCamera *GetPortalSky( void ) const;
void SetPortalSky( idCamera *cam );
// RAVEN END
void CalcFov( float base_fov, float &fov_x, float &fov_y ) const;
void AddEntityToHash( const char *name, idEntity *ent );
bool RemoveEntityFromHash( const char *name, idEntity *ent );
int GetTargets( const idDict &args, idList< idEntityPtr<idEntity> > &list, const char *ref ) const;
// returns the master entity of a trace. for example, if the trace entity is the player's head, it will return the player.
idEntity * GetTraceEntity( const trace_t &trace ) const;
static void ArgCompletion_EntityName( const idCmdArgs &args, void(*callback)( const char *s ) );
idEntity * FindTraceEntity( idVec3 start, idVec3 end, const idTypeInfo &c, const idEntity *skip ) const;
static void ArgCompletion_AIName( const idCmdArgs &args, void(*callback)( const char *s ) );
//RAVEN BEGIN
// bgeisler: added, I don't want to have to do this work myself every single time I have an entityNumber
idEntity * FindEntity( int entityNumber ) { return ((entityNumber >= 0 && entityNumber < MAX_GENTITIES) ? entities[entityNumber] : NULL); }
//RAVEN BEGIN
idEntity * FindEntity( const char *name ) const;
idEntity * FindEntityUsingDef( idEntity *from, const char *match ) const;
int EntitiesWithinRadius( const idVec3 org, float radius, idEntity **entityList, int maxCount ) const;
void KillBox( idEntity *ent, bool catch_teleport = false );
void RadiusPush( const idVec3 &origin, const float radius, const float push, const idEntity *inflictor, const idEntity *ignore, float inflictorScale, const bool quake );
// RAVEN BEGIN
// ddynerman: return number of people damaged
void RadiusDamage( const idVec3 &origin, idEntity *inflictor, idEntity *attacker, idEntity *ignoreDamage, idEntity *ignorePush, const char *damageDefName, float dmgPower = 1.0f, int* hitCount = NULL );
// bdube: inflictor
void RadiusPushClipModel( idEntity* inflictor, const idVec3 &origin, const float push, const idClipModel *clipModel );
// RAVEN END
void ProjectDecal( const idVec3 &origin, const idVec3 &dir, float depth, bool parallel, float size, const char *material, float angle = 0 );
// RAVEN BEGIN
// ddynerman: multiple collision worlds
void BloodSplat( const idEntity* ent, const idVec3 &origin, const idVec3 &dir, float size, const char *material );
// RAVEN END
void CallFrameCommand( idEntity *ent, const function_t *frameCommand );
// RAVEN BEGIN
// bdube: added script object frame commands
void CallFrameCommand( idScriptObject* obj, const function_t* frameCommand );
void CallFrameCommand( idEntity* ent, const char* frameCommand );
// RAVEN END
void CallObjectFrameCommand( idEntity *ent, const char *frameCommand );
const idVec3 & GetGravity( void ) const;
// added the following to assist licensees with merge issues
int GetFrameNum() const { return framenum; }
int GetTime() const { return time; }
int GetMSec() const { return msec; }
int GetMHz() const { return mHz; }
int GetNextClientNum( int current ) const;
idPlayer * GetClientByNum( int current ) const;
idPlayer * GetClientByName( const char *name ) const;
idPlayer * GetClientByCmdArgs( const idCmdArgs &args ) const;
int GetClientNumByName( const char *name ) const;
idPlayer * GetLocalPlayer() const;
// RAVEN BEGIN
// jshepard: update player data after main menu close
void UpdatePlayerPostMainMenu();
// bdube: added
int GetSpawnCount ( void ) const;
void SetSpawnCount ( int newSpawnCount ) { spawnCount = newSpawnCount; }
// ddynerman: team type
bool IsTeamGame ( void ) const;
// RAVEN END
void SpreadLocations();
idLocationEntity * LocationForPoint( const idVec3 &point ); // May return NULL
// RAVEN BEGIN
// bdube: added
idLocationEntity* AddLocation ( const idVec3& point, const char* name );
// ddynerman: new gametype specific spawn code
bool SpotWouldTelefrag( idPlayer* player, idPlayerStart* spawn );
idEntity* SelectSpawnPoint( idPlayer* player );
void UpdateForwardSpawns( rvCTFAssaultPlayerStart* point, int team );
void ClearForwardSpawns( void );
// RAVEN END
void SetPortalState( qhandle_t portal, int blockingBits );
void ServerSendChatMessage( int to, const char *name, const char *text, const char *parm = "" );
void SetGlobalMaterial( const idMaterial *mat );
const idMaterial * GetGlobalMaterial();
void SetGibTime( int _time ) { nextGibTime = _time; }
int GetGibTime() { return nextGibTime; }
// RITUAL BEGIN
// squirrel: added DeadZone multiplayer mode
void SetUnFreezeTime( int _time ) { unFreezeTime = _time; };
int GetUnFreezeTime() { return unFreezeTime; };
void SetIsFrozen( bool _isFrozen ) { isFrozen = _isFrozen; };
bool GetIsFrozen() { return isFrozen; };
// RITUAL END
bool NeedRestart();
// RAVEN BEGIN
// jshepard: update end of level on player hud
void UpdateEndLevel();
// MCG: added whizz-by sound
void CheckPlayerWhizzBy ( idVec3 start, idVec3 end, idEntity* hitEnt, idEntity *attacker );
// bdube: added hitscan
// twhitaker: added additionalIgnore parameter
idEntity* HitScan ( const idDict& hitscanDef, const idVec3& origin, const idVec3& dir, const idVec3& fxOrigin, idEntity* owner = NULL, bool noFX = false, float damageScale = 1.0f, idEntity * additionalIgnore = NULL, int *areas = NULL );
// bdube: added effect calls
virtual rvClientEffect* PlayEffect ( const idDecl *effect, const idVec3& origin, const idMat3& axis, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, bool predictedBit = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
rvClientEffect* PlayEffect ( const idDict& args, const char* effectName, const idVec3& origin, const idMat3& axis, bool loop = false, const idVec3& endOrigin = vec3_origin, bool broadcast = false, bool predictedBit = false, effectCategory_t category = EC_IGNORE, const idVec4& effectTint = vec4_one );
const idDecl *GetEffect ( const idDict& args, const char* effectName, const rvDeclMatType* materialType = NULL );
void UpdateRepeaterInfo( bool transmit = false );
idList<idEntity*> ambientLights; // lights that cast ambient
// ddynerman: multiple collision world - game collision wrapper functions to
// use the correct idClip
// ---------------------------------------------------------------
// These are wrapper functions around idClip collision detection
// functions. They expose the collision detection engine to the
// game code, but do collision world determination in one spot.
// 'ent' refers to the entity we want collision information about
bool Translation ( const idEntity* ent, trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity, const idEntity *passEntity2 = 0 );
bool Rotation ( const idEntity* ent, trace_t &results, const idVec3 &start, const idRotation &rotation, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
bool Motion ( const idEntity* ent, trace_t &results, const idVec3 &start, const idVec3 &end, const idRotation &rotation, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
int Contacts ( const idEntity* ent, contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity );
int Contents ( const idEntity* ent, const idVec3 &start, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity, idEntity **touchedEntity = NULL );
// special case translations versus the rest of the world
bool TracePoint ( const idEntity* ent, trace_t &results, const idVec3 &start, const idVec3 &end, int contentMask, const idEntity *passEntity );
bool TraceBounds ( const idEntity* ent, trace_t &results, const idVec3 &start, const idVec3 &end, const idBounds &bounds, int contentMask, const idEntity *passEntity );
// clip versus a specific model
void TranslationModel( const idEntity* ent, trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
void RotationModel ( const idEntity* ent, trace_t &results, const idVec3 &start, const idRotation &rotation, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
int ContactsModel ( const idEntity* ent, contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
int ContentsModel ( const idEntity* ent, const idVec3 &start, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, idCollisionModel *model, const idVec3 &modelOrigin, const idMat3 &modelAxis );
// clip versus all entities but not the world
void TranslationEntities( const idEntity* ent, trace_t &results, const idVec3 &start, const idVec3 &end, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity, const idEntity *passEntity2 = 0 );
// get a contact feature
bool GetModelContactFeature( const idEntity* ent, const contactInfo_t &contact, const idClipModel *clipModel, idFixedWinding &winding ) const;
// get entities/clip models within or touching the given bounds
int EntitiesTouchingBounds ( const idEntity* ent, const idBounds &bounds, int contentMask, idEntity **entityList, int maxCount ) const;
int ClipModelsTouchingBounds( const idEntity* ent, const idBounds &bounds, int contentMask, idClipModel **clipModelList, int maxCount ) const;
int PlayersTouchingBounds ( const idEntity* ent, const idBounds &bounds, int contentMask, idPlayer **entityList, int maxCount ) const;
const idBounds & GetWorldBounds( const idEntity* ent ) const;
void Link( idClipModel* clip, idEntity *ent, int newId, const idVec3 &newOrigin, const idMat3 &newAxis, int renderModelHandle = -1 );
idClip* GetEntityClipWorld( const idEntity* ent );
const idClip* GetEntityClipWorld( const idEntity* ent ) const;
int GetNumMapEntities( void ) const;
int AddClipWorld( int id );
void RemoveClipWorld( int id );
int AddInstance( int id = -1, bool deferPopulate = false );
void RemoveInstance( int id );
rvInstance* GetInstance( int id );
int GetNumInstances( void );
// ddynerman: multiple game instances
void SpawnMapEntities( int instance = 0, unsigned short* entityNumIn = NULL, unsigned short* entityNumOut = NULL, int* startSpawnCount = NULL );
void InstanceClear( void );
// ddynerman: utility function
virtual const char* GetLongGametypeName( const char* gametype );
virtual void ReceiveRemoteConsoleOutput( const char* output );
bool IsFlagGameType( void ) { return ( gameType == GAME_CTF || gameType == GAME_1F_CTF || gameType == GAME_ARENA_CTF || gameType == GAME_ARENA_1F_CTF ); }
bool IsTeamGameType( void ) { return ( gameType == GAME_TDM || gameType == GAME_CTF || gameType == GAME_ARENA_CTF || gameType == GAME_DEADZONE ); }
bool IsTeamPowerups( void );
// twhitaker: needed this for difficulty settings
float GetDifficultyModifier( void ) { const static float difficulty[] = { -0.3f, 0.0f, 0.4f, 0.8f }; return difficulty[ idMath::ClampInt( 0, 3, g_skill.GetInteger() ) ]; }
bool IsMultiplayer( void ) { return isMultiplayer; }
// mekberg: added
bool InCinematic( void ) { return inCinematic; }
// mekberg: so ban list can be populated outside of multiplayer game
void PopulateBanList( idUserInterface* hud );
// RAVEN END
// RAVEN BEGIN
// mwhitlock: Dynamic memory consolidation
#if defined(_RV_MEM_SYS_SUPPORT)
virtual void FlushBeforelevelLoad( void );
#endif
// RAVEN END
void ServerSendInstanceReliableMessageExcluding( const idEntity* owner, int excludeClient, const idBitMsg& msg );
void ServerSendInstanceReliableMessage( const idEntity* owner, int clientNum, const idBitMsg& msg );
void SendUnreliableMessage( const idBitMsg &msg, const int clientNum );
// note: listen server client is always excluded
void SendUnreliableMessagePVS( const idBitMsg &msg, const idEntity *instanceEnt, int area1 = -1, int area2 = -1 );
void RepeaterAppendUnreliableMessage( int icl, const idBitMsg &msg, const idBitMsg *header = NULL );
void RepeaterUnreliableMessage( const idBitMsg &msg, const int clientNum, const idBitMsg *header = NULL );
void RepeaterUnreliableMessagePVS( const idBitMsg &msg, const int *areas, int numAreas, const idBitMsg *header = NULL );
demoState_t GetDemoState( void ) const { return demoState; }
bool IsServerDemoPlaying( void ) const { return (demoState == DEMO_PLAYING && serverDemo) || serverIsRepeater; }
bool IsServerDemoRecording( void ) const { return demoState == DEMO_RECORDING && serverDemo; }
bool IsRepeaterDemoPlaying( void ) const { return (demoState == DEMO_PLAYING && !serverDemo) && serverIsRepeater; }
bool IsTimeDemo( void ) const { return timeDemo; }
/*
do not synchronize implicit decls over the network
implicit decls are created when loading sounds and materials that don't have an explicit entry in the def files
clients and server may load those in different orders in a same map, or even join in with different orders because of different map histories before this game
in D3 we maintain remap tables, but it's much better to have tighter multiplayer assets so we have no need at all
still, you want to catch when bad things happen, so indexes should ALL be read and written through these functions
*/
static void WriteDecl( idBitMsg &msg, const idDecl *decl );
static const idDecl* ReadDecl( const idBitMsg &msg, declType_t type );
static void WriteDecl( idBitMsgDelta &msg, const idDecl *decl );
static const idDecl* ReadDecl( const idBitMsgDelta &msg, declType_t type );
idPlayerStart *RandomSpawn( void );
int GetStartingIndexForInstance( int instanceID );
void ClientSetStartingIndex( int i ) { clientInstanceFirstFreeIndex = i; }
void ServerSetMinSpawnIndex( void );
void ServerSetEntityIndexWatermark( int instanceID );
idLagometer lagometer;
private:
// RAVEN BEGIN
// ddynerman: multiple instance for MP
idList<idClip*> clip; // collision detection
idList<rvInstance*> instances;