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
|
untyped
global function CloakerThink
global function CloakerShouldCloakGuy
global function CloakerCloaksGuy
global function CloakerDeCloaksGuy
function CloakerThink( entity cloaker, float radius, array<string> ents = [ "any" ], vector offset = Vector(0,0,0), var shouldCloakGuyFunc = null, float waitTime = 0.25 )
{
OnThreadEnd(
function() : ( cloaker )
{
local cloakList = clone cloaker.s.cloakList
foreach ( entity guy, value in cloakList )
{
if ( !IsAlive( guy ) )
continue
CloakerDeCloaksGuy( guy )
}
}
)
cloaker.s.cloakList <- {}
cloaker.s.decloakList <- {}
while( 1 )
{
vector origin = cloaker.GetOrigin() + offset
array<entity> guys
foreach ( entType in ents )
{
switch ( entType )
{
case "player":
case "players":
guys.extend( GetPlayerArrayEx( "any", cloaker.GetTeam(), TEAM_ANY, origin, radius ) )
break;
default:
guys.extend( GetNPCArrayEx( entType, cloaker.GetTeam(), TEAM_ANY, origin, radius ) )
break
}
}
int index = 0
float startTime = Time()
table cloakList = expect table( cloaker.s.cloakList )
cloaker.s.decloakList = clone cloakList
foreach ( guy in guys )
{
//only do 5 distanceSqr / cansee checks per frame
if ( index++ > 5 )
{
wait 0.1
index = 0
origin = cloaker.GetOrigin() + offset
}
bool shouldCloakGuy = CloakerShouldCloakGuy( cloaker, guy )
if ( shouldCloakGuy )
shouldCloakGuy = expect bool( shouldCloakGuyFunc( cloaker, guy ) )
if ( shouldCloakGuy )
{
if ( guy in cloaker.s.decloakList )
delete cloaker.s.decloakList[ guy ]
if ( IsCloaked( guy ) )
continue
cloakList[ guy ] <- true
CloakerCloaksGuy( guy )
}
}
foreach ( entity guy, value in cloaker.s.decloakList )
{
// any guys still in the decloakList shouldn't be decloaked ... if alive.
Assert( guy in cloakList )
delete cloakList[ guy ]
if ( IsAlive( guy ) )
CloakerDeCloaksGuy( guy )
}
float endTime = Time()
float elapsedTime = endTime - startTime
if ( elapsedTime < waitTime )
wait waitTime - elapsedTime
}
}
void function CloakerCloaksGuy( guy )
{
if( guy.IsNPC() )
guy.SetCanCloak(true) // if you don't want to cloak specific targets, it should be handled by shouldCloakGuyFunc in CloakerThink
guy.SetCloakDuration( 2.0, -1, 0 )
EmitSoundOnEntity( guy, CLOAKED_DRONE_CLOAK_START_SFX )
EmitSoundOnEntity( guy, CLOAKED_DRONE_CLOAK_LOOP_SFX )
guy.Minimap_Hide( TEAM_IMC, null )
guy.Minimap_Hide( TEAM_MILITIA, null )
}
void function CloakerDeCloaksGuy( guy )
{
guy.SetCloakDuration( 0, 0, 1.5 )
StopSoundOnEntity( guy, CLOAKED_DRONE_CLOAK_LOOP_SFX )
guy.Minimap_AlwaysShow( TEAM_IMC, null )
guy.Minimap_AlwaysShow( TEAM_MILITIA, null )
if( guy.IsNPC() )
guy.SetCanCloak(false)
}
bool function CloakerShouldCloakGuy( entity cloaker, entity guy )
{
if ( !IsAlive( guy ) )
return false
return true
}
|