Editing and Customization > Community Content

[Gameplay] Die Another Day

<< < (17/21) > >>

Joe:
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.

Joe:
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!
--- End quote ---


--- Code: ---
def REUsable(self,area):
      return area in self.REs.values() and not area in self.disabledREs and not area in self.usedREs
--- End code ---


--- Code: ---
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()
--- End code ---

killermonkey:
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: ---
def AddAnEntity( ent, array_store ):
    array_store.append( GEEntity.EntityHandle( ent ) )

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

--- End code ---

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: ---
ent_instance == ent_instance: TRUE

ent_instance == GEEntity.EntityHandle( ent_instance ): TRUE

ent_instance == ent_instance.GetUID(): TRUE

--- End code ---

Joe:
Thanks Killermonkey, I will make the changes you've suggested tommorow.

I'm going to put this mode's script into a 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.

Proxie:
Have you made a GitHub repo yet?  I could try fixing some bugs for you

My GitHub

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version