GoldenEye: Source Forums

Editing and Customization => Community Content => Topic started by: Joe on November 25, 2012, 03:07:08 am

Title: [Gameplay] Die Another Day
Post by: Joe on November 25, 2012, 03:07:08 am
Latest Release: Alpha 1.10
Released: 25/4/14
Download Page (https://github.com/JASheppard/GES_DieAnotherDay_Mode/releases/tag/v1.10-alpha)


RE: Resurrection Entity

Alpha 1.04 Screenshots
To display a screenshot in your browser, click on its preview image below.

(http://www.mediafire.com/conv/ec7a5d4a1c54b4b60038cdd271014c5e7bfacafeac9a3b567822505a3fe12cb86g.jpg) (http://www.mediafire.com/view/?uj6woh5xlr7zyej)     (http://www.mediafire.com/conv/83dda9aa6836a54dd062af61a54ba1235f0ccd64aae2979e0c7012995258637b6g.jpg) (http://www.mediafire.com/view/?wh9ba6zrieewd9s)     (http://www.mediafire.com/conv/72ffe9576d570b6126eb3cb3ee12399eef8f47dec7040c97586fb750f916c8476g.jpg) (http://www.mediafire.com/view/?tqrpcf82c4p0hix)

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

It's a team play elimination mode in which players can resurrect their eliminated team mates.

Version Change History
Alpha 1.10
1. Players can now resurrect their team mates by firing an infinite range resurrection beam at their side's resurrection entities.
2. Players can now resurrect multiple team mates simultaneously.
3. This mode now has an appropriate score system: player round scores no longer affect their team's match score so now the only way to score match points is by wining rounds by eliminating all the members of the opposing team.
4. Resurrection entities will now spawn at player death locations, except when players are killed on ladders or by falling off maps.
5. Players are no longer allowed to spawn after joining a team when there's eliminated players, they will instead be eliminated so they won't spawn until a team mate resurrects them or a new round begins.
6. Players can now increase their round scores by resurrecting team mates. Kills and resurrections are each worth 1 point.
7. When friendly fire is enabled players will now be able to eliminate their team mates: I've decided to allow this because allowing team mate kill victims to respawn allows them to respawn with full health. So a player could prevent a team mate from being eliminated by killing them when they have low health so that they can respawn with full health.
8. Server owners can now change the duration of resurrections by using this new CVAR: dad_resTime
9. Now when players are resurrected the radar icon for the used RE will become a "Run" icon and will be highlighted yellow for a few seconds showing opposing players where the RE was used. The display duration of this "used RE" radar icon can be changed with this new CVAR: dad_usedRELocationRevealTime
10. Elimination and resurrection announcement messages are now coloured blue and red for the different teams.
11. The triangle objective icons above resurrection entities now become yellow when they are being used.
12. This mode's translations are now included in the GoldenEye:Source language files.

Alpha 1.04
1. Added Spanish translation.
2. Added Italian translation.
3. Added Polish translation.
4. Pulsating rings now appear beneath active REs.
5. Players will no longer have to wait behind bots in their side's resurrection queue.
6. MI6 and Janus survivor counts are now displayed on eliminated players' screens.
7. MI6 and Janus survivor counts are now displayed on spectators' screens.
8. A permanent HUD message now tells eliminated players what their resurrection queue position is.

Alpha 1.03
1. Added German Translation.
2. Added French Translation.
3.  The chat message announcements for eliminations and resurrections now mention the names of the players who have been eliminated and resurrected.
4. These chat message announcements are now printed for bot eliminations and resurrections.

Alpha 1.02
1. Bugs from the previously released beta versions have been fixed.
2. REs are now represented by Kraid's gravestones
3. REs are now represented by a cross icon on the radar.
4. Players who kill themselves will now be eliminated.
5. Players are now shown a resurrection progress bar, instead of a remaining seconds count.
6. The count of survivors on each team will now be displayed from the start of a round, instead of becoming visible when the first elimination has taken place.
7. REs will now only been spawned when there is a free player spawn point. When a RE can't be spawned it will be added to a queue and spawned when a spawned RE is deleted.
8. The resurrection timer code is now simpler and better than it was in the previous versions.
Title: Re: Die Another Day
Post by: Troy on November 25, 2012, 03:12:42 am
I'll test it out for you.
Title: Re: Die Another Day
Post by: Troy on November 25, 2012, 04:33:02 am
1. You don't need to show the popupmessage when a player spawns every time.
2. Use the coordinates Euphonic used in Uplink for the MI6 and Janus players remaining at the top of the screen.  Yours is too close to the top and it's off centered.
Title: Re: Die Another Day
Post by: WNxEuphonic on November 25, 2012, 07:03:43 am
I'll download it and give it a test.

HUD Messages will hopefully be getting some tweaks in a future release to fix kerning problems (KM and I were talking about this just this morning), but for now the coordinates in Uplink probably are the best positions as Troy said.
Title: Re: Die Another Day
Post by: Joe on November 25, 2012, 11:53:49 am
I forgot to include the configuration file in the beta 1.00 zip when I uploaded it at 3 am this morning my time, I've now added it to the zip.

This configuration file has one command which will prevent enemies from appearing on players' radars. IMO this mode is a lot more enjoyable when players have to hunt down and kill their losing enemies before their enemies can resurrect enough team mates to fight back.

1. You don't need to show the popupmessage when a player spawns every time.
2. Use the coordinates Euphonic used in Uplink for the MI6 and Janus players remaining at the top of the screen.  Yours is too close to the top and it's off centered.

Thanks Troy and Euphonic for helping me test this, I will make the improvements suggested by Troy.
Title: Re: Die Another Day
Post by: liamcadhain on November 25, 2012, 12:01:57 pm
Well done on the new gamemode Joe. Hopefully we'll see it on a server's rotation some day once it's out of beta
Title: Re: Die Another Day
Post by: Joe on November 25, 2012, 12:14:41 pm
Well done on the new gamemode Joe. Hopefully we'll see it on a server's rotation some day once it's out of beta

Thanks
Title: Re: Die Another Day
Post by: TriDefiance on November 25, 2012, 10:17:40 pm
This pleases me to see a brand new custom gamemode released to the public. Thanks for all of your hard work Joe!

+rep
Title: Re: Die Another Day
Post by: Joe on November 25, 2012, 10:46:06 pm
Beta 1.01 changes:
* The "Die Another Day" pop up message will now only be shown to players when they spawn for the first time.
* The MI6 and Janus survivor counts are now more horizontally centred than they were in the previous version.
* There is now some space between the survivor counts and the top of the screen.

I didn't use any coordinates from Euphonic's script. I want to make GE:S display two value progress bars on the same line, so I can't use the -1 x coordinate to make GE:S horizontally centre them both perfectly.

This pleases me to see a brand new custom gamemode released to the public. Thanks for all of your hard work Joe!
+rep
Thanks, I hope you will enjoy playing this mode.
Title: Re: Die Another Day
Post by: WNxEuphonic on November 26, 2012, 05:44:10 pm
I suggest changing the resurrection timer from digits to a progress bar ("Resurrecting [||||||    ]"), it'll be less wordy and translate better. Make the top message (Janus 1/3 MI6 0/3 or w/e) thing display all the time (except when waiting for players)---it's nice to have something that immediately shows what gameplay you're playing. Have you considered using objective icons?

It plays pretty well, and I'm interested in seeing how it would play in a packed server. A custom model for the resurrection spots would also help, imo.
Title: Re: Die Another Day
Post by: Joe on November 26, 2012, 11:13:48 pm
I suggest changing the resurrection timer from digits to a progress bar ("Resurrecting [||||||    ]"), it'll be less wordy and translate better.
I would personally prefer to see  "Resurrecting:" followed by a seconds countdown. I will create a poll.

Make the top message (Janus 1/3 MI6 0/3 or w/e) thing display all the time (except when waiting for players)---it's nice to have something that immediately shows what gameplay you're playing.
I will do this.

Have you considered using objective icons?
Are you referring to a token radar icon?

I think the token radar icon would look better than the capture point icon.

A custom model for the resurrection spots would also help, imo.
What do you think the custom model should be?

One person has said that they would prefer to see gravestones.

I can only make very simple models and I can't make textures, so if there is going to be custom models I won't be able to make them.

I think the RE model which is used should be big enough to be easily targeted with the long range resurrection ability and its appearance should change when it's being used.


I will release a new beta version tomorrow.
Title: Re: Die Another Day
Post by: kraid on November 28, 2012, 10:27:14 am
Gravestone for sure. Here you are.
http://www.mediafire.com/file/zfzb0j4arorjd4d/gravestone.zip (http://www.mediafire.com/file/zfzb0j4arorjd4d/gravestone.zip)
I hope it'll work, just noticed i compiled it as prop_physics, rather should have been just static & dynamic.
But it was allready uploaded and i g2g to work, so no time to do it again right now.
i will do another compile later.
Title: Re: Die Another Day
Post by: Joe on November 28, 2012, 03:31:05 pm
(http://www.mediafire.com/conv/e98734746bec2baec2a56b44647ca40a9063cfb8195d96e35df5fa3096b521806g.jpg)

Gravestone for sure. Here you are.
http://www.mediafire.com/file/zfzb0j4arorjd4d/gravestone.zip (http://www.mediafire.com/file/zfzb0j4arorjd4d/gravestone.zip)
I hope it'll work, just noticed i compiled it as prop_physics, rather should have been just static & dynamic.
But it was allready uploaded and i g2g to work, so no time to do it again right now.
i will do another compile later.

Thanks for making these great looking gravestones,  I will include them in the beta 1.02 release.

I will try to make a gravestone radar icon.
Title: Re: Die Another Day
Post by: kraid on November 28, 2012, 09:00:02 pm
Maybe just do a cross for the radar icon.
Title: Re: Die Another Day
Post by: Troy on November 28, 2012, 11:14:53 pm
Whoa, nice gravestones!
Title: Re: Die Another Day
Post by: Wake[of]theBunT on November 28, 2012, 11:16:03 pm
Those are badass Kraid! Love how we get a custom game-mode with high quality models that really integrate well. Should make the mode stand out that much more. =)
Title: Re: Die Another Day
Post by: kraid on November 29, 2012, 12:28:05 am
I'd really like to add some text to it, but i'm not good in finding the right words for it.
Should be something that expresses how disapointed the janus group is about your failture or how mi6 honors your suffering.

Also i'd like to make them a little more differing e.g. make the Janus one old and withered with cracks and dirt on it while the mi6 one remains nice and polished.
Maybe even with a different model shape that has some evil vibe.

But than again this might be a little bit to much for the purpose of a gameplay object.
Rather keeping it simple.

BTW: Is there allready a possibility to see which player can be resurrected on that point, displaying the name of the player or something?
Title: Re: Die Another Day
Post by: Joe on November 29, 2012, 06:36:02 pm
Beta 1.02 may not be released until tomorrow because I've drastically altered its resurrection timer code and I want to make sure the changes haven't created new bugs.

This mode's script now uses a ResurrectionTimer class to handle resurrection timers.

BTW: Is there already a possibility to see which player can be resurrected on that point, displaying the name of the player or something?
Unlike in MOHAA Freeze Tag, resurrection entities aren't associated with eliminated players. Instead each side has a resurrection queue and when a side's RE is used the player who has been in their queue for the longest time is resurrected.

I chose to implement resurrections in this way because I think it's a better way of resurrecting players. With this way of doing it, players have a better idea of when they will be resurrected and no player will have a long wait to be resurrected because the RE associated with them isn't used.

If anyone disagrees with me, then please post a message.
Title: Re: Die Another Day
Post by: killermonkey on November 29, 2012, 11:54:21 pm
Queued resurrections are the best way, for the reasons stated.

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.

I am also adding the ability to use the color codes in HUD Messages. So instead of 1 color for HUD messages, you can have many colors. Just slip the code into the mix just like in the localization files.
Title: Re: Die Another Day
Post by: Rick Astley on November 30, 2012, 01:49:03 pm
(http://www.mediafire.com/conv/e98734746bec2baec2a56b44647ca40a9063cfb8195d96e35df5fa3096b521806g.jpg)

Thanks for making these great looking gravestones,  I will include them in the beta 1.02 release.

I will try to make a gravestone radar icon.

fantastic work :) Kraid i love the emblems
Title: Re: Die Another Day
Post by: Joe on November 30, 2012, 03:21:00 pm
There is now a screenshot from Beta 1.02 in this topic's first post.

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.

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.

Title: Re: Die Another Day
Post by: WNxEuphonic on November 30, 2012, 07:26:24 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.



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.
Title: Re: Die Another Day
Post by: Troy on November 30, 2012, 09:56:36 pm
Yea, imagine a floating tombstone lol.
Title: Re: Die Another Day
Post by: Joe on December 02, 2012, 03:59:26 pm
I'm sorry I still haven't released Beta 1.02, it still has bugs which need to be fixed.

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.
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: [Select]
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

Crash Bug Demo Script
Code: [Select]
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
       
Title: Re: Die Another Day
Post by: Joe on December 03, 2012, 11:20:46 pm
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.
Title: Re: Die Another Day
Post by: The Cy on December 04, 2012, 02:59:31 pm
Joe, I'm glad you're working on this promising gamemode, keep it up!
Title: Re: Die Another Day
Post by: Joe on December 05, 2012, 05:09:55 pm
I've now released beta 1.02, it can be downloaded from this topic's first post.

Beta 1.02 Improvements:
1. Bugs from the previously released versions have been fixed.
2. REs are now represented by Kraid's gravestones
3. REs are now represented by a cross icon on the radar.
4. Players who kill themselves will now be eliminated.
5. Players are now shown a resurrection progress bar, instead of a remaining seconds count.
6. The count of survivors on each team will now be displayed from the start of a round, instead of becoming visible when the first elimination has taken place.
7. REs will now only been spawned when there is a free player spawn point. When a RE can't be spawned it will be added to a queue and spawned when a spawned RE is deleted.
8. The resurrection timer code is now simpler and better than it was in the previous versions.

Joe, I'm glad you're working on this promising gamemode, keep it up!

Thanks
Title: Re: Die Another Day
Post by: Joe on December 12, 2012, 05:26:17 pm
Beta 1.03
I was going to release Beta 1.03 yesterday but I didn't because I found out that this game doesn't have a kick voting system.

This is a problem for Beta 1.03 because its purpose was going to be to fix two gameplay exploits by allowing players to eliminate their team mates when friendly fire is enabled.

I was going to make this change because I think players would be much more likely to use the gameplay exploits than to eliminate their team mates intentionally or accidentally because by not using these gameplay exploits they would put themselves and their team at a competitive disadvantage.

I Will Be Able To Implement A Long Range Resurrection Ability
Players will be able to use this ability by aiming at one of their team's gravestones and holding down a key on their keyboard for 5 seconds.

There won't be a resurrection ray like in MOHAA Freeze Tag because I don't think this can be implemented with the available scripting functions. I don't want to use the debug line drawing function because it's only meant to be used for debugging.

The drawback of using a RE from long range will be that your enemies will be able to see that it is being used on their radar because its radar cross icon will become yellow. If this didn't happen, the players on a RE's opposing team would not be able to see that an enemy was using it.
Title: Re: Die Another Day
Post by: TriDefiance on December 12, 2012, 06:40:28 pm
Do you have an estimated date of when this will be finished?
Title: Re: Die Another Day
Post by: Joe on December 12, 2012, 07:51:26 pm
Do you have an estimated date of when this will be finished?

I won't be able to finish this mode until the next GE:S patch is released because it will allow me to move REs to player death locations. I will try to have everything else implemented by the 1st of January.

I will start implementing the long range resurrection ability tomorrow.

I'm going to rent a GE:S server from a dedicated server provider. This dedicated server would be dedicated to running DAD mode and I will only rent it for a month. The purpose of this server will be to promote DAD mode and to provide a server where beta version test events can take place.

Before I release version 2.00 with its addition of the long range resurrection ability, I would like to run a weekend beta test event on my DAD server for Beta 1.02. I'm hoping that some players will attend this event if I announce it in this forum topic.

When I've finished working on this mode's script, I'm hoping that the GE:S developers will be willing to make this mode into an official game mode. If they will be willing to make it into an official mode, then I won't mind if they modify its script.
Title: Re: Die Another Day
Post by: Troy on December 13, 2012, 03:23:40 am
Nice resurrection sound effect.
Title: Re: Die Another Day
Post by: TriDefiance on December 14, 2012, 12:50:37 am
I won't be able to finish this mode until the next GE:S patch is released because it will allow me to move REs to player death locations. I will try to have everything else implemented by the 1st of January.

I will start implementing the long range resurrection ability tomorrow.

I'm going to rent a GE:S server from a dedicated server provider. This dedicated server would be dedicated to running DAD mode and I will only rent it for a month. The purpose of this server will be to promote DAD mode and to provide a server where beta version test events can take place.

Before I release version 2.00 with its addition of the long range resurrection ability, I would like to run a weekend beta test event on my DAD server for Beta 1.02. I'm hoping that some players will attend this event if I announce it in this forum topic.

When I've finished working on this mode's script, I'm hoping that the GE:S developers will be willing to make this mode into an official game mode. If they will be willing to make it into an official mode, then I won't mind if they modify its script.

I think it would be best to get in touch with server owners from GE:S instead of purchasing a server for a month. I wouldn't spend money on a server for just a month. =/
Title: Re: Die Another Day
Post by: major on December 14, 2012, 04:44:51 am

I'm going to rent a GE:S server from a dedicated server provider. This dedicated server would be dedicated to running DAD mode and I will only rent it for a month. The purpose of this server will be to promote DAD mode and to provide a server where beta version test events can take place.

Before I release version 2.00 with its addition of the long range resurrection ability, I would like to run a weekend beta test event on my DAD server for Beta 1.02. I'm hoping that some players will attend this event if I announce it in this forum topic.

When I've finished working on this mode's script, I'm hoping that the GE:S developers will be willing to make this mode into an official game mode. If they will be willing to make it into an official mode, then I won't mind if they modify its script.

We have a server you can use for a month is you want to save some $. Our token of appropriation. Contact me if want to use it.
Title: Re: Die Another Day
Post by: Joe on December 14, 2012, 12:53:24 pm
We have a server you can use for a month is you want to save some $. Our token of appropriation. Contact me if want to use it.

Thanks for the offer, unfortunately I've already paid for a server.

Contrary to what I said in a previous post, I will now not wait to test Beta 1.02 at a beta test event before I release the version which has the long range resurrection ability.

I think the next version of this mode which will have the long range resurrection ability might be finished by Monday.

Beta 1.03
I was going to release Beta 1.03 yesterday but I didn't because I found out that this game doesn't have a kick voting system.

This is a problem for Beta 1.03 because its purpose was going to be to fix two gameplay exploits by allowing players to eliminate their team mates when friendly fire is enabled.
Killermonkey has told me that the next GE:S patch will allow mode scripts to use console commands.

I think I will be able to use this new script ability to create a kick vote system for this mode, so that this mode's players can kick and temporarily ban griefers who eliminate their team mates intentionally when friendly fire is enabled. Server admins will be able to set the length of kick vote bans with a cvar and they will be able to disable kick voting with a cvar.

I will also use this new script ability to create a friendly fire cvar for DAD mode which will override the normal friendly fire cvar. I want to give admins a friendly fire cvar for this mode because the consequences of a team mate kill in this mode will be worse for a team than in other team play modes, when players are able to eliminate their team mates.
Title: Re: Die Another Day
Post by: Joe on December 17, 2012, 05:44:47 pm
I think the next version of this mode (which will include the long range resurrection ability) might be finished by Wednesday.

Does anyone have an idea for what an "in use" appearance could be for the gravestones?

It would be good if someone had a good idea which would only involve changing a gravestone's texture or model because I don't think graphical effects like smoke could be spawned with the available scripting functions.

I don't think the idea I've had could be implemented with the available scripting functions: I think it would look good if in use gravestones became surrounded by blue electricity, like the yellow electricity surrounding the car in the image on this web page: http://www.gimpusers.com/tutorials/electrifying-objects-electricity-effect (http://www.gimpusers.com/tutorials/electrifying-objects-electricity-effect)
Title: Re: Die Another Day
Post by: WNxEuphonic on December 17, 2012, 07:19:53 pm
Does anyone have an idea for what an "in use" appearance could be for the gravestones?

It would be good if someone had a good idea which would only involve changing a gravestone's texture or model because I don't think graphical effects like smoke could be spawned with the available scripting functions.

I don't think the idea I've had could be implemented with the available scripting functions: I think it would look good if in use gravestones became surrounded by blue electricity, like the yellow electricity surrounding the car in the image on this web page: http://www.gimpusers.com/tutorials/electrifying-objects-electricity-effect (http://www.gimpusers.com/tutorials/electrifying-objects-electricity-effect)

You could do pulsating rings like I do in Uplink (or increase the amplitude a bit).
Title: Re: Die Another Day
Post by: Joe on December 17, 2012, 09:13:01 pm
You could do pulsating rings like I do in Uplink (or increase the amplitude a bit).

Thanks for the suggestion, I've not seen the pulsating rings in Uplink mode.

I personally think changing the appearance of the gravestone may be a better visual response to a gravestone's use than creating a pulsating ring around the gravestone because I think it could create a better looking response.

If Kraid thinks that pulsating rings will be the best looking way to show that a gravestone is being used, then I will use pulsating rings. I can't make new graphics for the gravestones' "in use" appearance myself.

Title: Re: Die Another Day
Post by: Joe on December 21, 2012, 02:23:59 pm
I'm sorry I still haven't released a version of this mode which has the long range resurrection ability. I've not yet been able to make the long range resurrection ability work because I need to find a solution to a maths vector problem.

I've asked Killermonkey for help but he hasn't replied yet, so hopefully when he does reply he can tell me what I need to do or at least give me the information I need to try to find a solution to this problem.

Kraid has had a good idea for an appearance that gravestones could have when they are being used. He would like to make cracks appear in the gravestones and he wants these cracks to glow blue or red(depending on a gravestone's side). I personally would rather see this than pulsating rings around the gravestones.

Until this appearance is ready to be implemented, I will surround the gravestones which are in use with pulsating rings.
Title: Re: Die Another Day
Post by: Joe on December 22, 2012, 02:28:19 pm
Killermonkey has now told me how to solve the problem has been preventing me from being able to make the long range resurrection ability work.

I will try to release a new version which will include the long range resurrection ability by Christmas day.

This new version may also include these improvements:
* Pulsating rings might appear around gravestones which are being used (a future version will use Kraid's idea, if we can implement it).
* A thin line might be drawn between a LR ability user and the gravestones they target, so that if their enemies see the gravestone they are aiming at, they will then be able to see where the user is. I've asked Killermonkey if I can use the line drawing debug function to do this (a comment in this function says that it should only be used for debugging).
*Resurrection sound effects.

I'm going to keep releasing the new versions as beta versions until a beta version has been tested at an event on my DAD server.

If my DAD server isn't working when I test it in a few minutes, I will talk to the server provider to find out why it's still not working.
Title: Re: Die Another Day
Post by: Joe on December 22, 2012, 03:50:42 pm
My GE:S DAD server is still not working, despite me paying a server provider to setup a GE:S server for me on the 12th of December.

I only intended to rent a DAD server for one month, so I've requested the cancellation of my DAD server on the 1st of January, which is the date when its current billing period ends.

So my GE:S server probably won't be available to play DAD on in its last week.
Title: Re: Die Another Day
Post by: TriDefiance on December 23, 2012, 12:28:56 am
My GE:S DAD server is still not working, despite me paying a server provider to setup a GE:S server for me on the 12th of December.

I only intended to rent a DAD server for one month, so I've requested the cancellation of my DAD server on the 1st of January, which is the date when its current billing period ends.

So my GE:S server probably won't be available to play DAD on in its last week.

Get in touch with a server administrator on any of the GE:S servers. You can try WNx, [1138], , or TG
Title: Re: Die Another Day
Post by: Troy on December 23, 2012, 05:38:34 am
If you using JestServers, your server might have crashed or is stopped.  There's a control panel to reboot it.  I run a server and could host your mode if need be.
Title: Re: Die Another Day
Post by: Joe on December 31, 2012, 01:23:10 pm
I'm going to resume my development of this mode today.

I didn't release a new version on Christmas day because I wasn't able to make the GE:S trace function detect capture area entities (REs are implemented as capture area entities and represented by gravestone models), so I wasn't able to make the long range resurrection ability work. I had not worked on the other improvements I said I might include in this new version, so I decided to have a break from developing this mode.

I can make the trace ray touch a gravestone model but the gravestone model's associated capture area entity isn't returned by the trace function. I've tried using the TRACE_WORLD option.

If you using JestServers, your server might have crashed or is stopped.  There's a control panel to reboot it.  I run a server and could host your mode if need be.
Thanks for the advice, I wasn't using JestServers. I don't think my server was using GE:S server software on the 22nd of December.
Title: Re: Die Another Day
Post by: Joe on January 10, 2013, 06:45:10 pm
I will release a new version soon, it will include resurrection sound effects.
Title: Re: Die Another Day
Post by: Joe on March 06, 2013, 06:21:51 pm
Title: Re: Die Another Day
Post by: Joe on March 08, 2013, 07:05:03 pm
The latest released version of this mode can be downloaded from this topic's first post.

I've created a seperate forum topic for DAD mode where forum members can post translations: http://forums.geshl2.com/index.php/topic,7482.msg78055.html#msg78055 (http://forums.geshl2.com/index.php/topic,7482.msg78055.html#msg78055)

All the text which will need to be translated is listed in that topic's first post.
Title: Re: Die Another Day
Post by: Joe on March 11, 2013, 02:22:08 pm
I will release a new version of this mode this week which will use the French & German translations that have been created by kraid and namajnaG.

My Polish friend is working on a Polish translation, so I will wait for him to finish it before I release the new version.
Title: Re: Die Another Day
Post by: Joe on April 02, 2013, 11:44:01 am
I've released Alpha 1.03, its changes are listed in this topic's first post.
Title: Re: Die Another Day
Post by: Joe on April 11, 2013, 11:24:29 pm
Alpha 1.04 Development Status

I'm now not going to create a DAD bot for this version because I've had trouble using the current GE:S version's bot scripting system. So I will wait until I can use the next GE:S version's improved bot scripting system.

Development Task List (Updated: 16/4    13:05 GMT + 1)

Implemented:
• Add Spanish translation.
• Add Italian translation.
• Add Polish translation.
• Make pulsating rings appear beneath active REs.
• Prevent players from having to wait behind bots in their side's resurrection queue.
• Display MI6 and Janus survivor counts on eliminated players' screens.
• Display MI6 and Janus survivor counts on spectators' screens.
• Tell eliminated players what their resurrection queue position is by using a permanent HUD message instead of occasional pop up messages.
Title: Re: Die Another Day
Post by: Joe on April 20, 2013, 02:22:45 pm
I've now released Alpha 1.04 but I've not included resurrection sound effects with this version because I want to make them sound better and I want to make sure that I correctly use these licensed sound effects.

The released versions of this mode can be downloaded from this topic's first post.
Title: Re: Die Another Day
Post by: Joe on May 14, 2013, 07:53:05 pm
I've created  a GE:S wiki page (http://wiki.geshl2.com/community/scenarios/die_another_day) for this mode.
Title: Re: Die Another Day
Post by: The Cy on May 14, 2013, 08:07:23 pm
Hey Joe, you do a great job.
Title: Re: Die Another Day
Post by: killermonkey on May 15, 2013, 12:04:22 am
I've been super busy with work recently. Going to try and get you the 4.2.3 preview asap for your testing.
Title: Re: Die Another Day
Post by: Joe on May 16, 2013, 11:03:47 am
Thanks KillerMonkey.

Hey Joe, you do a great job.

Thanks
Title: Re: Die Another Day
Post by: Joe on May 31, 2013, 12:54:15 pm
Alpha 1.10's Development Status

Development Task
Status
Extra Info
Implement The Long Range Resurrection Ability.Done
Allow server owners to change the duration of resurrections with a CVAR.Done
Show all players the location of a used RE on their radar.DoneServer owners will be able to set the duration of this with a CVAR. In MOHAA Freeze Tag, players are told where their enemies' REs have been used. DAD mode is meant to be a recreation of this popular MOHAA mode, this is why I'm implementing this gameplay change.
Move RE Gravestones To Player Death Locations.UsableI still need to create an efficient function  (http://forums.geshl2.com/index.php/topic,7617.msg78944.html#msg78944)for working out the location of the ground beneath mid-air players, so gravestones can't yet be spawned beneath players who are killed in mid-air.
Display MI6 And Janus LRR Ability Lasers.Done
Add A Resurrection Sound Effect To This Mode.Can't be implemented in the current GE:S version The GEUtil.StopSound() function can't stop the resurrection sound when resurrections fail. (http://forums.geshl2.com/index.php/topic,7607.0.html)
Allow Players To Resurrect Multiple Team Mates Simultaneously.Done
Implement a DAD mode bot.Won't be implemented in this version.
Change Elim&Resurrection Messages' Font Colour To Blue & Red.Done
Add A Dutch Translation.CancelledThere's no Dutch translation file in the wiki (http://wiki.geshl2.com/) so I don't think the new GE:S version will have it.
Add Translations To The Official Language Files.Done
Fix The Friendly Fire Gameplay Exploits.Done
Make A Gravestone's HUD Objective Icon Become Yellow When It's Being Used.Done
Title: Re: Die Another Day
Post by: Joe on June 28, 2013, 10:47:48 pm
I've not spent much time working on this mode this month but I will start working on it again next week.

The latest released version can be downloaded from this topic's first post.
Title: Re: Die Another Day
Post by: Joe on July 06, 2013, 06:51:10 pm
I've now implemented the long range resurrection ability.

I will try to finish the new alpha version by July 14th.
Title: Re: Die Another Day
Post by: Joe on July 14, 2013, 04:56:45 pm
I don't think I will be able to release a new DAD mode version today, but I do think that I will be able to release version Alpha 1.10 soon.
Title: Re: Die Another Day
Post by: Joe on July 16, 2013, 04:27:29 pm
WARNING: Alpha 1.04 And Prior Releases May Contain Bugs
Killermonkey has noticed a mistake in the script for the latest WIP version of this mode, this mistake might be capable of causing bugs in all the alpha version's I've released.

As a precaution I have now removed the download attachment for Alpha 1.04 from this topic's first post.
Title: Re: Die Another Day
Post by: Joe on July 19, 2013, 05:33:00 pm
I will finish and release Alpha 1.10 tomorrow.
Title: Re: Die Another Day
Post by: Joe on July 21, 2013, 07:37:46 pm
I will probably release Alpha 1.10 tomorrow, when I've done some more bug testing.
Title: Re: Die Another Day
Post by: Joe on July 22, 2013, 05:11:36 pm
There's still one bug I need to find the cause of and then fix, before I can release the new version of this mode.

When I've fixed all the bugs I've found and have released it, I want to arrange a Alpha 1.10 public test event for this Sunday. So I will create a forum topic where this event can be discussed.
Title: Re: Die Another Day
Post by: The Cy on July 22, 2013, 07:44:08 pm
When I've fixed all the bugs I've found and have released it, I want to arrange a Alpha 1.10 public test event for this Sunday. So I will create a forum topic where this event can be discussed.

nice man, keep it up!
Title: Re: Die Another Day
Post by: Joe on July 26, 2013, 11:05:37 am
Hi,

I now don't want there to be a public test event this weekend because I've been experiencing bugs with this version which I've not been able to fix and I believe they are being caused by malicious software on my old single core PC's insecure Windows XP OS. So I can't fix these bugs and I can't test this version on my PC without experiencing bugs. I also believe that this malicious software is responsible for my Eclipse IDE not being usable (because it crashes all the time).

I don't want to release this new DAD mode version and arrange a public test event for it, until I can play it with bots on my PC without experiencing bugs.

So I'm going to buy a new PC next week, that will have a modern and more secure Windows OS. When I can run Alpha 1.10 with bots on this PC, without experiencing bugs, I will release this version and I will try to arrange a weekend public test event.
Title: Re: Die Another Day
Post by: killermonkey on July 26, 2013, 05:23:00 pm
Joe, mind sending me the code so I can do a quick review and test on my end?
Title: Re: Die Another Day
Post by: Joe on August 15, 2013, 12:18:17 pm
Hi guys,

I've not been able to afford to buy a modern PC with a secure Windows OS. So I'm stuck with my malicious software infested Windows XP PC, which now has malicious software preventing it from using a graphics driver.

I could obtain a £70 - £120 loan so that I can buy a used Windows 7 PC/ a new Windows OS for my existing PC. But I don't want to have this debt.

So I'm going to ask some experienced GE:S mode developers if they would be interested in taking over the development of this mode. If no one I ask wants to take over the development of this mode, then I will post a message in this forum topic inviting anyone to take over its development.
Title: Re: Die Another Day
Post by: Jonathon [SSL] on August 15, 2013, 04:14:57 pm
Hi guys,

I've not been able to afford to buy a modern PC with a secure Windows OS. So I'm stuck with my malicious software infested Windows XP PC, which now has malicious software preventing it from using a graphics driver.

I could obtain a £70 - £120 loan so that I can buy a used Windows 7 PC/ a new Windows OS for my existing PC. But I don't want to have this debt.

So I'm going to ask some experienced GE:S mode developers if they would be interested in taking over the development of this mode. If no one I ask wants to take over the development of this mode, then I will post a message in this forum topic inviting anyone to take over its development.

Why not reinstall XP?
Title: Re: Die Another Day
Post by: Joe on August 15, 2013, 04:34:02 pm
I probably wouldn't be able to reactivate it because its student license should now be invalid, now that I'm no longer a student.

I've tried to remove the malware and viruses with free security software but there's still malicious software on it which is preventing its graphics driver from working (even when it is reinstalled).

I had given up trying to make my XP OS secure enough to use, but I will try again.
Title: Re: Die Another Day
Post by: terps4life90 on August 15, 2013, 08:55:35 pm
Why not reinstall XP?

LOL XP SUCKS ASSS!
Title: Re: Die Another Day
Post by: killermonkey on August 16, 2013, 02:11:22 pm
I would be interested in making this mode an official mode if the community supports that.

I want to fold in more community driven modes as officially supported in the coming months.

As for your PC Joe, might I suggest simply installing Linux on your machine then running windows in a virtual environment (such as VirtualBox) and doing your coding in Linux?

You can run GES in a virtual env quite easily, in fact I believe GES works under WINE as well.
Title: Re: Die Another Day
Post by: Joe on August 21, 2013, 02:58:28 pm
I've been able to reactivate my Windows XP OS after reinstalling it on a formatted partition. I'm not going to try to run GE:S and test DAD Alpha 1.10, until I've received the new graphics card I've ordered to replace my PC's faulty graphics card. I will receive it by August 29th. I will then test Alpha 1.10 and I will release it asap.

Quote
I would be interested in making this mode an official mode if the community supports that.
I would like DAD mode to become an official mode because I think servers would be more likely to use it.

I wouldn't mind what the GE:S dev team programmers do with the code I've created. Though I would like them to keep this mode's gameplay based on the gameplay in the popular MOHAA Freeze Tag mode.

I've responded to KillerMonkey's suggestions about my PC's problems by sending him a message.
Title: Re: Die Another Day
Post by: Joe on August 21, 2013, 04:19:12 pm
Alpha 1.10's Development Status

Development state: awaiting pre-release testing.

Development Task
Status
Extra Info
Implement The Long Range Resurrection Ability.Done
Allow server owners to change the duration of resurrections with a CVAR.Done
Show all players the location of a used RE on their radar.DoneServer owners will be able to set the duration of this with a CVAR. In MOHAA Freeze Tag, players are told where their enemies' REs have been used. DAD mode is meant to be a recreation of this popular MOHAA mode, this is why I'm implementing this gameplay change.
Move RE Gravestones To Player Death Locations.UsableI still need to create an efficient function  (http://forums.geshl2.com/index.php/topic,7617.msg78944.html#msg78944)for working out the location of the ground beneath mid-air players, so gravestones can't yet be spawned beneath players who are killed in mid-air.
Display MI6 And Janus LRR Ability Lasers.Done
Add A Resurrection Sound Effect To This Mode.Can't be implemented in the current GE:S version The GEUtil.StopSound() function can't stop the resurrection sound when resurrections fail. (http://forums.geshl2.com/index.php/topic,7607.0.html)
Allow Players To Resurrect Multiple Team Mates Simultaneously.Done
Implement a DAD mode bot.Won't be implemented in this version.
Change Elim&Resurrection Messages' Font Colour To Blue & Red.Done
Add Translations To The Official Language Files.Done
Fix The Friendly Fire Gameplay Exploits.Done
Make A Gravestone's HUD Objective Icon Become Yellow When It's Being Used.Done
Title: Re: Die Another Day
Post by: Joe on August 21, 2013, 04:29:26 pm
I've created a new DAD mode forum topic here: http://forums.geshl2.com/index.php/topic,7646.0.html (http://forums.geshl2.com/index.php/topic,7646.0.html)

It has a poll asking forum members if they think this mode should become an official mode.
Title: Re: Die Another Day
Post by: terps4life90 on August 22, 2013, 03:55:05 pm
I would be interested in making this mode an official mode if the community supports that.

LOL that is the funniest thing i have heard all day. In all seriousness.....your joking right killermonkey?
Title: Re: Die Another Day
Post by: TriDefiance on September 02, 2013, 07:32:25 pm
LOL that is the funniest thing i have heard all day. In all seriousness.....your joking right killermonkey?

I'm proud to see Joe this dedicated to a mod so old! Creating a gamemode that hasn't been thought of in a while. Cut him some slack man!
Title: Re: Die Another Day
Post by: Joe on September 02, 2013, 08:34:39 pm
My PC still has a faulty graphics card so I can't test Alpha 1.10 yet. But I have ordered the parts for my new PC.

So when I've assembled it (I may not receive all of its parts until September 10th), I will resume my development of this mode and I will release alpha 1.10 asap.
 
Title: Re: Die Another Day
Post by: Joe on December 10, 2013, 02:48:04 pm
I'm sorry I haven't worked on this mode since September, I will resume my work on it today.
Title: Re: Die Another Day
Post by: StupidMarioBros1Fan[1138] on December 11, 2013, 01:37:11 am
So everything on your computer is good to go right? That sucks what happened...5 months ago.
Title: Re: Die Another Day
Post by: Joe on December 11, 2013, 03:15:26 pm
Quote
So everything on your computer is good to go right?
Yes, so I'm hoping the hacker(s) who interfered with my development of this mode months ago, won't bother to hack my new PC.

I've not yet experienced the error which prevented me from releasing Alpha 1.10 months ago. Imo it was probably caused by malicious software changing the values of DAD mode variables to make them invalid. The invalid values these variables had could not have been assigned by mistakes in my code.

Before I release Alpha 1.10 now, I'm going to thoroughly test it and I'm going to check all of this mode's code to try to spot mistakes which could cause bugs to occur.

Quote
...5 months ago.
I know I should have finished this mode months ago, so I'm sorry that I've been doing a crap job of developing it.

At least I've had the dedication to spend countless hours of my free time developing this mode and I've not abandoned its development. If I ever decide to not finish this mode I will announce this in this forum topic and I will upload my latest code so that someone can take over the responsibility of developing this mode.
Title: Re: Die Another Day
Post by: StupidMarioBros1Fan[1138] on December 11, 2013, 05:42:50 pm
I'm so sorry, you took that last part of my reply the wrong way. I wasn't upset about it being five months since any updates for us about the mode, I meant that it happened five months ago, and I didn't know about it until now. :P Trust me I know what it's like when it comes to completed mods or stuff should've been released a while back, got so many unfinished & finished stuff for Smash Bros Brawl it isn't funny. xD
Title: Re: Die Another Day
Post by: Joe on December 17, 2013, 12:57:27 pm
I will try to finish Alpha 1.10 before Christmas day.

Last week I made a lot of changes to this mode's script which have made its code more organised. So I'm now fixing all the bugs these changes have caused and I think I've now fixed the majority of them.
Title: Re: Die Another Day
Post by: Joe on January 04, 2014, 10:18:28 pm
There's at least one bug I will need to fix before I can release the latest DAD mode version, it's hard to fix because it occurs sporadically for particular spawned resurrection entities and I have no idea why it is happening.
Quote
Traceback (most recent call last):
  File "c:\program files (x86)\steam\steamapps\sourcemods\gesource\scripts\python\GamePlay\DieAnotherDay.py", line 217, in OnCaptureAreaEntered
    if REArea.GetTeamNumber() == player.GetTeamNumber() and self.REs.REUsable(REArea):
  File "c:\program files (x86)\steam\steamapps\sourcemods\gesource\scripts\python\GamePlay\DieAnotherDay.py", line 755, in REUsable
    return area in self.REs.values() and not area in self.disabledREs and not area in self.usedREs
RuntimeError: Access violation - no RTTI data!

Code: [Select]
def REUsable(self,area):
      return area in self.REs.values() and not area in self.disabledREs and not area in self.usedREs

Code: [Select]
class REDict:
        def __init__(self,DADP):
            self.unusedAreaID = 0
            self.DAD = DADP
            self.REs = {}
            self.REPulseTimers = {}
            self.REsWhichNeedToBeMoved = {}
            self.disabledREs = []
            self.usedREs = []
           
        def flagREAsUsed(self,RE):
            self.usedREs.append(RE)
           
        def hasREBeenUsed(self,RE):
            return RE in self.usedREs
           
        def getListOfTeamsREs(self,team):
            teamsREs = []
            for RE in self.REs.values():
                if RE.GetTeamNumber() == team: teamsREs.append(RE)
            return teamsREs
           
        def cleanup(self):
            self.DAD = None
            self.REs = None
            self.REPulseTimers = None
            self.REsWhichNeedToBeMoved = None
            self.disabledREs = None
            self.usedREs = None
           
        def spawnNewResurrectionEntity(self,victim,team,afterSpawnMoveTo=None):
            newAreasID = str(self.unusedAreaID)
            self.unusedAreaID += 1
            self.spawnResurrectionEntity(newAreasID,team,afterSpawnMoveTo)
       
        def spawnResurrectionEntity(self,areaID,team,afterSpawnMoveTo=None):
            skinNumber = 1
            if team == GEGlobal.TEAM_MI6: skinNumber = 0
           
            self.DAD.tokenManager.SetupCaptureArea(areaID,
                                                   radius = 35,
                                                   model="models/gameplay/gravestone.mdl",
                                                   limit=1,
                                                   #glow_color=self.DAD.getSidesColour(team),
                                                   #glow_dist=0,
                                                   skin=skinNumber,
                                                   rqd_team=team)
           
            if afterSpawnMoveTo != None: self.needsToBeMoved(areaID,afterSpawnMoveTo)
           
        def makeREGlow(self,RE):
            self.DAD.tokenManager.SetupCaptureArea(RE.GetGroupName(),glow_dist=350)
           
        def disableREGlow(self,RE):
            self.DAD.tokenManager.SetupCaptureArea(RE.GetGroupName(),glow_dist=0)
#         
        def REUsable(self,area):
            return area in self.REs.values() and not area in self.disabledREs and not area in self.usedREs
       
        def newRESpawned(self,area):
            self.disabledREs.append(area)
            idP = area.GetGroupName()
            self.REs[idP] = area
            self.REPulseTimers[idP] = DieAnotherDay.REDict.RingPulseTimer(self.DAD,area)
            self.disabledREs.remove(area)
           
        def deleteRE(self,RE):
            idP = RE.GetGroupName()
            del self.REs[idP]
            del self.REPulseTimers[idP]
            if self.REsWhichNeedToBeMoved.has_key(idP): del self.REsWhichNeedToBeMoved[id]
            if RE in self.disabledREs: self.disabledREs.remove(RE)
            if RE in self.usedREs: self.usedREs.remove(RE)
            self.DAD.tokenManager.RemoveCaptureArea(idP)
           
        def doesREExsist(self,area):
            return area in self.REs.values()
           
        def deleteREAfterDelay(self,RE,delay):
            timer = DieAnotherDay.ExtCallbackTimer(self.DAD.timerTracker,self.deleteREAfterDelayCallback,RE)
            timer.start(delay)
           
        def deleteREAfterDelayCallback(self,timer,update_type,RE):
            if update_type == Timer.UPDATE_FINISH: self.deleteRE(RE)
           
        def deleteAll(self):
            for REID in self.REs: self.DAD.tokenManager.RemoveCaptureArea(REID)
            self.REs = {}
            self.REPulseTimers = {}
            self.REsWhichNeedToBeMoved = {}
            self.disabledREs = []
            self.unusedAreaID = 0
           
        def isREDisabled(self,REArea):
            return REArea in self.disabledREs
           
        def makeREInvisible(self,RE):
            # Make RE Invisible
            self.DAD.tokenManager.SetupCaptureArea(RE.GetGroupName(),model="") #glow_dist=0
           
        def afterDelayChangeRERadarIcon(self,RE,icon,colour,delay):
            timer = DieAnotherDay.ExtCallbackTimer(self.DAD.timerTracker,self.changeRERadarIconAfterDelayCB,{"REArea":RE,"icon":icon,"colour":colour})
            timer.start(delay)
           
        def changeRERadarIconAfterDelayCB(self,timer,update_type,parameters):
            if update_type == Timer.UPDATE_FINISH: self.changeRERadarIcon(parameters["REArea"],parameters["icon"],parameters["colour"])
           
        def changeRERadarIcon(self,RE,newIcon,colour):
            self.DAD.radar.DropRadarContact(RE)
            self.DAD.radar.AddRadarContact(RE,GEGlobal.RADAR_TYPE_OBJECTIVE,True,newIcon,colour)
           
        def getMRELocations(self):
            foundLocations = []
            for RE in self.REs:
                if RE.GetTeamNumber() == GEGlobal.TEAM_MI6: foundLocations.append(RE.GetAbsOrigin())
            return foundLocations
       
        def getJRELocations(self):
            foundLocations = []
            for RE in self.REs:
                if RE.GetTeamNumber() == GEGlobal.TEAM_JANUS: foundLocations.append(RE.GetAbsOrigin())
            return foundLocations
           
        def needsToBeMoved(self,areasID,moveTo):
            self.REsWhichNeedToBeMoved[areasID] = moveTo
           
        def moved(self,RE):
            REID = RE.GetGroupName()
            if self.REsWhichNeedToBeMoved.has_key(REID): del self.REsWhichNeedToBeMoved[REID]
           
        def getMoveToLocation(self,area):
            REID = area.GetGroupName()
            if self.REsWhichNeedToBeMoved.has_key(REID): return self.REsWhichNeedToBeMoved[REID]
            return None
           
        def isPulsating(self,RE):
            return self.REPulseTimers[RE.GetGroupName()].isPulsating()
           
        def startPulsatingRings(self,REArea):
            self.REPulseTimers[REArea.GetGroupName()].start()
       
        def stopPulsatingRings(self,idP):
            self.REPulseTimers[idP].stop()

Title: Re: Die Another Day
Post by: killermonkey on January 05, 2014, 04:37:12 pm
Seems like this error is caused by bad C++ pointers still being held by Python. Most likely due to storing an entity in an array for a long duration.

Suggest that you use Entity Handles or simply the Entity ID for storage in a persistent array:

Code: [Select]
def AddAnEntity( ent, array_store ):
    array_store.append( GEEntity.EntityHandle( ent ) )

def DoesEntityExist( ent, array_store ):
    return ent in array_store

Note that there are implicit conversions occurring to do comparisons against entity instances, entity handles, and even entity ID numbers.

The following are equivalent:
Code: [Select]
ent_instance == ent_instance: TRUE

ent_instance == GEEntity.EntityHandle( ent_instance ): TRUE

ent_instance == ent_instance.GetUID(): TRUE
Title: Re: Die Another Day
Post by: Joe on January 08, 2014, 09:54:06 pm
Thanks Killermonkey, I will make the changes you've suggested tommorow.

I'm going to put this mode's script into a GitHub.com (https://github.com/) repository tommorow so that anyone who wants to help me get it finished can download a copy of the script and then commit their edited copy.

I will accept revisions which fix bugs. However if a revision changes this mode's gameplay,graphics or the behaviour of its bots then I may not accept the changes, so please ask me for my approval before you spend time coding such changes. Also I may not accept a revision intended to improve the quality of a script's code because I may not agree that the changes improves the code's quality.

I will also put this mode's bot script into this GitHub repository. I would gladly delegate the task of developing a DAD mode bot to someone else so that I would have less work to do. It just needs to be a death match bot which can find and use resurrection entities by standing next to them and by using the long range resurrection ability.
Title: Re: Die Another Day
Post by: Proxie on January 10, 2014, 12:13:13 am
Have you made a GitHub repo yet?  I could try fixing some bugs for you

My GitHub (https://github.com/punisher186)
Title: Re: Die Another Day
Post by: Joe on January 10, 2014, 04:40:28 pm
Thanks Proxie, I will make a Github repository later.
Title: Re: Die Another Day
Post by: Joe on January 10, 2014, 09:18:13 pm
I've created a GitHub.com repository for this mode and in my first commit I've uploaded the latest DAD mode script: Link (https://github.com/JASheppard/GES_DieAnotherDay_Mode)

Server admins: please only use released DAD mode versions on your server, the unfinished versions which will be stored in this repository will probably have bugs which could spoil this mode's gameplay or prevent this mode from loading.

How to use the GitHub.com repository
Before you work on something: please check the main repository's issues list (https://github.com/JASheppard/GES_DieAnotherDay_Mode/issues) to ensure no one is already working on it and please also add the issue your working on to this list.

I'm new to Git and version management software but I think the following instructions are correct:

1. Setup git
(See: Git Bootcamp: Setup Git) (https://help.github.com/articles/set-up-git))
2. Create your own DAD mode repository by copying (Forking) the main (https://github.com/JASheppard/GES_DieAnotherDay_Mode) DAD mode repository
(See: Git Bootcamp: Fork A Repo (https://help.github.com/articles/fork-a-repo))
3. Commit your changes to the DAD mode files in your copy of the main repository.
(See: Git Bootcamp: Create A Repo     Step 2 & Step 3 (https://help.github.com/articles/create-a-repo))
4. Get updates from the main repository.
(See: Git Bootcamp: Fork A Repo : Step 3: Configure remotes  and  Pull in upstream changes  (https://help.github.com/articles/fork-a-repo))
5. When your ready to commit the changes in your repository to the main DAD repository send me a pull request.
(See: Using Pull Requests (https://help.github.com/articles/using-pull-requests))
 
Title: Re: Die Another Day
Post by: Joe on January 19, 2014, 07:28:44 pm
I've fixed the "no RTTI data" bug now but I've noticed that the survivor counts become incorrect when a player has their team changed by the auto balance.

So I will need to fix this before I can release the new DAD mode version.
Title: Re: Die Another Day
Post by: Joe on February 16, 2014, 05:27:03 pm
I've fixed the survivor count displays and I now intend to work on DAD mode every day until it's finished.

I will try to finish and release Alpha 1.10 within the next few days.
Title: Re: Die Another Day
Post by: Joe on February 24, 2014, 12:51:44 pm
I'm thoroughly testing the latest version of this mode now with bots and a checklist of everything that should happen when there's no bugs.

I will also test it with a friend on a multiplayer server today or within the next few days.

I will then release the latest version of this mode and then I will make sure that a playable version of this mode is always downloadable.

I regret not quickly releasing a playable version of this mode after I removed the download link for the previously released version as a precaution because I had made a mistake in its code which could have caused bugs.

Title: Re: Die Another Day
Post by: Joe on February 28, 2014, 12:51:45 pm
I will try to finish and release the latest DAD mode version this weekend but I will probably need to spend more than 2 days finishing it.

https://github.com/JASheppard/GES_DieAnotherDay_Mode/
Title: Re: Die Another Day
Post by: Joe on March 04, 2014, 05:15:06 pm
I'm sorry I've as usual said that I was going to have a new version of this mode finished in x days time and then failed to finish it.

I've been distracted from finishing the latest version by my responsibility to finish a programming task for another game. I thought I had finished this task and could focus on finishing this GE:S mode, but another programmer who was going to finalise my other programming task had trouble doing so, so I decided to finalise it so he wouldn't have to.

I will have this other programming task finished soon and then maybe by this weekend I will be ready to release the latest version of this mode.
Title: Re: Die Another Day
Post by: Joe on March 22, 2014, 02:02:35 pm
I will resume my work on this mode now and I will get it finished as soon as I can.
Title: Re: Die Another Day
Post by: Joe on March 22, 2014, 07:33:51 pm
I've improved the Github repository (https://github.com/JASheppard/GES_DieAnotherDay_Mode) I created for this mode and I've created a page in its Wiki in case anyone wants to help me finish this mode:

How To: Setting Up Your "gesource" Folder To Use This Repository (https://github.com/JASheppard/GES_DieAnotherDay_Mode/wiki/How-To:-Setting-Up-Your-%22gesource%22-Folder-To-Use-This-Repository)
Title: Re: Die Another Day
Post by: killermonkey on March 22, 2014, 08:11:43 pm
Awesome, thanks Joe. Don't worry about timeliness. Quality is more important.
Title: Re: Die Another Day
Post by: Joe on April 22, 2014, 09:08:03 pm
I will probably release Alpha 1.10 tomorrow.
Title: Re: Die Another Day
Post by: Joe on April 23, 2014, 09:50:39 pm
I will release Alpha 1.10 tomorrow.
Title: Re: Die Another Day
Post by: Joe on April 24, 2014, 11:14:27 pm
Released: Version Alpha 1.10

Better late than never, I've finally finished and released Alpha 1.10:
Download page (https://github.com/JASheppard/GES_DieAnotherDay_Mode/releases/tag/v1.10-alpha)

Version Changelist
1. Players can now resurrect their team mates by firing an infinite range resurrection beam at their side's resurrection entities.
2. Players can now resurrect multiple team mates simultaneously.
3. This mode now has an appropriate score system: player round scores no longer affect their team's match score so now the only way to score match points is by wining rounds by eliminating all the members of the opposing team.
4. Resurrection entities will now spawn at player death locations, except when players are killed on ladders or by falling off maps.
5. Players are no longer allowed to spawn after joining a team when there's eliminated players, they will instead be eliminated so they won't spawn until a team mate resurrects them or a new round begins.
6. Players can now increase their round scores by resurrecting team mates. Kills and resurrections are each worth 1 point.
7. When friendly fire is enabled players will now be able to eliminate their team mates: I've decided to allow this because allowing team mate kill victims to respawn allows them to respawn with full health. So a player could prevent a team mate from being eliminated by killing them when they have low health so that they can respawn with full health.
8. Server owners can now change the duration of resurrections by using this new CVAR: dad_resTime
9. Now when players are resurrected the radar icon for the used RE will become a "Run" icon and will be highlighted yellow for a few seconds showing opposing players where the RE was used. The display duration of this "used RE" radar icon can be changed with this new CVAR: dad_usedRELocationRevealTime
10. Elimination and resurrection announcement messages are now coloured blue and red for the different teams.
11. The triangle objective icons above resurrection entities now become yellow when they are being used.
12. This mode's translations are now included in the GoldenEye:Source language files.
Title: Re: Die Another Day
Post by: Joe on May 07, 2014, 05:59:44 pm
I've noticed that I didn't remove a onRoundBegin() HUD "This version is not meant to be played" message from my Alpha 1.10 release so I've now removed this message and released Alpha 1.10B:
https://github.com/JASheppard/GES_DieAnotherDay_Mode/releases/tag/v1.10B-alpha
Title: Re: [Gameplay] Die Another Day
Post by: papel on January 14, 2018, 02:58:25 pm
Hello guys.
I am trying to run the mode but it is displaying this error. Can someone help me?

Traceback (most recent call last):
  File "c:\dedicated server\gesource\python/ges\GamePlayManager.py", line 46, in LoadScenario
    scenario = getattr( sys.modules[module], scenario_name )()
KeyError: 'GamePlay.DieAnotherDay'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\dedicated server\gesource\python/ges\GamePlayManager.py", line 50, in LoadScenario
    __import__( module, globals(), locals() )
  File "c:\dedicated server\gesource\python/ges\GamePlay\DieAnotherDay.py", line 3, in <module>
    from Utils.GETimer import TimerTracker, Timer
ImportError: No module named 'Utils'
Title: Re: [Gameplay] Die Another Day
Post by: Kujo on July 12, 2020, 09:15:47 pm
In case anyone else is looking for the 5.0 updated version of this game mode, darkdiplomat's fork seems to work.

https://github.com/darkdiplomat/GES_DieAnotherDay_Mode (https://github.com/darkdiplomat/GES_DieAnotherDay_Mode)