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
|
untyped
global function Evac_Init
global function Evac_AddLocation
global function Evac_SetSpacePosition
global function Evac_SetEnabled
global function Evac_IsEnabled
global function IsEvacDropship
global function EvacMain
const float EVAC_ARRIVAL_TIME = 40.0
const float EVAC_WAIT_TIME = 18.0
struct {
bool enabled = true
array<Point> evacPoints
Point spacePosition
entity evacDropship
array<entity> evacPlayers
} file
void function Evac_Init()
{
EvacShared_Init()
AddCallback_GameStateEnter( eGameState.Epilogue, Evac_OnEpilogue )
}
void function Evac_SetEnabled( bool enabled )
{
file.enabled = enabled
}
bool function Evac_IsEnabled()
{
return false // shit is busted rn lol
//return file.enabled && GetClassicMPMode() && !IsRoundBased()
}
void function Evac_AddLocation( vector origin, vector angles )
{
Point evacPoint
evacPoint.origin = origin
evacPoint.angles = angles
file.evacPoints.append( evacPoint )
}
void function Evac_SetSpacePosition( vector origin, vector angles )
{
file.spacePosition.origin = origin
file.spacePosition.angles = angles
}
bool function IsEvacDropship( entity ent )
{
return file.evacDropship == ent && IsValid( file.evacDropship )
}
void function Evac_OnEpilogue()
{
if ( Evac_IsEnabled() )
thread EvacMain( GetOtherTeam( GameScore_GetWinningTeam() ) )
}
void function EvacMain( int winningTeam )
{
if ( file.evacPoints.len() == 0 )
{
// automatically add evac locations if they aren't registered yet
int i = 1
entity current = null
while ( true )
{
current = GetEnt( "escape_node" + i )
print( current )
if ( current != null )
Evac_AddLocation( current.GetOrigin(), current.GetAngles() )
else
break
i++
}
if ( file.evacPoints.len() == 0 )
unreachable
}
if ( file.spacePosition.origin == < 0, 0, 0 > )
{
// automatically add a space node if not registered yet
entity defaultSpaceNode = GetEnt( "spaceNode" )
if ( defaultSpaceNode == null )
unreachable
Evac_SetSpacePosition( defaultSpaceNode.GetOrigin(), defaultSpaceNode.GetAngles() )
}
Point evacPoint = file.evacPoints[ RandomInt( file.evacPoints.len() ) ]
// create an entity for the evac point that clients will get
entity evacPointEntity = CreateEntity( MARKER_ENT_CLASSNAME )
evacPointEntity.SetOrigin( evacPoint.origin )
evacPointEntity.kv.spawnflags = SF_INFOTARGET_ALWAYS_TRANSMIT_TO_CLIENT
DispatchSpawn( evacPointEntity )
evacPointEntity.DisableHibernation()
// set objectives
//SetTeamActiveObjective( winningTeam, "EG_DropshipExtract", Time() + EVAC_ARRIVAL_TIME, evacPointEntity )
//SetTeamActiveObjective( GetOtherTeam( winningTeam ), "EG_StopExtract", Time() + EVAC_ARRIVAL_TIME, evacPointEntity )
// wanted to do this with an actual dropship to calculate embarkStartDelay but spawning it before it should exist ingame is weird
// could probably do it with a dummy entity but effort
wait EVAC_ARRIVAL_TIME - 4.33333//embarkStartDelay
// create dropship
entity dropship = CreateDropship( winningTeam, evacPoint.origin, evacPoint.angles )
file.evacDropship = dropship
DispatchSpawn( dropship )
dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" ) // gotta do this after dispatch for some reason
vector startPos = dropship.Anim_GetStartForRefEntity( "cd_dropship_rescue_side_start", evacPointEntity, "origin" ).origin
dropship.SetOrigin( startPos ) // set origin so the dropship isn't in the map
dropship.EndSignal( "OnDestroy" )
// calculate time until idle
float sequenceDuration = dropship.GetSequenceDuration( "cd_dropship_rescue_side_start" )
float cycleFrac = dropship.GetScriptedAnimEventCycleFrac( "cd_dropship_rescue_side_start", "ReadyToLoad" )
float embarkStartDelay = sequenceDuration * cycleFrac
// play anim
thread PlayAnim( dropship, "cd_dropship_rescue_side_start", evacPointEntity )
wait embarkStartDelay
print( "evac flyin done! ready to load players" )
// set objectives again
SetTeamActiveObjective( winningTeam, "EG_DropshipExtract2", Time() + EVAC_WAIT_TIME, evacPointEntity )
SetTeamActiveObjective( GetOtherTeam( winningTeam ), "EG_StopExtract2", Time() + EVAC_WAIT_TIME, evacPointEntity )
thread EvacShipThink( dropship ) // let people enter it
wait EVAC_WAIT_TIME
// fly away
thread PlayAnim( dropship, "cd_dropship_rescue_side_end", evacPointEntity )
// set objectives again
SetTeamActiveObjective( winningTeam, "EG_DropshipExtractDropshipFlyingAway" )
SetTeamActiveObjective( GetOtherTeam( winningTeam ), "EG_StopExtractDropshipFlyingAway" )
wait dropship.GetSequenceDuration( "cd_dropship_rescue_side_end" ) - WARPINFXTIME
foreach ( entity player in file.evacPlayers )
{
Remote_CallFunction_Replay( player, "ServerCallback_PlayScreenFXWarpJump" )
}
// todo screen effects and shit
//WaittillAnimDone( dropship )
wait WARPINFXTIME
// space
dropship.SetOrigin( file.spacePosition.origin )
dropship.SetAngles( file.spacePosition.angles )
thread PlayAnim( dropship, "ds_space_flyby_dropshipA" )
// display player [Evacuated] in killfeed
foreach ( entity player in GetPlayerArray() )
{
foreach ( entity evacPlayer in file.evacPlayers )
Remote_CallFunction_NonReplay( player, "ServerCallback_EvacObit", evacPlayer.GetEncodedEHandle() )
}
foreach ( entity player in file.evacPlayers )
{
// set skybox to space for all evac players
player.SetSkyCamera( GetEnt( "skybox_cam_intro" ) )
Remote_CallFunction_NonReplay( player, "ServerCallback_DisableHudForEvac" )
}
wait 5.0
foreach ( entity player in GetPlayerArray() )
ScreenFadeToBlackForever( player, 2.0 )
wait 2.0
// end game lol
SetGameState( eGameState.Postmatch )
}
void function EvacShipThink( entity dropship )
{
dropship.EndSignal( "OnDestroy" )
// this is the easiest way i could figure out to get a bounding box that's parented to the dropship
entity mover1 = CreateScriptMover( dropship.GetOrigin(), dropship.GetAngles() )
mover1.SetParent( dropship )
mover1.SetLocalOrigin( dropship.GetBoundingMaxs() - < 0, 0, 100> )
entity mover2 = CreateScriptMover( dropship.GetOrigin(), dropship.GetAngles() )
mover2.SetParent( dropship )
mover2.SetLocalOrigin( dropship.GetBoundingMins() - < 0, 0, 100 > )
while ( true )
{
foreach ( entity player in GetPlayerArrayOfTeam( dropship.GetTeam() ) )
{
if ( file.evacPlayers.contains( player ) || !IsAlive( player ) )
continue
vector playerPos = player.GetOrigin()
vector mover1Pos = mover1.GetOrigin()
vector mover2Pos = mover2.GetOrigin()
vector maxPos
maxPos.x = mover1Pos.x > mover2Pos.x ? mover1Pos.x : mover2Pos.x
maxPos.y = mover1Pos.y > mover2Pos.y ? mover1Pos.y : mover2Pos.y
maxPos.z = mover1Pos.z > mover2Pos.z ? mover1Pos.z : mover2Pos.z
vector minPos
minPos.x = mover1Pos.x < mover2Pos.x ? mover1Pos.x : mover2Pos.x
minPos.y = mover1Pos.y < mover2Pos.y ? mover1Pos.y : mover2Pos.y
minPos.z = mover1Pos.z < mover2Pos.z ? mover1Pos.z : mover2Pos.z
print( "\n" )
print( player )
print( playerPos )
print( minPos )
print( maxPos )
if ( playerPos.x > minPos.x && playerPos.y > minPos.y && playerPos.z > minPos.z &&
playerPos.x < maxPos.x && playerPos.y < maxPos.y && playerPos.z < maxPos.z )
{
print( player + " is evacuating!" )
file.evacPlayers.append( player )
player.SetParent( dropship )
// super duper temp
player.SetLocalOrigin( dropship.GetOrigin() - < 0, 10, 80 > )
}
}
WaitFrame()
}
}
/*void function TestEvac()
{
if ( file.evacShipSpawns.len() == 0 )
Evac_AddLocation( GetEnt( "escape_node1" ).GetOrigin(), GetEnt( "escape_node1" ).GetAngles() )
Point shipSpawn = file.evacShipSpawns[ RandomInt( file.evacShipSpawns.len() ) ]
entity dropship = CreateDropship( GetPlayerArray()[0].GetTeam(), shipSpawn.origin, shipSpawn.angles )
file.evacDropship = dropship
DispatchSpawn( dropship )
dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" )
print( dropship.GetSequenceDuration( "cd_dropship_rescue_side_start" ) )
print( dropship.GetScriptedAnimEventCycleFrac( "cd_dropship_rescue_side_start", "ReadyToLoad" ) )
float embarkStart = dropship.GetSequenceDuration( "cd_dropship_rescue_side_start" ) * dropship.GetScriptedAnimEventCycleFrac( "cd_dropship_rescue_side_start", "ReadyToLoad" )
print( embarkStart )
thread PlayAnim( dropship, "cd_dropship_rescue_side_start" )
wait embarkStart
print( "evac start anim done" )
thread TestEvacThink( dropship )
SetTeamActiveObjective( GetPlayerArray()[0].GetTeam(), "EG_DropshipExtract2", Time() + 30, dropship )
thread PlayAnim( dropship, "cd_dropship_rescue_side_idle", GetEnt( "escape_node1" ) )
}
void function TestEvacThink( entity dropship )
{
dropship.EndSignal( "OnDestroy" )
// these numbers are probably innacurate but there's no real way of getting accurate ones and these are good enough
entity mover = CreateScriptMover( dropship.GetOrigin(), dropship.GetAngles() )
mover.SetParent( dropship )
mover.SetLocalOrigin( dropship.GetBoundingMaxs() - < 0, 0, 100> )
entity mover2 = CreateScriptMover( dropship.GetOrigin(), dropship.GetAngles() )
mover2.SetParent( dropship )
mover2.SetLocalOrigin( dropship.GetBoundingMins() - < 0, 0, 100> )
while ( true )
{
foreach ( entity player in GetPlayerArrayOfTeam( dropship.GetTeam() ) )
{
if ( !IsAlive( player ) )
continue
vector playerOrigin = player.GetOrigin()
vector dropshipMax = mover.GetOrigin()
vector dropshipMin = mover2.GetOrigin()
// temp, might be permenant but idk if box triggers are a thing in script
if ( playerOrigin.x > dropshipMin.x && playerOrigin.y > dropshipMin.y && playerOrigin.z > dropshipMin.z &&
playerOrigin.x < dropshipMax.x && playerOrigin.y < dropshipMax.y && playerOrigin.z < dropshipMax.z )
player.Die()
}
WaitFrame()
}
}*/
|