Unfortunately we don't provide a way to "freeze" players using the Python API interface. You would have to combine the python code with a standard server plugin to provide the freezing effect.
You could accomplish this using server-side custom events to pass information across:
GEUtils.EmitGameplayEvent( ... )
Here is the wiki article: http://wiki.geshl2.com/index.php/GoldenEye:_Source_Plugin_Support#gameplay_event
Naming suggestion: Die another Day... not sure if it was allready taken by another gamemode, or if it was just an achivement.Good idea, I would like this mode to use that title but unfortunately there is a Die Another Day achievement. I personally don't think having a mode and achievement with the same name matters. So if the GE:S developers and community don't mind I now want this mode's title to be Die Another Day.
I'm curious in how players are able to resurrect their frozen team mates? Have you thought about someone getting killed in midair and his team mate unable to reach him?
Still there are maps like cradle, caves, runway, complex, etc. where players are able to fall into areas that are not part of the regulary playable map.Thanks for the helpful suggestion, I didn't know about the map problem you mentioned. I think spawning resurrection entities at spawn points would be the best alternative to spawning them at player death locations.
A solution might be that instead of having the players respawn at the place where they were killed, placing the resurrection entity on a token spawner or player start.
Also, what if you'd need to collect something like 1up items in order to be resurectable.Although I don't want DAD's game play to be different from MOHAA Freeze Tag's game play for the reason I gave above, I do like your item ideas and I think I would enjoy playing a mode which was like DAD but also used your game play ideas.
Everyone starts with one extra life, as soon as he needs to be resurrected, he looses this extra to the one who resurrected him.
Maybe you could also be allowed to resurrect players from the other team, stealing their lifes that way.
Instead of the T-posed Body, i'd rather see something like a gravestone there.I would like resurrection entities to use a character model which is in an unarmed standing stance with its arms down at its sides. Can character models use this stance?[/list]
These are some ideas I've had for dealing with the inaccessible map area problem:
- Jumping could be disabled in this mode.
- Player could have their resurrection entity spawn at a spawn point or accessible map area when:
- They fall to their death.
- When they use a suicide chat command.
I can see that there is a function in GEUtil which creates a temporary entity at a given vector ( CreateTempEnt(type,vector) ). I've got 2 questions about this function:
1) How is the created entity temporary? (or is a temporary entity a type of entity?)
2) How can a script reference an entity object which has been created by this function?
Yea, that's true as well. If someone is falling into a pit, and they're killed, the game mode would fail. It would be worthless to unfreeze them.I've decided that I'm going to make resurrection entities spawn at player spawn points because of this map problem and because resurrection entities could block doors if they spawn at player corpses.
from GamePlay import GEScenario
from Utils.GETimer import EndRoundCallback, TimerTracker, Timer
import GEEntity, GEPlayer, GEUtil, GEWeapon, GEMPGameRules, GEGlobal
USING_API = GEGlobal.API_VERSION_1_0_0
class Test( GEScenario ):
def GetPrintName( self ):
return "Test"
def GetScenarioHelp( self, help_obj ):
help_obj.SetDescription( "#GES_GP_DEATHMATCH_HELP" )
def GetGameDescription( self ):
if GEMPGameRules.IsTeamplay():
return "Team Deathmatch"
else:
return "Deathmatch"
def __init__( self ):
self.timerTracker = TimerTracker( self )
def GetTeamPlay( self ):
return GEGlobal.TEAMPLAY_TOGGLE
def OnLoadGamePlay( self ):
GEMPGameRules.SetAllowTeamSpawns( False )
self.CreateCVar( "dm_fraglimit", "0", "Enable frag limit for DeathMatch." )
timer = self.timerTracker.CreateTimer( "timer" )
timer.SetAgeRate( 1.0, 1.0 )
timer.SetUpdateCallback( self.TimerUpdate, 1.0 )
def TimerUpdate( self, timer, update_type ):
GEUtil.Msg("Timer Updated")
def OnThink( self ):
fragLimit = int( GEUtil.GetCVarValue( "dm_fraglimit" ) )
if fragLimit != 0:
if GEMPGameRules.IsTeamplay():
teamJ = GEMPGameRules.GetTeam( GEGlobal.TEAM_JANUS );
teamM = GEMPGameRules.GetTeam( GEGlobal.TEAM_MI6 );
jScore = teamJ.GetRoundScore() + teamJ.GetMatchScore()
mScore = teamM.GetRoundScore() + teamM.GetMatchScore()
if jScore >= fragLimit or mScore >= fragLimit:
GEMPGameRules.EndMatch()
else:
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
player = GEPlayer.GetMPPlayer( i )
if ( player.GetMatchScore() + player.GetScore() ) >= fragLimit:
GEMPGameRules.EndMatch()Traceback (most recent call last):
File "c:\program files\steam\steamapps\sourcemods\gesource\scripts\python\GamePlayManager.py", line 23, in SetGamePlay
scenario = getattr( sys.modules[module], ident )()
File "c:\program files\steam\steamapps\sourcemods\gesource\scripts\python\GamePlay\Test.py", line 21, in __init__
self.timerTracker = TimerTracker( self )
File "c:\program files\steam\steamapps\sourcemods\gesource\scripts\python\GamePlay\Utils\GETimer.py", line 20, in __init__
parent.RegisterEventHook( EventHooks.GP_THINK, self.AgeTimers )
File "c:\program files\steam\steamapps\sourcemods\gesource\scripts\python\GamePlay\__init__.py", line 22, in RegisterEventHook
if not self.__hooks.has_key( hook ):
AttributeError: 'Test' object has no attribute '_GEScenario__hooks'
Scenario loading failed for scenario Test
Hey, check out my Uplink gameplay for how capture areas work (and the older version archived somewhere around here for how to use tokens for a similar effect, the trick is to deny pickup). My advice would be to have two lists (deadJANUS and deadMI6) that keep track of dead players then create capture zones in a number equal to the length of those lists. When a player enters a capture zone, remove it and then remove the top player from the list. Players inside the list are denied spawning, keeping them eliminated until someone hits a capture zone.
I hope you're good at Sourcepawn. Better yet, you could just use someone else's code for the freeze.
You cannot move entities from Python. The reason for this is so that you don't inadvertently break something in the game (like moving a player into a wall) or moving an entity into a player. I am not sure how the capture points will react to being moved, but they should be ok. They were not designed to be moved after being placed.
You would have to create a sourcepawn script to handle this.
I am pretty interested to see what you do with this. If it works out I may move some of the sourcepawn script stuff into Python so you can do it all in Python.
BTW, did you end up getting the timers to work? You should use Capture The Key as an example of using advanced timers.
from . import GEScenario
from GamePlay.Utils.GEPlayerTracker import GEPlayerTracker
from Utils.GETimer import TimerTracker, Timer
from collections import defaultdict
from collections import deque
import GEPlayer, GEUtil, GEMPGameRules, GEGlobal
USING_API = GEGlobal.API_VERSION_1_0_0
'''
I chose to implement this mode by editing the "You Only Live Twice" mode script. So
this script uses lots of code that was created by the author(s) of the YOLT script.
I've also reused code from the "Capture The Key" mode's script.
@author: Joe
@version: Dev 12.00
'''
class DieAnotherDay( GEScenario ):
MRE_MODEL = "models/players/bond/bond.mdl"
JRE_MODEL = "models/players/jaws/jaws.mdl"
COLOR_MI6_RADAR = GEUtil.Color( 94, 171, 231, 255 )
COLOR_JANUS_RADAR = GEUtil.Color( 206, 43, 43, 255 )
JBountyFontColour = GEUtil.CColor( 206, 43, 43, 255 )
MBountyFontColour = GEUtil.CColor( 100, 184, 234, 220 )
#Progress bar positions
MBountyPBX = 0.4
MBountyPBY = 0
JBountyPBX = 0.6
JBountyPBY = 0
ResurrectionPBX = -1
ResurrectionPBY = 0.6
#-------------------------
resurrectionTime = 5.0
TR_ELIMINATED = "eliminated"
TR_SPAWNED = "spawned"
TOKEN_MI6 = 'token_mi6'
TOKEN_JANUS = 'token_janus'
resurrectionAreaID = 0
#Progress Bar Indexs
MBountyPBIndex = 0
JBountyPBIndex = 1
ResurrectionPBIndex = 2
def __init__( self ):
super( DieAnotherDay, self ).__init__()
self.waitingForPlayers = False
self.radarSet = False
self.mi6Bounty = 0
self.janusBounty = 0
self.pltracker = GEPlayerTracker( self )
self.timerTracker = TimerTracker( self )
self.tokenManager = GEMPGameRules.GetTokenMgr()
self.inUseResurrectionAreas = defaultdict(list)
self.rAreaIDs = []
self.inPlayMPlayers = []
self.inPlayJPlayers = []
self.mResurrectionQueue = deque()
self.jResurrectionQueue = deque()
def OnLoadGamePlay( self ):
GEUtil.PrecacheModel( self.MRE_MODEL )
GEUtil.PrecacheModel( self.JRE_MODEL )
def Cleanup( self ):
super( DieAnotherDay, self ).Cleanup()
self.pltracker = None
def GetPrintName( self ):
return "Die Another Day" #TODO use UI Language Files
def GetScenarioHelp( self, help_obj ):
#TODO use UI Language Files:
help_obj.SetDescription(
"""
Based on: Mefy's MOHAA Freeze Tag Mode
Version: Dev 12.00
*Eliminate the opposing team.
*Resurrect your eliminated team mates.
*To resurrect a team mate stand next
to them.
The ability to resurrect players from
a long distance will be added in
version 2.00, if it can be implemented.
""")
def GetGameDescription( self ):
return "Die Another Day"
def OnPlayerConnect( self, player ):
self.pltracker.SetValue( player, self.TR_SPAWNED, False )
#TODO
def OnPlayerDisconnect( self, player ):
if player.GetTeamNumber() != GEGlobal.TEAM_SPECTATOR:
self.UpdatePlayerBountyKilled( player )
def CanPlayerChangeTeam( self, player, oldTeam, newTeam ):
if GEMPGameRules.IsRoundLocked():
if self.IsInPlay( player ) and oldTeam != GEGlobal.TEAM_SPECTATOR:
self.UpdatePlayerBountyKilled( player )
elif oldTeam == GEGlobal.TEAM_SPECTATOR:
GEUtil.PopupMessage( player, "#GES_GPH_CANTJOIN_TITLE", "#GES_GPH_CANTJOIN", "", 5.0, False )
else:
GEUtil.PopupMessage( player, "#GES_GPH_ELIMINATED_TITLE", "#GES_GPH_ELIMINATED", "", 5.0, False )
# Changing teams will automatically eliminate you
self.pltracker.SetValue( player, self.TR_ELIMINATED, True )
return True
def OnPlayerSpawn( self, player ):
# Record us as "spawned"
if player.GetTeamNumber() != GEGlobal.TEAM_SPECTATOR:
self.pltracker.SetValue( player, self.TR_SPAWNED, True )
if player.IsInitialSpawn():
# If we spawned mid-round let them know why they can't play
if not self.IsInPlay( player ):
GEUtil.PopupMessage( player, "#GES_GPH_CANTJOIN_TITLE", "#GES_GPH_CANTJOIN" )
#TODO Use UI Language Files
GEUtil.PopupMessage( player, "Die Another Day", "Eliminate your opponents and resurrect your eliminated team mates." )
#Why does this not work? :
#Only show team mates on the local player's radar
if(GEMPGameRules.GetRadar().IsRadarContact(player)):
if(player.GetTeamNumber() != GEPlayer.GetMPPlayer(1).GetTeamNumber()):
GEMPGameRules.GetRadar().DropRadarContact(player)
def OnRoundBegin( self ):
if(not self.waitingForPlayers):
self.mi6Bounty = 0
self.janusBounty = 0
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
self.pltracker.SetValue( GEPlayer.GetMPPlayer( i ), self.TR_ELIMINATED, False )
GEMPGameRules.ResetAllPlayerDeaths()
GEMPGameRules.ResetAllPlayersScores()
def OnRoundEnd( self ):
GEMPGameRules.GetRadar().DropAllContacts()
GEUtil.RemoveHudProgressBar( None, self.MBountyPBIndex )
GEUtil.RemoveHudProgressBar( None, self.JBountyPBIndex )
GEUtil.RemoveHudProgressBar( None, self.ResurrectionPBIndex ) #TODO what if user doesn't have PB?
self.timerTracker.RemoveTimer(None) #Stop all timers
#Delete all capture areas:
for areaID in self.rAreaIDs: #rAreaIDs will only contains IDs for areas which exist
self.tokenManager.RemoveCaptureArea(areaID)
def OnPlayerKilled( self, victim, killer, weapon ):
super( DieAnotherDay, self ).OnPlayerKilled( victim, killer, weapon )
#Don't allow player's to accidentally/intentionally eliminate their team mates
#CVAR option will be added in version 2.
if(killer.GetTeamNumber() != victim.GetTeamNumber()):
#Prevent the killed player from respawning.
self.pltracker.SetValue( victim, self.TR_ELIMINATED, True )
#Create a resurrection area entity & add dead player to resurrection queue
areaID = str(self.resurrectionAreaID)
self.resurrectionAreaID += 1
if(victim.GetTeamNumber() == GEGlobal.TEAM_MI6):
self.tokenManager.SetupCaptureArea(areaID,
model=self.MRE_MODEL,
limit=1, location=GEGlobal.SPAWN_PLAYER,
rqd_team=GEGlobal.TEAM_MI6)
self.mResurrectionQueue.append(victim)
else:
self.tokenManager.SetupCaptureArea(areaID,
model=self.JRE_MODEL,
limit=1, location=GEGlobal.SPAWN_PLAYER,
rqd_team=GEGlobal.TEAM_JANUS)
self.jResurrectionQueue.append(victim)
self.rAreaIDs.append(areaID)
#Added to radar in captureAreaSpawned()
#Emit "Player Eliminated" event
GEUtil.EmitGameplayEvent( "DieAnotherDay_eliminated", "%i" % victim.GetUserID(), "%i" % ( killer.GetUserID() if killer else -1 ) ) #TODO
#Tell the victim That they've been eliminated
GEUtil.ClientPrint( None, GEGlobal.HUD_PRINTTALK, "#GES_GP_YOLT_ELIMINATED", victim.GetPlayerName() ) #TODO use UI Language Files
#Tell the other players that a player has been eliminated
GEUtil.PopupMessage( victim, "#GES_GPH_ELIMINATED_TITLE", "You have been eliminated. You could be resurrected by a team mate." ) # TODO use UI Language Files
#Update the displayed count of survivors on the victim's team:
self.InitializePlayerBounty()
self.UpdatePlayerBountyKilled(victim)
def OnCaptureAreaSpawned( self, area ):
#Don't show enemy resurrection areas on the local players radar
if(area.GetTeamNumber() == GEPlayer.GetMPPlayer(1).GetTeamNumber()):
team = None
if(area.getSide() == GEGlobal.TEAM_MI6):team = GEGlobal.TEAM_MI6
else:team = GEGlobal.TEAM_JANUS
GEMPGameRules.GetRadar().AddRadarContact(area,GEGlobal.RADAR_TYPE_OBJECTIVE,True,"sprites/hud/radar/capture_point",team)
def OnCaptureAreaEntered( self, area, player, token ):
if(area.GetTeamNumber() == player.GetTeamNumber()):
#Add player to area's user list
self.inUseResurrectionAreas[area.GetGroupName()].append(player)
#Create & configure resurrection timer & Give it the area's name and team
resurrectionTimer = self.timerTracker.CreateTimer(str(area.GetTeamNumber()) + "," + area.GetGroupName())
resurrectionTimer.SetUpdateCallback(self.ResurrectionTimerTick,1.0)
resurrectionTimer.SetAgeRate(1.0,0)
#Create a resurrection progress bar on the player's screen TODO: use language files
GEUtil.InitHudProgressBar(player,self.ResurrectionPBIndex, "Resurrecting Team Mate...", GEGlobal.HUDPB_SHOWVALUE, self.resurrectionTime, self.ResurrectionPBX, self.ResurrectionPBY, 120, 16, GEUtil.CColor( 220, 220, 220, 240 ) )
#Start Resurrection Timer
resurrectionTimer.Start(self.resurrectionTime,False)
def OnCaptureAreaExited( self, area, player ):
if(area.GetTeamNumber() == player.GetTeamNumber()):
#Remove player from the area's user list
self.inUseResurrectionAreas[area.GetGroupName()].remove(player)
#Remove the resurrection progress progress bar from the player's screen
GEUtil.RemoveHudProgressBar(player,self.ResurrectionPBIndex)
#If the area's user list is now empty, delete it
if(len(self.inUseResurrectionAreas[area.GetGroupName()]) == 0):
del self.inUseResurrectionAreas[area.GetGroupName()]
def ResurrectionTimerTick( self, timer, update_type ):
areasName = timer.GetName()[2:]
#Area still in use?
if(update_type != Timer.UPDATE_STOP and self.inUseResurrectionAreas.has_key(areasName)):
#Update each user's resurrection progress GUI
for areaUser in self.inUseResurrectionAreas[areasName]:
if(update_type == Timer.UPDATE_FINISH):
GEUtil.RemoveHudProgressBar(areaUser,self.ResurrectionPBIndex)
else:
GEUtil.UpdateHudProgressBar(areaUser,self.ResurrectionPBIndex,int(timer.GetCurrentTime()))
if(update_type == Timer.UPDATE_FINISH):
#Get area's team
areasTeam = int(timer.GetName()[0])
#Resurrect player
resurrectedPlayer = None
teamString = ""
if(areasTeam == GEGlobal.TEAM_MI6):
resurrectedPlayer = self.mResurrectionQueue.popleft()
teamString = "MI6"
else:
resurrectedPlayer = self.jResurrectionQueue.popleft()
teamString = "Janus"
self.resurrectPlayer(resurrectedPlayer)
#Update player bounty
self.UpdatePlayerBountyResurrection(resurrectedPlayer)
#Emit player resurrected event
if(resurrectedPlayer.__class__.__name__ != "CGEBotPlayer"):
GEUtil.EmitGameplayEvent("DieAnotherDay_resurrection", "%s" % resurrectedPlayer.GetName(),"%i" % resurrectedPlayer.GetTeamNumber())
#Announce event in console
if(resurrectedPlayer.__class__.__name__ != "CGEBotPlayer"):
GEUtil.Msg("Player resurrected: " + resurrectedPlayer.GetName() + " " + teamString)
#Delete the resurrection area
del self.inUseResurrectionAreas[areasName]
self.tokenManager.RemoveCaptureArea(areasName)
#WARNING:The following statement MUST be executed before this function can be interrupted for the execution of the OnRoundEnd() function:
self.rAreaIDs.remove(areasName)
#Activated if the timer hasn't expired in this tick and it's area no longer has users:
elif(update_type != Timer.UPDATE_STOP):
timer.Stop()
def resurrectPlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,False)
def getTeamsRadarColor(self,teamNumber):
if(teamNumber == GEGlobal.TEAM_MI6): return self.COLOR_MI6_RADAR
else: return self.COLOR_JANUS_RADAR
def OnThink( self ):
if GEMPGameRules.GetNumActivePlayers() < 2:
self.waitingForPlayers = True
return
if self.waitingForPlayers:
self.waitingForPlayers = False
GEUtil.HudMessage( None, "#GES_GP_GETREADY", -1, -1, GEUtil.CColor( 255, 255, 255, 255 ), 2.5 )
GEMPGameRules.EndRound( False )
#Check to see if the round is over!:
#check to see if each team has a player...
self.inPlayMPlayers = []
self.inPlayJPlayers = []
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
player = GEPlayer.GetMPPlayer( i )
if self.IsInPlay( player ):
if player.GetTeamNumber() == GEGlobal.TEAM_MI6:
self.inPlayMPlayers.append( player )
elif player.GetTeamNumber() == GEGlobal.TEAM_JANUS:
self.inPlayJPlayers.append( player )
numMI6Players = len( self.inPlayMPlayers )
numJanusPlayers = len( self.inPlayJPlayers )
if numMI6Players == 0 and numJanusPlayers == 0:
GEMPGameRules.EndRound()
elif numMI6Players == 0 and numJanusPlayers > 0:
janus = GEMPGameRules.GetTeam( GEGlobal.TEAM_JANUS )
janus.IncrementMatchScore( 5 )
GEMPGameRules.SetTeamWinner( janus )
GEMPGameRules.EndRound()
elif numMI6Players > 0 and numJanusPlayers == 0:
mi6 = GEMPGameRules.GetTeam( GEGlobal.TEAM_MI6 )
mi6.IncrementMatchScore( 5 )
GEMPGameRules.SetTeamWinner( mi6 )
GEMPGameRules.EndRound()
def CanPlayerRespawn( self, player ):
if self.pltracker.GetValue( player, self.TR_ELIMINATED ):
player.SetScoreBoardColor( GEGlobal.SB_COLOR_ELIMINATED )
return False
player.SetScoreBoardColor( GEGlobal.SB_COLOR_NORMAL )
return True
def InitializePlayerBounty( self ):
if self.mi6Bounty == 0 and self.janusBounty == 0:
self.mi6Bounty = GEMPGameRules.GetNumInRoundTeamPlayers( GEGlobal.TEAM_MI6 )
self.janusBounty = GEMPGameRules.GetNumInRoundTeamPlayers( GEGlobal.TEAM_JANUS )
GEUtil.InitHudProgressBar( GEGlobal.TEAM_MI6, self.MBountyPBIndex, "Janus: ", GEGlobal.HUDPB_SHOWVALUE, self.janusBounty, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
GEUtil.InitHudProgressBar( GEGlobal.TEAM_MI6, self.JBountyPBIndex, "MI6: ", GEGlobal.HUDPB_SHOWVALUE, self.mi6Bounty, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
GEUtil.InitHudProgressBar( GEGlobal.TEAM_JANUS, self.MBountyPBIndex, "Janus: ", GEGlobal.HUDPB_SHOWVALUE, self.janusBounty, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
GEUtil.InitHudProgressBar( GEGlobal.TEAM_JANUS, self.JBountyPBIndex, "MI6: ", GEGlobal.HUDPB_SHOWVALUE, self.mi6Bounty, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
def UpdatePlayerBountyKilled( self, victim ):
if victim.GetTeamNumber() == GEGlobal.TEAM_JANUS:
self.janusBounty -= 1
else:
self.mi6Bounty -= 1
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_MI6, self.JBountyPBIndex, self.janusBounty )
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_MI6, self.MBountyPBIndex, self.mi6Bounty )
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_JANUS, self.JBountyPBIndex, self.janusBounty )
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_JANUS, self.MBountyPBIndex, self.mi6Bounty )
def UpdatePlayerBountyResurrection( self, player ):
if player.GetTeamNumber() == GEGlobal.TEAM_JANUS:
self.janusBounty += 1
else:
self.mi6Bounty += 1
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_MI6, self.JBountyPBIndex, self.janusBounty )
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_MI6, self.MBountyPBIndex, self.mi6Bounty )
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_JANUS, self.JBountyPBIndex, self.janusBounty )
GEUtil.UpdateHudProgressBar( GEGlobal.TEAM_JANUS, self.MBountyPBIndex, self.mi6Bounty )
def IsInPlay( self, player ):
return player.GetTeamNumber() is not GEGlobal.TEAM_SPECTATOR and self.pltracker.GetValue( player, self.TR_SPAWNED ) and not self.pltracker.GetValue( player, self.TR_ELIMINATED )
def GetTeamPlay(self):
return GEGlobal.TEAMPLAY_ALWAYS
def OnPlayerSpawn( self, player ):
# Record us as "spawned"
if player.GetTeamNumber() != GEGlobal.TEAM_SPECTATOR:
self.pltracker.SetValue( player, self.TR_SPAWNED, True )
if player.IsInitialSpawn():
# If we spawned mid-round let them know why they can't play
if not self.IsInPlay( player ):
GEUtil.PopupMessage( player, "#GES_GPH_CANTJOIN_TITLE", "#GES_GPH_CANTJOIN" )
#TODO Use UI Language Files
GEUtil.PopupMessage( player, "Die Another Day", "Eliminate your opponents and resurrect your eliminated team mates." )
#Why does this not work? :
#Only show team mates on the local player's radar
if(GEMPGameRules.GetRadar().IsRadarContact(player)):
if(player.GetTeamNumber() != GEPlayer.GetMPPlayer(1).GetTeamNumber()):
GEMPGameRules.GetRadar().DropRadarContact(player)Your level of rigor is most impressive!
To answer your question, you cannot use the notion of "local player" when you are on the server. There is no such thing. The local player only exists from the client's side. There is a console command to disable enemy teams being shown on the radar (ge_radar_showenemyteam 0). Add this command to your script's config file:
gesource/cfg/dieanotherday.cfg
When you call GEPlayer.GetMPPlayer(1) you are actually looking at entity slot 1 and if a player is in that slot it returns the player instance. As your code is written, if three people are in the server and the first player to have joined quits, the code will throw an AttributeError because you will then be accessing a NoneType object.
Do you have any suggestions for API improvement?
from . import GEScenario
from GamePlay.Utils.GEPlayerTracker import GEPlayerTracker
from Utils.GETimer import TimerTracker, Timer
from collections import defaultdict
import GEPlayer, GEUtil, GEMPGameRules, GEGlobal
USING_API = GEGlobal.API_VERSION_1_0_0
'''
I chose to implement this mode by editing the "You Only Live Twice" mode script. So
this script uses lots of code that was created by the author(s) of the YOLT script.
I've also reused code from the "Capture The Key" mode's script.
Unresolved bugs:
* When an eliminated & unspawned player changes their team to spectator, there is a problem with their spectator view.
* Multiple resurrection entities can spawn at the same spawn point.
@author: Joe
@version: Dev 21.00 (19/11/12 16:03 GMT)
'''
class DieAnotherDay( GEScenario ):
MRE_MODEL = "models/players/bond/bond.mdl"
JRE_MODEL = "models/players/jaws/jaws.mdl"
COLOR_MI6_RADAR = GEUtil.Color( 94, 171, 231, 255 )
COLOR_JANUS_RADAR = GEUtil.Color( 206, 43, 43, 255 )
JBountyFontColour = GEUtil.CColor( 206, 43, 43, 255 )
MBountyFontColour = GEUtil.CColor( 100, 184, 234, 220 )
#Progress bar positions
MBountyPBX = 0.4
MBountyPBY = 0
JBountyPBX = 0.6
JBountyPBY = 0
ResurrectionPBX = -1
ResurrectionPBY = 0.6
#-------------------------
resurrectionTime = 5.0
TR_ELIMINATED = "eliminated"
TR_SPAWNED = "spawned"
TOKEN_MI6 = 'token_mi6'
TOKEN_JANUS = 'token_janus'
#Progress Bar Indexs
MBountyPBIndex = 0
JBountyPBIndex = 1
ResurrectionPBIndex = 2
def __init__( self ):
super( DieAnotherDay, self ).__init__()
self.eliminateNewPlayers = False
self.waitingForPlayers = False
self.radarSet = False
self.mi6Bounty = 0
self.janusBounty = 0
self.pltracker = GEPlayerTracker( self )
self.timerTracker = TimerTracker( self )
self.tokenManager = GEMPGameRules.GetTokenMgr()
self.inPlayMPlayers = []
self.inPlayJPlayers = []
self.changingTeamPlayers = {}
#Eliminated player collections
self.mResurrectionQueue = []
self.jResurrectionQueue = []
self.eliminatedSpectators = []
#Collections related to resurrection area entities
self.mAreas = {}
self.jAreas = {}
self.resurrectionAreaUserLists = defaultdict(list)
self.mResurrectionAreasUseStates = {}
self.jResurrectionAreasUseStates = {}
def OnLoadGamePlay( self ):
GEUtil.PrecacheModel( self.MRE_MODEL )
GEUtil.PrecacheModel( self.JRE_MODEL )
def Cleanup( self ):
super( DieAnotherDay, self ).Cleanup()
self.pltracker = None
def GetPrintName( self ):
return "Die Another Day"
def GetScenarioHelp( self, help_obj ):
#TODO use UI Language Files:
help_obj.SetDescription(
"""
Based on: Mefy's MOHAA Freeze Tag Mode
Version: Dev 19.00
*Eliminate the opposing team.
*Resurrect your eliminated team mates.
*To resurrect a team mate stand next
to them.
The ability to resurrect players from
a long distance will be added in
version 2.00, if it can be implemented.
""")
def GetGameDescription( self ):
return "Die Another Day"
def OnPlayerConnect( self, player ):
self.pltracker.SetValue( player, self.TR_SPAWNED, False )
def OnPlayerDisconnect( self, player ):
team = player.GetTeamNumber()
if team != GEGlobal.TEAM_SPECTATOR:
self.updateTeamsMaxPlayers(team) #Will the diconnecting player still be counted?
if self.isEliminatedPlayer(player): self.deleteNotInUseResurrectionEntityFromTeam(team)
else: self.decreaseTeamBounty(team)
def isEliminatedPlayer(self,player):
return self.pltracker.GetValue(player,self.TR_ELIMINATED)
#-------------------------------
def CanPlayerChangeTeam(self,player,oldTeam,newTeam ):
if oldTeam == GEGlobal.TEAM_NONE: return True
elif oldTeam == GEGlobal.TEAM_SPECTATOR and player.IsInitialSpawn(): self.newPlayerWantsToJoinTeam(player,newTeam)
elif oldTeam == GEGlobal.TEAM_SPECTATOR: self.spectatorWantsToJoinTeam(player,newTeam)
elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam != GEGlobal.TEAM_SPECTATOR: self.playerWantsToChangeTheirTeam(player,oldTeam,newTeam)
elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam == GEGlobal.TEAM_SPECTATOR:
#EPILEPSY WARNING: The view bug caused by an eliminated player becoming a spectator may be capable of causing epileptic seizures.
if self.isEliminatedPlayer(player):
GEUtil.PopupMessage(player, "You can't become a spectator","If eliminated players became spectators in this version, a bug would occur.")
GEUtil.ClientPrint(player,GEGlobal.HUD_PRINTTALK,"You can't become a spectator:A bug would occur if eliminated players could become spectators.")
return False
else: self.playerWantsToBecomeSpectator(player,oldTeam)
return True
def newPlayerWantsToJoinTeam(self,player,newTeam):
if self.eliminateNewPlayers:
#TODO use language files
GEUtil.PopupMessage(player, "You Can't Spawn Yet","To prevent resurrection rejoins, new players won't spawn until a team mate spawns them.")
self.eliminatePlayer(player)
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else: self.increaseTeamBounty(newTeam)
def playerWantsToChangeTheirTeam(self,player,oldTeam,newTeam):
self.changingTeamPlayers[player] = oldTeam
if self.isEliminatedPlayer(player):
self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
self.removePlayerFromTeamsRQueue(player,oldTeam)
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else:
self.decreaseTeamBounty(oldTeam)
self.increaseTeamBounty(newTeam)
def playerWantsToBecomeSpectator(self,player,oldTeam):
self.changingTeamPlayers[player] = GEGlobal.TEAM_SPECTATOR
self.decreaseTeamBounty(oldTeam)
#if self.isEliminatedPlayer(player):
#self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
#self.removePlayerFromTeamsRQueue(player,oldTeam)
#else: self.decreaseTeamBounty(oldTeam)
def spectatorWantsToJoinTeam(self,player,newTeam):
if self.isEliminatedPlayer(player):
#TODO use language files
GEUtil.PopupMessage(player, "You Can't Spawn Yet","You will have to wait for a team mate to spawn you because you were eliminated before becoming a specator.")
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else: self.increaseTeamBounty(newTeam)
#-------------------------------
def deleteNotInUseResurrectionEntityFromTeam(self,entitysTeam):
teamsResurrectionAreaUseStates = None
if entitysTeam == GEGlobal.TEAM_MI6: teamsResurrectionAreaUseStates = self.mResurrectionAreasUseStates
else: teamsResurrectionAreaUseStates = self.jResurrectionAreasUseStates
for currentAreaKey in teamsResurrectionAreaUseStates.keys():
if teamsResurrectionAreaUseStates[currentAreaKey] == False: #== not in use
teamsResurrectionAreaUseStates.pop(currentAreaKey)
self.deleteResurrectionArea(currentAreaKey,entitysTeam)
break
def deleteResurrectionArea(self,areasName,areasTeam):
if areasTeam == GEGlobal.TEAM_MI6: del self.mAreas[areasName]
else: del self.jAreas[areasName]
self.tokenManager.RemoveCaptureArea(areasName)
if areasName in self.resurrectionAreaUserLists: del self.resurrectionAreaUserLists[areasName]
#Delete the resurrection area's use record if it hasn't been deleted already:
if self.mResurrectionAreasUseStates.has_key(areasName) or self.jResurrectionAreasUseStates.has_key(areasName):
if areasTeam == GEGlobal.TEAM_MI6: del self.mResurrectionAreasUseStates[areasName]
else: del self.jResurrectionAreasUseStates[areasName]
def eliminatePlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,True)
def announceElimination(self,victim,killer):
#Emit "Player Eliminated" event
GEUtil.EmitGameplayEvent( "DieAnotherDay_eliminated", "%i" % victim.GetUserID(), "%i" % killer.GetUserID())
#Tell the victim that they've been eliminated
GEUtil.PopupMessage( victim, "Eliminated", "You have been eliminated. You could be resurrected by a team mate." ) # TODO use UI Language Files
#Tell the other players that a player has been eliminated
#GEUtil.ClientPrint(None,GEGlobal.HUD_PRINTTALK, "An %s player has been eliminated.",teamString) #TODO use UI Language Files
def getTeamString(self,teamNumber):
if(teamNumber == GEGlobal.TEAM_MI6): return "MI6"
elif(teamNumber == GEGlobal.TEAM_JANUS): return "Janus"
else: return "Spectator"
def addPlayerToResurrectionQueue(self,player,team):
if team == GEGlobal.TEAM_MI6: self.mResurrectionQueue.append(player)
else: self.jResurrectionQueue.append(player)
def removePlayerFromTeamsRQueue(self,player,team):
if team == GEGlobal.TEAM_MI6: self.mResurrectionQueue.remove(player)
else: self.jResurrectionQueue.remove(player)
def spawnNewResurrectionEntity(self,victim,team):
#Create a new resurrection area id
areaID = str(victim.GetUserID())
#Spawn a new resurrection area
self.spawnResurrectionEntity(areaID,team)
if team == GEGlobal.TEAM_MI6: self.mResurrectionAreasUseStates[areaID] = False
else: self.jResurrectionAreasUseStates[areaID] = False
#Added to radar in CaptureAreaSpawned()
def respawnResurrectionEntity(self,areaID,team):
self.tokenManager.RemoveCaptureArea(areaID)
self.spawnResurrectionEntity(areaID,team)
def spawnResurrectionEntity(self,areaID,team):
#Get Model Name
modelName = None
if team == GEGlobal.TEAM_MI6: modelName = self.MRE_MODEL
else: modelName = self.JRE_MODEL
#Spawn resurrection entity
self.tokenManager.SetupCaptureArea(areaID,
model=modelName,
limit=1, location=GEGlobal.SPAWN_PLAYER,
rqd_team=team)
def OnPlayerSpawn(self,player):
playersTeam = player.GetTeamNumber()
if playersTeam != GEGlobal.TEAM_SPECTATOR:
if self.changingTeamPlayers.has_key(player):
#update the max players in their new team's bounty progress bar:
self.updateTeamsMaxPlayers(playersTeam)
#update the max players in their old team's bounty progress bar:
if self.changingTeamPlayers[player] != GEGlobal.TEAM_SPECTATOR: self.updateTeamsMaxPlayers(self.changingTeamPlayers[player])
self.changingTeamPlayers.remove(player)
if player in self.eliminatedSpectators:
self.spawnNewResurrectionEntity(player,playersTeam)
self.updateTeamsMaxPlayers(playersTeam)
self.eliminatedSpectators.remove(player)
#If can spawn:
else:
self.pltracker.SetValue( player, self.TR_SPAWNED,True)
#TODO Use UI Language Files
GEUtil.PopupMessage( player, "Die Another Day", "Eliminate your opponents and resurrect your eliminated team mates." )
def OnRoundBegin( self ):
self.mi6Bounty = 0
self.janusBounty = 0
if not self.waitingForPlayers:
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
self.pltracker.SetValue( GEPlayer.GetMPPlayer( i ), self.TR_ELIMINATED, False )
GEMPGameRules.ResetAllPlayerDeaths()
GEMPGameRules.ResetAllPlayersScores()
def OnRoundEnd( self ):
self.eliminateNewPlayers = False
GEMPGameRules.GetRadar().DropAllContacts()
self.timerTracker.RemoveTimer(None) #Stop all timers
#Remove all progress bars
GEUtil.RemoveHudProgressBar( None,self.MBountyPBIndex)
GEUtil.RemoveHudProgressBar( None,self.JBountyPBIndex)
GEUtil.RemoveHudProgressBar( None,self.ResurrectionPBIndex)
#Empty resurrection qeues
del self.mResurrectionQueue[:]
del self.jResurrectionQueue[:]
self.deleteAllCaptureAreasAndTheirCollections()
def deleteAllCaptureAreasAndTheirCollections(self):
for areaID in self.mAreas.keys(): self.tokenManager.RemoveCaptureArea(areaID)
for areaID in self.jAreas.keys(): self.tokenManager.RemoveCaptureArea(areaID)
self.resurrectionAreaUserLists.clear()
self.mResurrectionAreasUseStates.clear()
self.jResurrectionAreasUseStates.clear()
self.mAreas.clear()
self.jAreas.clear()
def OnPlayerKilled( self, victim, killer, weapon ):
super( DieAnotherDay, self ).OnPlayerKilled( victim, killer, weapon )
self.InitializePlayerBounty()
self.eliminateNewPlayers = True
#Don't allow player's to accidentally/intentionally eliminate their team mates
if killer.GetTeamNumber() != victim.GetTeamNumber():
victimsTeam = victim.GetTeamNumber()
self.eliminatePlayer(victim)
self.spawnNewResurrectionEntity(victim,victimsTeam)
self.addPlayerToResurrectionQueue(victim,victimsTeam)
self.announceElimination(victim,killer)
self.decreaseTeamBounty(victim.GetTeamNumber())
if self.playerNotBot(victim):
queuePosition = None
if victimsTeam == GEGlobal.TEAM_MI6: queuePosition = self.mResurrectionQueue.index(victim)
else: queuePosition = self.jResurrectionQueue.index(victim)
#TODO use language files
self.tellPlayerWhatTheirResurrectionQueuePositionIs(victim,queuePositionP=queuePosition)
def OnCaptureAreaSpawned( self, area ):
areasTeam = area.GetTeamNumber()
#Map the new area object to its name a collection
if areasTeam == GEGlobal.TEAM_MI6: self.mAreas[area.GetGroupName()] = area
else: self.jAreas[area.GetGroupName()] = area
colour = None
radar = GEMPGameRules.GetRadar()
if area.GetTeamNumber() == GEGlobal.TEAM_MI6: colour = self.COLOR_MI6_RADAR
else: colour = self.COLOR_JANUS_RADAR
radar.AddRadarContact(area,GEGlobal.RADAR_TYPE_OBJECTIVE,True,"sprites/hud/radar/capture_point",colour)
radar.SetupObjective(area,area.GetTeamNumber(),"", "",colour, 0, False )
def OnCaptureAreaEntered( self, area, player, token ):
if area.GetTeamNumber() == player.GetTeamNumber():
areasTeam = area.GetTeamNumber()
#Add player to area's user list
self.resurrectionAreaUserLists[area.GetGroupName()].append(player)
#Set areas associated use state to: in use
if areasTeam == GEGlobal.TEAM_MI6: self.mResurrectionAreasUseStates[area.GetGroupName()] = True
else: self.jResurrectionAreasUseStates[area.GetGroupName()] = True
#Create & configure resurrection timer & Give it the area's name and team
resurrectionTimer = self.timerTracker.CreateTimer(str(areasTeam) + "," + area.GetGroupName())
resurrectionTimer.SetUpdateCallback(self.ResurrectionTimerTick,1.0)
resurrectionTimer.SetAgeRate(1.0,0)
#Create a resurrection progress bar on the player's screen TODO: use language files
GEUtil.InitHudProgressBar(player,self.ResurrectionPBIndex, "Resurrecting Team Mate...", GEGlobal.HUDPB_SHOWVALUE, self.resurrectionTime, self.ResurrectionPBX, self.ResurrectionPBY, 120, 16, GEUtil.CColor( 220, 220, 220, 240 ) )
#Start the resurrection timer
resurrectionTimer.Start(self.resurrectionTime,False)
def OnCaptureAreaExited( self, area, player ):
areasTeam = area.GetTeamNumber()
if areasTeam == player.GetTeamNumber():
#Remove player from the area's user list
self.resurrectionAreaUserLists[area.GetGroupName()].remove(player)
#Remove the resurrection progress progress bar from the player's screen
GEUtil.RemoveHudProgressBar(player,self.ResurrectionPBIndex)
#If the area's now has no users
if len(self.resurrectionAreaUserLists[area.GetGroupName()]) == 0:
#Delete its user list
del self.resurrectionAreaUserLists[area.GetGroupName()]
#Set its associated use state to: not in use
if areasTeam == GEGlobal.TEAM_MI6: self.mResurrectionAreasUseStates[area.GetGroupName()] = False
else: self.jResurrectionAreasUseStates[area.GetGroupName()] = False
def ResurrectionTimerTick( self, timer, update_type ):
areasName = timer.GetName()[2:]
#Area still in use?
if update_type != Timer.UPDATE_STOP and self.resurrectionAreaUserLists.has_key(areasName):
#Update each user's resurrection progress GUI
for areaUser in self.resurrectionAreaUserLists[areasName]:
if update_type == Timer.UPDATE_FINISH:
GEUtil.RemoveHudProgressBar(areaUser,self.ResurrectionPBIndex)
else:
GEUtil.UpdateHudProgressBar(areaUser,self.ResurrectionPBIndex,int(timer.GetCurrentTime()))
if update_type == Timer.UPDATE_FINISH:
#Get area's team
areasTeam = int(timer.GetName()[0])
teamString = self.getTeamString(areasTeam)
#Delete the resurrection area
self.deleteResurrectionArea(areasName,areasTeam)
#Choose player to be resurrected.
resurrectedPlayer = None
if areasTeam == GEGlobal.TEAM_MI6 and len(self.mResurrectionQueue) != 0: resurrectedPlayer = self.mResurrectionQueue.pop(0)
elif len(self.jResurrectionQueue) != 0: resurrectedPlayer = self.jResurrectionQueue.pop(0)
#If for some reason there is no player to resurrect, don't resurrect anyone.
if resurrectedPlayer != None:
#Resurrect player and respond to their resurrection
self.resurrectPlayer(resurrectedPlayer)
#Update player bounty
self.increaseTeamBounty(areasTeam)
#Update resurrection queue progress bars for team mates
self.resurrectionQueueUpdateNotify(areasTeam)
if self.playerNotBot(resurrectedPlayer):
#Remove resurrected player's resurrection queue progress bar
GEUtil.RemoveHudProgressBar(resurrectedPlayer,self.ResurrectionPBIndex)
#Emit player resurrected event
GEUtil.EmitGameplayEvent("DieAnotherDay_resurrection", "%s" % resurrectedPlayer.GetName(),"%s" % teamString)
#Announce event in console
GEUtil.Msg("A " + teamString + " player has been resurrected: " + resurrectedPlayer.GetName())
#Announce resurrection
GEUtil.ClientPrint(None, GEGlobal.HUD_PRINTTALK,"A " + teamString + " player has been resurrected.")
#If there are now no eliminated players, allow new players to join without needing
#to be spawned by their team mates.
numberOfMPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_MI6)
numberOfJPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_JANUS)
if numberOfMPlayers == self.mi6Bounty and numberOfJPlayers == self.janusBounty: self.eliminatedSpectators = False
#Activated if the timer hasn't expired in this tick and it's area no longer has users:
elif update_type != Timer.UPDATE_STOP:
timer.Stop()
def resurrectionQueueUpdateNotify(self,team):
resurrectionQueue = None
if(team == GEGlobal.TEAM_MI6): resurrectionQueue = self.mResurrectionQueue
else: resurrectionQueue = self.jResurrectionQueue
for player in resurrectionQueue:
if self.playerNotBot(player):
self.tellPlayerWhatTheirResurrectionQueuePositionIs(player,queueP=resurrectionQueue)
def tellPlayerWhatTheirResurrectionQueuePositionIs(self,player,queueP=None,queuePositionP=None):
if queuePositionP == None and queueP != None: queuePositionP = queueP.index(player)
if queuePositionP != None :
GEUtil.ClientPrint(player,GEGlobal.HUD_PRINTCONSOLE,"Team mates who will be resurrected before you = ")
GEUtil.PopupMessage(player, "Resurrection Queue", "Team mates who will be resurrected before you = " + str(queuePositionP))
def playerNotBot(self,player):
return player.__class__.__name__ != "CGEBotPlayer"
def resurrectPlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,False)
def getTeamsRadarColor(self,teamNumber):
if teamNumber == GEGlobal.TEAM_MI6: return self.COLOR_MI6_RADAR
else: return self.COLOR_JANUS_RADAR
def OnThink( self ):
if GEMPGameRules.GetNumActivePlayers() < 2:
self.waitingForPlayers = True
return
if self.waitingForPlayers:
self.waitingForPlayers = False
GEUtil.HudMessage( None, "#GES_GP_GETREADY", -1, -1, GEUtil.CColor( 255, 255, 255, 255 ), 2.5 )
GEMPGameRules.EndRound( False )
#Check to see if the round is over!:
#check to see if each team has a player...
self.inPlayMPlayers = []
self.inPlayJPlayers = []
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
player = GEPlayer.GetMPPlayer( i )
if self.IsInPlay( player ):
if player.GetTeamNumber() == GEGlobal.TEAM_MI6:
self.inPlayMPlayers.append( player )
elif player.GetTeamNumber() == GEGlobal.TEAM_JANUS:
self.inPlayJPlayers.append( player )
numMI6Players = len( self.inPlayMPlayers )
numJanusPlayers = len( self.inPlayJPlayers )
if numMI6Players == 0 and numJanusPlayers == 0:
GEMPGameRules.EndRound()
elif numMI6Players == 0 and numJanusPlayers > 0:
janus = GEMPGameRules.GetTeam( GEGlobal.TEAM_JANUS )
janus.IncrementMatchScore( 5 )
GEMPGameRules.SetTeamWinner( janus )
GEMPGameRules.EndRound()
elif numMI6Players > 0 and numJanusPlayers == 0:
mi6 = GEMPGameRules.GetTeam( GEGlobal.TEAM_MI6 )
mi6.IncrementMatchScore( 5 )
GEMPGameRules.SetTeamWinner( mi6 )
GEMPGameRules.EndRound()
def CanPlayerRespawn( self, player ):
if self.isEliminatedPlayer(player):
player.SetScoreBoardColor( GEGlobal.SB_COLOR_ELIMINATED )
return False
player.SetScoreBoardColor( GEGlobal.SB_COLOR_NORMAL )
return True
def InitializePlayerBounty( self ):
if self.mi6Bounty == 0 and self.janusBounty == 0:
self.mi6Bounty = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_MI6)
self.janusBounty = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_JANUS)
GEUtil.InitHudProgressBar(None,self.MBountyPBIndex,"MI6: ",GEGlobal.HUDPB_SHOWVALUE, self.mi6Bounty, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus: ",GEGlobal.HUDPB_SHOWVALUE, self.janusBounty, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
def updateTeamsMaxPlayers(self,team):
numberOfPlayersInTeam = GEMPGameRules.GetNumInRoundTeamPlayers(team)
if team == GEGlobal.TEAM_MI6:
GEUtil.RemoveHudProgressBar(None,self.MBountyPBIndex)
GEUtil.InitHudProgressBar(None, self.MBountyPBIndex,"MI6: ", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
else:
GEUtil.RemoveHudProgressBar(None,self.JBountyPBIndex)
GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus: ", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
def decreaseTeamBounty(self,team):
if team == GEGlobal.TEAM_JANUS: self.janusBounty -= 1
else: self.mi6Bounty -= 1
self.updateDisplayedBounties()
def increaseTeamBounty(self,team):
if team == GEGlobal.TEAM_JANUS: self.janusBounty += 1
else: self.mi6Bounty += 1
self.updateDisplayedBounties()
def updateDisplayedBounties(self):
GEUtil.UpdateHudProgressBar(None,self.JBountyPBIndex,self.janusBounty)
GEUtil.UpdateHudProgressBar(None,self.MBountyPBIndex,self.mi6Bounty)
def IsInPlay( self, player ):
return player.GetTeamNumber() is not GEGlobal.TEAM_SPECTATOR and self.pltracker.GetValue( player, self.TR_SPAWNED ) and not self.pltracker.GetValue( player, self.TR_ELIMINATED )
def GetTeamPlay(self):
return GEGlobal.TEAMPLAY_ALWAYS
I can add getting the steam id to my list of python API enhancements.
from . import GEScenario
from GamePlay.Utils.GEPlayerTracker import GEPlayerTracker
from Utils.GETimer import TimerTracker, Timer
from collections import defaultdict
import GEPlayer, GEUtil, GEMPGameRules, GEGlobal
USING_API = GEGlobal.API_VERSION_1_0_0
'''
I chose to implement this mode by editing the "You Only Live Twice" mode script. So
this script uses lots of code that was created by the author(s) of the YOLT script.
I've also reused code from the "Capture The Key" mode's script.
Unresolved bugs:
* When an eliminated & unspawned player changes their team to spectator, there is a problem with their spectator view.
@author: Joe
@version: Dev 24.00 (22/11/12 0:31 GMT)
'''
class DieAnotherDay( GEScenario ):
MRE_MODEL = "models/players/bond/bond.mdl"
JRE_MODEL = "models/players/jaws/jaws.mdl"
COLOR_MI6_RADAR = GEUtil.Color( 94, 171, 231, 255 )
COLOR_JANUS_RADAR = GEUtil.Color( 206, 43, 43, 255 )
JBountyFontColour = GEUtil.CColor( 206, 43, 43, 255 )
MBountyFontColour = GEUtil.CColor( 100, 184, 234, 220 )
#Progress bar positions
MBountyPBX = 0.4
MBountyPBY = 0
JBountyPBX = 0.6
JBountyPBY = 0
ResurrectionPBX = -1
ResurrectionPBY = 0.6
#-------------------------
resurrectionTime = 5.0
TR_ELIMINATED = "eliminated"
TR_SPAWNED = "spawned"
TOKEN_MI6 = 'token_mi6'
TOKEN_JANUS = 'token_janus'
#Progress Bar Indexs
MBountyPBIndex = 0
JBountyPBIndex = 1
ResurrectionPBIndex = 2
def __init__( self ):
super( DieAnotherDay, self ).__init__()
self.radar = None
self.eliminateNewPlayers = False
self.waitingForPlayers = False
self.radarSet = False
self.mi6Bounty = 0
self.janusBounty = 0
self.pltracker = GEPlayerTracker( self )
self.timerTracker = TimerTracker( self )
self.tokenManager = GEMPGameRules.GetTokenMgr()
self.changingTeamPlayers = {}
#Eliminated player collections
self.mResurrectionQueue = []
self.jResurrectionQueue = []
self.eliminatedSpectators = []
#Collections related to resurrection area entities
self.mAreaIDs = []
self.jAreaIDs = []
self.mAreaLocations = []
self.jAreaLocations = []
self.resurrectionAreaUserLists = defaultdict(list)
def OnLoadGamePlay( self ):
GEUtil.PrecacheModel( self.MRE_MODEL )
GEUtil.PrecacheModel( self.JRE_MODEL )
def Cleanup( self ):
super( DieAnotherDay, self ).Cleanup()
self.pltracker = None
def GetPrintName( self ):
return "Die Another Day"
def GetScenarioHelp( self, help_obj ):
#TODO use UI Language Files:
help_obj.SetDescription(
"""
Based on: Mefy's MOHAA Freeze Tag Mode
Version: Dev 24.00
*Eliminate the opposing team.
*Resurrect your eliminated team mates.
*To resurrect a team mate stand next
to them.
The ability to resurrect players from
a long distance will be added in
version 2.00, if it can be implemented.
""")
def GetGameDescription( self ):
return "Die Another Day"
def OnPlayerConnect( self, player ):
self.pltracker.SetValue( player, self.TR_SPAWNED, False )
def OnPlayerDisconnect( self, player ):
team = player.GetTeamNumber()
if team != GEGlobal.TEAM_SPECTATOR:
self.updateTeamsMaxPlayers(team) #Will the diconnecting player still be counted?
if self.isEliminatedPlayer(player): self.deleteNotInUseResurrectionEntityFromTeam(team)
else: self.decreaseTeamBounty(team)
def isEliminatedPlayer(self,player):
return self.pltracker.GetValue(player,self.TR_ELIMINATED)
#-------------------------------
def CanPlayerChangeTeam(self,player,oldTeam,newTeam ):
if oldTeam == GEGlobal.TEAM_NONE: return True
elif oldTeam == GEGlobal.TEAM_SPECTATOR and player.IsInitialSpawn(): self.newPlayerWantsToJoinTeam(player,newTeam)
elif oldTeam == GEGlobal.TEAM_SPECTATOR: self.spectatorWantsToJoinTeam(player,newTeam)
elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam != GEGlobal.TEAM_SPECTATOR: self.playerWantsToChangeTheirTeam(player,oldTeam,newTeam)
elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam == GEGlobal.TEAM_SPECTATOR:
#EPILEPSY WARNING: The view bug caused by an eliminated player becoming a spectator may be capable of causing epileptic seizures.
if self.isEliminatedPlayer(player):
GEUtil.PopupMessage(player, "You can't become a spectator","If eliminated players became spectators in this version, a bug would occur.")
GEUtil.ClientPrint(player,GEGlobal.HUD_PRINTTALK,"You can't become a spectator:A bug would occur if eliminated players could become spectators.")
return False
else: self.playerWantsToBecomeSpectator(player,oldTeam)
return True
def newPlayerWantsToJoinTeam(self,player,newTeam):
if self.eliminateNewPlayers:
#TODO use language files
GEUtil.PopupMessage(player, "You Can't Spawn Yet","To prevent resurrection rejoins, new players won't spawn until a team mate spawns them.")
self.eliminatePlayer(player)
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else: self.increaseTeamBounty(newTeam)
def playerWantsToChangeTheirTeam(self,player,oldTeam,newTeam):
self.changingTeamPlayers[player] = oldTeam
if self.isEliminatedPlayer(player):
self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
self.removePlayerFromTeamsRQueue(player,oldTeam)
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else:
self.decreaseTeamBounty(oldTeam)
self.increaseTeamBounty(newTeam)
def playerWantsToBecomeSpectator(self,player,oldTeam):
self.changingTeamPlayers[player] = GEGlobal.TEAM_SPECTATOR
self.decreaseTeamBounty(oldTeam)
#if self.isEliminatedPlayer(player):
#self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
#self.removePlayerFromTeamsRQueue(player,oldTeam)
#else: self.decreaseTeamBounty(oldTeam)
def spectatorWantsToJoinTeam(self,player,newTeam):
if self.isEliminatedPlayer(player):
#TODO use language files
GEUtil.PopupMessage(player, "You Can't Spawn Yet","You will have to wait for a team mate to spawn you because you were eliminated before becoming a specator.")
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else: self.increaseTeamBounty(newTeam)
#-------------------------------
def deleteNotInUseResurrectionEntityFromTeam(self,team):
teamsResurrectionAreaIDs = None
if team == GEGlobal.TEAM_MI6: teamsResurrectionAreaIDs = self.mAreaIDs
else: teamsResurrectionAreaIDs = self.jAreaIDs
for areaID in teamsResurrectionAreaIDs:
if not self.areaInUse(areaID):
self.deleteResurrectionArea(areaID,team)
break
def deleteResurrectionArea(self,areasID,areasTeam):
self.resurrectionAreaUserLists.pop(areasID)
if areasTeam == GEGlobal.TEAM_MI6: self.mAreaIDs.remove(areasID)
else: self.jAreaIDs.remove(areasID)
self.tokenManager.RemoveCaptureArea(areasID)
def areaInUse(self,areasID):
return len(self.resurrectionAreaUserLists[areasID]) > 0
def eliminatePlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,True)
def announceElimination(self,victim,killer):
#Emit "Player Eliminated" event
GEUtil.EmitGameplayEvent( "DieAnotherDay_eliminated", "%i" % victim.GetUserID(), "%i" % killer.GetUserID())
#Tell the other players that a player has been eliminated #TODO use UI Language Files
GEUtil.ClientPrint(None,GEGlobal.HUD_PRINTTALK, "A " + self.getTeamString(victim.GetTeamNumber()) + " player has been eliminated.")
def getTeamString(self,teamNumber):
if(teamNumber == GEGlobal.TEAM_MI6): return "MI6"
elif(teamNumber == GEGlobal.TEAM_JANUS): return "Janus"
else: return "Spectator"
def addPlayerToResurrectionQueue(self,player,team):
if team == GEGlobal.TEAM_MI6: self.mResurrectionQueue.append(player)
else: self.jResurrectionQueue.append(player)
def removePlayerFromTeamsRQueue(self,player,team):
if team == GEGlobal.TEAM_MI6: self.mResurrectionQueue.remove(player)
else: self.jResurrectionQueue.remove(player)
def spawnNewResurrectionEntity(self,victim,team):
#Create a new resurrection area id
newAreasID = str(victim.GetUserID())
#Spawn a new resurrection area
self.spawnResurrectionEntity(newAreasID,team)
#Create entries for the new area in resurrection entity collections
if team == GEGlobal.TEAM_MI6: self.mAreaIDs.append(newAreasID)
else: self.jAreaIDs.append(newAreasID)
#Added to radar in CaptureAreaSpawned()
def respawnResurrectionEntity(self,areaID,team):
self.tokenManager.RemoveCaptureArea(areaID)
self.spawnResurrectionEntity(areaID,team)
def spawnResurrectionEntity(self,areaID,team):
#Get Model Name
modelName = None
if team == GEGlobal.TEAM_MI6: modelName = self.MRE_MODEL
else: modelName = self.JRE_MODEL
#Spawn resurrection entity
self.tokenManager.SetupCaptureArea(areaID,
model=modelName,
limit=1, location=GEGlobal.SPAWN_PLAYER,
rqd_team=team)
def OnPlayerSpawn(self,player):
playersTeam = player.GetTeamNumber()
if playersTeam != GEGlobal.TEAM_SPECTATOR:
if self.changingTeamPlayers.has_key(player):
#update the max players in their new team's bounty progress bar:
self.updateTeamsMaxPlayers(playersTeam)
#update the max players in their old team's bounty progress bar:
if self.changingTeamPlayers[player] != GEGlobal.TEAM_SPECTATOR: self.updateTeamsMaxPlayers(self.changingTeamPlayers[player])
self.changingTeamPlayers.remove(player)
if player in self.eliminatedSpectators:
self.spawnNewResurrectionEntity(player,playersTeam)
self.updateTeamsMaxPlayers(playersTeam)
self.eliminatedSpectators.remove(player)
#If can spawn:
else:
self.pltracker.SetValue( player, self.TR_SPAWNED,True)
#TODO Use UI Language Files
GEUtil.PopupMessage( player, "Die Another Day", "Eliminate your opponents and resurrect your eliminated team mates." )
def OnRoundBegin( self ):
self.mi6Bounty = 0
self.janusBounty = 0
self.radar = GEMPGameRules.GetRadar()
if not self.waitingForPlayers:
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
self.pltracker.SetValue( GEPlayer.GetMPPlayer( i ), self.TR_ELIMINATED, False )
GEMPGameRules.ResetAllPlayerDeaths()
GEMPGameRules.ResetAllPlayersScores()
def OnRoundEnd( self ):
self.eliminateNewPlayers = False
self.radar.DropAllContacts()
self.timerTracker.RemoveTimer(None) #Stop all timers
#Remove all progress bars
GEUtil.RemoveHudProgressBar( None,self.MBountyPBIndex)
GEUtil.RemoveHudProgressBar( None,self.JBountyPBIndex)
GEUtil.RemoveHudProgressBar( None,self.ResurrectionPBIndex)
#Empty resurrection queues
del self.mResurrectionQueue[:]
del self.jResurrectionQueue[:]
self.deleteAllCaptureAreasAndTheirCollections()
def deleteAllCaptureAreasAndTheirCollections(self):
for areaID in self.mAreaIDs: self.tokenManager.RemoveCaptureArea(areaID)
for areaID in self.jAreaIDs: self.tokenManager.RemoveCaptureArea(areaID)
self.resurrectionAreaUserLists.clear()
del self.mAreaIDs[:]
del self.jAreaIDs[:]
def OnPlayerKilled( self, victim, killer, weapon ):
super( DieAnotherDay, self ).OnPlayerKilled( victim, killer, weapon )
self.InitializePlayerBounty() #if not initialised already
victimsTeam = victim.GetTeamNumber()
#Don't allow player's to accidentally/intentionally eliminate their team mates
if killer.GetTeamNumber()!= victimsTeam:
self.eliminatePlayer(victim)
self.announceElimination(victim,killer)
self.decreaseTeamBounty(victimsTeam)
#Get the survivor count for the victim's team.
teamsSurvivors = 0
if victimsTeam == GEGlobal.TEAM_MI6: teamsSurvivors = self.mi6Bounty
else: teamsSurvivors = self.janusBounty
#If the victim was the last player alive on their team then don't create a resurrection area because
#the game will be ended by OnThink() when this function has finished.
if teamsSurvivors > 0:
self.eliminateNewPlayers = True
self.spawnNewResurrectionEntity(victim,victimsTeam)
self.addPlayerToResurrectionQueue(victim,victimsTeam)
if self.playerNotBot(victim):
queuePosition = None
if victimsTeam == GEGlobal.TEAM_MI6: queuePosition = self.mResurrectionQueue.index(victim)
else: queuePosition = self.jResurrectionQueue.index(victim)
#TODO use language files
self.tellPlayerWhatTheirResurrectionQueuePositionIs(victim,queuePositionP=queuePosition)
elif teamsSurvivors < 0: GEUtil.Msg("ERROR:OnPlayerKilled():teamsSurvivors < 0: = " + str(teamsSurvivors))
def OnCaptureAreaSpawned( self, area ):
areasTeam = area.GetTeamNumber()
location = area.GetAbsOrigin()
#Recusrive Function Call Loop:
#If the area has spawned at an enemy resurrection area's location respawn it and exit this function call
#because this function will be called again when the area respawns and should only execute statements
#after the respawn IF block, when it is called for an area which has an acceptable location.
if areasTeam == GEGlobal.TEAM_MI6 and location in self.jAreaLocations or areasTeam == GEGlobal.TEAM_JANUS and location in self.mAreaLocations:
self.respawnResurrectionEntity(area.GetGroupName(),areasTeam)
return
colour = None
if area.GetTeamNumber() == GEGlobal.TEAM_MI6:
self.mAreaLocations.append(location)
colour = self.COLOR_MI6_RADAR
else:
self.jAreaLocations.append(location)
colour = self.COLOR_JANUS_RADAR
self.radar.AddRadarContact(area,GEGlobal.RADAR_TYPE_OBJECTIVE,True,"sprites/hud/radar/capture_point",colour)
self.radar.SetupObjective(area,area.GetTeamNumber(),"", "",colour, 0, False )
def OnCaptureAreaEntered( self, area, player, token ):
if area.GetTeamNumber() == player.GetTeamNumber():
areasTeam = area.GetTeamNumber()
#Add player to area's user list, creating if it hasn't been created already
self.resurrectionAreaUserLists[area.GetGroupName()].append(player)
#Create & configure resurrection timer & Give it the area's name and team
resurrectionTimer = self.timerTracker.CreateTimer(str(areasTeam) + "," + area.GetGroupName())
resurrectionTimer.SetUpdateCallback(self.ResurrectionTimerTick,1.0)
resurrectionTimer.SetAgeRate(1.0,0)
#Create a resurrection progress bar on the player's screen TODO: use language files
GEUtil.InitHudProgressBar(player,self.ResurrectionPBIndex, "Resurrecting Team Mate...", GEGlobal.HUDPB_SHOWVALUE, self.resurrectionTime, self.ResurrectionPBX, self.ResurrectionPBY, 120, 16, GEUtil.CColor( 220, 220, 220, 240 ) )
#Start the resurrection timer
resurrectionTimer.Start(self.resurrectionTime,False)
def OnCaptureAreaExited( self, area, player ):
areasTeam = area.GetTeamNumber()
areasName = area.GetGroupName()
if areasTeam == player.GetTeamNumber():
#Remove player from the area's user list
self.resurrectionAreaUserLists[areasName].remove(player)
#Remove the resurrection progress progress bar from the player's screen
GEUtil.RemoveHudProgressBar(player,self.ResurrectionPBIndex)
def ResurrectionTimerTick( self, timer, update_type ):
areasID = timer.GetName()[2:]
#Area still in use?
if update_type != Timer.UPDATE_STOP and self.areaInUse(areasID):
#Update each user's resurrection progress GUI
for areaUser in self.resurrectionAreaUserLists[areasID]:
if update_type == Timer.UPDATE_FINISH:
GEUtil.RemoveHudProgressBar(areaUser,self.ResurrectionPBIndex)
else:
GEUtil.UpdateHudProgressBar(areaUser,self.ResurrectionPBIndex,int(timer.GetCurrentTime()))
if update_type == Timer.UPDATE_FINISH:
#Get area's team
areasTeam = int(timer.GetName()[0])
teamString = self.getTeamString(areasTeam)
#Delete the resurrection area
self.deleteResurrectionArea(areasID,areasTeam)
#Choose player to be resurrected.
resurrectedPlayer = None
if areasTeam == GEGlobal.TEAM_MI6 and len(self.mResurrectionQueue) != 0: resurrectedPlayer = self.mResurrectionQueue.pop(0)
elif len(self.jResurrectionQueue) != 0: resurrectedPlayer = self.jResurrectionQueue.pop(0)
#If for some reason there is no player to resurrect, don't resurrect anyone.
if resurrectedPlayer != None:
#Resurrect player and respond to their resurrection
self.resurrectPlayer(resurrectedPlayer)
#Update player bounty
self.increaseTeamBounty(areasTeam)
#Update resurrection queue progress bars for team mates
self.resurrectionQueueUpdateNotify(areasTeam)
if self.playerNotBot(resurrectedPlayer):
#Remove resurrected player's resurrection queue progress bar
GEUtil.RemoveHudProgressBar(resurrectedPlayer,self.ResurrectionPBIndex)
#Emit player resurrected event
GEUtil.EmitGameplayEvent("DieAnotherDay_resurrection", "%s" % resurrectedPlayer.GetName(),"%s" % teamString)
#Announce event in console
GEUtil.Msg("A " + teamString + " player has been resurrected: " + resurrectedPlayer.GetName())
#Announce resurrection
GEUtil.ClientPrint(None, GEGlobal.HUD_PRINTTALK,"A " + teamString + " player has been resurrected.")
#If there are now no eliminated players, allow new players to join without needing
#to be spawned by their team mates.
numberOfMPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_MI6)
numberOfJPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_JANUS)
if numberOfMPlayers == self.mi6Bounty and numberOfJPlayers == self.janusBounty: self.eliminatedSpectators = False
#Activated if the timer hasn't expired in this tick and it's area no longer has users:
elif update_type != Timer.UPDATE_STOP:
timer.Stop()
def resurrectionQueueUpdateNotify(self,team):
resurrectionQueue = None
if(team == GEGlobal.TEAM_MI6): resurrectionQueue = self.mResurrectionQueue
else: resurrectionQueue = self.jResurrectionQueue
for player in resurrectionQueue:
if self.playerNotBot(player):
self.tellPlayerWhatTheirResurrectionQueuePositionIs(player,queueP=resurrectionQueue)
def tellPlayerWhatTheirResurrectionQueuePositionIs(self,player,queueP=None,queuePositionP=None):
if queuePositionP == None and queueP != None: queuePositionP = queueP.index(player)
if queuePositionP != None :
#TODO use language files
GEUtil.ClientPrint(player,GEGlobal.HUD_PRINTCONSOLE,"Team mates who will be resurrected before you = ")
GEUtil.PopupMessage(player, "You've Been Eliminated", "Team mates who will be resurrected before you = " + str(queuePositionP))
def playerNotBot(self,player):
return player.__class__.__name__ != "CGEBotPlayer"
def resurrectPlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,False)
def getTeamsRadarColor(self,teamNumber):
if teamNumber == GEGlobal.TEAM_MI6: return self.COLOR_MI6_RADAR
else: return self.COLOR_JANUS_RADAR
def OnThink( self ):
if GEMPGameRules.GetNumActivePlayers() < 2:
self.waitingForPlayers = True
return
if self.waitingForPlayers:
self.waitingForPlayers = False
GEUtil.HudMessage( None, "#GES_GP_GETREADY", -1, -1, GEUtil.CColor( 255, 255, 255, 255 ), 2.5 )
GEMPGameRules.EndRound( False )
#Check to see if the round is over!:
#check to see if each team has a player...
inPlayMPlayers = []
inPlayJPlayers = []
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
player = GEPlayer.GetMPPlayer( i )
if self.IsInPlay( player ):
if player.GetTeamNumber() == GEGlobal.TEAM_MI6:
inPlayMPlayers.append( player )
elif player.GetTeamNumber() == GEGlobal.TEAM_JANUS:
inPlayJPlayers.append( player )
numMI6Players = len(inPlayMPlayers)
numJanusPlayers = len(inPlayJPlayers)
if numMI6Players == 0 and numJanusPlayers == 0: GEMPGameRules.EndRound()
elif numMI6Players == 0 and numJanusPlayers > 0: self.teamWins(GEGlobal.TEAM_JANUS)
elif numMI6Players > 0 and numJanusPlayers == 0: self.teamWins(GEGlobal.TEAM_MI6)
def teamWins(self,teamNumber):
team = GEMPGameRules.GetTeam(teamNumber)
team.IncrementMatchScore( 5 )
GEMPGameRules.SetTeamWinner(team)
GEMPGameRules.EndRound()
def CanPlayerRespawn( self, player ):
if self.isEliminatedPlayer(player):
player.SetScoreBoardColor( GEGlobal.SB_COLOR_ELIMINATED )
return False
player.SetScoreBoardColor( GEGlobal.SB_COLOR_NORMAL )
return True
def InitializePlayerBounty( self ):
if self.mi6Bounty == 0 and self.janusBounty == 0:
self.mi6Bounty = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_MI6)
self.janusBounty = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_JANUS)
GEUtil.InitHudProgressBar(None,self.MBountyPBIndex,"MI6: ",GEGlobal.HUDPB_SHOWVALUE, self.mi6Bounty, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus: ",GEGlobal.HUDPB_SHOWVALUE, self.janusBounty, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
def updateTeamsMaxPlayers(self,team):
numberOfPlayersInTeam = GEMPGameRules.GetNumInRoundTeamPlayers(team)
if team == GEGlobal.TEAM_MI6:
GEUtil.RemoveHudProgressBar(None,self.MBountyPBIndex)
GEUtil.InitHudProgressBar(None, self.MBountyPBIndex,"MI6: ", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
else:
GEUtil.RemoveHudProgressBar(None,self.JBountyPBIndex)
GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus: ", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
def decreaseTeamBounty(self,team):
if team == GEGlobal.TEAM_JANUS: self.janusBounty -= 1
else: self.mi6Bounty -= 1
self.updateDisplayedBounties()
def increaseTeamBounty(self,team):
if team == GEGlobal.TEAM_JANUS: self.janusBounty += 1
else: self.mi6Bounty += 1
self.updateDisplayedBounties()
def updateDisplayedBounties(self):
GEUtil.UpdateHudProgressBar(None,self.JBountyPBIndex,self.janusBounty)
GEUtil.UpdateHudProgressBar(None,self.MBountyPBIndex,self.mi6Bounty)
def IsInPlay( self, player ):
return player.GetTeamNumber() is not GEGlobal.TEAM_SPECTATOR and self.pltracker.GetValue( player, self.TR_SPAWNED ) and not self.pltracker.GetValue( player, self.TR_ELIMINATED )
def GetTeamPlay(self):
return GEGlobal.TEAMPLAY_ALWAYS
def CanPlayerChangeTeam(self,player,oldTeam,newTeam ):
# if oldTeam == GEGlobal.TEAM_NONE: return True
# elif oldTeam == GEGlobal.TEAM_SPECTATOR and player.IsInitialSpawn(): self.newPlayerWantsToJoinTeam(player,newTeam)
# elif oldTeam == GEGlobal.TEAM_SPECTATOR: self.spectatorWantsToJoinTeam(player,newTeam)
# elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam != GEGlobal.TEAM_SPECTATOR: self.playerWantsToChangeTheirTeam(player,oldTeam,newTeam)
# elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam == GEGlobal.TEAM_SPECTATOR: self.playerWantsToBecomeSpectator(player,oldTeam)
#self.eliminatePlayer(player)
return True
def CanPlayerRespawn( self, player ):
#if self.isEliminatedPlayer(player):
#player.SetScoreBoardColor( GEGlobal.SB_COLOR_ELIMINATED )
#return False
#player.SetScoreBoardColor( GEGlobal.SB_COLOR_NORMAL )
return False
from . import GEScenario
from GamePlay.Utils.GEPlayerTracker import GEPlayerTracker
from Utils.GETimer import TimerTracker, Timer
from collections import defaultdict
import GEPlayer, GEUtil, GEMPGameRules, GEGlobal
USING_API = GEGlobal.API_VERSION_1_0_0
'''
I chose to implement this mode by editing the "You Only Live Twice" mode script. So
this script uses lots of code that was created by the author(s) of the YOLT script.
I've also reused code from the "Capture The Key" mode's script.
Unresolved bugs:
* When an eliminated & unspawned player changes their team to spectator, there is a problem with their spectator view.
@author: Joe
@version: Bug Test Version
'''
class DieAnotherDay( GEScenario ):
MRE_MODEL = "models/players/bond/bond.mdl"
JRE_MODEL = "models/players/jaws/jaws.mdl"
COLOR_MI6_RADAR = GEUtil.Color( 94, 171, 231, 255 )
COLOR_JANUS_RADAR = GEUtil.Color( 206, 43, 43, 255 )
JBountyFontColour = GEUtil.CColor( 206, 43, 43, 255 )
MBountyFontColour = GEUtil.CColor( 100, 184, 234, 220 )
#Progress bar positions
MBountyPBX = 0.4
MBountyPBY = 0
JBountyPBX = 0.6
JBountyPBY = 0
ResurrectionPBX = -1
ResurrectionPBY = 0.6
#-------------------------
resurrectionTime = 5.0
TR_ELIMINATED = "eliminated"
TR_SPAWNED = "spawned"
TOKEN_MI6 = 'token_mi6'
TOKEN_JANUS = 'token_janus'
#Progress Bar Indexs
MBountyPBIndex = 0
JBountyPBIndex = 1
ResurrectionPBIndex = 2
def __init__( self ):
super( DieAnotherDay, self ).__init__()
self.radar = None
self.eliminateNewPlayers = False
self.waitingForPlayers = False
self.radarSet = False
self.mBounty = 0
self.jBounty = 0
self.pltracker = GEPlayerTracker( self )
self.mBountyMaxPlayers = 0
self.jBountyMaxPlayers = 0
self.timerTracker = TimerTracker( self )
self.tokenManager = GEMPGameRules.GetTokenMgr()
#Eliminated player collections
self.mResurrectionQueue = []
self.jResurrectionQueue = []
self.eliminatedSpectators = []
#Collections related to resurrection area entities
self.mAreaIDs = []
self.jAreaIDs = []
self.mAreaLocations = []
self.jAreaLocations = []
self.resurrectionAreaUserLists = defaultdict(list)
def OnLoadGamePlay( self ):
GEUtil.PrecacheModel( self.MRE_MODEL )
GEUtil.PrecacheModel( self.JRE_MODEL )
self.radar = GEMPGameRules.GetRadar()
def Cleanup( self ):
super( DieAnotherDay, self ).Cleanup()
self.pltracker = None
def GetPrintName( self ):
return "Die Another Day"
def GetScenarioHelp( self, help_obj ):
#TODO use UI Language Files:
help_obj.SetDescription(
"""
Based on: Mefy's MOHAA Freeze Tag Mode
Version: Bug Test Version
*Eliminate the opposing team.
*Resurrect your eliminated team mates.
*To resurrect a team mate stand next
to them.
The ability to resurrect players from
a long distance will be added in
version 2.00, if it can be implemented.
""")
def GetGameDescription( self ):
return "Die Another Day"
def OnPlayerConnect( self, player ):
self.pltracker.SetValue( player, self.TR_SPAWNED, False )
def OnPlayerDisconnect( self, player ):
team = player.GetTeamNumber()
if team != GEGlobal.TEAM_SPECTATOR:
self.decrementTeamsPlayerCount(team)
self.updateTeamsDisplayedMaxPlayers(team)
if self.isEliminatedPlayer(player):
self.deleteNotInUseResurrectionEntityFromTeam(team)
self.removePlayerFromTeamsRQueue(player,team)
else: self.decreaseTeamBounty(team)
def isEliminatedPlayer(self,player):
return self.pltracker.GetValue(player,self.TR_ELIMINATED)
#-------------------------------
def CanPlayerChangeTeam(self,player,oldTeam,newTeam ):
# if oldTeam == GEGlobal.TEAM_NONE: return True
# elif oldTeam == GEGlobal.TEAM_SPECTATOR and player.IsInitialSpawn(): self.newPlayerWantsToJoinTeam(player,newTeam)
# elif oldTeam == GEGlobal.TEAM_SPECTATOR: self.spectatorWantsToJoinTeam(player,newTeam)
# elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam != GEGlobal.TEAM_SPECTATOR: self.playerWantsToChangeTheirTeam(player,oldTeam,newTeam)
# elif oldTeam != GEGlobal.TEAM_SPECTATOR and newTeam == GEGlobal.TEAM_SPECTATOR: self.playerWantsToBecomeSpectator(player,oldTeam)
#self.eliminatePlayer(player)
return True
def newPlayerWantsToJoinTeam(self,player,newTeam):
self.incrementTeamsPlayerCount(newTeam)
if self.eliminateNewPlayers:
#TODO use language files
GEUtil.PopupMessage(player, "You Can't Spawn Yet","To prevent resurrection rejoins, new players won't spawn until a team mate spawns them.")
self.eliminatePlayer(player)
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else: self.increaseTeamBounty(newTeam)
def playerWantsToChangeTheirTeam(self,player,oldTeam,newTeam):
self.incrementTeamsPlayerCount(newTeam)
self.decrementTeamsPlayerCount(oldTeam)
if self.isEliminatedPlayer(player):
self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
self.removePlayerFromTeamsRQueue(player,oldTeam)
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else:
self.decreaseTeamBounty(oldTeam)
self.increaseTeamBounty(newTeam)
def playerWantsToBecomeSpectator(self,player,oldTeam):
self.decrementTeamsPlayerCount(oldTeam)
if self.isEliminatedPlayer(player):
self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
self.removePlayerFromTeamsRQueue(player,oldTeam)
else: self.decreaseTeamBounty(oldTeam)
def spectatorWantsToJoinTeam(self,player,newTeam):
self.incrementTeamsPlayerCount(newTeam)
if self.isEliminatedPlayer(player):
#TODO use language files
GEUtil.PopupMessage(player, "You Can't Spawn Yet","You will have to wait for a team mate to spawn you because you were eliminated before becoming a specator.")
self.spawnNewResurrectionEntity(player,newTeam)
self.addPlayerToResurrectionQueue(player,newTeam)
else: self.increaseTeamBounty(newTeam)
#-------------------------------
def incrementTeamsPlayerCount(self,team):
if team == GEGlobal.TEAM_MI6: self.mBountyMaxPlayers += 1
else: self.jBountyMaxPlayers += 1
def decrementTeamsPlayerCount(self,team):
if team == GEGlobal.TEAM_MI6: self.mBountyMaxPlayers -= 1
else: self.jBountyMaxPlayers -= 1
def deleteNotInUseResurrectionEntityFromTeam(self,team):
teamsResurrectionAreaIDs = None
if team == GEGlobal.TEAM_MI6: teamsResurrectionAreaIDs = self.mAreaIDs
else: teamsResurrectionAreaIDs = self.jAreaIDs
for areaID in teamsResurrectionAreaIDs:
if not self.areaInUse(areaID):
self.deleteResurrectionArea(areaID,team)
break
def deleteResurrectionArea(self,areasID,areasTeam):
self.resurrectionAreaUserLists.pop(areasID)
if areasTeam == GEGlobal.TEAM_MI6: self.mAreaIDs.remove(areasID)
else: self.jAreaIDs.remove(areasID)
self.tokenManager.RemoveCaptureArea(areasID)
def areaInUse(self,areasID):
return len(self.resurrectionAreaUserLists[areasID]) > 0
def eliminatePlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,True)
def announceElimination(self,victim,killer):
#Emit "Player Eliminated" event
GEUtil.EmitGameplayEvent( "DieAnotherDay_eliminated", "%i" % victim.GetUserID(), "%i" % killer.GetUserID())
#Tell the other players that a player has been eliminated #TODO use UI Language Files
GEUtil.ClientPrint(None,GEGlobal.HUD_PRINTTALK, "A " + self.getTeamString(victim.GetTeamNumber()) + " player has been eliminated.")
def getTeamString(self,teamNumber):
if(teamNumber == GEGlobal.TEAM_MI6): return "MI6"
elif(teamNumber == GEGlobal.TEAM_JANUS): return "Janus"
else: return "Spectator"
def addPlayerToResurrectionQueue(self,player,team):
if team == GEGlobal.TEAM_MI6: self.mResurrectionQueue.append(player)
else: self.jResurrectionQueue.append(player)
def removePlayerFromTeamsRQueue(self,player,team):
if team == GEGlobal.TEAM_MI6: self.mResurrectionQueue.remove(player)
else: self.jResurrectionQueue.remove(player)
def spawnNewResurrectionEntity(self,victim,team):
#Create a new resurrection area id
newAreasID = str(victim.GetUserID())
#Spawn a new resurrection area
self.spawnResurrectionEntity(newAreasID,team)
#Create entries for the new area in resurrection entity collections
if team == GEGlobal.TEAM_MI6: self.mAreaIDs.append(newAreasID)
else: self.jAreaIDs.append(newAreasID)
#Added to radar in CaptureAreaSpawned()
def respawnResurrectionEntity(self,areaID,team):
self.tokenManager.RemoveCaptureArea(areaID)
self.spawnResurrectionEntity(areaID,team)
def spawnResurrectionEntity(self,areaID,team):
#Get Model Name
modelName = None
if team == GEGlobal.TEAM_MI6: modelName = self.MRE_MODEL
else: modelName = self.JRE_MODEL
#Spawn resurrection entity
self.tokenManager.SetupCaptureArea(areaID,
model=modelName,
limit=1, location=GEGlobal.SPAWN_PLAYER,
rqd_team=team)
def OnPlayerSpawn(self,player):
playersTeam = player.GetTeamNumber()
if playersTeam != GEGlobal.TEAM_SPECTATOR:
if player in self.eliminatedSpectators:
self.spawnNewResurrectionEntity(player,playersTeam)
self.updateTeamsDisplayedMaxPlayers(playersTeam)
self.eliminatedSpectators.remove(player)
#If can spawn:
else:
GEUtil.Msg("*** NON spectator spawned ***") #TODO remove
self.pltracker.SetValue( player, self.TR_SPAWNED,True)
else: GEUtil.Msg("*** Spectator spawned ***") #TODO remove
#TODO Use UI Language Files
GEUtil.PopupMessage( player, "Die Another Day", "Eliminate your opponents and resurrect your eliminated team mates." )
def OnRoundBegin( self ):
self.mBounty = 0
self.jBounty = 0
if not self.waitingForPlayers:
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
self.pltracker.SetValue( GEPlayer.GetMPPlayer( i ), self.TR_ELIMINATED, False )
GEMPGameRules.ResetAllPlayerDeaths()
GEMPGameRules.ResetAllPlayersScores()
def OnRoundEnd( self ):
self.eliminateNewPlayers = False
self.radar.DropAllContacts()
self.timerTracker.RemoveTimer(None) #Stop all timers
#Remove all progress bars
GEUtil.RemoveHudProgressBar( None,self.MBountyPBIndex)
GEUtil.RemoveHudProgressBar( None,self.JBountyPBIndex)
GEUtil.RemoveHudProgressBar( None,self.ResurrectionPBIndex)
#Empty resurrection queues
del self.mResurrectionQueue[:]
del self.jResurrectionQueue[:]
self.deleteAllCaptureAreasAndTheirCollections()
def deleteAllCaptureAreasAndTheirCollections(self):
for areaID in self.mAreaIDs: self.tokenManager.RemoveCaptureArea(areaID)
for areaID in self.jAreaIDs: self.tokenManager.RemoveCaptureArea(areaID)
self.resurrectionAreaUserLists.clear()
del self.mAreaIDs[:]
del self.jAreaIDs[:]
def OnPlayerKilled( self, victim, killer, weapon ):
super( DieAnotherDay, self ).OnPlayerKilled( victim, killer, weapon )
self.InitializePlayerBounty() #if not initialised already
victimsTeam = victim.GetTeamNumber()
#Don't allow player's to accidentally/intentionally eliminate their team mates
if killer.GetTeamNumber()!= victimsTeam:
self.eliminatePlayer(victim)
self.announceElimination(victim,killer)
self.decreaseTeamBounty(victimsTeam)
#Get the survivor count for the victim's team.
teamsSurvivors = 0
if victimsTeam == GEGlobal.TEAM_MI6: teamsSurvivors = self.mBounty
else: teamsSurvivors = self.jBounty
#If the victim was the last player alive on their team then don't create a resurrection area because
#the game will be ended by OnThink() when this function has finished.
if teamsSurvivors > 0:
self.eliminateNewPlayers = True
self.spawnNewResurrectionEntity(victim,victimsTeam)
self.addPlayerToResurrectionQueue(victim,victimsTeam)
if self.playerNotBot(victim):
queuePosition = None
if victimsTeam == GEGlobal.TEAM_MI6: queuePosition = self.mResurrectionQueue.index(victim)
else: queuePosition = self.jResurrectionQueue.index(victim)
#TODO use language files
self.tellPlayerWhatTheirResurrectionQueuePositionIs(victim,queuePositionP=queuePosition)
elif teamsSurvivors < 0: GEUtil.Msg("ERROR:OnPlayerKilled():teamsSurvivors < 0: = " + str(teamsSurvivors))
def OnCaptureAreaSpawned( self, area ):
areasTeam = area.GetTeamNumber()
location = area.GetAbsOrigin()
#Recusrive Function Call Loop:
#If the area has spawned at an enemy resurrection area's location respawn it and exit this function call
#because this function will be called again when the area respawns and should only execute statements
#after the respawn IF block, when it is called for an area which has an acceptable location.
if areasTeam == GEGlobal.TEAM_MI6 and location in self.jAreaLocations or areasTeam == GEGlobal.TEAM_JANUS and location in self.mAreaLocations:
self.respawnResurrectionEntity(area.GetGroupName(),areasTeam)
return
colour = None
if area.GetTeamNumber() == GEGlobal.TEAM_MI6:
self.mAreaLocations.append(location)
colour = self.COLOR_MI6_RADAR
else:
self.jAreaLocations.append(location)
colour = self.COLOR_JANUS_RADAR
self.radar.AddRadarContact(area,GEGlobal.RADAR_TYPE_OBJECTIVE,True,"sprites/hud/radar/capture_point",colour)
self.radar.SetupObjective(area,area.GetTeamNumber(),"", "",colour, 0, False )
def OnCaptureAreaEntered( self, area, player, token ):
if area.GetTeamNumber() == player.GetTeamNumber():
areasTeam = area.GetTeamNumber()
#Add player to area's user list, creating if it hasn't been created already
self.resurrectionAreaUserLists[area.GetGroupName()].append(player)
#Create & configure resurrection timer & Give it the area's name and team
resurrectionTimer = self.timerTracker.CreateTimer(str(areasTeam) + "," + area.GetGroupName())
resurrectionTimer.SetUpdateCallback(self.ResurrectionTimerTick,1.0)
resurrectionTimer.SetAgeRate(1.0,0)
#Create a resurrection progress bar on the player's screen TODO: use language files
GEUtil.InitHudProgressBar(player,self.ResurrectionPBIndex, "Resurrecting Team Mate...", GEGlobal.HUDPB_SHOWVALUE, self.resurrectionTime, self.ResurrectionPBX, self.ResurrectionPBY, 120, 16, GEUtil.CColor( 220, 220, 220, 240 ) )
#Start the resurrection timer
resurrectionTimer.Start(self.resurrectionTime,False)
def OnCaptureAreaExited( self, area, player ):
areasTeam = area.GetTeamNumber()
areasName = area.GetGroupName()
if areasTeam == player.GetTeamNumber():
#Remove player from the area's user list
self.resurrectionAreaUserLists[areasName].remove(player)
#Remove the resurrection progress progress bar from the player's screen
GEUtil.RemoveHudProgressBar(player,self.ResurrectionPBIndex)
def ResurrectionTimerTick( self, timer, update_type ):
areasID = timer.GetName()[2:]
#Area still in use?
if update_type != Timer.UPDATE_STOP and self.areaInUse(areasID):
#Update each user's resurrection progress GUI
for areaUser in self.resurrectionAreaUserLists[areasID]:
if update_type == Timer.UPDATE_FINISH:
GEUtil.RemoveHudProgressBar(areaUser,self.ResurrectionPBIndex)
else:
GEUtil.UpdateHudProgressBar(areaUser,self.ResurrectionPBIndex,int(timer.GetCurrentTime()))
if update_type == Timer.UPDATE_FINISH:
#Get area's team
areasTeam = int(timer.GetName()[0])
teamString = self.getTeamString(areasTeam)
#Delete the resurrection area
self.deleteResurrectionArea(areasID,areasTeam)
#Choose player to be resurrected.
resurrectedPlayer = None
if areasTeam == GEGlobal.TEAM_MI6 and len(self.mResurrectionQueue) != 0: resurrectedPlayer = self.mResurrectionQueue.pop(0)
elif len(self.jResurrectionQueue) != 0: resurrectedPlayer = self.jResurrectionQueue.pop(0)
#If for some reason there is no player to resurrect, don't resurrect anyone.
if resurrectedPlayer != None:
#Resurrect player and respond to their resurrection
self.resurrectPlayer(resurrectedPlayer)
#Update player bounty
self.increaseTeamBounty(areasTeam)
#Update resurrection queue progress bars for team mates
self.resurrectionQueueUpdateNotify(areasTeam)
if self.playerNotBot(resurrectedPlayer):
#Remove resurrected player's resurrection queue progress bar
GEUtil.RemoveHudProgressBar(resurrectedPlayer,self.ResurrectionPBIndex)
#Emit player resurrected event
GEUtil.EmitGameplayEvent("DieAnotherDay_resurrection", "%s" % resurrectedPlayer.GetName(),"%s" % teamString)
#Announce event in console
GEUtil.Msg("A " + teamString + " player has been resurrected: " + resurrectedPlayer.GetName())
#Announce resurrection
GEUtil.ClientPrint(None, GEGlobal.HUD_PRINTTALK,"A " + teamString + " player has been resurrected.")
#If there are now no eliminated players, allow new players to join without needing
#to be spawned by their team mates.
numberOfMPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_MI6)
numberOfJPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_JANUS)
if numberOfMPlayers == self.mBounty and numberOfJPlayers == self.jBounty: self.eliminatedSpectators = False
#Activated if the timer hasn't expired in this tick and it's area no longer has users:
elif update_type != Timer.UPDATE_STOP:
timer.Stop()
def resurrectionQueueUpdateNotify(self,team):
resurrectionQueue = None
if(team == GEGlobal.TEAM_MI6): resurrectionQueue = self.mResurrectionQueue
else: resurrectionQueue = self.jResurrectionQueue
for player in resurrectionQueue:
if self.playerNotBot(player):
self.tellPlayerWhatTheirResurrectionQueuePositionIs(player,queueP=resurrectionQueue)
def tellPlayerWhatTheirResurrectionQueuePositionIs(self,player,queueP=None,queuePositionP=None):
if queuePositionP == None and queueP != None: queuePositionP = queueP.index(player)
if queuePositionP != None :
#TODO use language files
GEUtil.ClientPrint(player,GEGlobal.HUD_PRINTCONSOLE,"Team mates who will be resurrected before you = ")
GEUtil.PopupMessage(player, "You've Been Eliminated", "Team mates who will be resurrected before you = " + str(queuePositionP))
def playerNotBot(self,player):
return player.__class__.__name__ != "CGEBotPlayer"
def resurrectPlayer(self,player):
self.pltracker.SetValue(player,self.TR_ELIMINATED,False)
def getTeamsRadarColor(self,teamNumber):
if teamNumber == GEGlobal.TEAM_MI6: return self.COLOR_MI6_RADAR
else: return self.COLOR_JANUS_RADAR
def OnThink( self ):
if GEMPGameRules.GetNumActivePlayers() < 2:
self.waitingForPlayers = True
return
if self.waitingForPlayers:
self.waitingForPlayers = False
GEUtil.HudMessage( None, "#GES_GP_GETREADY", -1, -1, GEUtil.CColor( 255, 255, 255, 255 ), 2.5 )
GEMPGameRules.EndRound( False )
#Check to see if the round is over!:
#check to see if each team has a player...
inPlayMPlayers = []
inPlayJPlayers = []
for i in range( 32 ):
if not GEPlayer.IsValidPlayerIndex( i ):
continue
player = GEPlayer.GetMPPlayer( i )
if self.IsInPlay( player ):
if player.GetTeamNumber() == GEGlobal.TEAM_MI6:
inPlayMPlayers.append( player )
elif player.GetTeamNumber() == GEGlobal.TEAM_JANUS:
inPlayJPlayers.append( player )
numMI6Players = len(inPlayMPlayers)
numJanusPlayers = len(inPlayJPlayers)
if numMI6Players == 0 and numJanusPlayers == 0: GEMPGameRules.EndRound()
elif numMI6Players == 0 and numJanusPlayers > 0: self.teamWins(GEGlobal.TEAM_JANUS)
elif numMI6Players > 0 and numJanusPlayers == 0: self.teamWins(GEGlobal.TEAM_MI6)
def teamWins(self,teamNumber):
team = GEMPGameRules.GetTeam(teamNumber)
team.IncrementMatchScore( 5 )
GEMPGameRules.SetTeamWinner(team)
GEMPGameRules.EndRound()
def CanPlayerRespawn( self, player ):
#if self.isEliminatedPlayer(player):
#player.SetScoreBoardColor( GEGlobal.SB_COLOR_ELIMINATED )
#return False
#player.SetScoreBoardColor( GEGlobal.SB_COLOR_NORMAL )
return False
def InitializePlayerBounty( self ):
if self.mBounty == 0 and self.jBounty == 0:
self.mBountyMaxPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_MI6)
self.jBountyMaxPlayers = GEMPGameRules.GetNumInRoundTeamPlayers(GEGlobal.TEAM_JANUS)
self.mBounty = self.mBountyMaxPlayers
self.jBounty = self.jBountyMaxPlayers
GEUtil.InitHudProgressBar(None,self.MBountyPBIndex,"MI6: ",GEGlobal.HUDPB_SHOWVALUE, self.mBountyMaxPlayers, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus: ",GEGlobal.HUDPB_SHOWVALUE, self.jBountyMaxPlayers, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
def getTeamsPlayerCount(self,team):
if team == GEGlobal.TEAM_MI6: return self.mBountyMaxPlayers
else: return self.jBountyMaxPlayers
def updateTeamsDisplayedMaxPlayers(self,team):
numberOfPlayersInTeam = self.getTeamsPlayerCount(team)
if team == GEGlobal.TEAM_MI6:
GEUtil.RemoveHudProgressBar(None,self.MBountyPBIndex)
GEUtil.InitHudProgressBar(None, self.MBountyPBIndex,"MI6: ", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
else:
GEUtil.RemoveHudProgressBar(None,self.JBountyPBIndex)
GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus: ", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
def decreaseTeamBounty(self,team):
if team == GEGlobal.TEAM_JANUS: self.jBounty -= 1
else: self.mBounty -= 1
self.updateDisplayedBounties()
def increaseTeamBounty(self,team):
if team == GEGlobal.TEAM_JANUS: self.jBounty += 1
else: self.mBounty += 1
self.updateDisplayedBounties()
def updateDisplayedBounties(self):
GEUtil.UpdateHudProgressBar(None,self.JBountyPBIndex,self.jBounty)
GEUtil.UpdateHudProgressBar(None,self.MBountyPBIndex,self.mBounty)
def IsInPlay( self, player ):
return player.GetTeamNumber() is not GEGlobal.TEAM_SPECTATOR and self.pltracker.GetValue( player, self.TR_SPAWNED ) and not self.pltracker.GetValue( player, self.TR_ELIMINATED )
def GetTeamPlay(self):
return GEGlobal.TEAMPLAY_ALWAYS
I have fixed the spectator bug and it will be out in the next patch.
I think I will be able to prevent this script from triggering that GE:S bug by simply making it spawn an eliminated player before allowing them to become a spectator.This workaround worked.
Although I see what you mean by the bug, it is rather rude haha.Sorry
Anyway, you can spawn bots when you are a spectator by setting the ge_bot_threshold to -1 then use ge_bot to spawn bots.Thanks, now that I know how to do this I will be able to do some extra bug tests.