This repository has been archived by the owner on May 10, 2019. It is now read-only.
/
sf2.sp
7961 lines (6692 loc) · 237 KB
/
sf2.sp
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
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <clientprefs>
#include <tf2items>
#include <tf2attributes>
#include <dhooks>
#include <navmesh>
#include <nativevotes>
#include <collisionhook>
#pragma semicolon 1
#include <tf2>
#include <tf2_stocks>
#include <morecolors>
#undef REQUIRE_PLUGIN
#include <adminmenu>
#tryinclude <store/store-tf2footprints>
#define REQUIRE_PLUGIN
#undef REQUIRE_EXTENSIONS
#tryinclude <steamtools>
#tryinclude <steamworks>
#tryinclude <sendproxy>
#define REQUIRE_EXTENSIONS
bool steamtools=false;
bool steamworks=false;
bool sendproxymanager=false;
#define DEBUG
#define SF2
#include <sf2>
#pragma newdecls required
#define PLUGIN_VERSION "1.5.0"
#define PLUGIN_VERSION_DISPLAY "1.5.0"
#define TFTeam_Spectator 1
#define TFTeam_Red 2
#define TFTeam_Blue 3
#define TFTeam_Boss 5
#define MASK_RED 33640459
#define MASK_BLUE 33638411
#define EF_ITEM_BLINK 0x100
public Plugin myinfo =
{
name = "Slender Fortress",
author = "KitRifty, Benoist3012",
description = "Based on the game Slender: The Eight Pages.",
version = PLUGIN_VERSION,
url = "http://steamcommunity.com/groups/SlenderFortress"
}
#define FILE_RESTRICTEDWEAPONS "configs/sf2/restrictedweapons.cfg"
#define BOSS_THINKRATE 0.1 // doesn't really matter much since timers go at a minimum of 0.1 seconds anyways
#define CRIT_SOUND "player/crit_hit.wav"
#define CRIT_PARTICLENAME "crit_text"
#define MINICRIT_SOUND "player/crit_hit_mini.wav"
#define MINICRIT_PARTICLENAME "minicrit_text"
#define ZAP_SOUND "weapons/barret_arm_zap.wav"
#define ZAP_PARTICLENAME "dxhr_arm_muzzleflash"
#define FIREWORKSBLU_PARTICLENAME "utaunt_firework_teamcolor_blue"
#define FIREWORKSRED_PARTICLENAME "utaunt_firework_teamcolor_red"
#define TELEPORTEDINBLU_PARTICLENAME "teleported_red"
#define SPECIALROUND_BOO_DISTANCE 120.0
#define SPECIALROUND_BOO_DURATION 4.0
#define PAGE_DETECTOR_BEEP "items/cart_explode_trigger.wav"
#define PAGE_MODEL "models/slender/sheet.mdl"
#define PAGE_MODELSCALE 1.1
#define SF_KEYMODEL "models/demani_sf/key_australium.mdl"
#define FLASHLIGHT_CLICKSOUND "slender/newflashlight.wav"
#define FLASHLIGHT_CLICKSOUND_NIGHTVISION "slender/nightvision.mp3"
#define FLASHLIGHT_BREAKSOUND "ambient/energy/spark6.wav"
#define FLASHLIGHT_NOSOUND "player/suit_denydevice.wav"
#define PAGE_GRABSOUND "slender/newgrabpage.wav"
#define MUSIC_CHAN SNDCHAN_AUTO
#define MUSIC_GOTPAGES1_SOUND "slender/ambience_1_new.wav"
#define MUSIC_GOTPAGES2_SOUND "slender/ambience_2_new.wav"
#define MUSIC_GOTPAGES3_SOUND "slender/ambience_3_new.wav"
#define MUSIC_GOTPAGES4_SOUND "slender/ambience_4_new.wav"
#define MUSIC_PAGE_VOLUME 1.0
#define SF2_INTRO_DEFAULT_MUSIC "slender/intro_new.mp3"
#define PROXY_RAGE_MODE_SOUND "slender/proxyrage.mp3"
#define SF2_HUD_TEXT_COLOR_R 127
#define SF2_HUD_TEXT_COLOR_G 167
#define SF2_HUD_TEXT_COLOR_B 141
#define SF2_HUD_TEXT_COLOR_A 255
enum MuteMode
{
MuteMode_Normal = 0,
MuteMode_DontHearOtherTeam,
MuteMode_DontHearOtherTeamIfNotProxy
};
char g_strSoundNightmareMode[][] =
{
"ambient/halloween/thunder_04.wav",
"ambient/halloween/thunder_05.wav",
"ambient/halloween/thunder_08.wav",
"ambient/halloween/mysterious_perc_09.wav",
"ambient/halloween/mysterious_perc_09.wav",
"ambient/halloween/windgust_08.wav"
};
//Update
bool g_bSeeUpdateMenu[MAXPLAYERS+1] = false;
//Command
bool g_bAdminNoPoints[MAXPLAYERS+1] = false;
// Offsets.
int g_offsPlayerFOV = -1;
int g_offsPlayerDefaultFOV = -1;
int g_offsPlayerFogCtrl = -1;
int g_offsPlayerPunchAngle = -1;
int g_offsPlayerPunchAngleVel = -1;
int g_offsFogCtrlEnable = -1;
int g_offsFogCtrlEnd = -1;
int g_offsCollisionGroup = -1;
#if defined DEBUG
//temp
int g_iPathLaserModelIndex;
#endif
//Commands
float g_flLastCommandTime[MAXPLAYERS + 1];
bool g_bEnabled;
Handle g_hConfig;
Handle g_hRestrictedWeaponsConfig;
Handle g_hSpecialRoundsConfig;
Handle g_hPageMusicRanges;
int g_iSlenderModel[MAX_BOSSES] = { INVALID_ENT_REFERENCE, ... };
int g_iSlenderPoseEnt[MAX_BOSSES] = { INVALID_ENT_REFERENCE, ... };
int g_iSlenderCopyMaster[MAX_BOSSES] = { -1, ... };
float g_flSlenderEyePosOffset[MAX_BOSSES][3];
float g_flSlenderEyeAngOffset[MAX_BOSSES][3];
float g_flSlenderDetectMins[MAX_BOSSES][3];
float g_flSlenderDetectMaxs[MAX_BOSSES][3];
Handle g_hSlenderThink[MAX_BOSSES];
Handle g_hSlenderEntityThink[MAX_BOSSES];
Handle g_hSlenderFakeTimer[MAX_BOSSES];
float g_flSlenderLastKill[MAX_BOSSES];
int g_iSlenderState[MAX_BOSSES];
int g_iSlenderHitbox[MAX_BOSSES];
int g_iSlenderTarget[MAX_BOSSES] = { INVALID_ENT_REFERENCE, ... };
float g_flSlenderAcceleration[MAX_BOSSES];
float g_flSlenderGoalPos[MAX_BOSSES][3];
float g_flSlenderStaticRadius[MAX_BOSSES];
float g_flSlenderChaseDeathPosition[MAX_BOSSES][3];
bool g_bSlenderChaseDeathPosition[MAX_BOSSES];
float g_flSlenderIdleAnimationPlaybackRate[MAX_BOSSES];
float g_flSlenderWalkAnimationPlaybackRate[MAX_BOSSES];
float g_flSlenderRunAnimationPlaybackRate[MAX_BOSSES];
float g_flSlenderJumpSpeed[MAX_BOSSES];
int g_iSlenderTeleportTarget[MAX_BOSSES] = { INVALID_ENT_REFERENCE, ... };
bool g_bSlenderTeleportTargetIsCamping[MAX_BOSSES] = false;
float g_flSlenderNextTeleportTime[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTeleportTargetTime[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTeleportMinRange[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTeleportMaxRange[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTeleportMaxTargetTime[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTeleportMaxTargetStress[MAX_BOSSES] = { 0.0, ... };
float g_flSlenderTeleportPlayersRestTime[MAX_BOSSES][MAXPLAYERS + 1];
// For boss type 2
// General variables
int g_iSlenderHealth[MAX_BOSSES];
bool g_bSlenderAttacking[MAX_BOSSES];
bool g_bSlenderGiveUp[MAX_BOSSES];
Handle g_hSlenderAttackTimer[MAX_BOSSES];
int g_iSlenderInterruptConditions[MAX_BOSSES];
float g_flSlenderLastFoundPlayer[MAX_BOSSES][MAXPLAYERS + 1];
float g_flSlenderLastFoundPlayerPos[MAX_BOSSES][MAXPLAYERS + 1][3];
float g_flSlenderNextPathTime[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderLastCalculPathTime[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderCalculatedWalkSpeed[MAX_BOSSES];
float g_flSlenderCalculatedSpeed[MAX_BOSSES];
float g_flSlenderCalculatedAirSpeed[MAX_BOSSES];
float g_flSlenderTimeUntilNoPersistence[MAX_BOSSES];
float g_flSlenderProxyTeleportMinRange[MAX_BOSSES];
float g_flSlenderProxyTeleportMaxRange[MAX_BOSSES];
// Sound variables
float g_flSlenderTargetSoundLastTime[MAX_BOSSES] = { -1.0, ... };
SoundType g_iSlenderTargetSoundType[MAX_BOSSES] = { SoundType_None, ... };
float g_flSlenderTargetSoundMasterPos[MAX_BOSSES][3]; // to determine hearing focus
float g_flSlenderTargetSoundTempPos[MAX_BOSSES][3];
float g_flSlenderTargetSoundDiscardMasterPosTime[MAX_BOSSES];
bool g_bSlenderInvestigatingSound[MAX_BOSSES];
int g_iSlenderTargetSoundCount[MAX_BOSSES];
float g_flSlenderLastHeardVoice[MAX_BOSSES];
float g_flSlenderLastHeardFootstep[MAX_BOSSES];
float g_flSlenderLastHeardWeapon[MAX_BOSSES];
float g_flSlenderNextStunTime[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderNextJumpScare[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderNextVoiceSound[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderNextMoanSound[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderNextWanderPos[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilRecover[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilAlert[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilIdle[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilChase[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilKill[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilNextProxy[MAX_BOSSES] = { -1.0, ... };
float g_flSlenderTimeUntilAttackEnd[MAX_BOSSES] = {-1.0, ... };
bool g_bSlenderInBacon[MAX_BOSSES];
//Healthbar
int g_ihealthBar;
// Page data.
int g_iPageCount;
int g_iPageMax;
float g_flPageFoundLastTime;
bool g_bPageRef;
char g_strPageRefModel[PLATFORM_MAX_PATH];
float g_flPageRefModelScale;
static Handle g_hPlayerIntroMusicTimer[MAXPLAYERS + 1] = { INVALID_HANDLE, ... };
// Seeing Mr. Slendy data.
float g_flLastVisibilityProcess[MAXPLAYERS + 1];
bool g_bPlayerSeesSlender[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerSeesSlenderLastTime[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerSightSoundNextTime[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerScareLastTime[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerScareNextTime[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerStaticAmount[MAXPLAYERS + 1];
float g_flPlayerLastChaseBossEncounterTime[MAXPLAYERS + 1][MAX_BOSSES];
// Player static data.
int g_iPlayerStaticMode[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerStaticIncreaseRate[MAXPLAYERS + 1];
float g_flPlayerStaticDecreaseRate[MAXPLAYERS + 1];
Handle g_hPlayerStaticTimer[MAXPLAYERS + 1];
int g_iPlayerStaticMaster[MAXPLAYERS + 1] = { -1, ... };
char g_strPlayerStaticSound[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
char g_strPlayerLastStaticSound[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
float g_flPlayerLastStaticTime[MAXPLAYERS + 1];
float g_flPlayerLastStaticVolume[MAXPLAYERS + 1];
Handle g_hPlayerLastStaticTimer[MAXPLAYERS + 1];
// Static shake data.
int g_iPlayerStaticShakeMaster[MAXPLAYERS + 1];
bool g_bPlayerInStaticShake[MAXPLAYERS + 1];
char g_strPlayerStaticShakeSound[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
float g_flPlayerStaticShakeMinVolume[MAXPLAYERS + 1];
float g_flPlayerStaticShakeMaxVolume[MAXPLAYERS + 1];
// Fake lag compensation for FF.
bool g_bPlayerLagCompensation[MAXPLAYERS + 1];
int g_iPlayerLagCompensationTeam[MAXPLAYERS + 1];
// Difficulty
bool g_bPlayerCalledForNightmare[MAXPLAYERS + 1];
bool g_bProxySurvivalRageMode = false;
// Hint data.
enum
{
PlayerHint_Sprint = 0,
PlayerHint_Flashlight,
PlayerHint_MainMenu,
PlayerHint_Blink,
PlayerHint_MaxNum
};
enum PlayerPreferences
{
bool:PlayerPreference_PvPAutoSpawn,
MuteMode:PlayerPreference_MuteMode,
bool:PlayerPreference_FilmGrain,
bool:PlayerPreference_ShowHints,
bool:PlayerPreference_EnableProxySelection,
bool:PlayerPreference_ProjectedFlashlight,
Float:PlayerPreference_MusicVolume,
};
bool g_bPlayerHints[MAXPLAYERS + 1][PlayerHint_MaxNum];
int g_iPlayerPreferences[MAXPLAYERS + 1][PlayerPreferences];
//Particle data.
enum
{
CriticalHit = 0,
MiniCritHit,
ZapParticle,
FireworksRED,
FireworksBLU,
TeleportedInBlu,
MaxParticle
};
int g_iParticle[MaxParticle] = -1;
// Player data.
bool g_bPlayerIsExitCamping[MAXPLAYERS + 1];
int g_iPlayerLastButtons[MAXPLAYERS + 1];
bool g_bPlayerChoseTeam[MAXPLAYERS + 1];
bool g_bPlayerEliminated[MAXPLAYERS + 1];
bool g_bPlayerHasRegenerationItem[MAXPLAYERS + 1];
bool g_bPlayerEscaped[MAXPLAYERS + 1];
int g_iPlayerPageCount[MAXPLAYERS + 1];
int g_iPlayerQueuePoints[MAXPLAYERS + 1];
bool g_bPlayerPlaying[MAXPLAYERS + 1];
bool g_bBackStabbed[MAXPLAYERS + 1];
Handle g_hPlayerOverlayCheck[MAXPLAYERS + 1];
Handle g_hPlayerSwitchBlueTimer[MAXPLAYERS + 1];
// Player stress data.
float g_flPlayerStress[MAXPLAYERS + 1];
float g_flPlayerStressNextUpdateTime[MAXPLAYERS + 1];
// Proxy data.
bool g_bPlayerProxy[MAXPLAYERS + 1];
bool g_bPlayerProxyAvailable[MAXPLAYERS + 1];
Handle g_hPlayerProxyAvailableTimer[MAXPLAYERS + 1];
bool g_bPlayerProxyAvailableInForce[MAXPLAYERS + 1];
int g_iPlayerProxyAvailableCount[MAXPLAYERS + 1];
int g_iPlayerProxyMaster[MAXPLAYERS + 1];
int g_iPlayerProxyControl[MAXPLAYERS + 1];
Handle g_hPlayerProxyControlTimer[MAXPLAYERS + 1];
float g_flPlayerProxyControlRate[MAXPLAYERS + 1];
Handle g_flPlayerProxyVoiceTimer[MAXPLAYERS + 1];
int g_iPlayerProxyAskMaster[MAXPLAYERS + 1] = { -1, ... };
float g_iPlayerProxyAskPosition[MAXPLAYERS + 1][3];
int g_iPlayerDesiredFOV[MAXPLAYERS + 1];
Handle g_hPlayerPostWeaponsTimer[MAXPLAYERS + 1] = { INVALID_HANDLE, ... };
// Music system.
int g_iPlayerMusicFlags[MAXPLAYERS + 1];
char g_strPlayerMusic[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
float g_flPlayerMusicVolume[MAXPLAYERS + 1];
float g_flPlayerMusicTargetVolume[MAXPLAYERS + 1];
Handle g_hPlayerMusicTimer[MAXPLAYERS + 1];
int g_iPlayerPageMusicMaster[MAXPLAYERS + 1];
// Chase music system, which apparently also uses the alert song system. And the idle sound system.
char g_strPlayerChaseMusic[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
char g_strPlayerChaseMusicSee[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
float g_flPlayerChaseMusicVolumes[MAXPLAYERS + 1][MAX_BOSSES];
float g_flPlayerChaseMusicSeeVolumes[MAXPLAYERS + 1][MAX_BOSSES];
Handle g_hPlayerChaseMusicTimer[MAXPLAYERS + 1][MAX_BOSSES];
Handle g_hPlayerChaseMusicSeeTimer[MAXPLAYERS + 1][MAX_BOSSES];
int g_iPlayerChaseMusicMaster[MAXPLAYERS + 1] = { -1, ... };
int g_iPlayerChaseMusicSeeMaster[MAXPLAYERS + 1] = { -1, ... };
char g_strPlayerAlertMusic[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
float g_flPlayerAlertMusicVolumes[MAXPLAYERS + 1][MAX_BOSSES];
Handle g_hPlayerAlertMusicTimer[MAXPLAYERS + 1][MAX_BOSSES];
int g_iPlayerAlertMusicMaster[MAXPLAYERS + 1] = { -1, ... };
char g_strPlayer20DollarsMusic[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
float g_flPlayer20DollarsMusicVolumes[MAXPLAYERS + 1][MAX_BOSSES];
Handle g_hPlayer20DollarsMusicTimer[MAXPLAYERS + 1][MAX_BOSSES];
int g_iPlayer20DollarsMusicMaster[MAXPLAYERS + 1] = { -1, ... };
SF2RoundState g_iRoundState = SF2RoundState_Invalid;
bool g_bRoundGrace = false;
float g_flRoundDifficultyModifier = DIFFICULTY_NORMAL;
bool g_bRoundInfiniteFlashlight = false;
bool g_bIsSurvivalMap = false;
bool g_bIsRaidMap = false;
bool g_bRoundInfiniteBlink = false;
bool g_bRoundInfiniteSprint = false;
Handle g_hRoundGraceTimer = INVALID_HANDLE;
static Handle g_hRoundTimer = INVALID_HANDLE;
static Handle g_hVoteTimer = INVALID_HANDLE;
static char g_strRoundBossProfile[SF2_MAX_PROFILE_NAME_LENGTH];
static int g_iRoundCount = 0;
static int g_iRoundEndCount = 0;
static int g_iRoundActiveCount = 0;
int g_iRoundTime = 0;
int g_iSpecialRoundTime = 0;
static int g_iTimeEscape = 0;
static int g_iRoundTimeLimit = 0;
static int g_iRoundEscapeTimeLimit = 0;
static int g_iRoundTimeGainFromPage = 0;
static bool g_bRoundHasEscapeObjective = false;
static int g_iRoundEscapePointEntity = INVALID_ENT_REFERENCE;
static int g_iRoundIntroFadeColor[4] = { 255, ... };
static float g_flRoundIntroFadeHoldTime;
static float g_flRoundIntroFadeDuration;
static Handle g_hRoundIntroTimer = INVALID_HANDLE;
static bool g_bRoundIntroTextDefault = true;
static Handle g_hRoundIntroTextTimer = INVALID_HANDLE;
static int g_iRoundIntroText;
static char g_strRoundIntroMusic[PLATFORM_MAX_PATH] = "";
static int g_iRoundWarmupRoundCount = 0;
static bool g_bRoundWaitingForPlayers = false;
// Special round variables.
bool g_bSpecialRound = false;
bool g_bSpecialRoundNew = false;
bool g_bSpecialRoundContinuous = false;
int g_iSpecialRoundCount = 1;
bool g_bPlayerPlayedSpecialRound[MAXPLAYERS + 1] = { true, ... };
// int boss round variables.
static bool g_bNewBossRound = false;
static bool g_bNewBossRoundNew = false;
static bool g_bNewBossRoundContinuous = false;
static int g_iNewBossRoundCount = 1;
static bool g_bPlayerPlayedNewBossRound[MAXPLAYERS + 1] = { true, ... };
static char g_strNewBossRoundProfile[64] = "";
static Handle g_hRoundMessagesTimer = INVALID_HANDLE;
static int g_iRoundMessagesNum = 0;
static Handle g_hBossCountUpdateTimer = INVALID_HANDLE;
static Handle g_hClientAverageUpdateTimer = INVALID_HANDLE;
// Server variables.
Handle g_cvVersion;
Handle g_cvEnabled;
Handle g_cvSlenderMapsOnly;
Handle g_cvPlayerViewbobEnabled;
Handle g_cvPlayerShakeEnabled;
Handle g_cvPlayerShakeFrequencyMax;
Handle g_cvPlayerShakeAmplitudeMax;
Handle g_cvGraceTime;
Handle g_cvAllChat;
Handle g_cv20Dollars;
Handle g_cvMaxPlayers;
Handle g_cvMaxPlayersOverride;
Handle g_cvCampingEnabled;
Handle g_cvCampingMaxStrikes;
Handle g_cvCampingStrikesWarn;
Handle g_cvExitCampingTimeAllowed;
Handle g_cvCampingMinDistance;
Handle g_cvCampingNoStrikeSanity;
Handle g_cvCampingNoStrikeBossDistance;
Handle g_cvDifficulty;
Handle g_cvBossMain;
Handle g_cvBossProfileOverride;
Handle g_cvPlayerBlinkRate;
Handle g_cvPlayerBlinkHoldTime;
Handle g_cvSpecialRoundBehavior;
Handle g_cvSpecialRoundForce;
Handle g_cvSpecialRoundOverride;
Handle g_cvSpecialRoundInterval;
Handle g_cvNewBossRoundBehavior;
Handle g_cvNewBossRoundInterval;
Handle g_cvNewBossRoundForce;
Handle g_cvPlayerVoiceDistance;
Handle g_cvPlayerVoiceWallScale;
Handle g_cvUltravisionEnabled;
Handle g_cvUltravisionRadiusRed;
Handle g_cvUltravisionRadiusBlue;
Handle g_cvUltravisionBrightness;
Handle g_cvNightvisionRadius;
Handle g_cvNightvisionEnabled;
Handle g_cvGhostModeConnection;
Handle g_cvGhostModeConnectionCheck;
Handle g_cvGhostModeConnectionTolerance;
Handle g_cvIntroEnabled;
Handle g_cvIntroDefaultHoldTime;
Handle g_cvIntroDefaultFadeTime;
Handle g_cvTimeLimit;
Handle g_cvTimeLimitEscape;
Handle g_cvTimeGainFromPageGrab;
Handle g_cvWarmupRound;
Handle g_cvWarmupRoundNum;
Handle g_cvPlayerViewbobHurtEnabled;
Handle g_cvPlayerViewbobSprintEnabled;
Handle g_cvPlayerFakeLagCompensation;
Handle g_cvPlayerProxyWaitTime;
Handle g_cvPlayerProxyAsk;
Handle g_cvHalfZatoichiHealthGain;
Handle g_cvBlockSuicideDuringRound;
Handle g_cvRaidMap;
Handle g_cvSurvivalMap;
Handle g_cvTimeEscapeSurvival;
Handle g_cvPlayerInfiniteSprintOverride;
Handle g_cvPlayerInfiniteFlashlightOverride;
Handle g_cvPlayerInfiniteBlinkOverride;
Handle g_cvGravity;
float g_flGravity;
Handle g_cvMaxRounds;
bool g_b20Dollars;
bool g_bPlayerShakeEnabled;
bool g_bPlayerViewbobEnabled;
bool g_bPlayerViewbobHurtEnabled;
bool g_bPlayerViewbobSprintEnabled;
Handle g_hHudSync;
Handle g_hHudSync2;
Handle g_hRoundTimerSync;
Handle g_hCookie;
// Global forwards.
Handle fOnBossAdded;
Handle fOnBossSpawn;
Handle fOnBossChangeState;
Handle fOnBossAnimationUpdate;
Handle fOnBossGetSpeed;
Handle fOnBossGetWalkSpeed;
Handle fOnBossRemoved;
Handle fOnPagesSpawned;
Handle fOnClientCollectPage;
Handle fOnClientBlink;
Handle fOnClientCaughtByBoss;
Handle fOnClientGiveQueuePoints;
Handle fOnClientActivateFlashlight;
Handle fOnClientDeactivateFlashlight;
Handle fOnClientBreakFlashlight;
Handle fOnClientEscape;
Handle fOnClientLooksAtBoss;
Handle fOnClientLooksAwayFromBoss;
Handle fOnClientStartDeathCam;
Handle fOnClientEndDeathCam;
Handle fOnClientGetDefaultWalkSpeed;
Handle fOnClientGetDefaultSprintSpeed;
Handle fOnClientTakeDamage;
Handle fOnClientSpawnedAsProxy;
Handle fOnClientDamagedByBoss;
Handle fOnGroupGiveQueuePoints;
Handle g_hSDKWeaponScattergun;
Handle g_hSDKWeaponPistolScout;
Handle g_hSDKWeaponBat;
Handle g_hSDKWeaponSniperRifle;
Handle g_hSDKWeaponSMG;
Handle g_hSDKWeaponKukri;
Handle g_hSDKWeaponRocketLauncher;
Handle g_hSDKWeaponShotgunSoldier;
Handle g_hSDKWeaponShovel;
Handle g_hSDKWeaponGrenadeLauncher;
Handle g_hSDKWeaponStickyLauncher;
Handle g_hSDKWeaponBottle;
Handle g_hSDKWeaponMinigun;
Handle g_hSDKWeaponShotgunHeavy;
Handle g_hSDKWeaponFists;
Handle g_hSDKWeaponSyringeGun;
Handle g_hSDKWeaponMedigun;
Handle g_hSDKWeaponBonesaw;
Handle g_hSDKWeaponFlamethrower;
Handle g_hSDKWeaponShotgunPyro;
Handle g_hSDKWeaponFireaxe;
Handle g_hSDKWeaponRevolver;
Handle g_hSDKWeaponKnife;
Handle g_hSDKWeaponInvis;
Handle g_hSDKWeaponShotgunPrimary;
Handle g_hSDKWeaponPistol;
Handle g_hSDKWeaponWrench;
Handle g_hSDKGetMaxHealth;
Handle g_hSDKGetLastKnownArea;
Handle g_hSDKUpdateLastKnownArea;
Handle g_hSDKWantsLagCompensationOnEntity;
Handle g_hSDKShouldTransmit;
Handle g_hSDKEquipWearable;
Handle g_hSDKPlaySpecificSequence;
Handle g_hSDKPointIsWithin;
Handle g_hSDKGetSmoothedVelocity;
Handle g_hSDKCBaseEntityVPhysicsInitNormal;
Handle g_hSDKGetVectors;
Handle g_hSDKResetSequence;
Handle g_hSDKStudioFrameAdvance;
Handle g_hSDKStartTouch;
Handle g_hSDKEndTouch;
Handle g_hSDKWeaponSwitch;
int g_iOffset_m_id;
// SourceTV userid used for boss name
int g_iSourceTVUserID = -1;
char g_sOldSourceTVClientName[64];
Handle g_hTimerChangeSourceTVBotName;
//Fail Timer
Handle g_hTimerFail;
ConVar g_cvLookAheadDist;
#if defined DEBUG
#include "sf2/debug.sp"
#endif
#include "sf2/nextbot/nextbot.sp"
#include "sf2/stocks.sp"
#include "sf2/baseanimating.sp"
#include "sf2/logging.sp"
#include "sf2/profiles.sp"
#include "sf2/nav.sp"
#include "sf2/effects.sp"
#include "sf2/playergroups.sp"
#include "sf2/menus.sp"
#include "sf2/tutorial.sp"
#include "sf2/npc.sp"
#include "sf2/pvp.sp"
#include "sf2/client.sp"
#include "sf2/specialround.sp"
#include "sf2/adminmenu.sp"
#define SF2_PROJECTED_FLASHLIGHT_CONFIRM_SOUND "ui/item_acquired.wav"
// ==========================================================
// GENERAL PLUGIN HOOK FUNCTIONS
// ==========================================================
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error,int err_max)
{
RegPluginLibrary("sf2");
fOnBossAdded = CreateGlobalForward("SF2_OnBossAdded", ET_Ignore, Param_Cell);
fOnBossSpawn = CreateGlobalForward("SF2_OnBossSpawn", ET_Ignore, Param_Cell);
fOnBossChangeState = CreateGlobalForward("SF2_OnBossChangeState", ET_Ignore, Param_Cell, Param_Cell, Param_Cell);
fOnBossAnimationUpdate = CreateGlobalForward("SF2_OnBossAnimationUpdate", ET_Hook, Param_Cell);
fOnBossGetSpeed = CreateGlobalForward("SF2_OnBossGetSpeed", ET_Hook, Param_Cell, Param_FloatByRef);
fOnBossGetWalkSpeed = CreateGlobalForward("SF2_OnBossGetWalkSpeed", ET_Hook, Param_Cell, Param_FloatByRef);
fOnBossRemoved = CreateGlobalForward("SF2_OnBossRemoved", ET_Ignore, Param_Cell);
fOnPagesSpawned = CreateGlobalForward("SF2_OnPagesSpawned", ET_Ignore);
fOnClientCollectPage = CreateGlobalForward("SF2_OnClientCollectPage", ET_Ignore, Param_Cell, Param_Cell);
fOnClientBlink = CreateGlobalForward("SF2_OnClientBlink", ET_Ignore, Param_Cell);
fOnClientCaughtByBoss = CreateGlobalForward("SF2_OnClientCaughtByBoss", ET_Ignore, Param_Cell, Param_Cell);
fOnClientGiveQueuePoints = CreateGlobalForward("SF2_OnClientGiveQueuePoints", ET_Hook, Param_Cell, Param_CellByRef);
fOnClientActivateFlashlight = CreateGlobalForward("SF2_OnClientActivateFlashlight", ET_Ignore, Param_Cell);
fOnClientDeactivateFlashlight = CreateGlobalForward("SF2_OnClientDeactivateFlashlight", ET_Ignore, Param_Cell);
fOnClientBreakFlashlight = CreateGlobalForward("SF2_OnClientBreakFlashlight", ET_Ignore, Param_Cell);
fOnClientEscape = CreateGlobalForward("SF2_OnClientEscape", ET_Ignore, Param_Cell);
fOnClientLooksAtBoss = CreateGlobalForward("SF2_OnClientLooksAtBoss", ET_Ignore, Param_Cell, Param_Cell);
fOnClientLooksAwayFromBoss = CreateGlobalForward("SF2_OnClientLooksAwayFromBoss", ET_Ignore, Param_Cell, Param_Cell);
fOnClientStartDeathCam = CreateGlobalForward("SF2_OnClientStartDeathCam", ET_Ignore, Param_Cell, Param_Cell);
fOnClientEndDeathCam = CreateGlobalForward("SF2_OnClientEndDeathCam", ET_Ignore, Param_Cell, Param_Cell);
fOnClientGetDefaultWalkSpeed = CreateGlobalForward("SF2_OnClientGetDefaultWalkSpeed", ET_Hook, Param_Cell, Param_CellByRef);
fOnClientGetDefaultSprintSpeed = CreateGlobalForward("SF2_OnClientGetDefaultSprintSpeed", ET_Hook, Param_Cell, Param_CellByRef);
fOnClientTakeDamage = CreateGlobalForward("SF2_OnClientTakeDamage", ET_Hook, Param_Cell, Param_Cell, Param_FloatByRef);
fOnClientSpawnedAsProxy = CreateGlobalForward("SF2_OnClientSpawnedAsProxy", ET_Ignore, Param_Cell);
fOnClientDamagedByBoss = CreateGlobalForward("SF2_OnClientDamagedByBoss", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Float, Param_Cell);
fOnGroupGiveQueuePoints = CreateGlobalForward("SF2_OnGroupGiveQueuePoints", ET_Hook, Param_Cell, Param_CellByRef);
CreateNative("SF2_IsRunning", Native_IsRunning);
CreateNative("SF2_GetRoundState", Native_GetRoundState);
CreateNative("SF2_GetCurrentDifficulty", Native_GetCurrentDifficulty);
CreateNative("SF2_GetDifficultyModifier", Native_GetDifficultyModifier);
CreateNative("SF2_IsClientEliminated", Native_IsClientEliminated);
CreateNative("SF2_IsClientInGhostMode", Native_IsClientInGhostMode);
CreateNative("SF2_IsClientProxy", Native_IsClientProxy);
CreateNative("SF2_GetClientBlinkCount", Native_GetClientBlinkCount);
CreateNative("SF2_GetClientProxyMaster", Native_GetClientProxyMaster);
CreateNative("SF2_GetClientProxyControlAmount", Native_GetClientProxyControlAmount);
CreateNative("SF2_GetClientProxyControlRate", Native_GetClientProxyControlRate);
CreateNative("SF2_SetClientProxyMaster", Native_SetClientProxyMaster);
CreateNative("SF2_SetClientProxyControlAmount", Native_SetClientProxyControlAmount);
CreateNative("SF2_SetClientProxyControlRate", Native_SetClientProxyControlRate);
CreateNative("SF2_IsClientLookingAtBoss", Native_IsClientLookingAtBoss);
CreateNative("SF2_DidClientEscape", Native_DidClientEscape);
CreateNative("SF2_CollectAsPage", Native_CollectAsPage);
CreateNative("SF2_GetMaxBossCount", Native_GetMaxBosses);
CreateNative("SF2_EntIndexToBossIndex", Native_EntIndexToBossIndex);
CreateNative("SF2_BossIndexToEntIndex", Native_BossIndexToEntIndex);
CreateNative("SF2_BossIndexToEntIndexEx", Native_BossIndexToEntIndexEx);
CreateNative("SF2_BossIDToBossIndex", Native_BossIDToBossIndex);
CreateNative("SF2_BossIndexToBossID", Native_BossIndexToBossID);
CreateNative("SF2_GetBossName", Native_GetBossName);
CreateNative("SF2_GetBossModelEntity", Native_GetBossModelEntity);
CreateNative("SF2_GetBossTarget", Native_GetBossTarget);
CreateNative("SF2_GetBossMaster", Native_GetBossMaster);
CreateNative("SF2_GetBossState", Native_GetBossState);
CreateNative("SF2_GetBossFOV", Native_GetBossFOV);
CreateNative("SF2_IsBossProfileValid", Native_IsBossProfileValid);
CreateNative("SF2_GetBossProfileNum", Native_GetBossProfileNum);
CreateNative("SF2_GetBossProfileFloat", Native_GetBossProfileFloat);
CreateNative("SF2_GetBossProfileString", Native_GetBossProfileString);
CreateNative("SF2_GetBossProfileVector", Native_GetBossProfileVector);
CreateNative("SF2_GetRandomStringFromBossProfile", Native_GetRandomStringFromBossProfile);
CreateNative("SF2_IsSurvivalMap", Native_IsSurvivalMap);
PvP_InitializeAPI();
SpecialRoundInitializeAPI();
#if defined _steamtools_included
MarkNativeAsOptional("Steam_SetGameDescription");
#endif
#if defined _SteamWorks_Included
MarkNativeAsOptional("SteamWorks_SetGameDescription");
#endif
return APLRes_Success;
}
public void OnPluginStart()
{
LoadTranslations("core.phrases");
LoadTranslations("common.phrases");
LoadTranslations("sf2.phrases");
LoadTranslations("basetriggers.phrases");
// Get offsets.
g_offsPlayerFOV = FindSendPropInfo("CBasePlayer", "m_iFOV");
if (g_offsPlayerFOV == -1) SetFailState("Couldn't find CBasePlayer offset for m_iFOV.");
g_offsPlayerDefaultFOV = FindSendPropInfo("CBasePlayer", "m_iDefaultFOV");
if (g_offsPlayerDefaultFOV == -1) SetFailState("Couldn't find CBasePlayer offset for m_iDefaultFOV.");
g_offsPlayerFogCtrl = FindSendPropInfo("CBasePlayer", "m_PlayerFog.m_hCtrl");
if (g_offsPlayerFogCtrl == -1) LogError("Couldn't find CBasePlayer offset for m_PlayerFog.m_hCtrl!");
g_offsPlayerPunchAngle = FindSendPropInfo("CBasePlayer", "m_vecPunchAngle");
if (g_offsPlayerPunchAngle == -1) LogError("Couldn't find CBasePlayer offset for m_vecPunchAngle!");
g_offsPlayerPunchAngleVel = FindSendPropInfo("CBasePlayer", "m_vecPunchAngleVel");
if (g_offsPlayerPunchAngleVel == -1) LogError("Couldn't find CBasePlayer offset for m_vecPunchAngleVel!");
g_offsFogCtrlEnable = FindSendPropInfo("CFogController", "m_fog.enable");
if (g_offsFogCtrlEnable == -1) LogError("Couldn't find CFogController offset for m_fog.enable!");
g_offsFogCtrlEnd = FindSendPropInfo("CFogController", "m_fog.end");
if (g_offsFogCtrlEnd == -1) LogError("Couldn't find CFogController offset for m_fog.end!");
g_offsCollisionGroup = FindSendPropInfo("CBaseEntity", "m_CollisionGroup");
if (g_offsCollisionGroup == -1) LogError("Couldn't find CBaseEntity offset for m_CollisionGroup!");
g_hPageMusicRanges = CreateArray(3);
// Register console variables.
g_cvVersion = CreateConVar("sf2_version", PLUGIN_VERSION, "The current version of Slender Fortress. DO NOT TOUCH!", FCVAR_SPONLY | FCVAR_NOTIFY | FCVAR_DONTRECORD);
SetConVarString(g_cvVersion, PLUGIN_VERSION);
g_cvEnabled = CreateConVar("sf2_enabled", "1", "Enable/Disable the Slender Fortress gamemode. This will take effect on map change.", FCVAR_NOTIFY | FCVAR_DONTRECORD);
g_cvSlenderMapsOnly = CreateConVar("sf2_slendermapsonly", "1", "Only enable the Slender Fortress gamemode on map names prefixed with \"slender_\" or \"sf2_\".");
g_cvGraceTime = CreateConVar("sf2_gracetime", "30.0");
g_cvIntroEnabled = CreateConVar("sf2_intro_enabled", "1");
g_cvIntroDefaultHoldTime = CreateConVar("sf2_intro_default_hold_time", "9.0");
g_cvIntroDefaultFadeTime = CreateConVar("sf2_intro_default_fade_time", "1.0");
g_cvBlockSuicideDuringRound = CreateConVar("sf2_block_suicide_during_round", "0");
g_cvAllChat = CreateConVar("sf2_alltalk", "0");
HookConVarChange(g_cvAllChat, OnConVarChanged);
g_cvPlayerVoiceDistance = CreateConVar("sf2_player_voice_distance", "800.0", "The maximum distance RED can communicate in voice chat. Set to 0 if you want them to be heard at all times.", _, true, 0.0);
g_cvPlayerVoiceWallScale = CreateConVar("sf2_player_voice_scale_blocked", "0.5", "The distance required to hear RED in voice chat will be multiplied by this amount if something is blocking them.");
g_cvPlayerViewbobEnabled = CreateConVar("sf2_player_viewbob_enabled", "1", "Enable/Disable player viewbobbing.", _, true, 0.0, true, 1.0);
HookConVarChange(g_cvPlayerViewbobEnabled, OnConVarChanged);
g_cvPlayerViewbobHurtEnabled = CreateConVar("sf2_player_viewbob_hurt_enabled", "0", "Enable/Disable player view tilting when hurt.", _, true, 0.0, true, 1.0);
HookConVarChange(g_cvPlayerViewbobHurtEnabled, OnConVarChanged);
g_cvPlayerViewbobSprintEnabled = CreateConVar("sf2_player_viewbob_sprint_enabled", "0", "Enable/Disable player step viewbobbing when sprinting.", _, true, 0.0, true, 1.0);
HookConVarChange(g_cvPlayerViewbobSprintEnabled, OnConVarChanged);
g_cvGravity = FindConVar("sv_gravity");
HookConVarChange(g_cvGravity, OnConVarChanged);
g_cvPlayerFakeLagCompensation = CreateConVar("sf2_player_fakelagcompensation", "0", "(EXPERIMENTAL) Enable/Disable fake lag compensation for some hitscan weapons such as the Sniper Rifle.", _, true, 0.0, true, 1.0);
g_cvPlayerShakeEnabled = CreateConVar("sf2_player_shake_enabled", "1", "Enable/Disable player view shake during boss encounters.", _, true, 0.0, true, 1.0);
HookConVarChange(g_cvPlayerShakeEnabled, OnConVarChanged);
g_cvPlayerShakeFrequencyMax = CreateConVar("sf2_player_shake_frequency_max", "255", "Maximum frequency value of the shake. Should be a value between 1-255.", _, true, 1.0, true, 255.0);
g_cvPlayerShakeAmplitudeMax = CreateConVar("sf2_player_shake_amplitude_max", "5", "Maximum amplitude value of the shake. Should be a value between 1-16.", _, true, 1.0, true, 16.0);
g_cvPlayerBlinkRate = CreateConVar("sf2_player_blink_rate", "0.33", "How long (in seconds) each bar on the player's Blink meter lasts.", _, true, 0.0);
g_cvPlayerBlinkHoldTime = CreateConVar("sf2_player_blink_holdtime", "0.15", "How long (in seconds) a player will stay in Blink mode when he or she blinks.", _, true, 0.0);
g_cvUltravisionEnabled = CreateConVar("sf2_player_ultravision_enabled", "1", "Enable/Disable player Ultravision. This helps players see in the dark when their Flashlight is off or unavailable.", _, true, 0.0, true, 1.0);
g_cvUltravisionRadiusRed = CreateConVar("sf2_player_ultravision_radius_red", "512.0");
g_cvUltravisionRadiusBlue = CreateConVar("sf2_player_ultravision_radius_blue", "800.0");
g_cvNightvisionRadius = CreateConVar("sf2_player_nightvision_radius", "400.0");
g_cvUltravisionBrightness = CreateConVar("sf2_player_ultravision_brightness", "-4");
g_cvNightvisionEnabled = CreateConVar("sf2_player_flashlight_isnightvision", "0", "Enable/Disable flashlight replacement with nightvision",_, true, 0.0, true, 1.0);
g_cvGhostModeConnection = CreateConVar("sf2_ghostmode_no_tolerance", "0", "If set on 1, it will instant kick out the client of the Ghost mode if the client has timed out.");
g_cvGhostModeConnectionCheck = CreateConVar("sf2_ghostmode_check_connection", "1", "Checks a player's connection while in Ghost Mode. If the check fails, the client is booted out of Ghost Mode and the action and client's SteamID is logged in the main SF2 log.");
g_cvGhostModeConnectionTolerance = CreateConVar("sf2_ghostmode_connection_tolerance", "5.0", "If sf2_ghostmode_check_connection is set to 1 and the client has timed out for at least this amount of time, the client will be booted out of Ghost Mode.");
g_cv20Dollars = CreateConVar("sf2_20dollarmode", "0", "Enable/Disable $20 mode.", _, true, 0.0, true, 1.0);
HookConVarChange(g_cv20Dollars, OnConVarChanged);
g_cvMaxPlayers = CreateConVar("sf2_maxplayers", "5", "The maximum amount of players that can be in one round.", _, true, 1.0);
HookConVarChange(g_cvMaxPlayers, OnConVarChanged);
g_cvMaxPlayersOverride = CreateConVar("sf2_maxplayers_override", "-1", "Overrides the maximum amount of players that can be in one round.", _, true, -1.0);
HookConVarChange(g_cvMaxPlayersOverride, OnConVarChanged);
g_cvCampingEnabled = CreateConVar("sf2_anticamping_enabled", "1", "Enable/Disable anti-camping system for RED.", _, true, 0.0, true, 1.0);
g_cvCampingMaxStrikes = CreateConVar("sf2_anticamping_maxstrikes", "4", "How many 5-second intervals players are allowed to stay in one spot before he/she is forced to suicide.", _, true, 0.0);
g_cvCampingStrikesWarn = CreateConVar("sf2_anticamping_strikeswarn", "2", "The amount of strikes left where the player will be warned of camping.");
g_cvExitCampingTimeAllowed = CreateConVar("sf2_exitcamping_allowedtime", "25.0", "The amount of time a player can stay near the exit before being flagged as camper.");
g_cvCampingMinDistance = CreateConVar("sf2_anticamping_mindistance", "128.0", "Every 5 seconds the player has to be at least this far away from his last position 5 seconds ago or else he'll get a strike.");
g_cvCampingNoStrikeSanity = CreateConVar("sf2_anticamping_no_strike_sanity", "0.1", "The camping system will NOT give any strikes under any circumstances if the players's Sanity is missing at least this much of his maximum Sanity (max is 1.0).");
g_cvCampingNoStrikeBossDistance = CreateConVar("sf2_anticamping_no_strike_boss_distance", "512.0", "The camping system will NOT give any strikes under any circumstances if the player is this close to a boss (ignoring LOS).");
g_cvBossMain = CreateConVar("sf2_boss_main", "slenderman", "The name of the main boss (its profile name, not its display name)");
g_cvBossProfileOverride = CreateConVar("sf2_boss_profile_override", "", "Overrides which boss will be chosen next. Only applies to the first boss being chosen.");
g_cvDifficulty = CreateConVar("sf2_difficulty", "1", "Difficulty of the game. 1 = Normal, 2 = Hard, 3 = Insane, 4 = Nightmare.", _, true, 1.0, true, 5.0);
HookConVarChange(g_cvDifficulty, OnConVarChanged);
g_cvSpecialRoundBehavior = CreateConVar("sf2_specialround_mode", "0", "0 = Special Round resets on next round, 1 = Special Round keeps going until all players have played (not counting spectators, recently joined players, and those who reset their queue points during the round)", _, true, 0.0, true, 1.0);
g_cvSpecialRoundForce = CreateConVar("sf2_specialround_forceenable", "-1", "Sets whether a Special Round will occur on the next round or not.", _, true, -1.0, true, 1.0);
g_cvSpecialRoundOverride = CreateConVar("sf2_specialround_forcetype", "-1", "Sets the type of Special Round that will be chosen on the next Special Round. Set to -1 to let the game choose.", _, true, -1.0);
g_cvSpecialRoundInterval = CreateConVar("sf2_specialround_interval", "5", "If this many rounds are completed, the next round will be a Special Round.", _, true, 0.0);
g_cvNewBossRoundBehavior = CreateConVar("sf2_newbossround_mode", "0", "0 = boss selection will return to normal after the boss round, 1 = the new boss will continue being the boss until all players in the server have played against it (not counting spectators, recently joined players, and those who reset their queue points during the round).", _, true, 0.0, true, 1.0);
g_cvNewBossRoundInterval = CreateConVar("sf2_newbossround_interval", "3", "If this many rounds are completed, the next round's boss will be randomly chosen, but will not be the main boss.", _, true, 0.0);
g_cvNewBossRoundForce = CreateConVar("sf2_newbossround_forceenable", "-1", "Sets whether a new boss will be chosen on the next round or not. Set to -1 to let the game choose.", _, true, -1.0, true, 1.0);
g_cvTimeLimit = CreateConVar("sf2_timelimit_default", "300", "The time limit of the round. Maps can change the time limit.", _, true, 0.0);
g_cvTimeLimitEscape = CreateConVar("sf2_timelimit_escape_default", "90", "The time limit to escape. Maps can change the time limit.", _, true, 0.0);
g_cvTimeGainFromPageGrab = CreateConVar("sf2_time_gain_page_grab", "12", "The time gained from grabbing a page. Maps can change the time gain amount.");
g_cvWarmupRound = CreateConVar("sf2_warmupround", "1", "Enables/disables Warmup Rounds after the \"Waiting for Players\" phase.", _, true, 0.0, true, 1.0);
g_cvWarmupRoundNum = CreateConVar("sf2_warmupround_num", "1", "Sets the amount of Warmup Rounds that occur after the \"Waiting for Players\" phase.", _, true, 0.0);
g_cvPlayerProxyWaitTime = CreateConVar("sf2_player_proxy_waittime", "35", "How long (in seconds) after a player was chosen to be a Proxy must the system wait before choosing him again.");
g_cvPlayerProxyAsk = CreateConVar("sf2_player_proxy_ask", "0", "Set to 1 if the player can choose before becoming a Proxy, set to 0 to force.");
g_cvHalfZatoichiHealthGain = CreateConVar("sf2_halfzatoichi_healthgain", "20", "How much health should be gained from killing a player with the Half-Zatoichi? Set to -1 for default behavior.");
g_cvPlayerInfiniteSprintOverride = CreateConVar("sf2_player_infinite_sprint_override", "-1", "1 = infinite sprint, 0 = never have infinite sprint, -1 = let the game choose.", _, true, -1.0, true, 1.0);
g_cvPlayerInfiniteFlashlightOverride = CreateConVar("sf2_player_infinite_flashlight_override", "-1", "1 = infinite flashlight, 0 = never have infinite flashlight, -1 = let the game choose.", _, true, -1.0, true, 1.0);
g_cvPlayerInfiniteBlinkOverride = CreateConVar("sf2_player_infinite_blink_override", "-1", "1 = infinite blink, 0 = never have infinite blink, -1 = let the game choose.", _, true, -1.0, true, 1.0);
g_cvRaidMap = CreateConVar("sf2_israidmap", "0", "Set to 1 if the map is a raid map.", _, true, 0.0, true, 1.0);
g_cvSurvivalMap = CreateConVar("sf2_issurvivalmap", "0", "Set to 1 if the map is a survival map.", _, true, 0.0, true, 1.0);
g_cvTimeEscapeSurvival = CreateConVar("sf2_survival_time_limit", "30", "when X secs left the mod will turn back the Survive! text to Escape! text", _, true, 0.0);
g_cvMaxRounds = FindConVar("mp_maxrounds");
g_hHudSync = CreateHudSynchronizer();
g_hHudSync2 = CreateHudSynchronizer();
g_hRoundTimerSync = CreateHudSynchronizer();
g_hCookie = RegClientCookie("sf2_newcookies", "", CookieAccess_Private);
// Register console commands.
RegConsoleCmd("sm_sf2", Command_MainMenu);
RegConsoleCmd("sm_sl", Command_MainMenu);
RegConsoleCmd("sm_slender", Command_MainMenu);
RegConsoleCmd("sm_sltutorial", Command_Tutorial);
RegConsoleCmd("sm_sltuto", Command_Tutorial);
RegConsoleCmd("sm_sf2tutorial", Command_Tutorial);
RegConsoleCmd("sm_sf2tuto", Command_Tutorial);
RegConsoleCmd("sm_slupdate", Command_Update);
RegConsoleCmd("sm_slpack", Command_Pack);
RegConsoleCmd("sm_sf2pack", Command_Pack);
RegConsoleCmd("sm_slnextpack", Command_NextPack);
RegConsoleCmd("sm_sf2nextpack", Command_NextPack);
RegConsoleCmd("sm_slnext", Command_Next);
RegConsoleCmd("sm_slgroup", Command_Group);
RegConsoleCmd("sm_slgroupname", Command_GroupName);
RegConsoleCmd("sm_slghost", Command_GhostMode);
RegConsoleCmd("sm_slhelp", Command_Help);
RegConsoleCmd("sm_slsettings", Command_Settings);
RegConsoleCmd("sm_slcredits", Command_Credits);
RegConsoleCmd("sm_flashlight", Command_ToggleFlashlight);
RegConsoleCmd("+sprint", Command_SprintOn);
RegConsoleCmd("-sprint", Command_SprintOff);
RegAdminCmd("sm_sf2_bosspack_vote", DevCommand_BossPackVote, ADMFLAG_CHEATS);
RegAdminCmd("sm_sf2_nopoints", Command_NoPoints, ADMFLAG_CHEATS);
RegAdminCmd("sm_sf2_scare", Command_ClientPerformScare, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_spawn_boss", Command_SpawnSlender, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_add_boss", Command_AddSlender, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_add_boss_fake", Command_AddSlenderFake, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_remove_boss", Command_RemoveSlender, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_getbossindexes", Command_GetBossIndexes, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_setplaystate", Command_ForceState, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_boss_attack_waiters", Command_SlenderAttackWaiters, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_boss_no_teleport", Command_SlenderNoTeleport, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_force_proxy", Command_ForceProxy, ADMFLAG_SLAY);
//RegAdminCmd("sm_slnightfision", Command_NightVision, ADMFLAG_SLAY);
RegAdminCmd("sm_sf2_force_escape", Command_ForceEscape, ADMFLAG_CHEATS);
// Hook onto existing console commands.
AddCommandListener(Hook_CommandBuild, "build");
AddCommandListener(Hook_CommandTaunt, "taunt");
AddCommandListener(Hook_CommandDisguise, "disguise");
AddCommandListener(Hook_CommandSuicideAttempt, "kill");
AddCommandListener(Hook_CommandSuicideAttempt, "explode");
AddCommandListener(Hook_CommandSuicideAttempt, "joinclass");
AddCommandListener(Hook_CommandSuicideAttempt, "join_class");
AddCommandListener(Hook_CommandSuicideAttempt, "jointeam");
AddCommandListener(Hook_CommandSuicideAttempt, "autoteam");
AddCommandListener(Hook_CommandSuicideAttempt, "spectate");
AddCommandListener(Hook_CommandVoiceMenu, "voicemenu");
AddCommandListener(Hook_CommandSay, "say");
AddCommandListener(Hook_CommandSayTeam, "say_team");
// Hook events.
HookEvent("teamplay_round_start", Event_RoundStart);
HookEvent("teamplay_round_win", Event_RoundEnd);
HookEvent("teamplay_win_panel", Event_WinPanel, EventHookMode_Pre);
HookEvent("player_team", Event_DontBroadcastToClients, EventHookMode_Pre);
HookEvent("player_team", Event_PlayerTeam);
HookEvent("player_spawn", Event_PlayerSpawn);
HookEvent("player_hurt", Event_PlayerHurt);
HookEvent("npc_hurt", Event_HitBoxHurt);
HookEvent("post_inventory_application", Event_PostInventoryApplication);
HookEvent("item_found", Event_DontBroadcastToClients, EventHookMode_Pre);
HookEvent("teamplay_teambalanced_player", Event_DontBroadcastToClients, EventHookMode_Pre);
HookEvent("fish_notice", Event_PlayerDeathPre, EventHookMode_Pre);
HookEvent("fish_notice__arm", Event_PlayerDeathPre, EventHookMode_Pre);
HookEvent("player_death", Event_PlayerDeathPre, EventHookMode_Pre);
HookEvent("player_death", Event_PlayerDeath);
// Hook entities.
HookEntityOutput("info_npc_spawn_destination", "OnUser1", NPCSpawn);
HookEntityOutput("trigger_multiple", "OnStartTouch", Hook_TriggerOnStartTouch);
HookEntityOutput("trigger_multiple", "OnEndTouch", Hook_TriggerOnEndTouch);
HookEntityOutput("trigger_teleport", "OnStartTouch", Hook_TriggerTeleportOnStartTouch);
//HookEntityOutput("trigger_teleport", "OnEndTouch", Hook_TriggerTeleportOnEndTouch);
// Hook usermessages.
HookUserMessage(GetUserMessageId("VoiceSubtitle"), Hook_BlockUserMessage, true);
HookUserMessage(GetUserMessageId("PlayerTauntSoundLoopStart"), Hook_TauntUserMessage, true);
HookUserMessage(GetUserMessageId("SayText2"), Hook_BlockUserMessageEx, true);
//HookUserMessage(GetUserMessageId("TextMsg"), Hook_BlockUserMessage, true);
// Hook sounds.
AddNormalSoundHook(view_as<NormalSHook>(Hook_NormalSound));
AddTempEntHook("Fire Bullets", Hook_TEFireBullets);
steamtools = LibraryExists("SteamTools");
steamworks = LibraryExists("SteamWorks");
sendproxymanager = LibraryExists("sendproxy");
InitializeBossProfiles();
NPCInitialize();
SetupMenus();
Tutorial_Initialize();
SetupAdminMenu();
SetupClassDefaultWeapons();
SetupPlayerGroups();
PvP_Initialize();
Nav_Initialize();
// @TODO: When cvars are finalized, set this to true.
AutoExecConfig(false);
#if defined DEBUG
InitializeDebug();
#endif
}