Editing and Customization > Community Content

[Gameplay] Die Another Day

<< < (5/21) > >>

Joe:
There is now a screenshot from Beta 1.02 in this topic's first post.


--- Quote from: killermonkey on November 29, 2012, 11:54:21 pm ---Joe, I added in the ability to set an entities' position in Python (players and held weapons will ignore the command for obvious reasons). This will be in the next patch to GE:S.

--- End quote ---

Thanks, when this patch is released I will use this new ability to make resurrection entities appear at player death locations instead of player spawn points.

WNxEuphonic:

--- Quote from: Joe on November 30, 2012, 03:21:00 pm ---There is now a screenshot from Beta 1.02 in this topic's first post.

Thanks, when this patch is released I will use this new ability to make resurrection entities appear at player death locations instead of player spawn points.



--- End quote ---

I've been thinking about this, and you should spawn them at player death points only when the player is killed by another player or themselves, not when it's an environmental death -- that way you prevent them spawning at the bottom of pits. You still will have the issue of players killed mid-air (like falling from Cradle and getting shot on the way down), but it's an improvement.

Troy:
Yea, imagine a floating tombstone lol.

Joe:
I'm sorry I still haven't released Beta 1.02, it still has bugs which need to be fixed.


--- Quote from: WNxEuphonic on November 30, 2012, 07:26:24 pm ---I've been thinking about this, and you should spawn them at player death points only when the player is killed by another player or themselves, not when it's an environmental death -- that way you prevent them spawning at the bottom of pits.

--- End quote ---
Thanks for the help, I will do this.

The Crash Bug
Does anyone know why telling the token manager to delete a capture area in the Beta 1.02 script's OnCaptureAreaSpawned() function is making GE:S regularly crash?

This bug will crash GE:S every 4-10 minutes on the Silo map with 31 bots.


--- Code: ---
def OnCaptureAreaSpawned( self, area ):
        areasID = area.GetGroupName()
        areasTeam = area.GetTeamNumber()
        location = area.GetAbsOrigin()
           
        #TODO remove when REs are moved to player death locations:
        #Don't allow a MI6 and Janus RE to be located at the same player spawn point.
        if areasTeam == GEGlobal.TEAM_MI6 and location in self.jAreaLocations.values() or areasTeam == GEGlobal.TEAM_JANUS and location in self.mAreaLocations.values():
            self.respawnResurrectionEntity(areasID,areasTeam) #Recursive Function Call Loop
            return
       
        if location in self.mAreaLocations.values() or location in self.jAreaLocations.values():
            GEUtil.Msg("------- Same Team RE Location Overlap -------")
            #Deleting the area in this callback function makes GE:S regularly crash:
            self.tokenManager.RemoveCaptureArea(areasID)

            if area.GetTeamNumber() == GEGlobal.TEAM_MI6: self.mAreaIDs.remove(areasID)
            else: self.jAreaIDs.remove(areasID)
           
            areaIDAssociatedWithLocation = self.getREAreaIDAssociatedWithLocation(location,areasTeam)
            if not self.multiResurrectionRE.has_key(areaIDAssociatedWithLocation): self.multiResurrectionRE[areaIDAssociatedWithLocation] = 1
           
            self.multiResurrectionRE[areaIDAssociatedWithLocation] += 1
       
        else:
            colour = self.getSidesColour(areasTeam)
           
            if areasTeam == GEGlobal.TEAM_MI6: self.mAreaLocations[areasID] = location
            else: self.jAreaLocations[areasID] = location
                   
            self.radar.AddRadarContact(area,GEGlobal.RADAR_TYPE_OBJECTIVE,True,self.RERadarIcon,colour)
            self.radar.SetupObjective(area,areasTeam,"", "",colour,self.REObjectiveIconFadeOutDistance, False)

#TODO remove when REs are moved to player death locations
def getREAreaIDAssociatedWithLocation(self,location,side):
            sidesAreaLocations = None
            if side == GEGlobal.TEAM_MI6: sidesAreaLocations = self.mAreaLocations
            else: sidesAreaLocations = self.jAreaLocations
       
            for areaID in sidesAreaLocations.keys():
                if sidesAreaLocations[areaID] == location: return areaID

--- End code ---

Crash Bug Demo Script

--- Code: ---
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

'''
This mode is based on Mefy's MOHAA Freeze Tag Mode.

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.

The gravestones were created by Kraid.

The up and down arrows in the crucifix RE icon were taken from the run icons.

@author: Joe
@version: Crash Bug Demo
'''

class DieAnotherDay( GEScenario ):
    ResurrectionTime = 5.0
    CompletedResPBRemovalDelay = 1.0
   
    MREModel = "models/gameplay/gravestone.mdl"
    JREModel = "models/gameplay/gravestone.mdl"
   
    MRESkin = 0
    JRESkin = 1
   
    RERadarIcon = "sprites/hud/radar/RE"
   
    REObjectiveIconFadeOutDistance = 200
   
    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.315
    MBountyPBY = 0.03
   
    JBountyPBX = 0.515
    JBountyPBY = 0.03
   
    ResurrectionPBX = -1
    ResurrectionPBY = 0.6
    #-------------------------
   
    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.mBounty = 0
        self.jBounty = 0
        self.pltracker = GEPlayerTracker( self )
       
        self.bountiesInitialised = False
       
        self.mBountyMaxPlayers = 0
        self.jBountyMaxPlayers = 0
       
        self.timerTracker = TimerTracker( self )
        self.tokenManager = GEMPGameRules.GetTokenMgr()
       
        #Eliminated player collections
        self.mResurrectionQueue = []
        self.jResurrectionQueue = []
       
        #Collections related to resurrection area entities
        self.mAreaIDs = []
        self.jAreaIDs = []
       
        self.mAreaLocations = {}
        self.jAreaLocations = {}
       
        self.REResTimers = defaultdict(list)
       
        #TODO remove when REs are moved from spawn points to player death locations:
        self.multiResurrectionRE = {}
       
        #Needed because deleting a RE in onCaptureAreaSpawned makes GE:S regularly crash.
        #Emptied in onCaptureAreaEntered.
        #self.REBin = []
       
    def OnLoadGamePlay( self ):
        GEUtil.PrecacheModel( self.MREModel )
        GEUtil.PrecacheModel( self.JREModel )
       
        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(
                                 """-- Version: Crash Bug Demo --
Eliminate your opponents.

To resurrect a team mate: stand next
to one of your team's gravestones.
---------- Credits ---------
Based on Mefy's MOHAA Freeze Tag Mode.
Kraid created the gravestones.
                                 """)
       
    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)
           
            if self.isEliminatedPlayer(player):
                self.deleteNotInUseResurrectionEntityFromTeam(team)
                self.removePlayerFromTeamsRQueue(player,team)
            else: self.decreaseTeamBounty(team)
           
            if self.bountiesInitialised: self.updateTeamsDisplayedMaxPlayers(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 newTeam == GEGlobal.TEAM_SPECTATOR:
            if self.isEliminatedPlayer(player): self.eliminatedPlayerWantsToBecomeSpectator(player,oldTeam)
            else: self.playerWantsToBecomeSpectator(player,oldTeam)
       
        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","New players won't spawn until a team mate spawns them, this prevents resurrection rejoins.")
            self.eliminatePlayer(player)
            self.spawnNewResurrectionEntity(player,newTeam)
            self.addPlayerToResurrectionQueue(player,newTeam)
            if self.playerNotBot(player): self.tellPlayerWhatTheirResurrectionQueuePositionIs(player,newTeam)
           
        else: self.increaseTeamBounty(newTeam)
       
        if self.bountiesInitialised: self.updateTeamsDisplayedMaxPlayers(newTeam)
   
    def playerWantsToChangeTheirTeam(self,player,oldTeam,newTeam):
        self.decrementTeamsPlayerCount(oldTeam)
        self.incrementTeamsPlayerCount(newTeam)
       
        if self.isEliminatedPlayer(player):
            #Old team
            self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
            self.removePlayerFromTeamsRQueue(player,oldTeam)
            self.resurrectionQueueUpdateNotify(oldTeam)
           
            #New Team
            self.spawnNewResurrectionEntity(player,newTeam)
            self.addPlayerToResurrectionQueue(player,newTeam)
            if self.playerNotBot(player): self.tellPlayerWhatTheirResurrectionQueuePositionIs(player,newTeam)
           
        else:
            self.decreaseTeamBounty(oldTeam)
            self.increaseTeamBounty(newTeam)
           
        if self.bountiesInitialised:
            self.updateTeamsDisplayedMaxPlayers(oldTeam)
            self.updateTeamsDisplayedMaxPlayers(newTeam)
           
    def eliminatedPlayerWantsToBecomeSpectator(self,player,oldTeam):
        self.decrementTeamsPlayerCount(oldTeam)
       
        self.deleteNotInUseResurrectionEntityFromTeam(oldTeam)
        self.removePlayerFromTeamsRQueue(player,oldTeam)
        self.resurrectionQueueUpdateNotify(oldTeam)
       
        #Prevent GE:S spectator view bug from being triggered (this bug will be fixed in the next patch):
        self.resurrectPlayer(player)
        player.ForceRespawn()
        self.eliminatePlayer(player) #Doesn't kill them but does set eliminated? attribute to true.
       
        if self.bountiesInitialised: self.updateTeamsDisplayedMaxPlayers(oldTeam)
   
    def playerWantsToBecomeSpectator(self,player,oldTeam):
        self.decrementTeamsPlayerCount(oldTeam)
        self.decreaseTeamBounty(oldTeam)
       
        if self.bountiesInitialised: self.updateTeamsDisplayedMaxPlayers(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 won't spawn until a team mate spawns you because you were eliminated before you became a spectator.")
            self.spawnNewResurrectionEntity(player,newTeam)
            self.addPlayerToResurrectionQueue(player,newTeam)
            if self.playerNotBot(player): self.tellPlayerWhatTheirResurrectionQueuePositionIs(player,newTeam)
           
        else: self.increaseTeamBounty(newTeam)
       
        if self.bountiesInitialised: self.updateTeamsDisplayedMaxPlayers(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 areaInUse(self,areaID):
        return len(self.REResTimers[areaID]) > 0
   
    def deleteResurrectionArea(self,areasID,areasTeam):
        if self.multiResurrectionRE.has_key(areasID): del self.multiResurrectionRE[areasID]
       
        if areasTeam == GEGlobal.TEAM_MI6:
            self.mAreaIDs.remove(areasID)
            del self.mAreaLocations[areasID]
        else:
            self.jAreaIDs.remove(areasID)
            del self.jAreaLocations[areasID]
           
        del self.REResTimers[areasID]
        self.tokenManager.RemoveCaptureArea(areasID)
       
    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
        skinNumber = None
       
        if team == GEGlobal.TEAM_MI6:
            modelName = self.MREModel
            skinNumber = self.MRESkin
        else:
            modelName = self.JREModel
            skinNumber = self.JRESkin
       
        #Spawn resurrection entity
        self.tokenManager.SetupCaptureArea(areaID,
                                   model=modelName,
                                   skin=skinNumber,
                                   limit=1, location=GEGlobal.SPAWN_PLAYER,
                                   rqd_team=team)

    def OnPlayerSpawn(self,player):
        if player.GetTeamNumber() != GEGlobal.TEAM_SPECTATOR: self.pltracker.SetValue(player,self.TR_SPAWNED,True) 
           
        #TODO Use UI Language Files
        if player.IsInitialSpawn(): 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 ):
        GEUtil.Msg("One Round End----")
        self.eliminateNewPlayers = False
        self.radar.DropAllContacts()
        self.timerTracker.RemoveTimer(None) #Stop all timers
       
        #Remove all progress bars
        self.bountiesInitialised = False
       
        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)
       
        del self.mAreaIDs[:]
        del self.jAreaIDs[:]
       
        self.mAreaLocations.clear()
        self.jAreaLocations.clear()
       
        self.REResTimers.clear()

    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 players 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):
                    self.tellPlayerWhatTheirResurrectionQueuePositionIs(victim)
               
            elif teamsSurvivors < 0: GEUtil.Msg("ERROR:OnPlayerKilled():teamsSurvivors < 0: = " + str(teamsSurvivors))

    def OnCaptureAreaSpawned( self, area ):
        areasID = area.GetGroupName()
        areasTeam = area.GetTeamNumber()
        location = area.GetAbsOrigin()
           
        #TODO remove when REs are moved to player death locations:
        #Don't allow a MI6 and Janus RE to be located at the same player spawn point.
        if areasTeam == GEGlobal.TEAM_MI6 and location in self.jAreaLocations.values() or areasTeam == GEGlobal.TEAM_JANUS and location in self.mAreaLocations.values():
            self.respawnResurrectionEntity(areasID,areasTeam) #Recursive Function Call Loop
            return
       
        #TODO modify the following statements when REs are moved to player death locations:
        #Deal with the situation of 2 or more RE from the same side being located at the same spawn point (the resurrection function
        #is also responsible for dealing with this situation):
        if location in self.mAreaLocations.values() or location in self.jAreaLocations.values():
            GEUtil.Msg("------- Same Team RE Location Overlap -------")
            #Deleting the area in this callback function makes GE:S regularly crash, on Silo when it has 31 bots.
    #(it will crash once every 4 - 10 minutes)
            self.tokenManager.RemoveCaptureArea(areasID)

            if area.GetTeamNumber() == GEGlobal.TEAM_MI6: self.mAreaIDs.remove(areasID)
            else: self.jAreaIDs.remove(areasID)
           
            areaIDAssociatedWithLocation = self.getREAreaIDAssociatedWithLocation(location,areasTeam)
            if not self.multiResurrectionRE.has_key(areaIDAssociatedWithLocation): self.multiResurrectionRE[areaIDAssociatedWithLocation] = 1
           
            self.multiResurrectionRE[areaIDAssociatedWithLocation] += 1
       
        else:
            colour = self.getSidesColour(areasTeam)
           
            if areasTeam == GEGlobal.TEAM_MI6: self.mAreaLocations[areasID] = location
            else: self.jAreaLocations[areasID] = location
                   
            self.radar.AddRadarContact(area,GEGlobal.RADAR_TYPE_OBJECTIVE,True,self.RERadarIcon,colour)
            self.radar.SetupObjective(area,areasTeam,"", "",colour,self.REObjectiveIconFadeOutDistance, False)
   
    #TODO remove when REs are moved to player death locations
    def getREAreaIDAssociatedWithLocation(self,location,side):
        sidesAreaLocations = None
        if side == GEGlobal.TEAM_MI6: sidesAreaLocations = self.mAreaLocations
        else: sidesAreaLocations = self.jAreaLocations
       
        for areaID in sidesAreaLocations.keys():
            if sidesAreaLocations[areaID] == location: return areaID
   
    def OnCaptureAreaEntered( self, area, player, token ):
        if area.GetTeamNumber() == player.GetTeamNumber():
            #TODO remove
            GEUtil.ClientPrint(None,GEGlobal.HUD_PRINTNOTIFY,"Multi RE entered")
           
            #Create a new resurrection timer and add it to the resurrection timer collection
            resurrectionTimer = DieAnotherDay.ResurrectionTimer(self,area,player)
            resurrectionTimer.create()
            self.REResTimers[area.GetGroupName()].append(resurrectionTimer)
           
            #Create a resurrection progress bar on the player's screen TODO: use language files
            GEUtil.InitHudProgressBar(player,self.ResurrectionPBIndex, "Resurrecting:", GEGlobal.HUDPB_SHOWBAR, self.ResurrectionTime, self.ResurrectionPBX, self.ResurrectionPBY, 120, 16,self.getSidesColour(area.GetTeamNumber()))
           
            resurrectionTimer.start()
   
#    def emptyREBin(self):
#        if len(self.REBin) != 0:
#            for RE in self.REBin:
#                areasID = RE.GetGroupName()
#                if RE.GetTeamNumber() == GEGlobal.TEAM_MI6: self.mAreaIDs.remove(areasID)   
#                else: self.jAreaIDs.remove(areasID)
#               
#                self.tokenManager.RemoveCaptureArea(areasID)
           
    def getSidesColour(self,side):
        if side == GEGlobal.TEAM_MI6: return self.COLOR_MI6_RADAR
        else: return self.COLOR_JANUS_RADAR
       
    def OnCaptureAreaExited( self, area, player ):
        if area.GetTeamNumber() == player.GetTeamNumber():
            if self.getREUsersResurrectionTimer(area,player) != None:
                self.getREUsersResurrectionTimer(area,player).cancel()
           
    def getREUsersResurrectionTimer(self,area,userP):
        for resurrectionTimer in self.REResTimers[area.GetGroupName()]:
            if resurrectionTimer.user == userP: return resurrectionTimer
           
        return None
           
    class ResurrectionTimer:
        def __init__(self,DADP,areaP,userP):
            self.timer = None
            self.DAD = DADP
            self.area = areaP
            self.user = userP
           
        def create(self):
            self.timer = self.DAD.timerTracker.CreateTimer(self.area.GetGroupName())
            self.timer.SetUpdateCallback(self.TimerTick,1)
            self.timer.SetAgeRate(1.0,0)
           
        def start(self):
            self.timer.Start(DieAnotherDay.ResurrectionTime,False)
           
        def cancel(self):
            self.timer.Stop()
            self.removeUsersResurrectionPB()
            self.delete()
           
        def delete(self):
            self.DAD.timerTracker.RemoveTimer(self.timer.GetName())
            self.DAD.REResTimers[self.area.GetGroupName()].remove(self)
           
        def TimerTick( self, timer, update_type ):
            if update_type != Timer.UPDATE_STOP:
                self.updateUsersResurrectionPB()
               
                if update_type == Timer.UPDATE_FINISH:
                    self.cancelTimerAreasOtherResTimers()
                    self.startUsersResurrectionPBsDelayedRemovalTimer(self.area.GetGroupName())
                    self.resurrectPlayerFromTimersTeam()
                    self.delete() #Must be called before deleteResurrectionArea()
                    self.DAD.deleteResurrectionArea(self.area.GetGroupName(),self.area.GetTeamNumber())
       
        def cancelTimerAreasOtherResTimers(self):
            for resurrectionTimer in self.DAD.REResTimers[self.area.GetGroupName()]:
                if resurrectionTimer != self: resurrectionTimer.cancel()
       
        def removeUsersResurrectionPB(self):
            GEUtil.RemoveHudProgressBar(self.user,DieAnotherDay.ResurrectionPBIndex)
           
        def updateUsersResurrectionPB(self):
            GEUtil.UpdateHudProgressBar(self.user,DieAnotherDay.ResurrectionPBIndex,int(self.timer.GetCurrentTime()))
       
        def startUsersResurrectionPBsDelayedRemovalTimer(self,timerID):
            resPBRemoveTimer = self.DAD.timerTracker.CreateTimer(timerID)
            resPBRemoveTimer.SetUpdateCallback(self.DelayedResurrectionPBRemoval,1)
            resPBRemoveTimer.SetAgeRate(1.0,0)
           
            resPBRemoveTimer.Start(DieAnotherDay.CompletedResPBRemovalDelay,False)
           
        def DelayedResurrectionPBRemoval(self,timer,update_type ):
            if update_type == Timer.UPDATE_FINISH: self.removeUsersResurrectionPB()
                   
        def resurrectPlayerFromTimersTeam(self):
            areasTeam = self.area.GetTeamNumber()
            areasID = self.area.GetGroupName()
           
            #Get team string
            teamString = None
            if areasTeam == GEGlobal.TEAM_MI6: teamString = "MI6"
            else: teamString = "Janus"
           
            #TODO modify when REs are moved from spawn points to death locations:
            numberOfPlayersToResurrect = 1
            if self.DAD.multiResurrectionRE.has_key(areasID): numberOfPlayersToResurrect = self.DAD.multiResurrectionRE[areasID]
           
            #For each resurrection...
            while numberOfPlayersToResurrect > 0:
                numberOfPlayersToResurrect -= 1
               
                #TODO remove
                if numberOfPlayersToResurrect > 1: GEUtil.Msg("*** Multi Resurrection: " + str(numberOfPlayersToResurrect) + " ***")
               
                #Choose player to be resurrected.
                resurrectedPlayer = None
                if areasTeam == GEGlobal.TEAM_MI6 and len(self.DAD.mResurrectionQueue) != 0: resurrectedPlayer = self.DAD.mResurrectionQueue.pop(0)
                elif areasTeam == GEGlobal.TEAM_JANUS and len(self.DAD.jResurrectionQueue) != 0: resurrectedPlayer = self.DAD.jResurrectionQueue.pop(0)
               
                #If for some reason there is no player to resurrect, don't resurrect anyone.
                if resurrectedPlayer != None:
                    #Resurrect player
                    self.DAD.resurrectPlayer(resurrectedPlayer)
                   
                    #Update player bounty
                    self.DAD.increaseTeamBounty(areasTeam)
                   
                    #Update resurrection queue progress bars for team mates
                    self.DAD.resurrectionQueueUpdateNotify(areasTeam)
                   
                    if self.DAD.playerNotBot(resurrectedPlayer):
                        #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.DAD.mBounty and numberOfJPlayers == self.DAD.jBounty: self.DAD.eliminateNewPlayers = False
   
    #Only called when a resurrection has taken place.
    def DelayedResurrectionPBRemoval( self, timer, update_type ):
        timersAreasID = timer.getName()
        timersUser = self.resurrectionAreaUserLists[timersAreasID][0]
        GEUtil.RemoveHudProgressBar(timersUser,self.ResurrectionPBIndex)
           
    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)
           
    def tellPlayerWhatTheirResurrectionQueuePositionIs(self,player,team=None):
        if team == None: team = player.GetTeamNumber()
       
        queuePosition = None
        if team == GEGlobal.TEAM_MI6: queuePosition = self.mResurrectionQueue.index(player)
        else: queuePosition = self.jResurrectionQueue.index(player)
       
        #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(queuePosition))       
           
    def playerNotBot(self,player):
        return player.__class__.__name__ != "CGEBotPlayer"

    def resurrectPlayer(self,player):
        self.pltracker.SetValue(player,self.TR_ELIMINATED,False)

    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.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)
           
            self.bountiesInitialised = True

    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.InitHudProgressBar(None, self.MBountyPBIndex,"MI6:", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.MBountyPBX,self.MBountyPBY, 0, 10, self.MBountyFontColour)
            GEUtil.UpdateHudProgressBar(None,self.MBountyPBIndex,self.mBounty)
        else:
            GEUtil.InitHudProgressBar(None,self.JBountyPBIndex,"Janus:", GEGlobal.HUDPB_SHOWVALUE,numberOfPlayersInTeam, self.JBountyPBX,self.JBountyPBY, 0, 10,self.JBountyFontColour)
            GEUtil.UpdateHudProgressBar(None,self.JBountyPBIndex,self.jBounty)     

    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
       
--- End code ---

Joe:
I've now fixed all the Beta 1.02 bugs.

I will do some more bug tests tomorrow and if I don't find any more problems, I will release it.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version