-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClient.hpp
1539 lines (1263 loc) · 67 KB
/
Client.hpp
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
//
// Copyright © 2003-2010, by YaPB Development Team. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// Client.hpp
//
// Class: Client
//
// Description: Contains the 'Client' class Function Prototypes.
//
// Client class hierachy:
// Client:
// FakeClient:
// FakeClient_NotYaPB
// ZBot
// YaPB
// Human:
// Host
// Player
//
// Version: $ID:$
//
#if defined COMPILER_VISUALC && COMPILER_VISUALC > 1000
# pragma once
#endif // if defined COMPILER_VISUALC && COMPILER_VISUALC > 1000
#ifndef CLIENT_INCLUDED
#define CLIENT_INCLUDED
class Client
{
friend ClientManagerTemplate <Client>;
friend ClientManagerTemplate <FakeClient>;
friend ClientManagerTemplate <FakeClient_NotYaPB>;
friend ClientManagerTemplate <ZBot>;
friend ClientManagerTemplate <YaPB>;
friend ClientManagerTemplate <Human>;
friend ClientManagerTemplate <Host>;
friend ClientManagerTemplate <Player>;
friend ClientManager;
friend FakeClientManager;
friend OwningItem;
friend CurrentWeapon;
DECLARE_CLASS_WITHOUT_BASE (Client);
//
// Group: Protected constants.
//
protected:
enum Type_t
{
Type_FakeClient, // Not really type.... (subtype)
Type_FakeClient_NotYaPB = Type_FakeClient, // Other bots, not YaPB's.
Type_ZBot, // ZBot.
Type_YaPB, // This bot.
Type_Human, // Not really type.... (subtype)
Type_Host = Type_Human, // Listen server hosting client, with full access to YaPB.
Type_Player // Just a regular player, without access to YaPB menus, commands, etc....
};
//
// Group: Type definitions.
//
public:
typedef void (Client::*FunctionThink_t) (void);
//
// Group: Private members.
//
private:
float m_thinkIntervalTime; // think timer interval
bool m_isAlive; // whether client/bot is alive
// fundamental callbacks
FunctionThink_t m_functionThink;
// HalfLifeEngine::SDK::TypeDefinitions::BoneTransformMatrix_t m_boneTransformMatrix; // individual bone transformation matrix for this client
Math::Frustum m_frustum;
//
// Group: Protected members.
//
protected:
template <typename ownerType> class SubSystem
{
public:
typedef ownerType OwnerType_t;
protected:
ownerType *const m_owner; // Pointer to client/bot which owns this sub system.
protected:
inline SubSystem (ownerType *const owner) : m_owner (owner) { /* VOID */ }
virtual inline ~SubSystem (void) { /* VOID */ }
//
// Group: Private operators.
//
private:
inline SubSystem &operator = (const SubSystem &/*right*/); // Avoid "warning C4512: 'SubSystem' : assignment operator could not be generated".
public:
//
// Function: GetOwner
//
// Description: Gets a owner, owning this sub system.
//
// Returns: Owner, owning this sub system.
//
inline ownerType *const GetOwner (void) { return m_owner; }
inline const ownerType *const GetOwner (void) const { return m_owner; }
};
HalfLifeEngine::SDK::Classes::Edict *const m_edict; // shortcut pointer to client/bot edict pointer, set up on client/bot create nullified on initialise, client/bot functions assume this is not NULL.
struct Ammo_t
{
char clip; // ammo in clip
unsigned char total; // total ammo amounts
} m_ammo[HalfLifeEngine::SDK::Constants::MaximumWeapons]; // Stores clip/total ammo amounts for each weapons.
#include <CurrentWeapon.hpp>
OwningItemsManager *m_owningItemsManager;
CurrentWeapon *m_currentWeapon; // some info about current client/bot weapon
Waypoint *m_currentWaypoint; // some info about current client/bot waypoint
NavigationMesh::NavigationArea *m_lastNavigationArea; // Last known navigation area of client - NULL if unknown.
// DynamicString m_lastPlaceName; // Last navigation place name.
#include <ClientHostageManager.hpp>
HostageManager m_hostageManager;
class MapScenario
{
public:
virtual void Think (void);
};
class MapScenario_Assassination : public MapScenario
{
private:
public:
void Think (void);
};
class MapScenario_Rescue : public MapScenario
{
private:
HostageManager m_hostageManager;
public:
void Think (void);
};
class MapScenario_Defusion : public MapScenario
{
private:
public:
void Think (void);
};
class MapScenario_Escape : public MapScenario
{
private:
public:
void Think (void);
};
class MapScenario_RescueAndDefusion : virtual public MapScenario_Rescue, virtual public MapScenario_Defusion
{
private:
public:
void Think (void);
};
class Team
{
protected:
MapScenario *m_mapScenario;
public:
inline Team (void) : m_mapScenario (NULL) { /* VOID */ }
public:
virtual void RoundStarted (void);
virtual void Think (void);
};
class Team_Terrorist : public Team
{
private:
public:
inline Team_Terrorist (void) : Team () { /* VOID */ }
public:
void RoundStarted (void);
void Think (void);
};
class Team_CounterTerrorist : public Team
{
private:
public:
inline Team_CounterTerrorist (void) : Team () { /* VOID */ }
public:
void RoundStarted (void);
void Think (void);
};
Team *m_team; // UNUSED!
HalfLifeEngine::SDK::Constants::TeamID_t m_currentTeamID; // Need only for compare with new team in TeamChanged() function.
struct NoisedSound_t
{
float hearingDistance; // distance this sound is heared
float timeLasting; // time sound is played/heared
float maximumLastingTime; // maximum time sound is played/heared (to divide the difference between that above one and the current one)
unsigned char master_vol; // 0-255 master volume
float dist_mult; // distance multiplier (attenuation / HalfLifeEngine::SDK::Constants::SoundNominalClipDistance)
inline NoisedSound_t (void) : hearingDistance (0.0f), timeLasting (0.0f), maximumLastingTime (0.0f) { /* VOID */ }
inline void Reset (void) { hearingDistance = timeLasting = maximumLastingTime = 0.0f; }
inline void Initialize (const HalfLifeEngine::SDK::Classes::Edict *const/* entity*/, const DynamicString &sample, const float volume, const float attenuation, const HalfLifeEngine::SDK::Constants::SoundFlag_t/* flags*/, const HalfLifeEngine::SDK::Constants::SoundPitch_t/* pitch*/)
{
const DynamicString fullFilename ("/sound/" + sample);
const DynamicString CSfullFilename (HalfLifeEngine::Globals::g_halfLifeEngine->GetGameModName () + fullFilename);
hearingDistance = SOUND_ATTENUATION_TO_RADIUS (attenuation)/* * volume*/; /// @warning SCALING ON volume GIVES WRONG RESULTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
maximumLastingTime = STDIOFile::IsExists (CSfullFilename, "rb") ? GetWaveSoundPlayDuration (CSfullFilename) : GetWaveSoundPlayDuration ("valve" + fullFilename);
timeLasting = HalfLifeEngine::Globals::g_halfLifeEngine->GetTime () + maximumLastingTime;
master_vol = static_cast <unsigned char> (volume * 255.0f);
dist_mult = attenuation / HalfLifeEngine::SDK::Constants::SoundNominalClipDistance;
// HalfLifeEngine::Globals::g_halfLifeEngine->PrintFormat (HalfLifeEngine::SDK::Constants::HUDPrint_Talk, "\"%s\"::EmitSound(): sample: \"%s\", vol=%.1f, attn=%.2f, radius=%.2f, dur=%.2f.", entity->GetNetName ().GetData (), sample.GetData (), volume, attenuation, hearingDistance, maximumLastingTime);
// HalfLifeEngine::Globals::g_halfLifeEngine->ServerPrintFormat ("\"%s\"::EmitSound(): sample: \"%s\", vol=%.1f, attn=%.2f, radius=%.2f, dur=%.2f.\n", entity->GetNetName ().GetData (), sample.GetData (), volume, attenuation, hearingDistance, maximumLastingTime);
}
};
NoisedSound_t m_lastNoisedSound, m_currentNoisedSound; // Last and current noised sounds (for bots, to react on it).
HalfLifeEngine::SDK::Constants::RadioMenu_t m_radioSelect; // used radio menu (0 == none, 1 == 'Radio Commands', 2 == 'Group Radio Commands', 3 == 'Radio Responses/Reports')
//
// Group: (Con/De)structors.
//
public:
inline Client (HalfLifeEngine::SDK::Classes::Edict *const client) :
m_edict (client), // Set client edict.
// Assume dead....
m_isAlive (false),
m_functionThink (&Client::DeathThink),
m_thinkIntervalTime (0.0f),
m_currentWaypoint (NULL),
m_lastNavigationArea (NULL),
m_team (NULL),
m_currentTeamID (HalfLifeEngine::SDK::Constants::TeamID_Unassigned),
m_radioSelect (HalfLifeEngine::SDK::Constants::RadioMenu_None)
{
// Clear all weapon stuff.
for (unsigned char index (HalfLifeEngine::SDK::Constants::WeaponID_None); index < HalfLifeEngine::SDK::Constants::MaximumWeapons; ++index)
m_ammo[index].clip = m_ammo[index].total = 0u;
// Initialize subsystems....
m_owningItemsManager = new OwningItemsManager (this);
m_currentWeapon = new CurrentWeapon (this);
#if defined _DEBUG
// Reliability check.
if (m_currentWeapon == NULL || m_owningItemsManager == NULL)
TerminateOnMalloc ();
#endif // if defined _DEBUG
}
virtual inline ~Client (void)
{
// This is client destructor.
// Delete subsystems....
delete m_owningItemsManager;
delete m_currentWeapon;
}
//
// Group: Private operators.
//
private:
inline Client &operator = (const Client &/*right*/); // Avoid "warning C4512: 'Client' : assignment operator could not be generated".
//
// Group: Operators.
//
public:
// client will now automatically convert to 'HalfLifeEngine::SDK::Classes::Edict *' and 'const HalfLifeEngine::SDK::Classes::Edict *const' when needed
inline operator HalfLifeEngine::SDK::Classes::Edict *const (void) { return GetEdict (); }
inline operator HalfLifeEngine::SDK::Classes::Edict *const (void) const { return m_edict; } // needed too :{O
inline operator const HalfLifeEngine::SDK::Classes::Edict *const (void) const { return GetEdict (); }
// client will now automatically convert to 'HalfLifeEngine::SDK::Structures::EntityVariables_t *' and 'const HalfLifeEngine::SDK::Structures::EntityVariables_t *const' when needed
inline operator HalfLifeEngine::SDK::Structures::EntityVariables_t *const (void) { return &GetEdict ()->variables; }
inline operator HalfLifeEngine::SDK::Structures::EntityVariables_t *const (void) const { return &m_edict->variables; } // needed too :{O
inline operator const HalfLifeEngine::SDK::Structures::EntityVariables_t *const (void) const { return &GetEdict ()->variables; }
// client will now automatically convert to 'HalfLifeEngine::SDK::Classes::BasePlayer *' and 'const HalfLifeEngine::SDK::Classes::BasePlayer *const' when needed
inline operator HalfLifeEngine::SDK::Classes::BasePlayer *const (void) { return GetEdict ()->privateData->GetBasePlayerPointer (); }
inline operator HalfLifeEngine::SDK::Classes::BasePlayer *const (void) const { return GetEdict ()->privateData->GetBasePlayerPointer (); } // needed too :{O
inline operator const HalfLifeEngine::SDK::Classes::BasePlayer *const (void) const { return GetEdict ()->privateData->GetBasePlayerPointer (); }
//
// Group: Private functions.
//
private:
virtual inline const Type_t GetType (void) const =/*>*/ 0; // nothing, used by sub classes
void LastNavigationAreaUpdate (void);
// void SoundSimulateUpdate (void);
inline void TryReceiveLastNoisedSound (void); // Note: This function declared in YaPBManager.hpp.
inline void SetAlive (void)
{
m_isAlive = true;
SetFunctionThink (&Client::AliveThink);
}
inline void SetDead (void)
{
m_isAlive = false;
SetFunctionThink (&Client::DeathThink);
}
inline void CallThinkFunction (void)
{
// Reliability check.
InternalAssert (m_functionThink != NULL);
(this->*m_functionThink) ();
}
virtual inline void CheckWalk (void)
{
if (!IsYaPB () && !IsDucking () && IsOnFloor () ? GetEdict ()->GetSpeedSquared2D () <= HalfLifeEngine::SDK::Constants::MaximumPlayerWalkSpeedSquared : IsOnLadder () && GetEdict ()->GetSpeedSquared () <= HalfLifeEngine::SDK::Constants::MaximumPlayerWalkSpeedSquared)
GetEdict ()->variables.buttons |= HalfLifeEngine::SDK::Constants::IN_RUN;
}
//
// Group: Protected functions.
//
protected:
//
// Function: GetWalkSpeed
//
// Description: Gets the client/bot walk speed for his current weapon.
//
// Returns: True if entity is valid, false otherwise.
//
inline const float GetWalkSpeed (void) const { return static_cast <float> (static_cast <int> (GetEdict ()->variables.maximumSpeed) / 2 + static_cast <int> (GetEdict ()->variables.maximumSpeed) / 50)/* - 18.0f*/; }
template <typename derivedClassType> inline void SetFunctionThink (void (derivedClassType::*const newFunctionThink) (void)) { m_functionThink = static_cast <const FunctionThink_t> (newFunctionThink); }
template </* Client::FunctionThink_t */> inline void SetFunctionThink (const FunctionThink_t newFunctionThink) { m_functionThink = newFunctionThink; }
virtual void LastNavigationAreaChanged (NavigationMesh::NavigationArea *const newNavigationArea);
//
// Group: Functions.
//
public:
//
// Function: IsValid
//
// Description: Checks whether client/bot and his entity is valid.
//
// Note: This function declared in ClientManager.hpp.
//
// Returns: True if client/bot and his entity is valid, false otherwise.
//
inline const bool IsValid (void) const
{
#if defined _DEBUG
if (this == NULL)
return false;
// Reliability checks.
InternalAssert (GetEdict ()->IsValid ());
InternalAssert (!GetName ().IsEmpty ());
return true;
#else // if defined _DEBUG
return this != NULL;
#endif // if !defined _DEBUG
}
inline const float GetThinkIntervalTime (void) const { return m_thinkIntervalTime; }
inline NavigationMesh::NavigationArea *const GetLastNavigationArea (void) const { return m_lastNavigationArea; }
//
// Function: IsAlive
//
// Description: Checks whether client/bot is alive.
//
// Returns: True if client/bot is alive, false otherwise.
//
inline const bool IsAlive (void) const { return m_isAlive; }
inline const Math::Frustum &GetFrustum (void) const { return m_frustum; }
inline const bool IsPrimaryFireAllowed (void) const { return GetEdict ()->privateData->GetBasePlayerPointer ()->m_isPrimaryFireAllowed; }
//
// Function: IsAttacking
//
// Description: Checks whether client/bot is currently attacking.
//
// Returns: True if client/bot is currently attacking, false otherwise.
//
inline const bool IsAttacking (void) const
{
return (GetEdict ()->variables.buttons & HalfLifeEngine::SDK::Constants::IN_ATTACK) && IsPrimaryFireAllowed () && m_currentWeapon->IsValid () && m_currentWeapon->IsCanAttack () && !m_currentWeapon->IsGrenade ();
}
//
// Function: IsShooting
//
// Description: Checks whether client/bot is currently shooting.
//
// Returns: True if client/bot is currently shooting, false otherwise.
//
inline const bool IsShooting (void) const { return IsAttacking () && !m_currentWeapon->IsKnife (); }
//
// Function: IsUsesFlashlight
//
// Description: Checks whether client/bot is uses a flashlight.
//
// Returns: True if client/bot is uses a flashlight, false otherwise.
//
inline const bool IsUsesFlashlight (void) const { return (GetEdict ()->variables.effects & HalfLifeEngine::SDK::Constants::EntityEffect_DimLight) > 0u; }
//
// Function: GetOrigin
//
// Description: Gets the client's current origin.
//
// Returns: Client's current origin.
//
inline const Math::Vector3D &GetOrigin (void) const { return GetEdict ()->variables.origin; }
inline const Math::Vector3D &GetVelocity (void) const { return GetEdict ()->variables.velocity; }
inline const Math::Angles3D &GetModelAngles (void) const { return GetEdict ()->variables.modelAngles; }
inline const Math::Angles3D &GetViewAngles (void) const { return GetEdict ()->variables.viewAngles; }
inline const Math::Angles3D &GetPunchAngles (void) const { return GetEdict ()->variables.punchAngles; }
inline const unsigned short GetFieldOfView (void) const { return static_cast <unsigned short> (GetEdict ()->variables.fov); }
inline const unsigned short GetSafeFieldOfView (void) const { return GetFieldOfView () > 0u ? GetFieldOfView () : HalfLifeEngine::SDK::Constants::DefaultPlayerFieldOfView; }
inline const DynamicString GetName (void) const { return GetEdict ()->GetNetName (); }
//
// Function: GetMoney
//
// Description: Gets the amount of money in client's bank.
//
// Returns: Amount of money in client's bank.
//
inline const unsigned short GetMoney (void) const { return static_cast <const unsigned short> (GetEdict ()->GetPrivateDataReference <unsigned int> (HalfLifeEngine::SDK::Constants::OFFSET_MONEY)); }
inline void SetMoney (const unsigned short newMoneyAmount) { return GetEdict ()->SetPrivateData <unsigned int> (HalfLifeEngine::SDK::Constants::OFFSET_MONEY, newMoneyAmount); }
//
// Function: GetSpawnsNumber
//
// Description: Gets the number of times client has spawned this round.
//
// Returns: Number of times client has spawned this round.
//
inline const unsigned short GetSpawnsNumber (void) const { return static_cast <const unsigned short> (GetEdict ()->GetPrivateDataReference <unsigned int> (HalfLifeEngine::SDK::Constants::OFFSET_SPAWNS_NUMBER)); }
//
// Function: GetFlashlightBattery
//
// Description: Gets the client's flashlight battery amount.
//
// Returns: Amount of client's flashlight battery.
//
inline const unsigned char GetFlashlightBattery (void) const { return static_cast <const unsigned char> (GetEdict ()->GetPrivateDataReference <unsigned int> (HalfLifeEngine::SDK::Constants::OFFSET_FLASH_LIGHT_BATTERY)); }
//
// Function: IsHasNightVisionGoggles
//
// Description: Checks whether the client have night vision goggles.
//
// Returns: True if client have night vision goggles, false otherwise.
//
inline const bool IsHasNightVisionGoggles (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_HAS_NVGOGGLES); }
//
// Function: IsUsingNightVisionGoggles
//
// Description: Checks whether the client using night vision goggles.
//
// Returns: True if client using night vision goggles, false otherwise.
//
inline const bool IsUsingNightVisionGoggles (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_USES_NVGOGGLES); }
//
// Function: IsDefusing
//
// Description: Checks whether the client is defusing C4.
//
// Returns: True if client is defusing C4, false otherwise.
//
inline const bool IsDefusing (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_IS_DEFUSING); }
//
// Function: IsHasDefuseKit
//
// Description: Checks whether the client have defuse kit.
//
// Returns: True if client have defuse kit, false otherwise.
//
inline const bool IsHasDefuseKit (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_HAS_DEFUSE_KIT); }
//
// Function: IsCanPlantBomb
//
// Description: Checks whether the client can plant bomb.
//
// Returns: True if client can plant bomb, false otherwise.
//
inline const bool IsCanPlantBomb (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_CAN_PLANT_BOMB); }
//
// Function: IsTeamChanged
//
// Description: Checks whether the client is changed team after respawn.
//
// Returns: True if client is changed team after respawn, false otherwise.
//
inline const bool IsTeamChanged (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_IS_TEAM_CHANGED); }
//
// Function: IsCanHearRadio
//
// Description: Checks whether the client can hear radio commands.
//
// Returns: True if client can hear radio commands, false otherwise.
//
inline const bool IsCanHearRadio (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_CANT_HEAR_RADIO) == false; }
//
// Function: IsNotKilled
//
// Description: Checks whether the client has been just respawned (not killed).
//
// Returns: True if client has been just respawned (not killed), false otherwise.
//
inline const bool IsNotKilled (void) const { return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_IS_NOT_KILLED); }
/*! DON'T USE US!!!
//
// Function: GetNextChatTime
//
// Description: Gets the client's chat delay time.
//
// Returns: Amount of client's delay between two chat messages.
//
inline const float GetNextChatTime (void) const { return GetEdict ()->GetPrivateDataReference <float> (HalfLifeEngine::SDK::Constants::OFFSET_Player_NextChatUseTime); }
//
// Function: GetNextTeamChatTime
//
// Description: Gets the client's team chat delay time.
//
// Returns: Amount of client's delay between two team chat messages.
//
inline const float GetNextTeamChatTime (void) const { return GetEdict ()->GetPrivateDataReference <float> (HalfLifeEngine::SDK::Constants::OFFSET_Player_NextTeamChatUseTime); }
*/
//
// Function: GetNextRadioTime
//
// Description: Gets the client's radio delay time.
//
// Returns: Amount of client's delay between two radio commands.
//
inline const float GetNextRadioTime (void) const { return GetEdict ()->GetPrivateDataReference <float> (HalfLifeEngine::SDK::Constants::OFFSET_NEXT_RADIO_TIME); }
//
// Function: GetRadioCommandsUseAmount
//
// Description: Gets the client's radio commands amount.
//
// Returns: Amount of client's radio commands.
//
inline const unsigned char GetRadioCommandsUseAmount (void) const { return static_cast <const unsigned char> (GetEdict ()->GetPrivateDataReference <unsigned int> (HalfLifeEngine::SDK::Constants::OFFSET_RADIO_COMMANDS_USE_AMOUNT)); }
//
// Function: GetFallDamage
//
// Description: Gets the client's fall damage.
//
// Returns: Amount of client's fall damage.
//
inline const float GetFallDamage (void) const
{
if (GetEdict ()->variables.fallVelocity <= HalfLifeEngine::SDK::Constants::PlayerMaximumSafeFallSpeed)
return 0.0f; // After this point, we start doing damage.
// Subtract off the speed at which a player is allowed to fall without being hurt, so damage will be based on speed beyond that, not the entire fall.
return (GetEdict ()->variables.fallVelocity - HalfLifeEngine::SDK::Constants::PlayerMaximumSafeFallSpeed) * HalfLifeEngine::SDK::Constants::DamageForFallSpeed;
}
inline const float GetFOVDistanceAdjustFactor (void) const
{
const float defaultFOVInverted (1.0f / HalfLifeEngine::SDK::Constants::DefaultPlayerFieldOfView);
const float localFOV (GetFieldOfView ());
// If FOV is lower, then we're "zoomed" in and this will give a factor < 1 so apparent LOD distances can be shorted accordingly
return localFOV * defaultFOVInverted;
}
static inline const float GetMinimumShootingConeDeviation (const float distanceSquared, const float radius)
{
const float squaredDistanceWithRadius (distanceSquared + MATH_GET_SQUARED (radius));
const float coneMinimum (distanceSquared / squaredDistanceWithRadius);
return coneMinimum;
}
inline const float GetShootingConeDeviation (const Math::Vector3D &position) const
{
// Find the length to the point, get the player's forward direction
const Math::Vector3D directionToPositionNormalized ((position - GetEyePosition ()).Normalize ());
// he's facing it, he meant it
return directionToPositionNormalized | GetEyeForwardDirection ();
}
inline const float GetShootingConeDeviationWithPunchAngles (const Math::Vector3D &position) const
{
// Find the length to the point, get the player's forward direction
const Math::Vector3D directionToPositionNormalized ((position - GetEyePosition ()).Normalize ());
// he's facing it, he meant it
return directionToPositionNormalized | GetEyeForwardDirectionWithPunchAngles ();
}
inline const bool IsInFieldOfView (const Math::Vector3D &location) const
{
// this function returns TRUE if the spatial vector location 'location' is located inside
// the field of view cone of the client entity, FALSE otherwise. It is assumed that entities
// have a human-like field of view, that is, about 90 degrees.
// compute deviation angles (angles between player's forward direction and location)
const Math::Angles2D deviation (((location - GetEyePosition ()).ToAngles2D () - GetViewAngles ()).Clamp ());
const float fieldOfView (GetFieldOfView ());
// is location outside player's FOV width (90 degree)?
if (Math::fabsf (deviation.yaw) > fieldOfView * 0.5f)
return false; // then location is not visible
// is location outside player's FOV height (60 degree: consider the 4:3 screen ratio)?
if (Math::fabsf (deviation.pitch) > Math::Frustum::CalcFovY (fieldOfView, 4.0f / 3.0f)/*! @todo MAKE PRECALCULATED VALUE!!!!!!!!!!!!!!!!! */ * 0.5f)
return false; // then location is not visible
return true; // else location has to be in player's field of view cone
}
inline const float GetFieldOfViewCone (const float fov) const { return Math::cosf (Math::DegreeToRadian (fov * 0.5f)); }
inline const float GetFieldOfViewCone (void) const { return GetFieldOfViewCone (GetSafeFieldOfView ()); }
inline const bool IsInViewCone (const Math::Vector3D &origin, const float fov) const
{
// This function returns true if the spatial vector location origin is located inside the field of view cone of the bot entity, false otherwise.
// origin has to be in entity's field of view cone?
return GetShootingConeDeviation (origin) >= GetFieldOfViewCone (fov);
}
inline const bool IsInViewCone (const Math::Vector3D &origin) const
{
// this function returns true if the spatial vector location origin is located inside the field of view cone of the bot entity, false otherwise.
// origin has to be in entity's field of view cone?
return IsInViewCone (origin, GetSafeFieldOfView ());
}
inline const bool IsInViewConeWithRadius (const Math::Vector3D &origin, const float radius, const float fov) const
{
// This function returns true if the spatial vector location origin is located inside the field of view cone of the bot entity, false otherwise.
/// @warning SLOW FUNCTION!
// TODO: For safety sake, we might want to do a more fully qualified test against the frustum using the bbox
// This is the additional number of degrees to add to account for our distance
const float arcAddition (Math::atan2f (radius, GetEyePosition ().GetDistance (origin)));
// Find if the sphere is within our FOV
// origin has to be in entity's field of view cone?
return GetShootingConeDeviation (origin) >= GetFieldOfViewCone (fov) - arcAddition;
}
inline const bool IsInViewConeWithRadius (const Math::Vector3D &origin, const float radius) const
{
return IsInViewConeWithRadius (origin, radius, GetSafeFieldOfView ());
}
inline const OwningItemsManager *const GetOwningItemsManager (void) const { return m_owningItemsManager; }
inline const CurrentWeapon *const GetCurrentWeapon (void) const { return m_currentWeapon; }
inline const unsigned short/*float*/ GetAbsoluteFieldOfView (const Math::Vector3D &destination) const
{
// This function returns the absolute value of angle to destination entity.
float viewAngle (GetViewAngles ().yaw); // get client's current view angle....
float entityAngle ((destination - GetEyePosition ()).ToYaw ()); // find yaw angle from source to destination....
// make yaw angle 0.0 to 360.0 degrees if negative....
if (entityAngle < 0.0f)
entityAngle += 360.0f;
// make view angle 0.0 to 360.0 degrees if negative....
if (viewAngle < 0.0f)
viewAngle += 360.0f;
// Return the absolute value of angle to destination entity. Zero degrees means straight ahead, 45 degrees to the left or 45 degrees to the right is the limit of the normal view angle
const unsigned short absoluteAngle (static_cast <unsigned short> (abs (static_cast <int> (viewAngle) - static_cast <int> (entityAngle)))); // rsm - START angle bug fix.
// const float absoluteAngle (Math::fabsf (viewAngle - entityAngle)); // rsm - START angle bug fix.
// Reliability check.
InternalAssert (absoluteAngle <= 360u);
return absoluteAngle > 180u ? 360u - absoluteAngle : absoluteAngle; // rsm - END
// return absoluteAngle > 180.0f ? 360.0f - absoluteAngle : absoluteAngle; // rsm - END
}
inline const float GetFieldOfView (const Math::Vector3D &destination) const
{
// This function returns the value of angle to destination entity.
return Math::GetDifferenceBetweenAngles ((destination - GetEyePosition ()).ToYaw (), GetViewAngles ().yaw);
}
inline const float GetFieldOfView (const float destinationAngle) const
{
// This function returns the value of angle to destination angle.
return Math::GetDifferenceBetweenAngles (destinationAngle, GetViewAngles ().yaw);
}
/* inline const Math::Angles2D GetAbsoluteFieldOfView2D (Math::Vector3D destination) const
{
// This function returns the absolute value of angle to destination entity.
destination -= GetEyePosition ();
/// @error PITCH IS WRONG!!!
float viewAngle (GetViewAngles ().pitch); // get client's current view angle....
float entityAngle (destination.ToPitch ()); // find pitch angle from source to destination....
Math::Angles2D absoluteFieldOfView;
entityAngle = 180.0f - entityAngle;
// make pitch angle 0.0 to 180.0 degrees if negative....
if (entityAngle < 0.0f)
entityAngle += 180.0f;
// make view angle 0.0 to 180.0 degrees if negative....
if (viewAngle < 0.0f)
viewAngle += 180.0f;
// Return the absolute value of angle to destination entity. Zero degrees means straight ahead, 45 degrees upwards or 45 degrees downwards is the limit of the normal view angle
absoluteFieldOfView.pitch = static_cast <unsigned short> (abs (static_cast <int> (viewAngle) - static_cast <int> (entityAngle))); // rsm - START angle bug fix.
// absoluteFieldOfView.pitch = Math::fabsf (viewAngle - entityAngle); // rsm - START angle bug fix.
// Reliability check.
InternalAssert (absoluteFieldOfView.pitch <= 180.0f);
if (absoluteFieldOfView.pitch > 90.0f)
absoluteFieldOfView.pitch = 180.0f - absoluteFieldOfView.pitch;
// rsm - END
viewAngle = GetViewAngles ().yaw; // get client's current view angle....
entityAngle = destination.ToYaw (); // find yaw angle from source to destination....
// make yaw angle 0.0 to 360.0 degrees if negative....
if (entityAngle < 0.0f)
entityAngle += 360.0f;
// make view angle 0.0 to 360.0 degrees if negative....
if (viewAngle < 0.0f)
viewAngle += 360.0f;
// Return the absolute value of angle to destination entity. Zero degrees means straight ahead, 45 degrees to the left or 45 degrees to the right is the limit of the normal view angle
absoluteFieldOfView.yaw = static_cast <unsigned short> (abs (static_cast <int> (viewAngle) - static_cast <int> (entityAngle))); // rsm - START angle bug fix.
// absoluteFieldOfView.yaw = Math::fabsf (viewAngle - entityAngle); // rsm - START angle bug fix.
// Reliability check.
InternalAssert (absoluteFieldOfView.yaw <= 360.0f);
if (absoluteFieldOfView.yaw > 180.0f)
absoluteFieldOfView.yaw = 360.0f - absoluteFieldOfView.yaw;
// rsm - END
return absoluteFieldOfView;
}
*/
inline const bool IsLookingAtPosition (const Math::Vector3D &position, const unsigned char maximumAngleDifference = 20u) const
{
const Math::Vector3D direction (position - GetEyePosition ());
Math::Angles2D angles (direction.ToAngles2D ());
if (abs (static_cast <short> (Math::AngleNormalize (angles.yaw - GetViewAngles ().yaw))) >= maximumAngleDifference)
return false;
angles.pitch = 360.0f - angles.pitch;
return abs (static_cast <short> (Math::AngleNormalize (angles.pitch - GetViewAngles ().pitch))) < maximumAngleDifference;
}
inline const unsigned char GetAbsoluteFieldOfView (void) const
{
// This function returns the zoom type of a client/bot.
return static_cast <const unsigned char> (GetEdict ()->GetPrivateDataReference <unsigned int> (HalfLifeEngine::SDK::Constants::Offset_Player_FieldOfView));
}
inline const HalfLifeEngine::SDK::Constants::ZoomType_t GetZoomType (void) const
{
// This function returns the zoom type of a client/bot.
return static_cast <const HalfLifeEngine::SDK::Constants::ZoomType_t> (GetAbsoluteFieldOfView ());
}
inline const bool IsUsingScope (void) const { return GetFieldOfView () < HalfLifeEngine::SDK::Constants::DefaultPlayerFieldOfView; }
//
// Function: IsOnTrain
//
// Description: Checks whether client is on train.
//
// Returns: True if client is currently standing on the train, false otherwise.
//
inline const bool IsOnTrain (void) const { return GetEdict ()->IsPlayerOnTrain (); }
//
// Function: GetEdict
//
// Description: Gets the client entity pointer.
//
// Returns: Client entity pointer.
//
inline HalfLifeEngine::SDK::Classes::Edict *const GetEdict (void) { return m_edict; }
inline const HalfLifeEngine::SDK::Classes::Edict *const GetEdict (void) const { return m_edict; }
//
// Function: GetCurrentWaypoint
//
// Description: Gets the current client/bot waypoint pointer.
//
// Returns: Current client/bot waypoint pointer.
//
inline Waypoint *const GetCurrentWaypoint (void) { return m_currentWaypoint; }
inline const Waypoint *const GetCurrentWaypoint (void) const { return m_currentWaypoint; }
inline const bool HasWeapon (const HalfLifeEngine::SDK::Constants::WeaponID_t index) const { return (GetEdict ()->variables.weapons & BIT (index)) > 0u; }
inline const bool HasWeapons (const HalfLifeEngine::SDK::Constants::WeaponBit_t weaponBits) const { return (GetEdict ()->variables.weapons & weaponBits) > 0u; }
inline const bool HasPrimaryWeapon (void) const
{
// This function returns true if bot has a primary weapon, false otherwise.
return HasWeapons (HalfLifeEngine::SDK::Constants::WeaponBits_Primary);
}
inline const bool HasSecondaryWeapon (void) const
{
// This function returns true if bot has a secondary weapon, false otherwise.
return HasWeapons (HalfLifeEngine::SDK::Constants::WeaponBits_Secondary);
}
inline const bool HasShield (void) const
{
// This function returns true if client/bot has a tactical shield, false otherwise.
return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_HAS_SHIELD);
}
inline const bool IsShieldDrawn (void) const
{
// This function returns true if the tactical shield is drawn, false otherwise.
return GetEdict ()->GetPrivateDataReference <bool> (HalfLifeEngine::SDK::Constants::OFFSET_USES_SHIELD);
}
//
// Function: GetSpecialMapZones
//
// Description: Gets the client special map zones bitmask.
//
// Returns: Special map zones bitmask.
//
inline const HalfLifeEngine::SDK::Constants::MapZone_t GetSpecialMapZones (void) const { return GetEdict ()->GetPrivateDataReference <HalfLifeEngine::SDK::Constants::MapZone_t> (HalfLifeEngine::SDK::Constants::Offset_Player_ClientMapZone); }
inline const bool IsInBuyZone (void) const { return (GetSpecialMapZones () & HalfLifeEngine::SDK::Constants::IN_BUY_ZONE) > 0u; }
inline const bool IsInBombPlace (void) const { return (GetSpecialMapZones () & HalfLifeEngine::SDK::Constants::IN_BOMB_PLACE) > 0u; }
inline const bool IsInHostagesRescueZone (void) const { return (GetSpecialMapZones () & HalfLifeEngine::SDK::Constants::IN_HOSTAGES_RESCUE_ZONE) > 0u; }
inline const bool IsInEscapeZone (void) const { return (GetSpecialMapZones () & HalfLifeEngine::SDK::Constants::IN_ESCAPE_ZONE) > 0u; }
inline const bool IsInVIPRescueZone (void) const { return (GetSpecialMapZones () & HalfLifeEngine::SDK::Constants::IN_VIP_RESCUE_ZONE) > 0u; }
inline const HalfLifeEngine::SDK::Constants::SpectatorObserverMode_t GetObserverMode (void) const { return GetEdict ()->GetPlayerObserverMode (); }
inline const unsigned char GetObserverTargetEdictIndex (void) const { return GetEdict ()->GetPlayerObserverTargetEdictIndex (); }
inline const Client *const GetObserverTarget (void) const; // Note: This function declared in ClientManager.hpp.
inline const HalfLifeEngine::SDK::Constants::PlayerArmorType_t GetArmorType (void) const { return GetEdict ()->GetPrivateDataReference <HalfLifeEngine::SDK::Constants::PlayerArmorType_t> (HalfLifeEngine::SDK::Constants::OFFSET_PLAYER_ARMOR_TYPE); }
// Note: The below 2 functions are declared in FakeClient.hpp.
inline FakeClient *const GetFakeClientPointer (void);
inline const FakeClient *const GetFakeClientPointer (void) const;
// Note: The below 2 functions are declared in OtherBot.hpp.
inline FakeClient_NotYaPB *const GetFakeClientNotYaPBPointer (void);
inline const FakeClient_NotYaPB *const GetFakeClientNotYaPBPointer (void) const;
// Note: The below 2 functions are declared in ZBot.hpp.
inline ZBot *const GetZBotPointer (void);
inline const ZBot *const GetZBotPointer (void) const;
// Note: The below 2 functions are declared in YaPB.hpp.
inline YaPB *const GetYaPBPointer (void);
inline const YaPB *const GetYaPBPointer (void) const;
// Note: The below 2 functions are declared in Human.hpp.
inline Human *const GetHumanPointer (void);
inline const Human *const GetHumanPointer (void) const;
// Note: The below 2 functions are declared in Host.hpp.
inline Host *const GetHostPointer (void);
inline const Host *const GetHostPointer (void) const;
// Note: The below 2 functions are declared in Player.hpp.
inline Player *const GetPlayerPointer (void);
inline const Player *const GetPlayerPointer (void) const;
inline HalfLifeEngine::SDK::Structures::Client_t &GetEngineClient (void) { return g_server->GetStatic ().clients[GetEdict ()->GetIndex () - 1u]; }
inline const HalfLifeEngine::SDK::Structures::Client_t &GetEngineClient (void) const { return g_server->GetStatic ().clients[GetEdict ()->GetIndex () - 1u]; }
inline const HalfLifeEngine::SDK::Classes::Edict *const GetViewEdict (void) const { return GetEngineClient ().pViewEntity; }
//
// Function: IsFakeClient
//
// Description: Checks whether client is bot (fake client).
//
// Returns: True if client is bot (fake client), false otherwise.
//
// inline const bool IsFakeClient (void) const { return GetType () < Type_Human; }
virtual inline const bool IsFakeClient (void) const =/*>*/ 0; // nothing, used by sub classes
//
// Function: IsYaPB
//
// Description: Checks whether client is YaPB.
//
// Returns: True if client is YaPB, false otherwise.
//
// inline const bool IsYaPB (void) const { return GetType () == Type_YaPB; }
virtual inline const bool IsYaPB (void) const =/*>*/ 0; // nothing, used by sub classes
//
// Function: IsHuman
//
// Description: Checks whether client is human, not a bot.
//
// Returns: True if client is human, false otherwise.
//
// inline const bool IsHuman (void) const { return GetType () >= Type_Human; }
virtual inline const bool IsHuman (void) const =/*>*/ 0; // nothing, used by sub classes
//
// Function: IsHuman