-
Notifications
You must be signed in to change notification settings - Fork 0
/
LaunchCode.py
569 lines (470 loc) · 21.2 KB
/
LaunchCode.py
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
#
# Updated by darkdiplomat
#
################ Copyright 2005-2013 Team GoldenEye: Source #################
#
# This file is part of GoldenEye: Source's Python Library.
#
# GoldenEye: Source's Python Library is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the License,
# or(at your option) any later version.
#
# GoldenEye: Source's Python Library is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GoldenEye: Source's Python Library.
# If not, see <http://www.gnu.org/licenses/>.
#############################################################################
from . import GEScenario
from .Utils.GEWarmUp import GEWarmUp
from .Utils.GETimer import TimerTracker, Timer
import GEEntity, GEPlayer, GEUtil, GEWeapon, GEMPGameRules as GERules, GEGlobal as Glb
import random
USING_API = Glb.API_VERSION_1_2_0
def getPlayerFromUID(uid):
if not uid:
return None
plr = GEEntity.GetEntByUID(uid)
if plr is not None and isinstance(plr, GEPlayer.CGEMPPlayer):
return plr
else:
return None
class LaunchCode(GEScenario):
# ------------------ #
# GLOBAL CONSTANTS #
# ------------------ #
JANUS_HACKER_COSTUME = "boris"
MI6_HACKER_COSTUME = "female_scientist"
MIN_PLAYERS = 2
LOW_PLAYER_NOTICE_INTERVAL = 10.0
TOOL_CLASSNAME = "token_custom1"
TOOL_WMODEL = "models/weapons/tokens/w_keytoken.mdl"
TOOL_VMODEL = "models/weapons/tokens/v_keytoken.mdl"
COLOR_INFO = GEUtil.CColor(240, 200, 120, 170)
COLOR_NOTICE = GEUtil.CColor(240, 200, 120, 170)
COLOR_RADAR_MI6 = GEUtil.CColor(94, 171, 231, 255)
COLOR_RADAR_JANUS = GEUtil.CColor(206, 43, 43, 255)
TAG = "[LaunchCode]"
DEFAULT_PARAMS = {
# Hacker Variables
"hacker_notice": 0,
"hacker_playerUID": None,
"hacker_oldCostume": "",
"hacker_oldSkin": 0,
"hacker_switched": False,
"hacker_hasTool": False,
"hacker_hasWeapon": False,
# Game Variables
"game_startTime": GEUtil.GetTime(),
"game_hackersWin": False,
"game_tool": None,
"game_lastTerminalUID": None,
"game_currTerminalUID": None,
}
# ---------------- #
# CORE FUNCTIONS #
# ---------------- #
def __init__(self):
super(LaunchCode, self).__init__()
self.warmUpTimer = GEWarmUp(self)
self.timerTracker = TimerTracker(self)
self.__debug = False
# Defining some vars
self.game_terminals = {}
self.team_hacker = None
self.team_preventor = None
self.timer_endRound = None
self.timer_hacking = None
self.game_roundCount = 0
self.hacker_hasWeapon = False
self.hacker_canArm = True
self.game_lastTerminalUID = None
self.game_currTerminalUID = None
self.hacker_hasTool = False
self.game_lowPlayers = True
self.game_lowPlayersNotice = 0
self.game_terminal_model = "models/props/bunker/oldlaptop.mdl"
# Hacker Variables
self.hacker_notice = 0
self.hacker_playerUID = None
self.hacker_oldCostume = ""
self.hacker_oldSkin = 0
self.hacker_switched = False
self.hacker_hasTool = False
self.hacker_hasWeapon = False
# Game Variables
self.game_startTime = GEUtil.GetTime()
self.game_hackersWin = False
self.game_lastTerminalUID = None
self.game_currTerminalUID = None
self.game_tool = None
def Cleanup(self):
super(LaunchCode, self).Cleanup()
self.timer_endRound = None
self.timer_hacking = None
self.warmUpTimer = None
self.timerTracker = None
def GetPrintName(self):
return "Launch Code"
def GetScenarioHelp(self, help_obj):
pass
def GetGameDescription(self):
return "Launch Code"
def GetTeamPlay(self):
return Glb.TEAMPLAY_ALWAYS
def OnLoadGamePlay(self):
# Precache our custom items
GEUtil.PrecacheModel(self.game_terminal_model)
# Clear the timer list
self.timerTracker.RemoveTimer()
# Create the hacking timer
self.timer_hacking = self.timerTracker.CreateTimer("hack")
self.timer_hacking.SetAgeRate(0.75, 2.0)
self.timer_hacking.SetUpdateCallback(self.lc_OnHackTimer)
# Delay of End Round timer
self.timer_endRound = self.timerTracker.CreateTimer("endround")
self.timer_endRound.SetUpdateCallback(self.lc_OnEndRoundTimer)
# Setup all our vars
self.lc_InitRound()
# Reset the some vars
self.game_terminals = {}
self.team_hacker = None
self.team_preventor = None
self.game_roundCount = 0
# Enable team spawns
GERules.SetAllowTeamSpawns(True)
# Exclude hacker costumes
GERules.SetExcludedCharacters("female_scientist, boris")
GERules.GetTokenMgr().SetupCaptureArea("terminals", model=self.game_terminal_model,
limit=4, radius=32, location=Glb.SPAWN_PLAYER)
self.CreateCVar("lc_warmup", "30", "Warmup time before the match begins")
self.CreateCVar("lc_hackerboost", "0", "Allow the hacker to gain an ego-boost")
self.CreateCVar("lc_hackertool", "1", "Allow the Insta-Hack tool")
self.CreateCVar("lc_hacktime", "15", "Base number of seconds to hack a terminal")
self.CreateCVar("lc_hackerdefense", "1", "Allows the hacker to have a DD44 to protect themselves")
self.CreateCVar("lc_debug", "0", "Enabled/Disables debugging prompts")
def OnRoundBegin(self):
self.__debug = GEUtil.GetCVarValue("lc_debug") == 1
if self.__debug:
GEUtil.ClientPrint(None, Glb.HUD_PRINTTALK, self.TAG + "Debugging Enabled")
else:
GEUtil.ClientPrint(None, Glb.HUD_PRINTTALK, self.TAG + "Debugging Disabled")
GERules.GetRadar().SetForceRadar(True)
GERules.ResetAllPlayersScores()
self.hacker_canArm = GEUtil.GetCVarValue("lc_hackerdefense") == 1
self.game_roundCount += 1
self.lc_DerobeHacker()
self.lc_InitRound()
self.lc_ChooseHacker()
self.lc_CreateHackingTool()
def OnRoundEnd(self):
GERules.GetRadar().DropAllContacts()
if self.lc_HavePlayers() and not self.game_hackersWin:
pTeam = GERules.GetTeam(self.team_preventor)
GERules.SetTeamWinner(pTeam)
for t in self.game_terminals.values():
if not t["hacked"]:
pTeam.IncrementRoundScore(1)
def OnPlayerSpawn(self, player):
# Properly arm the hacker
if self.hacker_playerUID == player.GetUID():
if self.hacker_canArm:
self.lc_ArmHacker(player) # Give the hacker back their weapon on respawn
if self.hacker_notice < 3:
self.hacker_notice += 1
GEUtil.HudMessage(player, "You are the hacker, hack the terminals by standing next to them", -1, -1,
self.COLOR_NOTICE, 5.0, 2)
def OnPlayerKilled(self, victim, killer, weapon):
if victim is None:
return
if victim.GetUID() == self.hacker_playerUID:
self.hacker_hasWeapon = False
if self.team_preventor:
GERules.GetTeam(self.team_preventor).IncrementRoundScore(1)
if killer and victim != killer:
killer.IncrementScore(1)
else:
victim.IncrementScore(-1)
def OnCaptureAreaSpawned(self, area):
aUID = area.GetUID()
self.game_terminals[aUID] = {"hacked": False}
GERules.GetRadar().AddRadarContact(area, Glb.RADAR_TYPE_TOKEN, True, "sprites/hud/radar/capture_point",
self.lc_GetHackerTeamColor())
def OnCaptureAreaRemoved(self, area):
aUID = area.GetUID()
if aUID in self.game_terminals:
del self.game_terminals[aUID]
GERules.GetRadar().DropRadarContact(area)
def OnCaptureAreaEntered(self, area, player, token):
aUID = area.GetUID()
if aUID not in self.game_terminals or self.game_terminals[aUID]["hacked"]:
return
if player.GetUID() == self.hacker_playerUID:
time_hack = float(GEUtil.GetCVarValue("lc_hacktime"))
if self.timer_hacking.state is Timer.STATE_STOP or self.game_lastTerminalUID != area.GetUID():
GEUtil.InitHudProgressBar(None, 1, "Hack Progress:", 1, time_hack, -1, 0.75, 120, 15,
GEUtil.CColor(220, 220, 220, 240))
self.game_lastTerminalUID = aUID
self.game_currTerminalUID = aUID
self.timer_hacking.Start(time_hack)
def OnCaptureAreaExited(self, area, player):
if player.GetUID() == self.hacker_playerUID:
self.timer_hacking.Pause()
self.game_currTerminalUID = None
def CanPlayerChangeChar(self, player, ident):
if player is None:
return False
if ident == self.JANUS_HACKER_COSTUME or ident == self.MI6_HACKER_COSTUME:
GEUtil.HudMessage(player, "You cannot impersonate the hacker!", -1, 0.1, self.COLOR_INFO, 2.0)
return False
elif player.GetUID() == self.hacker_playerUID:
if self.lc_CanHackerSwitch():
self.lc_ChooseHacker()
return True
else:
GEUtil.HudMessage(player, "You cannot switch from the hacker!", -1, 0.1, self.COLOR_INFO, 2.0)
return False
return True
def CanPlayerHaveItem(self, player, item):
name = item.GetClassname()
if player.GetUID() == self.hacker_playerUID:
# The hacker can only pickup armor
if name.startswith("item_armorvest"):
return True
elif name == "weapon_slappers" or name == self.TOOL_CLASSNAME:
return True
elif name == "weapon_dd44" and self.hacker_canArm:
return True
return False
else:
if name == self.TOOL_CLASSNAME:
return False
return True
def OnTokenSpawned(self, token):
GERules.GetRadar().AddRadarContact(token, Glb.RADAR_TYPE_TOKEN, True)
def OnTokenRemoved(self, token):
GERules.GetRadar().DropRadarContact(token)
def OnTokenPicked(self, token, player):
self.hacker_hasTool = True
GEUtil.PlaySoundTo(player, "GEGamePlay.Token_Grab")
GEUtil.ClientPrint(None, Glb.HUD_PRINTTALK, self.TAG + " The hacker picked up the Insta-Hack")
GEUtil.HudMessage(self.team_hacker, "The hacker has the Insta-Hack, protect them at all costs!", -1, 0.65,
self.COLOR_NOTICE, 4.0, 1)
GEUtil.HudMessage(self.team_preventor, "Warning! The hacker has the Insta-Hack!!", -1, 0.65, self.COLOR_NOTICE,
4.0, 1)
GEUtil.PlaySoundTo(self.team_hacker, "GEGamePlay.Token_Grab")
GEUtil.PlaySoundTo(self.team_preventor, "GEGamePlay.Token_Grab_Enemy")
GERules.GetRadar().DropRadarContact(token)
def OnTokenDropped(self, token, player):
self.hacker_hasTool = False
GEUtil.ClientPrint(None, Glb.HUD_PRINTTALK, self.TAG + " The Insta-Hack has been destroyed")
GEUtil.HudMessage(None, "The Insta-Hack has been destroyed!", -1, 0.65, self.COLOR_NOTICE, 4.0, 1)
GEUtil.PlaySoundTo(None, "GEGamePlay.Token_Drop_Friend")
GERules.GetTokenMgr().RemoveTokenType(self.TOOL_CLASSNAME)
def OnThink(self):
if self.game_lowPlayers:
if self.lc_HavePlayers():
# We have enough players, start the warmup period
self.warmUpTimer.StartWarmup(float(GEUtil.GetCVarValue("lc_warmup")))
self.game_lowPlayers = False
self.lc_DerobeHacker()
elif GEUtil.GetTime() >= self.game_lowPlayersNotice:
# Notify anyone in the serve that we don't have enough players
GEUtil.HudMessage(None, "Not enough players, please wait...", -1, -1, self.COLOR_NOTICE,
self.LOW_PLAYER_NOTICE_INTERVAL / 4.0)
self.game_lowPlayersNotice = GEUtil.GetTime() + self.LOW_PLAYER_NOTICE_INTERVAL
elif not self.lc_HavePlayers():
# Put us back into low player state
self.warmUpTimer.Reset()
self.game_lowPlayers = True
self.game_lowPlayersNotice = 0
self.lc_DerobeHacker()
def CanPlayerChangeTeam(self, player, oldteam, newteam, wasforced):
# The hacker cannot change teams
if player.GetUID() == self.hacker_playerUID:
GEUtil.HudMessage(player, "You cannot change teams as the hacker!", -1, -1,
GEUtil.CColor(255, 255, 255, 255), 3.0)
return False
return True
def OnPlayerDisconnect(self, player):
# If the hacker disconnects we must choose a new one
if player.GetUID() == self.hacker_playerUID:
self.hacker_hasWeapon = False
self.hacker_hasTool = False
self.lc_ChooseHacker(True)
def OnPlayerSay(self, player, text):
if text == "!voodoo":
if player.GetUID() == self.hacker_playerUID and self.hacker_hasTool and self.game_currTerminalUID:
self.lc_OnHackCompleted()
self.timer_hacking.Stop()
GERules.GetTokenMgr().RemoveTokenType(self.TOOL_CLASSNAME)
return True
return False
# ------------------ #
# CUSTOM FUNCTIONS #
# ------------------ #
def lc_InitRound(self):
# Hacker Variables
self.hacker_notice = 0
self.hacker_playerUID = None
self.hacker_oldCostume = ""
self.hacker_oldSkin = 0
self.hacker_switched = False
self.hacker_hasTool = False
self.hacker_hasWeapon = False
# Game Variables
self.game_startTime = GEUtil.GetTime()
self.game_hackersWin = False
self.game_lastTerminalUID = None
self.game_currTerminalUID = None
self.game_tool = None
# Reset Timers
self.timerTracker.ResetTimer()
# Check for low player counts
self.game_lowPlayersNotice = 0
if not self.lc_HavePlayers():
self.game_lowPlayers = True
else:
self.game_lowPlayers = False
# Setup Teams
if self.team_hacker:
# Swap the teams
tmp = self.team_hacker
self.team_hacker = self.team_preventor
self.team_preventor = tmp
else:
# First time? Pick a random team
self.team_hacker = random.choice([Glb.TEAM_MI6, Glb.TEAM_JANUS])
if self.team_hacker == Glb.TEAM_JANUS:
self.team_preventor = Glb.TEAM_MI6
else:
self.team_preventor = Glb.TEAM_JANUS
def lc_ChooseHacker(self, force=False):
if not self.team_hacker:
self.lc_ErrorShout("Hacker assignment attempted before team chosen!")
return
# Enumerate the number of eligible players
players = self.lc_ListPlayers(self.team_hacker, self.hacker_playerUID)
self.lc_DerobeHacker()
if self.hacker_playerUID:
if len(players) > 1 and (force or self.lc_CanHackerSwitch()):
self.lc_DebugShout("Hacker being switched")
self.lc_EnrobeHacker(random.choice(players))
self.hacker_switched = True
elif len(players) > 0:
self.lc_DebugShout("New hacker being selected")
self.lc_EnrobeHacker(random.choice(players))
self.hacker_switched = False
def lc_CanHackerSwitch(self):
timeIn = GEUtil.GetTime() - self.game_startTime;
plrCount = GERules.GetNumActiveTeamPlayers(self.team_hacker)
if self.hacker_playerUID and plrCount > 1 and not self.hacker_switched and timeIn < 15.0:
return True
return False
def lc_CreateHackingTool(self):
# Only create the hacking tool if allowed
if GEUtil.GetCVarValue("lc_hackertool") == 1:
mgr = GERules.GetTokenMgr()
mgr.SetupToken(self.TOOL_CLASSNAME, limit=1, location=Glb.SPAWN_AMMO,
allow_switch=True, glow_color=GEUtil.CColor(80, 80, 80, 255), glow_dist=500.0)
def lc_EnrobeHacker(self, uid):
player = GEPlayer.ToMPPlayer(uid)
if player is not None:
model = self.MI6_HACKER_COSTUME
if player.GetTeamNumber() == Glb.TEAM_JANUS:
model = self.JANUS_HACKER_COSTUME
# Store away his old costume and set him as the hacker
self.hacker_oldCostume = player.GetPlayerModel()
self.hacker_oldSkin = player.GetSkin()
player.SetPlayerModel(model, 0)
# Add me to the radar as always visible
GERules.GetRadar().AddRadarContact(player, Glb.RADAR_TYPE_PLAYER, True, "sprites/hud/radar/run",
GEUtil.CColor(255, 180, 225, 170))
# Reset notices
self.hacker_notice = 0
self.hacker_playerUID = uid
if self.hacker_canArm:
self.lc_ArmHacker(player)
def lc_DerobeHacker(self):
player = getPlayerFromUID(self.hacker_playerUID)
if player is not None:
# Revert back to the old costume
player.SetPlayerModel(self.hacker_oldCostume, self.hacker_oldSkin)
player.StripAllWeapons()
player.GiveDefaultWeapons()
GERules.GetRadar().DropRadarContact(player)
self.hacker_hasWeapon = False
self.hacker_hasTool = False
self.hacker_playerUID = None
def lc_ArmHacker(self, player):
if player is not None:
player.StripAllWeapons()
player.GiveNamedWeapon("weapon_slappers", 0)
player.GiveNamedWeapon("weapon_dd44", 14) # DD44 starts w/ 10 bullets: 8|16
player.SetArmor(int(Glb.GE_MAX_ARMOR))
def lc_OnHackTimer(self, timer, update_type):
assert isinstance(timer, Timer)
if update_type is Timer.UPDATE_FINISH:
# Complete the hack
self.lc_OnHackCompleted()
elif update_type is Timer.UPDATE_STOP:
GEUtil.RemoveHudProgressBar(None, 1)
# Reset the terminal usage since we abandoned our current effort
self.game_lastTerminalUID = self.game_currTerminalUID = None
elif update_type is Timer.UPDATE_RUN:
GEUtil.UpdateHudProgressBar(None, 1, timer.GetCurrentTime())
def lc_OnHackCompleted(self):
GERules.GetTeam(self.team_hacker).IncrementRoundScore(1)
GERules.GetRadar().DropRadarContact(GEEntity.GetEntByUID(self.game_lastTerminalUID))
GEUtil.PlaySoundTo(self.team_hacker, "GEGameplay.Token_Capture_Friend", True)
GEUtil.PlaySoundTo(self.team_preventor, "GEGamePlay.Token_Capture_Enemy", True)
GEUtil.HudMessage(None, "The hacker has taken over a terminal!", -1, -1, self.COLOR_NOTICE, 2.0, 2)
self.game_terminals[self.game_lastTerminalUID]["hacked"] = True
self.game_lastTerminalUID = self.game_currTerminalUID = None
self.lc_CheckHackerWin()
def lc_OnEndRoundTimer(self, timer, update_type):
if update_type is Timer.UPDATE_FINISH:
GERules.EndRound()
def lc_CheckHackerWin(self):
for t in self.game_terminals.values():
if not t["hacked"]:
return
# If we made it here, hackers won! End the round
self.game_hackersWin = True
hTeam = GERules.GetTeam(self.team_hacker)
GERules.SetTeamWinner(hTeam)
hTeam.IncrementRoundScore(len(self.game_terminals))
# End the round in 3 seconds (this should be a variable in EndRound(...))
self.timer_endRound.Start(3.0)
def lc_GetHackerTeamColor(self):
if self.team_hacker == Glb.TEAM_MI6:
return self.COLOR_RADAR_MI6
else:
return self.COLOR_RADAR_JANUS
def lc_ListPlayers(self, team, ignore=None, npcs=False):
list = []
for j in range(32):
if GEPlayer.IsValidPlayerIndex(j):
player = GEPlayer.GetMPPlayer(j)
if player.GetTeamNumber() == team and player.GetUID() != ignore:
# Favor humans over NPCs
if not npcs and player.IsNPC():
continue
list.append(player.GetUID())
if len(list) == 0: # No humans on hacker team, regrab list without stripping NPCs
self.lc_ListPlayers(team, ignore, True)
return list
def lc_HavePlayers(self):
if GERules.GetNumActivePlayers() >= self.MIN_PLAYERS:
return True
return False
def lc_DebugShout(self, msg):
if self.__debug:
GEUtil.Msg(self.TAG + msg + "\n")
def lc_ErrorShout(self, msg):
if self.__debug:
GEUtil.Warning(self.TAG + msg + "\n")