浏览代码

moved to /usr/darren/player/otp/src/level

Darren Ranalli 21 年之前
父节点
当前提交
28e0aaddec
共有 41 个文件被更改,包括 0 次插入4409 次删除
  1. 0 37
      direct/src/level/AmbientSound.py
  2. 0 32
      direct/src/level/AttribDesc.py
  3. 0 130
      direct/src/level/BasicEntities.py
  4. 0 191
      direct/src/level/CutScene.py
  5. 0 54
      direct/src/level/DistributedEntity.py
  6. 0 43
      direct/src/level/DistributedEntityAI.py
  7. 0 148
      direct/src/level/DistributedInteractiveEntity.py
  8. 0 140
      direct/src/level/DistributedInteractiveEntityAI.py
  9. 0 815
      direct/src/level/DistributedLevel.py
  10. 0 228
      direct/src/level/DistributedLevelAI.py
  11. 0 7
      direct/src/level/EditMgr.py
  12. 0 60
      direct/src/level/EditMgrAI.py
  13. 0 34
      direct/src/level/EditMgrBase.py
  14. 0 52
      direct/src/level/EditorGlobals.py
  15. 0 149
      direct/src/level/Entity.py
  16. 0 52
      direct/src/level/EntityCreator.py
  17. 0 65
      direct/src/level/EntityCreatorAI.py
  18. 0 40
      direct/src/level/EntityCreatorBase.py
  19. 0 126
      direct/src/level/EntityTypeDesc.py
  20. 0 134
      direct/src/level/EntityTypeRegistry.py
  21. 0 126
      direct/src/level/EntityTypes.py
  22. 0 39
      direct/src/level/EntrancePoint.py
  23. 0 391
      direct/src/level/Level.py
  24. 0 12
      direct/src/level/LevelConstants.py
  25. 0 80
      direct/src/level/LevelMgr.py
  26. 0 59
      direct/src/level/LevelMgrAI.py
  27. 0 12
      direct/src/level/LevelMgrBase.py
  28. 0 460
      direct/src/level/LevelSpec.py
  29. 0 51
      direct/src/level/LevelUtil.py
  30. 0 143
      direct/src/level/LogicGate.py
  31. 0 42
      direct/src/level/ModelEntity.py
  32. 0 57
      direct/src/level/PathEntity.py
  33. 0 53
      direct/src/level/PropSpinner.py
  34. 0 3
      direct/src/level/Sources.pp
  35. 0 124
      direct/src/level/SpecUtil.py
  36. 0 52
      direct/src/level/VisibilityBlocker.py
  37. 0 67
      direct/src/level/VisibilityExtender.py
  38. 0 57
      direct/src/level/ZoneEntity.py
  39. 0 16
      direct/src/level/ZoneEntityAI.py
  40. 0 28
      direct/src/level/ZoneEntityBase.py
  41. 0 0
      direct/src/level/__init__.py

+ 0 - 37
direct/src/level/AmbientSound.py

@@ -1,37 +0,0 @@
-from direct.interval.IntervalGlobal import *
-import BasicEntities
-import random
-
-class AmbientSound(BasicEntities.NodePathEntity):
-    def __init__(self, level, entId):
-        BasicEntities.NodePathEntity.__init__(self, level, entId)
-        self.initSound()
-
-    def destroy(self):
-        self.destroySound()
-        BasicEntities.NodePathEntity.destroy(self)
-
-    def initSound(self):
-        if not self.enabled:
-            return
-        if self.soundPath == '':
-            return
-        self.sound = base.loadSfx(self.soundPath)
-        if self.sound is None:
-            return
-        self.soundIval = SoundInterval(self.sound, node=self,
-                                       volume=self.volume)
-        self.soundIval.loop()
-        self.soundIval.setT(random.random() * self.sound.length())
-
-    def destroySound(self):
-        if hasattr(self, 'soundIval'):
-            self.soundIval.pause()
-            del self.soundIval
-        if hasattr(self, 'sound'):
-            del self.sound
-
-    if __dev__:
-        def attribChanged(self, *args):
-            self.destroySound()
-            self.initSound()

+ 0 - 32
direct/src/level/AttribDesc.py

@@ -1,32 +0,0 @@
-"""AttribDesc.py module: contains the AttribDesc class"""
-
-class AttribDesc:
-    """
-    Entity attribute descriptor
-    name == name of attribute
-    default == default value for attrib
-    """
-    def __init__(self, name, default, datatype='string', params = {}):
-        self.name = name
-        self.default = default
-        self.datatype = datatype
-        self.params = params
-
-    def getName(self):
-        return self.name
-    def getDefaultValue(self):
-        return self.default
-    def getDatatype(self):
-        return self.datatype
-    def getParams(self):
-        return self.params
-
-    def __str__(self):
-        return self.name
-    def __repr__(self):
-        return "AttribDesc(%s, %s, %s, %s)" % (
-            repr(self.name),
-            repr(self.default),
-            repr(self.datatype),
-            repr(self.params),
-            )

+ 0 - 130
direct/src/level/BasicEntities.py

@@ -1,130 +0,0 @@
-"""BasicEntities module: contains fundamental entity types and base classes"""
-
-import Entity
-import DistributedEntity
-from pandac import NodePath
-
-# base class for entities that support NodePath attributes
-# *** Don't derive directly from this class; derive from the appropriate
-# specialized class from the classes defined below.
-class NodePathEntityBase:
-    # we don't call this __init__ because it doesn't have to be called
-    # upon object init
-    def initNodePathAttribs(self, doReparent=1):
-        """Call this after the entity has been initialized"""
-        self.callSetters('pos','x','y','z',
-                         'hpr','h','p','r',
-                         'scale','sx','sy','sz')
-        if doReparent:
-            self.callSetters('parentEntId')
-
-        self.getNodePath().setName('%s-%s' %
-                                   (self.__class__.__name__, self.entId))
-
-        if __dev__:
-            # for the editor
-            self.getNodePath().setTag('entity', '1')
-
-    def setParentEntId(self, parentEntId):
-        self.parentEntId = parentEntId
-        self.level.requestReparent(self, self.parentEntId)
-
-    def destroy(self):
-        if __dev__:
-            # for the editor
-            self.getNodePath().clearTag('entity')
-
-# Entities that already derive from NodePath and Entity should derive
-# from this class
-class NodePathAttribs(NodePathEntityBase):
-    def initNodePathAttribs(self, doReparent=1):
-        NodePathEntityBase.initNodePathAttribs(self, doReparent)
-
-    def destroy(self):
-        NodePathEntityBase.destroy(self)
-
-    def getNodePath(self):
-        return self
-
-# Entities that already derive from Entity, and do not derive from NodePath,
-# but want to be a NodePath, should derive from this.
-class NodePathAndAttribs(NodePathEntityBase, NodePath.NodePath):
-    def __init__(self):
-        node = hidden.attachNewNode('EntityNodePath')
-        NodePath.NodePath.__init__(self, node)
-
-    def initNodePathAttribs(self, doReparent=1):
-        NodePathEntityBase.initNodePathAttribs(self, doReparent)
-
-    def destroy(self):
-        NodePathEntityBase.destroy(self)
-        self.removeNode()
-
-    def getNodePath(self):
-        return self
-        
-# Entities that already derive from Entity, and do not derive from NodePath,
-# but HAVE a NodePath that they want to represent them, should derive from
-# this. They must define getNodePath(), which should return their 'proxy'
-# NodePath instance.
-class NodePathAttribsProxy(NodePathEntityBase):
-    def initNodePathAttribs(self, doReparent=1):
-        """Call this after the entity has been initialized"""
-        NodePathEntityBase.initNodePathAttribs(self, doReparent)
-        assert self.getNodePath() != self
-
-    def destroy(self):
-        NodePathEntityBase.destroy(self)
-
-    def setPos(self, *args): self.getNodePath().setPos(*args)
-    def setX(self, *args): self.getNodePath().setX(*args)
-    def setY(self, *args): self.getNodePath().setY(*args)
-    def setZ(self, *args): self.getNodePath().setZ(*args)
-
-    def setHpr(self, *args): self.getNodePath().setHpr(*args)
-    def setH(self, *args): self.getNodePath().setH(*args)
-    def setP(self, *args): self.getNodePath().setP(*args)
-    def setR(self, *args): self.getNodePath().setR(*args)
-
-    def setScale(self, *args): self.getNodePath().setScale(*args)
-    def setSx(self, *args): self.getNodePath().setSx(*args)
-    def setSy(self, *args): self.getNodePath().setSy(*args)
-    def setSz(self, *args): self.getNodePath().setSz(*args)
-    
-    def reparentTo(self, *args): self.getNodePath().reparentTo(*args)
-
-# This is an entity that represents a NodePath on the client.
-# It may be instantiated directly or used as a base class for other
-# entity types that 'are' NodePaths.
-class NodePathEntity(Entity.Entity, NodePath.NodePath, NodePathAttribs):
-    def __init__(self, level, entId):
-        node = hidden.attachNewNode('NodePathEntity')
-        NodePath.NodePath.__init__(self, node)
-        Entity.Entity.__init__(self, level, entId)
-        self.initNodePathAttribs(self)
-
-    def destroy(self):
-        NodePathAttribs.destroy(self)
-        Entity.Entity.destroy(self)
-        self.removeNode()
-
-# This is a distributed version of NodePathEntity. It should not
-# be instantiated directly; distributed entities that are also NodePaths
-# may derive from this instead of DistributedEntity.
-class DistributedNodePathEntity(DistributedEntity.DistributedEntity,
-                                NodePath.NodePath, NodePathAttribs):
-    def __init__(self, cr):
-        DistributedEntity.DistributedEntity.__init__(self, cr)
-
-    def generateInit(self):
-        DistributedEntity.DistributedEntity.generateInit(self)
-        node = hidden.attachNewNode('DistributedNodePathEntity')
-        NodePath.NodePath.__init__(self, node)
-
-    def announceGenerate(self):
-        DistributedEntity.DistributedEntity.announceGenerate(self)
-        self.initNodePathAttribs(self)
-
-    def delete(self):
-        self.removeNode()
-        DistributedEntity.DistributedEntity.delete(self)

+ 0 - 191
direct/src/level/CutScene.py

@@ -1,191 +0,0 @@
-"""CutScene.py"""
-
-
-from direct.showbase import DirectObject
-from direct.directnotify import DirectNotifyGlobal
-import BasicEntities
-
-from pandac.PandaModules import *
-from direct.showbase.ShowBaseGlobal import *
-from direct.interval.IntervalGlobal import *
-from direct.distributed.ClockDelta import *
-
-from toontown.toonbase import ToontownGlobals
-from direct.directnotify import DirectNotifyGlobal
-from direct.fsm import ClassicFSM
-#import DistributedInteractiveEntity
-from direct.distributed import DelayDelete
-
-# effects #
-
-def nothing(self, track, subjectNodePath, duration):
-    assert(self.debugPrint(
-            "nothing(track=%s, subjectNodePath=%s, duration=%s)"%(
-            track, subjectNodePath, duration)))
-    return track
-
-def irisInOut(self, track, subjectNodePath, duration):
-    assert(self.debugPrint(
-            "irisInOut(track=%s, subjectNodePath=%s, duration=%s)"%(
-            track, subjectNodePath, duration)))
-    track.append(Sequence(
-        Func(base.transitions.irisOut, 0.5),
-        Func(base.transitions.irisIn, 1.5),
-        Wait(duration),
-        Func(base.transitions.irisOut, 1.0),
-        Func(base.transitions.irisIn, 0.5),
-        ))
-    return track
-
-def letterBox(self, track, subjectNodePath, duration):
-    assert(self.debugPrint(
-            "letterBox(track=%s, subjectNodePath=%s, duration=%s)"%(
-            track, subjectNodePath, duration)))
-    track.append(Sequence(
-        #Func(base.transitions.letterBox, 0.5),
-        Wait(duration),
-        #Func(base.transitions.letterBox, 0.5),
-        ))
-    return track
-
-# motions #
-
-def foo1(self, track, subjectNodePath, duration):
-    assert(self.debugPrint(
-            "foo1(track=%s, subjectNodePath=%s, duration=%s)"%(
-            track, subjectNodePath, duration)))
-    track.append(Sequence(
-        Func(base.localAvatar.stopUpdateSmartCamera),
-        PosHprInterval(
-            camera,
-            other=subjectNodePath,
-            pos=Point3(-2, -35, 7.5),
-            hpr=VBase3(-7, 0, 0)),
-        LerpPosHprInterval(
-            nodePath=camera,
-            other=subjectNodePath,
-            duration=duration,
-            pos=Point3(2, -22, 7.5),
-            hpr=VBase3(4, 0, 0),
-            blendType="easeInOut"),
-        PosHprInterval(
-            camera,
-            other=subjectNodePath,
-            pos=Point3(0, -28, 7.5),
-            hpr=VBase3(0, 0, 0)),
-        Func(base.localAvatar.startUpdateSmartCamera),
-        ))
-    return track
-
-def doorUnlock(self, track, subjectNodePath, duration):
-    assert(self.debugPrint(
-            "doorUnlock(track=%s, subjectNodePath=%s, duration=%s)"%(
-            track, subjectNodePath, duration)))
-    track.append(Sequence(
-        Func(base.localAvatar.stopUpdateSmartCamera),
-        PosHprInterval(
-            camera,
-            other=self,
-            pos=Point3(-2, -35, 7.5),
-            hpr=VBase3(-7, 0, 0)),
-        LerpPosHprInterval(
-            nodePath=camera,
-            other=self,
-            duration=duration,
-            pos=Point3(2, -22, 7.5),
-            hpr=VBase3(4, 0, 0),
-            blendType="easeInOut"),
-        PosHprInterval(
-            camera,
-            other=self,
-            pos=Point3(0, -28, 7.5),
-            hpr=VBase3(0, 0, 0)),
-        Func(base.localAvatar.startUpdateSmartCamera),
-        ))
-    return track
-
-
-class CutScene(BasicEntities.NodePathEntity, DirectObject.DirectObject):
-    if __debug__:
-        notify = DirectNotifyGlobal.directNotify.newCategory('CutScene')
-    
-    effects={
-        "nothing": nothing,
-        "irisInOut": irisInOut,
-        "letterBox": letterBox,
-    }
-    
-    motions={
-        "foo1": foo1,
-        "doorUnlock": doorUnlock,
-    }
-
-    def __init__(self, level, entId):
-        assert(self.debugPrint(
-                "CutScene(level=%s, entId=%s)"
-                %(level, entId)))
-        DirectObject.DirectObject.__init__(self)
-        BasicEntities.NodePathEntity.__init__(self, level, entId)
-        self.track = None
-        self.setEffect(self.effect)
-        self.setMotion(self.motion)
-        self.subjectNodePath = render.attachNewNode("CutScene")
-        self.subjectNodePath.setPos(self.pos)
-        self.subjectNodePath.setHpr(self.hpr)
-        #self.setSubjectNodePath(self.subjectNodePath)
-        self.setStartStop(self.startStopEvent)
-
-    def destroy(self):
-        assert(self.debugPrint("destroy()"))
-        self.ignore(self.startStopEvent)
-        self.startStopEvent = None
-        BasicEntities.NodePathEntity.destroy(self)
-        #DirectObject.DirectObject.destroy(self)
-    
-    def setEffect(self, effect):
-        assert(self.debugPrint("setEffect(effect=%s)"%(effect,)))
-        self.effect=effect
-        assert self.effects[effect]
-        self.getEffect=self.effects[effect]
-    
-    def setMotion(self, motion):
-        assert(self.debugPrint("setMotion(motion=%s)"%(motion,)))
-        self.motionType=motion
-        assert self.motions[motion]
-        self.getMotion=self.motions[motion]
-    
-    def setSubjectNodePath(self, subjectNodePath):
-        assert(self.debugPrint("setSubjectNodePath(subjectNodePath=%s)"%(subjectNodePath,)))
-        self.subjectNodePath=subjectNodePath
-    
-    def startOrStop(self, start):
-        assert(self.debugPrint("startOrStop(start=%s)"%(start,)))
-        trackName = "cutSceneTrack-%d" % (id(self),)
-        if start:
-            if self.track:
-                self.track.finish()
-                self.track = None
-            track = Parallel(name = trackName)
-            track = self.getEffect(self, track, self.subjectNodePath, self.duration)
-            track = self.getMotion(self, track, self.subjectNodePath, self.duration)
-            track = Sequence(Wait(0.4), track)
-            track.start(0.0)
-            assert(self.debugPrint("starting track=%s"%(track,)))
-            self.track = track
-        else:
-            if self.track:
-                self.track.pause()
-                self.track = None
-                base.localAvatar.startUpdateSmartCamera()
-    
-    def setStartStop(self, event):
-        assert(self.debugPrint("setStartStop(event=%s)"%(event,)))
-        if self.startStopEvent:
-            self.ignore(self.startStopEvent)
-        self.startStopEvent = self.getOutputEventName(event)
-        if self.startStopEvent:
-            self.accept(self.startStopEvent, self.startOrStop)
-    
-    def getName(self):
-        #return "CutScene-%s"%(self.entId,)
-        return "switch-%s"%(self.entId,)

+ 0 - 54
direct/src/level/DistributedEntity.py

@@ -1,54 +0,0 @@
-from direct.distributed import DistributedObject
-import Entity
-from direct.directnotify import DirectNotifyGlobal
-
-class DistributedEntity(DistributedObject.DistributedObject, Entity.Entity):
-    notify = DirectNotifyGlobal.directNotify.newCategory(
-        'DistributedEntity')
-
-    def __init__(self, cr):
-        DistributedObject.DistributedObject.__init__(self, cr)
-        Entity.Entity.__init__(self)
-
-    def generateInit(self):
-        DistributedEntity.notify.debug('generateInit')
-        DistributedObject.DistributedObject.generateInit(self)
-        # load stuff
-
-    def generate(self):
-        DistributedEntity.notify.debug('generate')
-        DistributedObject.DistributedObject.generate(self)
-
-    def setLevelDoId(self, levelDoId):
-        DistributedEntity.notify.debug('setLevelDoId: %s' % levelDoId)
-        self.levelDoId = levelDoId
-
-    def setEntId(self, entId):
-        DistributedEntity.notify.debug('setEntId: %s' % entId)
-        self.entId = entId
-
-    def announceGenerate(self):
-        ###
-        ### THIS IS WHERE CLIENT-SIDE DISTRIBUTED ENTITIES GET THEIR
-        ### ATTRIBUTES SET
-        ###
-        DistributedEntity.notify.debug('announceGenerate (%s)' % self.entId)
-
-        # ask our level obj for our spec data
-        level = base.cr.doId2do[self.levelDoId]
-        self.initializeEntity(level, self.entId)
-        # announce our presence (Level does this for non-distributed entities)
-        self.level.onEntityCreate(self.entId)
-
-        DistributedObject.DistributedObject.announceGenerate(self)
-
-    def disable(self):
-        DistributedEntity.notify.debug('disable (%s)' % self.entId)
-        # stop things
-        self.destroy()
-        DistributedObject.DistributedObject.disable(self)
-
-    def delete(self):
-        DistributedEntity.notify.debug('delete')
-        # unload things
-        DistributedObject.DistributedObject.delete(self)

+ 0 - 43
direct/src/level/DistributedEntityAI.py

@@ -1,43 +0,0 @@
-from direct.distributed import DistributedObjectAI
-import Entity
-from direct.directnotify import DirectNotifyGlobal
-
-class DistributedEntityAI(DistributedObjectAI.DistributedObjectAI,
-                          Entity.Entity):
-    notify = DirectNotifyGlobal.directNotify.newCategory(
-        'DistributedEntityAI')
-
-    def __init__(self, level, entId):
-        ###
-        ### THIS IS WHERE AI-SIDE DISTRIBUTED ENTITIES GET THEIR ATTRIBUTES SET
-        ###
-        DistributedObjectAI.DistributedObjectAI.__init__(self, level.air)
-        self.levelDoId = level.doId
-        Entity.Entity.__init__(self, level, entId)
-
-    def generate(self):
-        self.notify.debug('generate')
-        DistributedObjectAI.DistributedObjectAI.generate(self)
-
-    def destroy(self):
-        self.notify.debug('destroy')
-        Entity.Entity.destroy(self)
-        self.requestDelete()
-
-    def delete(self):
-        self.notify.debug('delete')
-        DistributedObjectAI.DistributedObjectAI.delete(self)
-
-    def getLevelDoId(self):
-        return self.levelDoId
-
-    def getEntId(self):
-        return self.entId
-
-    if __dev__:
-        def setParentEntId(self, parentEntId):
-            self.parentEntId = parentEntId
-            # switch to new zone
-            newZoneId = self.getZoneEntity().getZoneId()
-            if newZoneId != self.zoneId:
-                self.sendSetZone(newZoneId)

+ 0 - 148
direct/src/level/DistributedInteractiveEntity.py

@@ -1,148 +0,0 @@
-""" DistributedInteractiveEntity module: contains the DistributedInteractiveEntity
-    class, the client side representation of a 'landmark door'."""
-
-from direct.showbase.ShowBaseGlobal import *
-from direct.distributed.ClockDelta import *
-
-from direct.directnotify import DirectNotifyGlobal
-from direct.fsm import ClassicFSM
-import DistributedEntity
-
-class DistributedInteractiveEntity(DistributedEntity.DistributedEntity):
-    """
-    DistributedInteractiveEntity class:  The client side representation of any
-    simple animated prop.
-    """
-
-    if __debug__:
-        notify = DirectNotifyGlobal.directNotify.newCategory('DistributedInteractiveEntity')
-
-    def __init__(self, cr):
-        """constructor for the DistributedInteractiveEntity"""
-        DistributedEntity.DistributedEntity.__init__(self, cr)
-        assert(self.debugPrint("DistributedInteractiveEntity()"))
-
-        self.fsm = ClassicFSM.ClassicFSM('DistributedInteractiveEntity',
-                           [State.State('off',
-                                        self.enterOff,
-                                        self.exitOff,
-                                        ['playing',
-                                        'attract']),
-                            State.State('attract',
-                                        self.enterAttract,
-                                        self.exitAttract,
-                                        ['playing']),
-                            State.State('playing',
-                                        self.enterPlaying,
-                                        self.exitPlaying,
-                                        ['attract'])],
-                           # Initial State
-                           'off',
-                           # Final State
-                           'off',
-                          )
-        self.fsm.enterInitialState()
-        # self.generate will be called automatically.
-        
-    def generate(self):
-        """
-        This method is called when the DistributedEntity is introduced
-        to the world, either for the first time or from the cache.
-        """
-        assert(self.debugPrint("generate()"))
-        DistributedEntity.DistributedEntity.generate(self)
-
-    def disable(self):
-        assert(self.debugPrint("disable()"))
-        # Go to the off state when the object is put in the cache
-        self.fsm.request("off")
-        DistributedEntity.DistributedEntity.disable(self)
-        # self.delete() will automatically be called.
-    
-    def delete(self):
-        assert(self.debugPrint("delete()"))
-        del self.fsm
-        DistributedEntity.DistributedEntity.delete(self)
-    
-    def setAvatarInteract(self, avatarId):
-        """
-        required dc field.
-        """
-        assert(self.debugPrint("setAvatarInteract(%s)"%(avatarId,)))
-        assert(not self.__dict__.has_key(avatarId))
-        self.avatarId=avatarId
-    
-    def setOwnerDoId(self, ownerDoId):
-        """
-        required dc field.
-        """
-        assert(self.debugPrint("setOwnerDoId(%s)"%(ownerDoId,)))
-        assert(not self.__dict__.has_key("ownerDoId"))
-        self.ownerDoId=ownerDoId
-        
-    def setState(self, state, timestamp):
-        assert(self.debugPrint("setState(%s, %d)" % (state, timestamp)))
-        if self.isGenerated():
-            self.fsm.request(state, [globalClockDelta.localElapsedTime(timestamp)])
-        else:
-            self.initialState = state
-            self.initialStateTimestamp = timestamp
-    
-    #def __getPropNodePath(self):
-    #    assert(self.debugPrint("__getPropNodePath()"))
-    #    if (not self.__dict__.has_key('propNodePath')):
-    #        self.propNodePath=self.cr.playGame.hood.loader.geom.find(
-    #                "**/prop"+self.entID+":*_DNARoot")
-    #    return self.propNodePath
-    
-    def enterTrigger(self, args=None):
-        assert(self.debugPrint("enterTrigger(args="+str(args)+")"))
-        messenger.send("DistributedInteractiveEntity_enterTrigger")
-        self.sendUpdate("requestInteract")
-        # the AI server will reply with toonInteract or rejectInteract.
-    
-    def exitTrigger(self, args=None):
-        assert(self.debugPrint("exitTrigger(args="+str(args)+")"))
-        messenger.send("DistributedInteractiveEntity_exitTrigger")
-        self.sendUpdate("requestExit")
-        # the AI server will reply with avatarExit.
-    
-    def rejectInteract(self):
-        """
-        Server doesn't let the avatar interact with prop.
-        """
-        assert(self.debugPrint("rejectInteract()"))
-        self.cr.playGame.getPlace().setState('walk')
-        
-    def avatarExit(self, avatarId):
-        assert(self.debugPrint("avatarExit(avatarId=%s)"%(avatarId,)))
-    
-    ##### off state #####
-    
-    def enterOff(self):
-        assert(self.debugPrint("enterOff()"))
-    
-    def exitOff(self):
-        assert(self.debugPrint("exitOff()"))
-    
-    ##### attract state #####
-    
-    def enterAttract(self, ts):
-        assert(self.debugPrint("enterAttract()"))
-    
-    def exitAttract(self):
-        assert(self.debugPrint("exitAttract()"))
-    
-    ##### playing state #####
-    
-    def enterPlaying(self, ts):
-        assert(self.debugPrint("enterPlaying()"))
-    
-    def exitPlaying(self):
-        assert(self.debugPrint("exitPlaying()"))
-    
-    if __debug__:
-        def debugPrint(self, message):
-            """for debugging"""
-            return self.notify.debug(
-                    str(self.__dict__.get('entId', '?'))+' '+message)

+ 0 - 140
direct/src/level/DistributedInteractiveEntityAI.py

@@ -1,140 +0,0 @@
-""" DistributedInteractiveEntityAI module: contains the DistributedInteractiveEntityAI
-    class, the server side representation of a simple, animated, interactive 
-    prop."""
-
-
-from otp.ai.AIBaseGlobal import *
-from direct.distributed.ClockDelta import *
-
-from direct.directnotify import DirectNotifyGlobal
-from direct.fsm import ClassicFSM
-import DistributedEntityAI
-from direct.fsm import State
-
-
-class DistributedInteractiveEntityAI(DistributedEntityAI.DistributedEntityAI):
-    """
-    DistributedInteractiveEntityAI class:  The server side representation of
-    an animated prop.  This is the object that remembers what the
-    prop is doing.  The child of this object, the DistributedAnimatedProp
-    object, is the client side version and updates the display that
-    client's display based on the state of the prop.
-    """
-
-    if __debug__:
-        notify = DirectNotifyGlobal.directNotify.newCategory('DistributedInteractiveEntityAI')
-
-    def __init__(self, level, entId):
-        """entId: a unique identifier for this prop."""
-        DistributedEntityAI.DistributedEntityAI.__init__(self, level, entId)
-        assert(self.debugPrint(
-                "DistributedInteractiveEntityAI(entId=%s)"
-                %(entId)))
-        self.fsm = ClassicFSM.ClassicFSM('DistributedInteractiveEntityAI',
-                           [State.State('off',
-                                        self.enterOff,
-                                        self.exitOff,
-                                        ['playing']),
-                            # Attract is an idle mode.  It is named attract
-                            # because the prop is not interacting with an
-                            # avatar, and is therefore trying to attract an
-                            # avatar.
-                            State.State('attract',
-                                        self.enterAttract,
-                                        self.exitAttract,
-                                        ['playing']),
-                            # Playing is for when an avatar is interacting
-                            # with the prop.
-                            State.State('playing',
-                                        self.enterPlaying,
-                                        self.exitPlaying,
-                                        ['attract'])],
-                           # Initial State
-                           'off',
-                           # Final State
-                           'off',
-                          )
-        self.fsm.enterInitialState()
-        self.avatarId=0
-
-
-    def delete(self):
-        del self.fsm
-        DistributedEntityAI.DistributedEntityAI.delete(self)
-    
-    def getAvatarInteract(self):
-        assert(self.debugPrint("getAvatarInteract() returning: %s"%(self.avatarId,)))
-        return self.avatarId
-    
-    #def getOwnerDoId(self):
-    #    assert(self.debugPrint("getOwnerDoId() returning: %s"%(self.ownerDoId,)))
-    #    return self.ownerDoId
-    
-    def requestInteract(self):
-        assert(self.debugPrint("requestInteract()"))
-        avatarId = self.air.msgSender
-        assert(self.notify.debug("  avatarId:%s"%(avatarId,)))
-        stateName = self.fsm.getCurrentState().getName()
-        if stateName != 'playing':
-            self.sendUpdate("setAvatarInteract", [avatarId])
-            self.avatarId=avatarId
-            self.fsm.request('playing')
-        else:
-            self.sendUpdateToAvatarId(avatarId, "rejectInteract", [])
-    
-    def requestExit(self):
-        assert(self.debugPrint("requestExit()"))
-        avatarId = self.air.msgSender
-        assert(self.notify.debug("  avatarId:%s"%(avatarId,)))
-        if avatarId==self.avatarId:
-            stateName = self.fsm.getCurrentState().getName()
-            if stateName == 'playing':
-                self.sendUpdate("avatarExit", [avatarId])
-                self.fsm.request('attract')
-        else:
-            assert(self.notify.debug("  requestExit: invalid avatarId"))
-    
-    def getState(self):
-        r = [
-            self.fsm.getCurrentState().getName(),
-            globalClockDelta.getRealNetworkTime()]
-        assert(self.debugPrint("getState() returning %s"%(r,)))
-        return r
-    
-    def sendState(self):
-        assert(self.debugPrint("sendState()"))
-        self.sendUpdate('setState', self.getState())
-    
-    ##### off state #####
-    
-    def enterOff(self):
-        assert(self.debugPrint("enterOff()"))
-        #self.setState('off')
-    
-    def exitOff(self):
-        assert(self.debugPrint("exitOff()"))
-    
-    ##### attract state #####
-    
-    def enterAttract(self):
-        assert(self.debugPrint("enterAttract()"))
-        self.sendState()
-    
-    def exitAttract(self):
-        assert(self.debugPrint("exitAttract()"))
-    
-    ##### open state #####
-    
-    def enterPlaying(self):
-        assert(self.debugPrint("enterPlaying()"))
-        self.sendState()
-    
-    def exitPlaying(self):
-        assert(self.debugPrint("exitPlaying()"))
-    
-    if __debug__:
-        def debugPrint(self, message):
-            """for debugging"""
-            return self.notify.debug(
-                    str(self.__dict__.get('entId', '?'))+' '+message)
-

+ 0 - 815
direct/src/level/DistributedLevel.py

@@ -1,815 +0,0 @@
-"""DistributedLevel.py: contains the DistributedLevel class"""
-
-from direct.distributed.ClockDelta import *
-from pandac.PandaModules import *
-from direct.showbase.PythonUtil import Functor, sameElements, list2dict, uniqueElements
-from direct.interval.IntervalGlobal import *
-from toontown.distributed.ToontownMsgTypes import *
-from toontown.toonbase import ToontownGlobals
-from otp.otpbase import OTPGlobals
-from direct.distributed import DistributedObject
-import Level
-import LevelConstants
-from direct.directnotify import DirectNotifyGlobal
-import EntityCreator
-from direct.gui import OnscreenText
-from direct.task import Task
-import LevelUtil
-from toontown.coghq import FactoryCameraViews
-import random
-
-class DistributedLevel(DistributedObject.DistributedObject,
-                       Level.Level):
-    """DistributedLevel"""
-    notify = DirectNotifyGlobal.directNotify.newCategory('DistributedLevel')
-
-    WantVisibility = config.GetBool('level-visibility', 1)
-    # set this to true to get all distrib objs when showing hidden zones
-    ColorZonesAllDOs = 0
-
-    # TODO: move level-model stuff to LevelMgr or FactoryLevelMgr?
-    FloorCollPrefix = 'zoneFloor'
-
-    OuchTaskName = 'ouchTask'
-    VisChangeTaskName = 'visChange'
-
-    def __init__(self, cr):
-        DistributedObject.DistributedObject.__init__(self, cr)
-        Level.Level.__init__(self)
-        self.lastToonZone = None
-        self.lastCamZone = 0
-        self.titleColor = (1,1,1,1)
-        self.titleText = OnscreenText.OnscreenText(
-            "",
-            fg = self.titleColor,
-            shadow = (0,0,0,1),
-            font = ToontownGlobals.getSuitFont(),
-            pos = (0,-0.5),
-            scale = 0.16,
-            drawOrder = 0,
-            mayChange = 1,
-            )
-
-        self.smallTitleText = OnscreenText.OnscreenText(
-            "",
-            fg = self.titleColor,
-            font = ToontownGlobals.getSuitFont(),
-            pos = (0.65,0.9),
-            scale = 0.08,
-            drawOrder = 0,
-            mayChange = 1,
-            bg = (.5,.5,.5,.5),
-            align = TextNode.ARight,
-            )
-        self.zonesEnteredList = []
-        self.fColorZones = 0
-        self.scenarioIndex = 0
-
-    def generate(self):
-        DistributedLevel.notify.debug('generate')
-        DistributedObject.DistributedObject.generate(self)
-
-        # this dict stores entity reparents if the parent hasn't been
-        # created yet
-        self.parent2pendingChildren = {}
-
-        # if the AI sends us a full spec, it will be put here
-        self.curSpec = None
-
-        # Most (if not all) of the timed entities of levels
-        # run on looping intervals that are started once based on
-        # the level's start time.
-        # This sync request is *NOT* guaranteed to finish by the time
-        # the entities get created.
-        # We should listen for any and all time-sync events and re-sync
-        # all our entities at that time.
-        base.cr.timeManager.synchronize('DistributedLevel.generate')
-
-        # add special camera views
-        self.factoryViews = FactoryCameraViews.FactoryCameraViews(self)
-
-
-    # the real required fields
-    def setLevelZoneId(self, zoneId):
-        # this is the zone that the level is in; we should listen to this
-        # zone the entire time we're in here
-        self.levelZone = zoneId
-
-    def setPlayerIds(self, avIdList):
-        self.avIdList = avIdList
-        assert base.localAvatar.doId in self.avIdList
-
-    def setEntranceId(self, entranceId):
-        self.entranceId = entranceId
-
-    def getEntranceId(self):
-        return self.entranceId
-
-    # "required" fields (these ought to be required fields, but
-    # the AI level obj doesn't know the data values until it has been
-    # generated.)
-    def setZoneIds(self, zoneIds):
-        DistributedLevel.notify.debug('setZoneIds: %s' % zoneIds)
-        self.zoneIds = zoneIds
-
-    def setStartTimestamp(self, timestamp):
-        DistributedLevel.notify.debug('setStartTimestamp: %s' % timestamp)
-        self.startTime = globalClockDelta.networkToLocalTime(timestamp,bits=32)
-
-        # ugly hack: we treat a few DC fields as if they were required,
-        # and use 'levelAnnounceGenerate()' in place of regular old
-        # announceGenerate(). Note that we have to call
-        # gotAllRequired() in the last 'faux-required' DC update
-        # handler. If you add another field, move this to the last one.
-        self.privGotAllRequired()
-
-        """
-        # this is no longer used
-    def setScenarioIndex(self, scenarioIndex):
-        self.scenarioIndex = scenarioIndex
-
-        # ugly hack: we treat a few DC fields as if they were required,
-        # and use 'levelAnnounceGenerate()' in place of regular old
-        # announceGenerate(). Note that we have to call
-        # gotAllRequired() in the last 'faux-required' DC update
-        # handler. If you add another field, move this to the last one.
-        self.privGotAllRequired()
-        """
-
-    def privGotAllRequired(self):
-        self.levelAnnounceGenerate()
-    def levelAnnounceGenerate(self):
-        pass
-
-    def initializeLevel(self, levelSpec):
-        """subclass should call this as soon as it's located its level spec.
-        Must be called after obj has been generated."""
-        if __dev__:
-            # if we're in dev, give the server the opportunity to send us
-            # a full spec
-            self.candidateSpec = levelSpec
-            self.sendUpdate('requestCurrentLevelSpec',
-                            [hash(levelSpec),
-                             levelSpec.entTypeReg.getHashStr()])
-        else:
-            self.privGotSpec(levelSpec)
-
-    if __dev__:
-        def reportModelSpecSyncError(self, msg):
-            DistributedLevel.notify.error(
-                '%s\n'
-                '\n'
-                'your spec does not match the level model\n'
-                'use SpecUtil.updateSpec, then restart your AI and client' %
-                (msg))
-
-        def setSpecDeny(self, reason):
-            DistributedLevel.notify.error(reason)
-            
-        def setSpecSenderDoId(self, doId):
-            DistributedLevel.notify.debug('setSpecSenderDoId: %s' % doId)
-            blobSender = base.cr.doId2do[doId]
-
-            def setSpecBlob(specBlob, blobSender=blobSender, self=self):
-                blobSender.sendAck()
-                from LevelSpec import LevelSpec
-                spec = eval(specBlob)
-                if spec is None:
-                    spec = self.candidateSpec
-                del self.candidateSpec
-                self.privGotSpec(spec)
-
-            if blobSender.isComplete():
-                setSpecBlob(blobSender.getBlob())
-            else:
-                evtName = self.uniqueName('specDone')
-                blobSender.setDoneEvent(evtName)
-                self.acceptOnce(evtName, setSpecBlob)
-
-    def privGotSpec(self, levelSpec):
-        Level.Level.initializeLevel(self, self.doId, levelSpec,
-                                    self.scenarioIndex)
-
-        # all of the local entities have been created now.
-        # TODO: have any of the distributed entities been created at this point?
-
-        # there should not be any pending reparents left at this point
-        # TODO: is it possible for a local entity to be parented to a
-        # distributed entity? I think so!
-        assert len(self.parent2pendingChildren) == 0
-        # make sure the zoneNums from the model match the zoneNums from
-        # the zone entities
-        modelZoneNums = self.zoneNums
-        specZoneNums = self.zoneNum2zoneId.keys()
-        if not sameElements(modelZoneNums, specZoneNums):
-            self.reportModelSpecSyncError(
-                'model zone nums (%s) do not match spec zone nums (%s)' %
-                (modelZoneNums, specZoneNums))
-
-        # load stuff
-        self.initVisibility()
-        self.placeLocalToon()
-
-    def announceLeaving(self):
-        """call this just before leaving the level; this may result in
-        the factory being destroyed on the AI"""
-        DistributedLevel.notify.debug('announceLeaving')
-        self.doneBarrier()
-
-    def placeLocalToon(self):
-        # the entrancePoint entities register themselves with us
-        if self.entranceId not in self.entranceId2entity:
-            self.notify.warning('unknown entranceId %s' % self.entranceId)
-            base.localAvatar.reparentTo(render)
-            base.localAvatar.setPosHpr(0,0,0,0,0,0)
-            self.notify.warning('showing all zones')
-            self.setColorZones(1)
-            # put the toon in a random zone to start
-            zoneEntIds = self.entType2ids['zone']
-            while 1:
-                zoneEntId = random.choice(zoneEntIds)
-                if zoneEntId is not LevelConstants.UberZoneEntId:
-                    initialZoneEnt = self.getEntity(zoneEntId)
-                    base.localAvatar.setPos(
-                        render,
-                        initialZoneEnt.getZoneNode().getPos(render))
-                    break
-        else:
-            epEnt = self.entranceId2entity[self.entranceId]
-            epEnt.placeToon(base.localAvatar,
-                            self.avIdList.index(base.localAvatar.doId),
-                            len(self.avIdList))
-            initialZoneEnt = self.getEntity(epEnt.getZoneEntId())
-
-        # kickstart the visibility
-        self.enterZone(initialZoneEnt.entId)
-
-    def createEntityCreator(self):
-        """Create the object that will be used to create Entities.
-        Inheritors, override if desired."""
-        return EntityCreator.EntityCreator(level=self)
-
-    def onEntityTypePostCreate(self, entType):
-        """listen for certain entity types to be created"""
-        Level.Level.onEntityTypePostCreate(self, entType)
-        # NOTE: these handlers are private in order to avoid overriding
-        # similar handlers in base classes
-        if entType == 'levelMgr':
-            self.__handleLevelMgrCreated()
-
-    def __handleLevelMgrCreated(self):
-        # as soon as the levelMgr has been created, load up the model
-        # and extract zone info. We need to do this before any entities
-        # get parented to the level!
-        levelMgr = self.getEntity(LevelConstants.LevelMgrEntId)
-        self.geom = levelMgr.geom
-
-        # find the zones in the model and fix them up
-        self.zoneNum2node = LevelUtil.getZoneNum2Node(self.geom)
-
-        self.zoneNums = self.zoneNum2node.keys()
-        self.zoneNums.sort()
-        self.zoneNumDict = list2dict(self.zoneNums)
-        DistributedLevel.notify.debug('zones from model: %s' % self.zoneNums)
-
-        # give the level a chance to muck with the model before the entities
-        # get placed
-        self.fixupLevelModel()
-        
-    def fixupLevelModel(self):
-        # fix up the floor collisions for walkable zones *before*
-        # any entities get put under the model
-        for zoneNum,zoneNode in self.zoneNum2node.items():
-            # don't do this to the uberzone
-            if zoneNum == LevelConstants.UberZoneEntId:
-                continue
-            # if this is a walkable zone, fix up the model
-            allColls = zoneNode.findAllMatches('**/+CollisionNode').asList()
-            # which of them, if any, are floors?
-            floorColls = []
-            for coll in allColls:
-                bitmask = coll.node().getIntoCollideMask()
-                if not (bitmask & ToontownGlobals.FloorBitmask).isZero():
-                    floorColls.append(coll)
-            if len(floorColls) > 0:
-                # rename the floor collision nodes, and make sure no other
-                # nodes under the ZoneNode have that name
-                floorCollName = '%s%s' % (DistributedLevel.FloorCollPrefix,
-                                          zoneNum)
-                others = zoneNode.findAllMatches(
-                    '**/%s' % floorCollName).asList()
-                for other in others:
-                    other.setName('%s_renamed' % floorCollName)
-                for floorColl in floorColls:
-                    floorColl.setName(floorCollName)
-
-                # listen for zone enter events from floor collisions
-                def handleZoneEnter(collisionEntry,
-                                    self=self, zoneNum=zoneNum):
-                    self.toonEnterZone(zoneNum)
-                    floorNode = collisionEntry.getIntoNode()
-                    if floorNode.hasTag('ouch'):
-                        ouchLevel = int(floorNode.getTag('ouch'))
-                        self.startOuch(ouchLevel)
-                self.accept('enter%s' % floorCollName, handleZoneEnter)
-
-                # also listen for zone exit events for the sake of the
-                # ouch system
-                def handleZoneExit(collisionEntry,
-                                   self=self, zoneNum=zoneNum):
-                    floorNode = collisionEntry.getIntoNode()
-                    if floorNode.hasTag('ouch'):
-                        self.stopOuch()
-                self.accept('exit%s' % floorCollName, handleZoneExit)
-
-    def announceGenerate(self):
-        DistributedLevel.notify.debug('announceGenerate')
-        DistributedObject.DistributedObject.announceGenerate(self)
-
-    def disable(self):
-        DistributedLevel.notify.debug('disable')
-
-        # geom is owned by the levelMgr
-        if hasattr(self, 'geom'):
-            del self.geom
-
-        self.shutdownVisibility()
-        self.destroyLevel()
-        self.ignoreAll()
-
-        # NOTE:  this should be moved to FactoryInterior
-        taskMgr.remove(self.uniqueName("titleText"))
-        if self.smallTitleText:
-            self.smallTitleText.cleanup()
-            self.smallTitleText = None
-        if self.titleText:
-            self.titleText.cleanup()
-            self.titleText = None
-        self.zonesEnteredList = []
-
-        DistributedObject.DistributedObject.disable(self)
-
-    def delete(self):
-        DistributedLevel.notify.debug('delete')
-        DistributedObject.DistributedObject.delete(self)
-        # remove special camera views
-        del self.factoryViews
-        # make sure the ouch task is stopped
-        self.stopOuch()
-        
-    def requestReparent(self, entity, parentId):
-        if __debug__:
-            # some things (like cogs) are not actually entities yet;
-            # they don't have an entId. Big deal, let it go through.
-            if hasattr(entity, 'entId'):
-                assert(entity.entId != parentId)
-        parent = self.getEntity(parentId)
-        if parent is not None:
-            # parent has already been created
-            entity.reparentTo(parent.getNodePath())
-        else:
-            # parent hasn't been created yet; schedule the reparent
-            DistributedLevel.notify.debug(
-                'entity %s requesting reparent to %s, not yet created' %
-                (entity, parentId))
-
-            entity.reparentTo(hidden)
-
-            # if this parent doesn't already have another child pending,
-            # do some setup
-            if not self.parent2pendingChildren.has_key(parentId):
-                self.parent2pendingChildren[parentId] = []
-
-                # do the reparent(s) once the parent is initialized
-                def doReparent(parentId=parentId, self=self):
-                    assert self.parent2pendingChildren.has_key(parentId)
-                    parent=self.getEntity(parentId)
-                    for child in self.parent2pendingChildren[parentId]:
-                        DistributedLevel.notify.debug(
-                            'performing pending reparent of %s to %s' %
-                            (child, parent))
-                        child.reparentTo(parent.getNodePath())
-                    del self.parent2pendingChildren[parentId]
-                    self.ignore(self.getEntityCreateEvent(parentId))
-                    
-                self.accept(self.getEntityCreateEvent(parentId), doReparent)
-
-            self.parent2pendingChildren[parentId].append(entity)
-    
-    def getZoneNode(self, zoneEntId):
-        return self.zoneNum2node.get(zoneEntId)
-
-    def warpToZone(self, zoneNum):
-        """put avatar at the origin of the given zone"""
-        zoneNode = self.getZoneNode(zoneNum)
-        if zoneNode is None:
-            return
-        base.localAvatar.setPos(zoneNode,0,0,0)
-        base.localAvatar.setHpr(zoneNode,0,0,0)
-        self.enterZone(zoneNum)
-
-    def showZone(self, zoneNum):
-        zone = self.getZoneNode(zoneNum)
-        zone.unstash()
-        zone.clearColor()
-
-    def setColorZones(self, fColorZones):
-        self.fColorZones = fColorZones
-        self.resetVisibility()
-
-    def getColorZones(self):
-        return self.fColorZones
-
-    def hideZone(self, zoneNum):
-        zone = self.getZoneNode(zoneNum)
-        if self.fColorZones:
-            zone.unstash()
-            zone.setColor(1,0,0)
-        else:
-            zone.stash()
-
-    def setTransparency(self, alpha, zone=None):
-        self.geom.setTransparency(1)
-        if zone is None:
-            node = self.geom
-        else:
-            node = self.getZoneNode(zoneNum)
-        node.setAlphaScale(alpha)
-
-    def initVisibility(self):
-        # start out with every zone visible, since none of the zones have
-        # been hidden
-        self.curVisibleZoneNums = list2dict(self.zoneNums)
-        # the UberZone is always visible, so it's not included in the
-        # zones' viz lists
-        del self.curVisibleZoneNums[LevelConstants.UberZoneEntId]
-        # we have not entered any zone yet
-        self.curZoneNum = None
-
-        self.visChangedThisFrame = 0
-        self.fForceSetZoneThisFrame = 0
-
-        # listen for camera-ray/floor collision events
-        def handleCameraRayFloorCollision(collEntry, self=self):
-            name = collEntry.getIntoNode().getName()
-            self.notify.debug('camera floor ray collided with: %s' % name)
-            prefixLen = len(DistributedLevel.FloorCollPrefix)
-            if (name[:prefixLen] == DistributedLevel.FloorCollPrefix):
-                try:
-                    zoneNum = int(name[prefixLen:])
-                except:
-                    DistributedLevel.notify.warning(
-                        'Invalid zone floor collision node: %s'
-                        % name)
-                else:
-                    self.camEnterZone(zoneNum)
-        self.accept('on-floor', handleCameraRayFloorCollision)
-
-        # if no viz, listen to all the zones
-        if not DistributedLevel.WantVisibility:
-            zoneNums = list(self.zoneNums)
-            zoneNums.remove(LevelConstants.UberZoneEntId)
-            # make sure a setZone goes out on the first frame
-            self.forceSetZoneThisFrame()
-            self.setVisibility(zoneNums)
-
-        # send out any zone changes at the end of the frame, just before
-        # rendering
-        taskMgr.add(self.visChangeTask,
-                    self.uniqueName(DistributedLevel.VisChangeTaskName),
-                    priority=49)
-
-    def shutdownVisibility(self):
-        taskMgr.remove(self.uniqueName(DistributedLevel.VisChangeTaskName))
-
-    def toonEnterZone(self, zoneNum, ouchLevel=None):
-        """
-        zoneNum is an int.
-        ouchLevel is a ??.
-        
-        The avatar (and not necessarily the camera) has entered
-        a zone.
-        See camEnterZone()
-        """
-        DistributedLevel.notify.debug('toonEnterZone%s' % zoneNum)
-
-        if zoneNum != self.lastToonZone:
-            self.lastToonZone = zoneNum
-            self.notify.debug("toon is standing in zone %s" % zoneNum)
-            messenger.send("factoryZoneChanged", [zoneNum])
-
-    def camEnterZone(self, zoneNum):
-        """
-        zoneNum is an int.
-        
-        The camera (and not necessarily the avatar) has entered
-        a zone.
-        See toonEnterZone()
-        """
-        DistributedLevel.notify.debug('camEnterZone%s' % zoneNum)
-        self.enterZone(zoneNum)
-
-        if zoneNum != self.lastCamZone:
-            self.lastCamZone = zoneNum
-            self.smallTitleText.hide()
-            self.spawnTitleText()
-
-    def lockVisibility(self, zoneNum=None, zoneId=None):
-        """call this to lock the visibility to a particular zone
-        pass in either network zoneId or zoneNum
-
-        this was added for battles in the HQ factories; if you engage a suit
-        in zone A with your camera in zone B, and you don't call this func,
-        your client will remain in zone B. If there's a door between A and B,
-        and it closes, zone B might disappear, along with the suit and the
-        battle objects.
-        """
-        assert (zoneNum is None) or (zoneId is None)
-        assert not ((zoneNum is None) and (zoneId is None))
-        if zoneId is not None:
-            zoneNum = self.getZoneNumFromId(zoneId)
-
-        self.notify.debug('lockVisibility to zoneNum %s' % zoneNum)
-        self.lockVizZone = zoneNum
-        self.enterZone(self.lockVizZone)
-
-    def unlockVisibility(self):
-        """release the visibility lock"""
-        self.notify.debug('unlockVisibility')
-        if not hasattr(self, 'lockVizZone'):
-            self.notify.warning('visibility already unlocked')
-        else:
-            del self.lockVizZone
-            self.updateVisibility()
-            
-
-    def enterZone(self, zoneNum):
-        DistributedLevel.notify.info("entering zone %s" % zoneNum)
-
-        if not DistributedLevel.WantVisibility:
-            return
-        
-        if zoneNum == self.curZoneNum:
-            return
-
-        if zoneNum not in self.zoneNumDict:
-            DistributedLevel.notify.error(
-                'no ZoneEntity for this zone (%s)!!' % zoneNum)
-
-        self.updateVisibility(zoneNum)
-
-    def updateVisibility(self, zoneNum=None):
-        """update the visibility assuming that we're in the specified
-        zone; don't check to see if it's the zone we're already in"""
-        #self.notify.debug('updateVisibility %s' % globalClock.getFrameCount())
-        if zoneNum is None:
-            zoneNum = self.curZoneNum
-            if zoneNum is None:
-                return
-        if hasattr(self, 'lockVizZone'):
-            zoneNum = self.lockVizZone
-            
-        zoneEnt = self.getEntity(zoneNum)
-        # use dicts to efficiently ensure that there are no duplicates
-        visibleZoneNums = list2dict([zoneNum])
-        visibleZoneNums.update(list2dict(zoneEnt.getVisibleZoneNums()))
-
-        if not __debug__:
-            # HACK
-            # make sure that the visibility list includes the zone that the toon
-            # is standing in
-            if self.lastToonZone not in visibleZoneNums:
-                # make sure there IS a last zone
-                if self.lastToonZone is not None:
-                    self.notify.warning(
-                        'adding zoneNum %s to visibility list '
-                        'because toon is standing in that zone!' %
-                        self.lastToonZone)
-                    visibleZoneNums.update(list2dict([self.lastToonZone]))
-
-        # we should not have the uberZone in the list at this point
-        assert not LevelConstants.UberZoneEntId in visibleZoneNums
-
-        # this flag will prevent a network msg from being sent if
-        # the list of visible zones has not changed
-        vizZonesChanged = 1
-        # figure out which zones are new and which are going invisible
-        # use dicts because 'x in dict' is faster than 'x in list'
-        addedZoneNums = []
-        removedZoneNums = []
-        allVZ = dict(visibleZoneNums)
-        allVZ.update(self.curVisibleZoneNums)
-        for vz,dummy in allVZ.items():
-            new = vz in visibleZoneNums
-            old = vz in self.curVisibleZoneNums
-            if new and old:
-                continue
-            if new:
-                addedZoneNums.append(vz)
-            else:
-                removedZoneNums.append(vz)
-
-        if (not addedZoneNums) and (not removedZoneNums):
-            DistributedLevel.notify.debug(
-                'visible zone list has not changed')
-            vizZonesChanged = 0
-        else:
-            # show the new, hide the old
-            DistributedLevel.notify.debug('showing zones %s' %
-                                          addedZoneNums)
-            for az in addedZoneNums:
-                self.showZone(az)
-            DistributedLevel.notify.debug('hiding zones %s' %
-                                          removedZoneNums)
-            for rz in removedZoneNums:
-                self.hideZone(rz)
-
-        # it's important for us to send a setZone request on the first
-        # frame, whether or not the visibility is different from what
-        # we already have
-        if vizZonesChanged or self.fForceSetZoneThisFrame:
-            self.setVisibility(visibleZoneNums.keys())
-            self.fForceSetZoneThisFrame = 0
-
-        self.curZoneNum = zoneNum
-        self.curVisibleZoneNums = visibleZoneNums
-
-    def setVisibility(self, vizList):
-        """
-        vizList is a list of visible zone numbers.
-        """
-        # if we're showing all zones, get all the DOs
-        if self.fColorZones and DistributedLevel.ColorZonesAllDOs:
-            vizList = list(self.zoneNums)
-            vizList.remove(LevelConstants.UberZoneEntId)
-        # convert the zone numbers into their actual zoneIds
-        # always include Toontown and factory uberZones
-        uberZone = self.getZoneId(LevelConstants.UberZoneEntId)
-        # the level itself is in the 'level zone'
-        visibleZoneIds = [OTPGlobals.UberZone, self.levelZone, uberZone]
-        for vz in vizList:
-            visibleZoneIds.append(self.getZoneId(vz))
-        assert(uniqueElements(visibleZoneIds))
-        DistributedLevel.notify.debug('new viz list: %s' % visibleZoneIds)
-
-        base.cr.sendSetZoneMsg(self.levelZone, visibleZoneIds)
-
-    def resetVisibility(self):
-        # start out with every zone visible, since none of the zones have
-        # been hidden
-        self.curVisibleZoneNums = list2dict(self.zoneNums)
-        # the UberZone is always visible, so it's not included in the
-        # zones' viz lists
-        del self.curVisibleZoneNums[LevelConstants.UberZoneEntId]
-        # Make sure every zone is visible
-        for vz,dummy in self.curVisibleZoneNums.items():
-            self.showZone(vz)
-        # Redo visibility using current zone num
-        self.updateVisibility()
-
-    def handleVisChange(self):
-        """the zone visibility lists have changed on-the-fly"""
-        Level.Level.handleVisChange(self)
-        self.visChangedThisFrame = 1
-
-    def forceSetZoneThisFrame(self):
-        # call this to ensure that a setZone call will be generated this frame
-        self.fForceSetZoneThisFrame = 1
-
-    def visChangeTask(self, task):
-        # this runs just before igLoop; if viz lists have changed
-        # this frame, updates the visibility and sends out a setZoneMsg
-        if self.visChangedThisFrame or self.fForceSetZoneThisFrame:
-            self.updateVisibility()
-            self.visChangedThisFrame = 0
-        return Task.cont
-
-    if __dev__:
-        # level editing stuff
-        def setAttribChange(self, entId, attribName, valueStr, username):
-            """every time the spec is edited, we get this message
-            from the AI"""
-            value = eval(valueStr)
-            self.levelSpec.setAttribChange(entId, attribName, value, username)
-
-    def spawnTitleText(self):
-        def getDescription(zoneNum, self=self):
-            ent = self.entities.get(zoneNum)
-            if ent and hasattr(ent, 'description'):
-                return ent.description
-            return None
-
-        description = getDescription(self.lastCamZone)
-        if description and description != '':
-            taskMgr.remove(self.uniqueName("titleText"))
-            self.smallTitleText.setText(description)
-            self.titleText.setText(description)
-            self.titleText.setColor(Vec4(*self.titleColor))
-            self.titleText.setFg(self.titleColor)
-
-            # Only show the big title once per session.
-            # If we've already seen it, just show the small title
-
-            titleSeq = None
-            if not self.lastCamZone in self.zonesEnteredList:
-                self.zonesEnteredList.append(self.lastCamZone)
-                titleSeq = Task.sequence(
-                    Task.Task(self.hideSmallTitleTextTask),
-                    Task.Task(self.showTitleTextTask),
-                    Task.pause(0.1),
-                    Task.pause(6.0),
-                    self.titleText.lerpColor(Vec4(self.titleColor[0],
-                                                  self.titleColor[1],
-                                                  self.titleColor[2],
-                                                  self.titleColor[3]),
-                                             Vec4(self.titleColor[0],
-                                                  self.titleColor[1],
-                                                  self.titleColor[2],
-                                                  0.0),
-                                             0.5),
-                    )
-            smallTitleSeq = Task.sequence(Task.Task(self.hideTitleTextTask),
-                                          Task.Task(self.showSmallTitleTask))
-            if titleSeq:
-                seq = Task.sequence(titleSeq, smallTitleSeq)
-            else:
-                seq = smallTitleSeq
-            taskMgr.add(seq, self.uniqueName("titleText"))
-        
-    def showTitleTextTask(self, task):
-        assert(DistributedLevel.notify.debug("hideTitleTextTask()"))
-        self.titleText.show()
-        return Task.done
-
-    def hideTitleTextTask(self, task):
-        assert(DistributedLevel.notify.debug("hideTitleTextTask()"))
-        if self.titleText:
-            self.titleText.hide()
-        return Task.done
-
-    def showSmallTitleTask(self, task):
-        # make sure large title is hidden
-        if self.titleText:
-            self.titleText.hide()
-        # show the small title
-        self.smallTitleText.show()
-        return Task.done
-    
-    def hideSmallTitleTextTask(self, task):
-        assert(DistributedLevel.notify.debug("hideTitleTextTask()"))
-        if self.smallTitleText:
-            self.smallTitleText.hide()
-        return Task.done
-
-    # Ouch!
-    def startOuch(self, ouchLevel, period=2):
-        self.notify.debug('startOuch %s' % ouchLevel)
-        if not hasattr(self, 'doingOuch'):
-            def doOuch(task, self=self, ouchLevel=ouchLevel, period=period):
-                self.b_setOuch(ouchLevel)
-                self.lastOuchTime = globalClock.getFrameTime()
-                taskMgr.doMethodLater(period, doOuch,
-                                      DistributedLevel.OuchTaskName)
-
-            # check to make sure we haven't done an ouch too recently
-            delay = 0
-            if hasattr(self, 'lastOuchTime'):
-                curFrameTime = globalClock.getFrameTime()
-                timeSinceLastOuch = (curFrameTime - self.lastOuchTime)
-                if timeSinceLastOuch < period:
-                    delay = period - timeSinceLastOuch
-
-            if delay > 0:
-                taskMgr.doMethodLater(
-                        period, doOuch,
-                        DistributedLevel.OuchTaskName)
-            else:
-                doOuch(None)
-            self.doingOuch = 1
-
-    def stopOuch(self):
-        if hasattr(self, 'doingOuch'):
-            taskMgr.remove(DistributedLevel.OuchTaskName)
-            del self.doingOuch
-
-    def b_setOuch(self, penalty, anim=None):
-        self.notify.debug('b_setOuch %s' % penalty)
-        av = base.localAvatar
-
-        # play the stun track (flashing toon) 
-        if not av.isStunned:
-            self.d_setOuch(penalty)
-            self.setOuch(penalty, anim)
-
-    def d_setOuch(self, penalty):
-        self.sendUpdate("setOuch", [penalty])
-
-    def setOuch(self, penalty, anim = None):
-        if anim == "Squish":
-            base.cr.playGame.getPlace().fsm.request('squished')
-        elif anim == "Fall":
-            base.cr.playGame.getPlace().fsm.request('fallDown')
-            
-        av = base.localAvatar
-        av.stunToon()
-        av.playDialogueForString("!")

+ 0 - 228
direct/src/level/DistributedLevelAI.py

@@ -1,228 +0,0 @@
-"""DistributedLevelAI.py: contains the DistributedLevelAI class"""
-
-from otp.ai.AIBaseGlobal import *
-from direct.distributed.ClockDelta import *
-from direct.distributed import DistributedObjectAI
-import Level
-from direct.directnotify import DirectNotifyGlobal
-import EntityCreatorAI
-from direct.showbase.PythonUtil import Functor, weightedChoice
-
-class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
-                         Level.Level):
-    """DistributedLevelAI"""
-    notify = DirectNotifyGlobal.directNotify.newCategory('DistributedLevelAI')
-
-    def __init__(self, air, zoneId, entranceId, avIds):
-        DistributedObjectAI.DistributedObjectAI.__init__(self, air)
-        Level.Level.__init__(self)
-        # these are required fields
-        self.zoneId = zoneId
-        self.entranceId = entranceId
-
-        assert len(avIds) > 0 and len(avIds) <= 4
-        assert 0 not in avIds
-        assert None not in avIds
-        self.avIdList = avIds
-        self.numPlayers = len(self.avIdList)
-        # this is the list of avatars that are actually present
-        self.presentAvIds = list(self.avIdList)
-        self.notify.debug("expecting avatars: %s" % str(self.avIdList))
-
-        if __dev__:
-            self.modified = 0
-
-    def generate(self, levelSpec):
-        self.notify.debug('generate')
-        DistributedObjectAI.DistributedObjectAI.generate(self)
-
-        self.initializeLevel(levelSpec)
-
-        # self.zoneIds comes from LevelMgrAI
-        self.sendUpdate('setZoneIds', [self.zoneIds])
-        self.sendUpdate('setStartTimestamp', [self.startTimestamp])
-        # this is no longer used
-        #self.sendUpdate('setScenarioIndex', [self.scenarioIndex])
-        if __dev__:
-            assert self.scenarioIndex == 0
-
-    def getLevelZoneId(self):
-        """no entities should be generated in the level's zone; it causes
-        nasty race conditions on the client if there are entities in the
-        same zone with the level"""
-        return self.zoneId
-
-    def getPlayerIds(self):
-        return self.avIdList
-
-    def getEntranceId(self):
-        return self.entranceId
-
-    def delete(self, deAllocZone=True):
-        self.notify.debug('delete')
-        if __dev__:
-            self.removeAutosaveTask()
-        self.destroyLevel()
-        self.ignoreAll()
-        if deAllocZone:
-            self.air.deallocateZone(self.zoneId)
-        DistributedObjectAI.DistributedObjectAI.delete(self)
-
-    def initializeLevel(self, levelSpec):
-        # record the level's start time so that we can sync the clients
-        self.startTime = globalClock.getRealTime()
-        self.startTimestamp = globalClockDelta.localToNetworkTime(
-            self.startTime, bits=32)
-
-        # choose a scenario
-        # make list of lists: [(weight, scenarioIndex), ...]
-        lol = zip([1] * levelSpec.getNumScenarios(),
-                  range(levelSpec.getNumScenarios()))
-        scenarioIndex = weightedChoice(lol)
-
-        Level.Level.initializeLevel(self, self.doId, levelSpec, scenarioIndex)
-
-        if __dev__:
-            # listen for requests to save the spec
-            self.accept(self.editMgrEntity.getSpecSaveEvent(), self.saveSpec)
-
-        # listen for avatar disconnects
-        for avId in self.avIdList:
-            self.acceptOnce(self.air.getAvatarExitEvent(avId),
-                            Functor(self.handleAvatarDisconnect, avId))
-
-        # set up a barrier that will clear when all avs have left or
-        # disconnected
-        self.allToonsGoneBarrier = self.beginBarrier(
-            'allToonsGone', self.avIdList, 3*24*60*60, self.allToonsGone)
-
-    def handleAvatarDisconnect(self, avId):
-        try:
-            self.presentAvIds.remove(avId)
-            DistributedLevelAI.notify.warning('av %s has disconnected' % avId)
-        except:
-            DistributedLevelAI.notify.warning(
-                'got disconnect for av %s, not in list' % avId)
-        if not self.presentAvIds:
-            self.allToonsGone([])
-
-    def allToonsGone(self, toonsThatCleared):
-        print 'allToonsGone'
-        if hasattr(self, 'allToonsGoneBarrier'):
-            self.ignoreBarrier(self.allToonsGoneBarrier)
-            del self.allToonsGoneBarrier
-        for avId in self.avIdList:
-            self.ignore(self.air.getAvatarExitEvent(avId))
-        self.requestDelete()
-
-    def createEntityCreator(self):
-        """Create the object that will be used to create Entities.
-        Inheritors, override if desired."""
-        return EntityCreatorAI.EntityCreatorAI(level=self)
-
-    def setOuch(self, penalty):
-        avId = self.air.msgSender
-        av = self.air.doId2do.get(avId)
-        self.notify.debug("setOuch %s" % penalty)
-        # make sure penalty is > 0
-        if av and (penalty > 0):
-            av.takeDamage(penalty * self.levelMgrEntity.ouchMultiplier)
-        
-    def requestCurrentLevelSpec(self, specHash, entTypeRegHash):
-        senderId = self.air.msgSender
-
-        self.notify.info('av %s: specHash %s, entTypeRegHash %s' %
-                         (senderId, specHash, entTypeRegHash))
-
-        if not __dev__:
-            # client is running in dev mode and we're not; that won't fly
-            self.notify.info("client is in dev mode and we are not")
-            self.sendUpdateToAvatarId(
-                senderId, 'setSpecDeny',
-                ['AI server is not running in dev mode. '
-                 'Set want-dev to false on your client or true on the AI.'])
-            return
-
-        # first check the typeReg hash -- if it doesn't match, the
-        # client should not be connecting. Their entityTypeRegistry
-        # is different from ours.
-        srvHash = self.levelSpec.entTypeReg.getHashStr()
-        self.notify.info('srv entTypeRegHash %s' % srvHash)
-        if srvHash != entTypeRegHash:
-            self.sendUpdateToAvatarId(
-                senderId, 'setSpecDeny',
-                ['EntityTypeRegistry hashes do not match! '
-                 '(server:%s, client:%s' % (srvHash, entTypeRegHash)])
-            return
-
-        # now compare the hashes of the client and server specs
-        if hash(self.levelSpec) != specHash:
-            self.notify.info('spec hashes do not match, sending our spec')
-            spec = self.levelSpec
-            useDisk=simbase.config.GetBool('spec-by-disk', 0)
-        else:
-            self.notify.info('spec hashes match, sending null spec')
-            spec = None
-            # don't need to hit disk if we're just sending 'None' over the wire
-            useDisk = 0
-        specStr = repr(spec)
-
-        from direct.directutil import DistributedLargeBlobSenderAI
-        largeBlob = DistributedLargeBlobSenderAI.\
-                    DistributedLargeBlobSenderAI(
-            self.air, self.zoneId, senderId, specStr,
-            useDisk=useDisk)
-        self.sendUpdateToAvatarId(senderId,
-                                  'setSpecSenderDoId', [largeBlob.doId])
-
-    if __dev__:
-        # level editors should call this func to tweak attributes of level
-        # entities
-        def setAttribChange(self, entId, attribName, value, username='SYSTEM'):
-            DistributedLevelAI.notify.info(
-                "setAttribChange(%s): %s, %s = %s" %
-                (username, entId, attribName, repr(value)))
-            # send a copy to the client-side level obj FIRST
-            # (it may be a message that creates an entity)
-            self.sendUpdate('setAttribChange',
-                            [entId, attribName, repr(value), username])
-            self.levelSpec.setAttribChange(entId, attribName, value, username)
-
-            self.modified = 1
-            self.scheduleAutosave()
-
-        # backups are made every N minutes, starting from the time that
-        # the first edit is made
-        AutosavePeriod = simbase.config.GetFloat(
-            'level-autosave-period-minutes', 5)
-
-        def scheduleAutosave(self):
-            if hasattr(self, 'autosaveTask'):
-                return
-            self.autosaveTaskName = self.uniqueName('autosaveSpec')
-            self.autosaveTask = taskMgr.doMethodLater(
-                DistributedLevelAI.AutosavePeriod * 60,
-                self.autosaveSpec,
-                self.autosaveTaskName)
-
-        def removeAutosaveTask(self):
-            if hasattr(self, 'autosaveTask'):
-                taskMgr.remove(self.autosaveTaskName)
-                del self.autosaveTask
-
-        def autosaveSpec(self, task=None):
-            self.removeAutosaveTask()
-            if self.modified:
-                DistributedLevelAI.notify.info('autosaving spec')
-                filename = self.levelSpec.getFilename()
-                filename = '%s.autosave' % filename
-                self.levelSpec.saveToDisk(filename, makeBackup=0)
-
-        def saveSpec(self, task=None):
-            DistributedLevelAI.notify.info('saving spec')
-            self.removeAutosaveTask()
-            if not self.modified:
-                DistributedLevelAI.notify.info('no changes to save')
-                return
-            self.levelSpec.saveToDisk()
-            self.modified = 0

+ 0 - 7
direct/src/level/EditMgr.py

@@ -1,7 +0,0 @@
-"""EditMgr module: contains the EditMgr class"""
-
-import EditMgrBase
-
-class EditMgr(EditMgrBase.EditMgrBase):
-    """This class handles client-side editor-specific functionality"""
-    pass

+ 0 - 60
direct/src/level/EditMgrAI.py

@@ -1,60 +0,0 @@
-"""EditMgrAI module: contains the EditMgrAI class"""
-
-import EditMgrBase
-if __dev__:
-    from direct.showbase.PythonUtil import list2dict
-    import EditorGlobals
-
-class EditMgrAI(EditMgrBase.EditMgrBase):
-    """This class handles AI-side editor-specific functionality"""
-    if __dev__:
-        def setRequestNewEntity(self, data):
-            # pick an unused entId
-            spec = self.level.levelSpec
-            entIds = spec.getAllEntIds()
-            entIdDict = list2dict(entIds)
-
-            # Note that this uses the ID range associated with the
-            # AI's username, not the username of the user who requested
-            # the new entity.
-            allocRange = EditorGlobals.getEntIdAllocRange()
-
-            if not hasattr(self, 'lastAllocatedEntId'):
-                self.lastAllocatedEntId = allocRange[0]
-
-            idChosen = 0
-            while not idChosen:
-                # linear search for an unused entId starting with the
-                # last-allocated id
-                for id in xrange(self.lastAllocatedEntId, allocRange[1]):
-                    print id
-                    if not id in entIdDict:
-                        idChosen = 1
-                        break
-                else:
-                    # we ran off the end of the range.
-                    if self.lastAllocatedEntId != allocRange[0]:
-                        # if we started in the middle, try again from
-                        # the beginning
-                        self.lastAllocatedEntId = allocRange[0]
-                    else:
-                        # every entId is used!!
-                        self.notify.error('out of entIds')
-
-            # OK, we've chosen an unused entId. Add the entId to the data
-            # dict and do the insert
-            data.update({'entId': id})
-            self.lastAllocatedEntId = id
-            self.level.setAttribChange(self.entId, 'insertEntity', data)
-
-            # clear out the attrib, it shouldn't be kept in the spec
-            self.level.levelSpec.doSetAttrib(self.entId, 'requestNewEntity',
-                                             None)
-
-        def getSpecSaveEvent(self):
-            return 'requestSave-%s' % self.level.levelId
-        def setRequestSave(self, data):
-            messenger.send(self.getSpecSaveEvent())
-            # clear out the attrib, it shouldn't be kept in the spec
-            self.level.levelSpec.doSetAttrib(self.entId, 'requestSave',
-                                             None)

+ 0 - 34
direct/src/level/EditMgrBase.py

@@ -1,34 +0,0 @@
-"""EditMgrBase module: contains the EditMgrBase class"""
-
-import Entity
-from direct.directnotify import DirectNotifyGlobal
-
-class EditMgrBase(Entity.Entity):
-    """This class contains EditMgr code shared between AI and client"""
-    notify = DirectNotifyGlobal.directNotify.newCategory("EditMgr")
-    def __init__(self, level, entId):
-        Entity.Entity.__init__(self, level, entId)
-
-    def destroy(self):
-        Entity.Entity.destroy(self)
-        self.ignoreAll()
-
-    if __dev__:
-        def setInsertEntity(self, data):
-            # tell the level who created this entity
-            self.level.setEntityCreatorUsername(data['entId'], data['username'])
-            # create the entity
-            self.level.levelSpec.insertEntity(data['entId'],
-                                              data['entType'],
-                                              data['parentEntId'],
-                                              )
-            # clear out the attrib, it shouldn't be kept in the spec
-            self.level.levelSpec.doSetAttrib(self.entId, 'insertEntity',
-                                             None)
-
-        def setRemoveEntity(self, data):
-            self.level.levelSpec.removeEntity(data['entId'],
-                                              )
-            # clear out the attrib, it shouldn't be kept in the spec
-            self.level.levelSpec.doSetAttrib(self.entId, 'removeEntity',
-                                             None)

+ 0 - 52
direct/src/level/EditorGlobals.py

@@ -1,52 +0,0 @@
-"""EditorGlobals module: contains global editor data"""
-
-from direct.showbase.PythonUtil import uniqueElements
-
-# levels should put themselves into the bboard under this posting
-# to assert themselves as the level to be edited by ~edit
-EditTargetPostName = 'inGameEditTarget'
-
-EntIdRange = 10000
-# Once a range has been assigned to a user, please don't change it.
-username2entIdBase = {
-    'darren':   1*EntIdRange,
-    'samir':    2*EntIdRange,
-    'skyler':   3*EntIdRange,
-    'joe':      4*EntIdRange,
-    'DrEvil':   5*EntIdRange,
-    'asad':     6*EntIdRange,
-    'drose':    7*EntIdRange,
-    'pappy':    8*EntIdRange,
-    'patricia': 9*EntIdRange,
-    }
-assert uniqueElements(username2entIdBase.values())
-
-usernameConfigVar = 'level-edit-username'
-undefinedUsername = 'UNDEFINED_USERNAME'
-editUsername = config.GetString(usernameConfigVar, undefinedUsername)
-
-# call this to make sure things have been set up correctly
-def checkNotReadyToEdit():
-    # returns error string if not ready, None if ready
-    if editUsername == undefinedUsername:
-        return "you must config '%s'; see %s.py" % (
-            usernameConfigVar, __name__)
-    # Feel free to add your name to the table if it's not in there
-    if editUsername not in username2entIdBase:
-        return "unknown editor username '%s'; see %s.py" % (
-            editUsername, __name__)
-    return None
-
-def assertReadyToEdit():
-    msg = checkNotReadyToEdit()
-    if msg is not None:
-        assert False, msg
-
-def getEditUsername():
-    return editUsername
-
-def getEntIdAllocRange():
-    """range of valid entId values for this user.
-    returns [min, max+1] (values taken by range() and xrange())"""
-    baseId = username2entIdBase[editUsername]
-    return [baseId, baseId+EntIdRange]

+ 0 - 149
direct/src/level/Entity.py

@@ -1,149 +0,0 @@
-"""Entity.py: contains the Entity class"""
-
-from direct.showbase.DirectObject import *
-from direct.showbase.PythonUtil import lineInfo
-import string
-from direct.directnotify import DirectNotifyGlobal
-
-class Entity(DirectObject):
-    """Entity is the base class for all objects that exist in a Level
-    and can be edited with the LevelEditor."""
-    notify = DirectNotifyGlobal.directNotify.newCategory('Entity')
-
-    def __init__(self, level=None, entId=None):
-        self.initializeEntity(level, entId)
-
-    def initializeEntity(self, level, entId):
-        ###
-        ### THIS IS WHERE ENTITIES GET THEIR ATTRIBUTES SET
-        ###
-        """Distributed entities on the client don't know their level or
-        entId values until they've been generated, so they call this
-        after they've been generated. At that point, the entity is good
-        to go."""
-        self.level = level
-        self.entId = entId
-        if (self.level is not None) and (self.entId is not None):
-            self.level.initializeEntity(self)
-
-    def __str__(self):
-        return 'ent%s(%s)' % (self.entId, self.level.getEntityType(self.entId))
-    
-    def destroy(self):
-        """This is called when the level wants this entity to go away.
-        Once this is called, the Entity should be considered defunct.
-        NOTE: distributed entities are still valid distributed objects
-        after this is called, but they are no longer valid entities.
-        Distributed entities ought to be disabled and/or deleted shortly
-        after this is called.
-        """
-        Entity.notify.debug('Entity.destroy() %s' % self.entId)
-        # client-side distributed entities might be doing this after
-        # the level has been been destroyed...?
-        if self.level.isInitialized():
-            self.level.onEntityDestroy(self.entId)
-        else:
-            Entity.notify.warning('Entity %s destroyed after level??' %
-                                  self.entId)
-        self.ignoreAll()
-        del self.level
-        del self.entId
-        
-    def getUniqueName(self, name, entId=None):
-        """returns a name that is unique for a particular entity;
-        defaults to this entity"""
-        if entId is None:
-            entId = self.entId
-        return '%s-%s-%s' % (name, self.level.levelId, entId)
-
-    def getParentToken(self):
-        """returns a value that uniquely identifies this entity for purposes
-        of distributed parenting"""
-        # give the level the option of modifying our entId, to handle instances
-        # where there are multiple levels present on the client simultaneously
-        return self.level.getParentTokenForEntity(self.entId)
-
-    def getOutputEventName(self, entId=None):
-        """returns the event generated by an entity; defaults to this entity"""
-        if entId is None:
-            entId = self.entId
-        return self.getUniqueName('entityOutput', entId)
-
-    def getZoneEntId(self):
-        """returns entId of zone that contains this entity"""
-        return self.level.getEntityZoneEntId(self.entId)
-
-    def getZoneEntity(self):
-        """returns zone entity for zone that contains this entity"""
-        return self.level.getEntity(self.getZoneEntId())
-
-    def getZoneNode(self):
-        """returns zoneNode for zone that contains this entity"""
-        return self.getZoneEntity().getNodePath()
-
-    def privGetSetter(self, attrib):
-        setFuncName = 'set%s%s' % (string.upper(attrib[0]), attrib[1:])
-        if hasattr(self, setFuncName):
-            return getattr(self, setFuncName)
-        return None
-
-    def callSetters(self, *attribs):
-        """call this with a list of attribs, and any that exist on the
-        entity and have setters will be passed to their setter"""
-        self.privCallSetters(0, *attribs)
-
-    def callSettersAndDelete(self, *attribs):
-        """same as callSetters, but also removes attribs from entity"""
-        self.privCallSetters(1, *attribs)
-
-    def privCallSetters(self, doDelete, *attribs):
-        """common implementation of callSetters and callSettersAndDelete"""
-        for attrib in attribs:
-            if hasattr(self, attrib):
-                setter = self.privGetSetter(attrib)
-                if setter is not None:
-                    value = getattr(self, attrib)
-                    if doDelete:
-                        delattr(self, attrib)
-                    setter(value)
-
-    # this will be called with each item of our spec data on initialization
-    def setAttribInit(self, attrib, value):
-        if __debug__:
-            if hasattr(self, attrib):
-                Entity.notify.warning(
-                    '%s already has member %s in setAttribInit' %
-                    (self, attrib))
-        # TODO: we should probably put this crep in a dictionary
-        # rather than dump it into the entity's namespace
-        self.__dict__[attrib] = value
-
-    if __debug__:
-        def debugPrint(self, message):
-            """for debugging"""
-            return self.notify.debug(
-                    str(self.__dict__.get('entId', '?'))+' '+message)
-
-    if __dev__:
-        # support for level editing
-        def handleAttribChange(self, attrib, value):
-            # call callback function if it exists
-            # otherwise set attrib directly and call notify func
-            setter = self.privGetSetter(attrib)
-            if setter is not None:
-                # call the setter
-                setter(value)
-            else:
-                # set the attrib directly
-                self.__dict__[attrib] = value
-                # and call the notify func
-                self.attribChanged(attrib, value)
-
-        def attribChanged(self, attrib, value):
-            """This is called when a parameter is tweaked and no setter
-            is called; i.e. the value is set directly on the object.
-            Some Entities might want to completely reset every time anything
-            is tweaked; this is the place to do it, just override this func
-            in your derived class
-            """
-            pass

+ 0 - 52
direct/src/level/EntityCreator.py

@@ -1,52 +0,0 @@
-"""EntityCreator module: contains the EntityCreator class"""
-
-import CutScene
-import EntityCreatorBase
-import BasicEntities
-from direct.directnotify import DirectNotifyGlobal
-import EditMgr
-import EntrancePoint
-import LevelMgr
-import LogicGate
-import ZoneEntity
-import ModelEntity
-import PathEntity
-import VisibilityExtender
-import PropSpinner
-import AmbientSound
-
-# some useful constructor functions
-# ctor functions must take (level, entId)
-# and they must return the entity that was created, or 'nothing'
-def nothing(*args):
-    """For entities that don't need to be created by the client or don't
-    exist on the client at all"""
-    return 'nothing'
-
-class EntityCreator(EntityCreatorBase.EntityCreatorBase):
-    """
-    This class is responsible for creating instances of Entities on the
-    client. It can be subclassed to handle more Entity types.
-    """
-    
-    def __init__(self, level):
-        EntityCreatorBase.EntityCreatorBase.__init__(self, level)
-        self.level = level
-        self.privRegisterTypes({
-            'ambientSound': AmbientSound.AmbientSound,
-            'cutScene': CutScene.CutScene,
-            'editMgr': EditMgr.EditMgr,
-            'entityGroup': nothing,
-            'entrancePoint': EntrancePoint.EntrancePoint,
-            'levelMgr': LevelMgr.LevelMgr,
-            'logicGate': LogicGate.LogicGate,
-            'model' : ModelEntity.ModelEntity,
-            'nodepath': BasicEntities.NodePathEntity,
-            'path' : PathEntity.PathEntity,
-            'propSpinner' : PropSpinner.PropSpinner,
-            'visibilityExtender': VisibilityExtender.VisibilityExtender,
-            'zone': ZoneEntity.ZoneEntity,
-            })
-
-    def doCreateEntity(self, ctor, entId):
-        return ctor(self.level, entId)

+ 0 - 65
direct/src/level/EntityCreatorAI.py

@@ -1,65 +0,0 @@
-"""EntityCreatorAI module: contains the EntityCreatorAI class"""
-
-import EntityCreatorBase
-import LogicGate
-import EditMgrAI
-import LevelMgrAI
-import ZoneEntityAI
-from direct.showbase.PythonUtil import Functor
-
-# some useful constructor functions
-# ctor functions for entities must take
-#  (level, entId, zoneId)
-# and they must return the entity that was created, or 'nothing'
-
-# this func creates distributed entities whose constructors take
-#  (air, level doId, entId)
-# and do not generate themselves
-def createDistributedEntity(AIclass, level, entId, zoneId):
-    """create a distributed entity and call generate"""
-    ent = AIclass(level, entId)
-    ent.generateWithRequired(zoneId)
-    return ent
-
-# this func creates local entities whose constructors take
-#  (level, entId)
-def createLocalEntity(AIclass, level, entId, zoneId):
-    """create a local entity"""
-    ent = AIclass(level, entId)
-    return ent
-
-# take any number of args to support local and distributed entities
-def nothing(*args):
-    """Create entity that doesn't have a server side representation."""
-    return 'nothing'
-
-class EntityCreatorAI(EntityCreatorBase.EntityCreatorBase):
-    """This class is responsible for creating instances of Entities on the AI.
-    It can be subclassed to handle more Entity types."""
-
-    def __init__(self, level):
-        EntityCreatorBase.EntityCreatorBase.__init__(self, level)
-        
-        # create short aliases for ctor funcs
-        cLE = createLocalEntity
-
-        self.privRegisterTypes({
-            'ambientSound': nothing,
-            'cutScene': nothing,
-            'editMgr': Functor(cLE, EditMgrAI.EditMgrAI),
-            'entityGroup': nothing,
-            'entrancePoint': nothing,
-            'levelMgr': Functor(cLE, LevelMgrAI.LevelMgrAI),
-            'logicGate': Functor(cLE, LogicGate.LogicGate),
-            'model' : nothing,
-            'nodepath': nothing,
-            'path': nothing,
-            'propSpinner': nothing,
-            'visibilityExtender': nothing,
-            'zone': Functor(cLE, ZoneEntityAI.ZoneEntityAI),
-            })
-
-    def doCreateEntity(self, ctor, entId):
-        zoneId = self.level.getEntityZoneId(entId)
-        self.notify.debug('creating entity %s in zone %s' % (entId, zoneId))
-        return ctor(self.level, entId, zoneId)

+ 0 - 40
direct/src/level/EntityCreatorBase.py

@@ -1,40 +0,0 @@
-"""EntityCreatorBase module: contains the EntityCreatorBase class"""
-
-from direct.directnotify import DirectNotifyGlobal
-
-class EntityCreatorBase:
-    """This class is responsible for creating instances of Entities on the
-    AI and on the client. It must be subclassed to specify what entity
-    types it can create, and to provide the creation implementation."""
-    notify = DirectNotifyGlobal.directNotify.newCategory('EntityCreator')
-
-    def __init__(self, level):
-        self.level = level
-        self.entType2Ctor = {}
-
-    def createEntity(self, entId):
-        entType = self.level.getEntityType(entId)
-        
-        if not self.entType2Ctor.has_key(entType):
-            self.notify.error('unknown entity type: %s (ent%s)' %
-                              (entType, entId))
-
-        # inheritor must define doCreateEntity
-        ent = self.doCreateEntity(self.entType2Ctor[entType], entId)
-        assert ent is not None # must be Entity or 'nothing'
-        return ent
-
-    def getEntityTypes(self):
-        """by definition, this object knows the full list of entity types
-        that may exist within the level"""
-        return self.entType2Ctor.keys()
-
-    def privRegisterType(self, entType, ctor):
-        if self.entType2Ctor.has_key(entType):
-            self.notify.warning('replacing %s ctor %s with %s' %
-                                (entType, self.entType2Ctor[entType], ctor))
-        self.entType2Ctor[entType] = ctor
-
-    def privRegisterTypes(self, type2ctor):
-        for entType, ctor in type2ctor.items():
-            self.privRegisterType(entType, ctor)

+ 0 - 126
direct/src/level/EntityTypeDesc.py

@@ -1,126 +0,0 @@
-"""EntityTypeDesc module: contains the EntityTypeDesc class"""
-
-from direct.directnotify import DirectNotifyGlobal
-import AttribDesc
-from direct.showbase.PythonUtil import mostDerivedLast
-
-class EntityTypeDesc:
-    """This class is meta-data that describes an Entity type."""
-    notify = DirectNotifyGlobal.directNotify.newCategory('EntityTypeDesc')
-
-    output = None
-
-    def __init__(self):
-        self.__class__.privCompileAttribDescs(self.__class__)
-
-        self.attribNames = []
-        self.attribDescDict = {}
-
-        # ordered list of attrib descriptors
-        attribDescs = self.__class__._attribDescs
-
-        # create ordered list of attrib names, dict of attrib name to attribDesc
-        for desc in attribDescs:
-            attribName = desc.getName()
-            self.attribNames.append(attribName)
-            self.attribDescDict[attribName] = desc
-
-    def isConcrete(self):
-        """ means that entity of this exact type can be created """
-        return not self.__class__.__dict__.has_key('abstract')
-
-    def isPermanent(self):
-        """ means that entity of this exact type cannot be inserted or
-        removed in the editor """
-        return self.__class__.__dict__.has_key('permanent')
-
-    def getOutputType(self):
-        return self.output
-
-    def getAttribNames(self):
-        """ returns ordered list of attribute names for this entity type """
-        return self.attribNames
-
-    def getAttribDescDict(self):
-        """ returns dict of attribName -> attribDescriptor """
-        return self.attribDescDict
-
-    def getAttribsOfType(self, type):
-        """returns list of attrib names of the given type"""
-        names = []
-        for attribName, desc in self.attribDescDict.items():
-            if desc.getDatatype() == type:
-                names.append(attribName)
-        return names
-
-    def privCompileAttribDescs(entTypeClass):
-        """this compiles an ordered list of attribDescs for the Entity class
-        passed in. The attribute descriptors describe the properties of each
-        of the Entity type's attributes"""
-        # has someone already compiled the info?
-        if entTypeClass.__dict__.has_key('_attribDescs'):
-            return
-
-        c = entTypeClass
-        EntityTypeDesc.notify.debug('compiling attrib descriptors for %s' %
-                                    c.__name__)
-
-        # make sure all of our base classes have their complete list of
-        # attribDescs
-        for base in c.__bases__:
-            EntityTypeDesc.privCompileAttribDescs(base)
-
-        # aggregate the attribute descriptors from our direct base classes
-        blockAttribs = c.__dict__.get('blockAttribs', [])
-        baseADs = []
-
-        bases = list(c.__bases__)
-        # make sure base-class attribs show up before derived-class attribs
-        mostDerivedLast(bases)
-
-        for base in bases:
-            for desc in base._attribDescs:
-                # are we blocking this attribute?
-                if desc.getName() in blockAttribs:
-                    continue
-                    
-                # make sure we haven't already picked up this attribute
-                # from an earlier base class
-                for d in baseADs:
-                    if desc.getName() == d.getName():
-                        EntityTypeDesc.notify.warning(
-                            '%s inherits attrib %s from multiple bases' %
-                            (c.__name__, desc.getName()))
-                        break
-                else:
-                    baseADs.append(desc)
-
-        # now that we have all of the descriptors from our base classes,
-        # add the descriptors from this class
-        attribDescs = []
-        if c.__dict__.has_key('attribs'):
-            for attrib in c.attribs:
-                desc = AttribDesc.AttribDesc(*attrib)
-                
-                # if we picked up an attribute with the same name from a base
-                # class, this overrides it
-                for ad in baseADs:
-                    if ad.getName() == desc.getName():
-                        baseADs.remove(ad)
-                        # there ought to be no more than one desc with
-                        # this name from the base classes
-                        assert ad not in baseADs
-                        break
-                    
-                attribDescs.append(desc)
-
-        c._attribDescs = baseADs + attribDescs
-    privCompileAttribDescs = staticmethod(privCompileAttribDescs)
-
-    def __str__(self):
-        return str(self.__class__)
-    def __repr__(self):
-        # this is used to produce a hash value
-        return (str(self.__class__.__dict__.get('type',None))+
-                str(self.output)+
-                str(self.attribDescDict))

+ 0 - 134
direct/src/level/EntityTypeRegistry.py

@@ -1,134 +0,0 @@
-"""EntityTypeRegistry module: contains the EntityTypeRegistry class"""
-
-from pandac.PandaModules import *
-from direct.directnotify import DirectNotifyGlobal
-import types
-import AttribDesc
-import EntityTypeDesc
-from direct.showbase.PythonUtil import mostDerivedLast
-import os
-
-class EntityTypeRegistry:
-    notify = DirectNotifyGlobal.directNotify.newCategory('EntityTypeRegistry')
-
-    def __init__(self, entityTypeModule):
-        """pass in a module that contains EntityTypeDesc classes"""
-        self.entTypeModule = entityTypeModule
-
-        # compute the hash of the source modules as of the time of creation
-        hv = HashVal()
-        import EntityTypes
-        reload(EntityTypes)
-        reload(self.entTypeModule)
-
-        # Convert a pyc or pyo to a py
-        # If the client runs genPyCode -n then ihooks will not be installed
-        # and you will get a pyc file instead of a py file. Then the AI and
-        # client will be mismatched because the AI automatically installs
-        # ihooks and thus will hash the py instead of the pyc. Then the
-        # hashes do not match and everybody is sad. Let's just make sure
-        # for once and for all that we use the .py file and not a .pyc or a
-        # .pyo in case that ever happened.
-        def getPyExtVersion(filename):
-            base, ext = os.path.splitext(filename)
-            if (ext == ".pyc") or (ext == ".pyo"):
-                filename = base + ".py"
-            return filename
-        
-        hv.hashFile(Filename.fromOsSpecific(getPyExtVersion(EntityTypes.__file__)))
-        s = str(hv.asHex())
-        s += '.'
-        hv.hashFile(Filename.fromOsSpecific(getPyExtVersion(self.entTypeModule.__file__)))
-        s += str(hv.asHex())
-        self.hashStr = s
-
-        # get a list of the EntityTypeDesc classes in the type module
-        classes = []
-        for key, value in entityTypeModule.__dict__.items():
-            if type(value) is types.ClassType:
-                if issubclass(value, EntityTypeDesc.EntityTypeDesc):
-                    classes.append(value)
-
-        self.entTypeName2typeDesc = {}
-
-        # create an instance of each EntityType class with a typename
-        # make sure that derived classes come after bases
-        mostDerivedLast(classes)
-        for c in classes:
-            if c.__dict__.has_key('type'):
-                if self.entTypeName2typeDesc.has_key(c.type):
-                    # a more-derived class is replacing a less-derived class
-                    # to implement a particular entity type
-                    EntityTypeRegistry.notify.info(
-                        "replacing %s with %s for entity type '%s'" %
-                        (self.entTypeName2typeDesc[c.type].__class__,
-                         c, c.type))
-                self.entTypeName2typeDesc[c.type] = c()
-
-        # create mapping of entity output types to list of concrete entity
-        # typenames with that output type
-        self.output2typeNames = {}
-        for typename, typeDesc in self.entTypeName2typeDesc.items():
-            if typeDesc.isConcrete():
-                if hasattr(typeDesc, 'output'):
-                    outputType = typeDesc.output
-                    self.output2typeNames.setdefault(outputType, [])
-                    self.output2typeNames[outputType].append(typename)
-
-        # create list of permanent entity typenames (entity types that cannot
-        # be inserted or removed in the editor)
-        self.permanentTypeNames = []
-        for typename, typeDesc in self.entTypeName2typeDesc.items():
-            if typeDesc.isPermanent():
-                assert typeDesc.isConcrete()
-                self.permanentTypeNames.append(typename)
-
-        # create mapping of entity typename (abstract or concrete) to list
-        # of entity typenames are concrete and are of that type or derive
-        # from that type
-        self.typeName2derivedTypeNames = {}
-        for typename, typeDesc in self.entTypeName2typeDesc.items():
-            typenames = []
-            for tn, td in self.entTypeName2typeDesc.items():
-                if td.isConcrete():
-                    if issubclass(td.__class__, typeDesc.__class__):
-                        typenames.append(tn)
-            self.typeName2derivedTypeNames[typename] = typenames
-
-    def getTypeDesc(self, entTypeName):
-        """returns EntityTypeDesc instance for concrete Entity type"""
-        assert entTypeName in self.entTypeName2typeDesc,\
-               "unknown entity type '%s'" % entTypeName
-        # the table has descriptors for abstract entity types, but I don't
-        # think there's any need for anyone outside this class to access them
-        assert self.entTypeName2typeDesc[entTypeName].isConcrete(),\
-               "entity type '%s' is abstract" % entTypeName
-        return self.entTypeName2typeDesc[entTypeName]
-
-    def getTypeNamesFromOutputType(self, outputType):
-        """return Entity typenames for Entity types with particular output"""
-        return self.output2typeNames.get(outputType, [])
-
-    def getDerivedTypeNames(self, entTypeName):
-        """return Entity typenames that are of or derive from an entity type,
-        which may be concrete or abstract"""
-        assert entTypeName in self.typeName2derivedTypeNames,\
-               "unknown entity type '%s'" % entTypeName
-        return self.typeName2derivedTypeNames[entTypeName]
-
-    def isDerivedAndBase(self, entType, baseEntType):
-        return entType in self.getDerivedTypeNames(baseEntType)
-
-    def getPermanentTypeNames(self):
-        return self.permanentTypeNames
-
-    def getHashStr(self):
-        return self.hashStr
-
-    def __hash__(self):
-        # THIS IS NOT GUARANTEED TO PRODUCE THE SAME VALUE ACROSS DIFFERENT
-        # MACHINES; use getHashStr instead
-        return hash(repr(self))
-    def __repr__(self):
-        # this is used to produce a hash value
-        return str(self.entTypeName2typeDesc)

+ 0 - 126
direct/src/level/EntityTypes.py

@@ -1,126 +0,0 @@
-"""EntityTypes module: contains classes that describe Entity types"""
-
-from EntityTypeDesc import EntityTypeDesc
-from toontown.coghq.SpecImports import *
-
-class Entity(EntityTypeDesc):
-    abstract = 1
-    type = 'entity'
-    attribs = (
-        ('type', None, 'const'),
-        ('name', '<unnamed>', 'string'),
-        ('comment', '', 'string'),
-        ('parentEntId', 0, 'entId'),
-        )
-
-class LevelMgr(Entity):
-    type = 'levelMgr'
-    permanent = 1
-    attribs = (
-        ('name', 'LevelMgr', 'const'),
-        ('parentEntId', 0, 'const'),
-        ('modelFilename', '', 'const'),
-        ('ouchMultiplier', 1, 'int', {'min':1}),
-        )
-
-class EditMgr(Entity):
-    type = 'editMgr'
-    permanent = 1
-    blockAttribs = (
-        'comment',
-        )
-    attribs = (
-        ('name', 'LevelMgr', 'const'),
-        ('parentEntId', 0, 'const'),
-        ('requestSave', None, 'const'),
-        ('requestNewEntity', None, 'const'),
-        ('insertEntity', None, 'const'),
-        ('removeEntity', None, 'const'),
-        )
-
-class Nodepath(Entity):
-    type = 'nodepath'
-    attribs = (
-        ('parentEntId', 0, 'entId', {'type':'nodepath'}),
-        ('pos', Point3(0,0,0), 'pos'),
-        ('hpr', Vec3(0,0,0), 'hpr'),
-        ('scale', 1, 'scale'),
-        )
-
-class Zone(Nodepath):
-    type = 'zone'
-    permanent = 1
-    blockAttribs = (
-        'pos',
-        'hpr',
-        )
-    attribs = (
-        ('parentEntId', 0, 'const'),
-        ('description', '', 'string'),
-        ('visibility', [], 'visZoneList'),
-        )
-
-class EntrancePoint(Nodepath):
-    type = 'entrancePoint'
-    attribs = (
-        ('entranceId', -1, 'int'),
-        ('radius', 15, 'float', {'min':0}),
-        ('theta', 20, 'float', {'min':0}),
-        )
-
-class LogicGate(Entity):
-    type = 'logicGate'
-    output = 'bool'
-    attribs = (
-        ('input1Event', 0, 'entId', {'output':'bool'}),
-        ('input2Event', 0, 'entId', {'output':'bool'}),
-        ('isInput1', 0, 'bool'),
-        ('isInput2', 0, 'bool'),
-        ('logicType', 'or', 'choice',
-         {'choiceSet':['or','and','xor','nand','nor','xnor']}),
-        )
-
-class CutScene(Entity):
-    type = 'cutScene'
-    output = 'bool'
-    attribs = (
-        ('pos', Point3(0,0,0), 'pos'),
-        ('hpr', Vec3(0,0,0), 'hpr'),
-        ('startStopEvent', 0, 'entId', {'output':'bool'}),
-        ('effect', 'irisInOut', 'choice', {'choiceSet':['nothing','irisInOut','letterBox']}),
-        ('motion', 'foo1', 'choice', {'choiceSet':['foo1']}),
-        ('duration', 5.0, 'float'),
-        )
-
-class Model(Nodepath):
-    type = 'model'
-    attribs = (
-        ('modelPath', None, 'bamfilename'),
-        )
-
-class Path(Nodepath):
-    type = 'path'
-    attribs = (
-        ('pathIndex', 0, 'int'),
-        )
-
-class VisibilityExtender(Entity):
-    type = 'visibilityExtender'
-    attribs = (
-        ('event', None, 'entId', {'output':'bool'}),
-        ('newZones', [], 'visZoneList'),
-        )
-
-class AmbientSound(Nodepath):
-    type = 'ambientSound'
-    attribs = (
-        ('soundPath', '', 'bamfilename'),
-        ('volume', 1, 'float', {'min':0,'max':1}),
-        ('enabled', 1, 'bool'),
-        )
-
-class PropSpinner(Entity):
-    type = 'propSpinner'
-
-class EntityGroup(Entity):
-    type = 'entityGroup'

+ 0 - 39
direct/src/level/EntrancePoint.py

@@ -1,39 +0,0 @@
-from toontown.toonbase.ToontownGlobals import *
-from direct.directnotify import DirectNotifyGlobal
-import BasicEntities
-from pandac import NodePath
-
-class EntrancePoint(BasicEntities.NodePathEntity):
-    def __init__(self, level, entId):
-        BasicEntities.NodePathEntity.__init__(self, level, entId)
-        self.rotator = self.attachNewNode('rotator')
-        self.placer = self.rotator.attachNewNode('placer')
-        self.initEntrancePoint()
-
-    def destroy(self):
-        self.destroyEntrancePoint()
-        self.placer.removeNode()
-        self.rotator.removeNode()
-        del self.placer, self.rotator
-        BasicEntities.NodePathEntity.destroy(self)
-
-    def placeToon(self, toon, toonIndex, numToons):
-        self.placer.setY(-self.radius)
-        self.rotator.setH((-self.theta*(numToons-1)*.5) +
-                          (toonIndex*self.theta))
-        toon.setPosHpr(self.placer, 0,0,0, 0,0,0)
-
-    def initEntrancePoint(self):
-        if self.entranceId >= 0:
-            self.level.entranceId2entity[self.entranceId] = self
-
-    def destroyEntrancePoint(self):
-        if self.entranceId >= 0:
-            if self.level.entranceId2entity.has_key(self.entranceId):
-                del self.level.entranceId2entity[self.entranceId]
-
-    if __dev__:
-        def attribChanged(self, *args):
-            BasicEntities.NodePathEntity.attribChanged(self, *args)
-            self.destroyEntrancePoint()
-            self.initEntrancePoint()

+ 0 - 391
direct/src/level/Level.py

@@ -1,391 +0,0 @@
-"""Level.py: contains the Level class"""
-
-from direct.directnotify import DirectNotifyGlobal
-import string
-import LevelConstants
-from direct.showbase.PythonUtil import lineInfo, uniqueElements
-import types
-
-"""
-Any data that can be edited by a level editor must be represented as
-an attribute of an entity owned by the level, in order to keep the
-level-editing interface simple and constant (there are at least three
-places where the entire editing interface must be duplicated).
-
-To support this, we have entities such as 'levelMgr' and 'zoneEntity' that
-contain crucial level information, much of which is needed when setting
-up the level object, and is needed before other entity types can be
-effectively created. (If you try to create a distributed entity, but
-you don't yet have the information for the zone that it's in, because
-you haven't created the zone's ZoneEntity, you're hurting.)
-"""
-
-"""
-ZONE TERMINOLOGY
-zoneNum / zoneEntId: the number that a modeler chooses for a zone, and also
-                     the entity ID of the ZoneEntity that represents a zone
-zoneId : the network ID of a zone
-"""
-
-class Level:
-    """Level: representation of a game level, keeps track of all of the
-    entities and their interrelations, and creates and destroys entities"""
-    notify = DirectNotifyGlobal.directNotify.newCategory('Level')
-
-    def __init__(self):
-        self.levelSpec = None
-        self.initialized = 0
-
-    def initializeLevel(self, levelId, levelSpec, scenarioIndex):
-        """subclass should call this as soon as it has located
-        its spec data. levelId should be a unique integer (a doId works
-        just fine) that differentiates this level from all other levels
-        that may exist concurrently."""
-        self.levelId = levelId
-        self.levelSpec = levelSpec
-        self.scenarioIndex = scenarioIndex
-
-        self.levelSpec.setScenario(self.scenarioIndex)
-        if __dev__:
-            self.levelSpec.setLevel(self)
-
-        # create some handy tables
-
-        # entranceId to entrance entity
-        self.entranceId2entity = {}
-
-        # dict of entId -> list of callbacks to be called upon creation
-        self.entId2createCallbacks = {}
-
-        # this list contains the entIds of entities that we have actually
-        # created, in order of creation
-        self.createdEntIds = []
-
-        # get an entity creator object
-        self.entityCreator = self.createEntityCreator()
-
-        # entity type -> list of entIds
-        self.entType2ids = self.levelSpec.getEntType2ids(
-            self.levelSpec.getAllEntIds())
-        # create empty list for any entity types that are not represented
-        # in the spec
-        for entType in self.entityCreator.getEntityTypes():
-            self.entType2ids.setdefault(entType, [])
-
-        # create all the entities
-        # TODO: maybe we should leave this to a subclass or the level user
-        self.createAllEntities(priorityTypes=['levelMgr','zone','propSpinner'])
-
-        # check on the singleton entities
-        # we make our own references to them rather than expect them to
-        # create the references so that the editor can create dummy
-        # do-nothing entities
-
-        # there should be one and only one levelMgr
-        assert len(self.entType2ids['levelMgr']) == 1
-        assert self.entType2ids['levelMgr'][0] == LevelConstants.LevelMgrEntId
-        self.levelMgrEntity = self.getEntity(LevelConstants.LevelMgrEntId)
-
-        # there should be one and only one editMgr
-        assert len(self.entType2ids['editMgr']) == 1
-        assert self.entType2ids['editMgr'][0] == LevelConstants.EditMgrEntId
-        if __debug__:
-            self.editMgrEntity = self.getEntity(LevelConstants.EditMgrEntId)
-
-        # there should be one and only one UberZone
-        assert LevelConstants.UberZoneEntId in self.entType2ids['zone']
-        self.uberZoneEntity = self.getEntity(LevelConstants.UberZoneEntId)
-
-        self.initialized = 1
-
-    def isInitialized(self):
-        return self.initialized
-
-    def getLevelId(self):
-        return self.levelId
-
-    def destroyLevel(self):
-        self.destroyAllEntities()
-        self.initialized = 0
-        del self.createdEntIds
-        if hasattr(self, 'entities'):
-            del self.entities
-        if hasattr(self, 'levelSpec'):
-            del self.levelSpec
-
-    def createEntityCreator(self):
-        Level.notify.error(
-            'concrete Level class must override %s' % lineInfo()[2])
-
-    def createAllEntities(self, priorityTypes=[]):
-        """creates all entities in the spec. priorityTypes is an
-        optional ordered list of entity types to create first."""
-        # this will be filled in as the entities are created and report in
-        # this includes distributed objects on the client
-        self.entities = {}
-
-        # get list of all entity types we need to create
-        entTypes = self.entityCreator.getEntityTypes()
-
-        self.onLevelPreCreate()
-
-        # first create the types in the priority list
-        for type in priorityTypes:
-            assert type in entTypes
-            self.createAllEntitiesOfType(type)
-            entTypes.remove(type)
-
-        # create the other entities in any old order
-        for type in entTypes:
-            self.createAllEntitiesOfType(type)
-
-        self.onLevelPostCreate()
-
-    def destroyAllEntities(self):
-        assert uniqueElements(self.createdEntIds)
-        # destroy the entities in reverse order
-        while len(self.createdEntIds) > 0:
-            entId = self.createdEntIds.pop()
-            entity = self.getEntity(entId)
-            if entity is not None:
-                Level.notify.debug('destroying %s %s' % (
-                    self.getEntityType(entId), entId))
-                entity.destroy()
-                assert not entId in self.entities
-            else:
-                Level.notify.error('trying to destroy entity %s, but '
-                                   'it is already gone' % entId)
-
-    def createAllEntitiesOfType(self, entType):
-        """creates all entities of a given type"""
-        assert entType in self.entityCreator.getEntityTypes()
-
-        self.onEntityTypePreCreate(entType)
-
-        for entId in self.entType2ids[entType]:
-            self.createEntity(entId)
-
-        self.onEntityTypePostCreate(entType)
-
-    def createEntity(self, entId):
-        assert not entId in self.createdEntIds
-        spec = self.levelSpec.getEntitySpec(entId)
-        Level.notify.debug('creating %s %s' % (spec['type'], entId))
-        entity = self.entityCreator.createEntity(entId)
-        # NOTE: the entity is not considered to really be created until
-        # it has all of its initial spec data; see 'initializeEntity'
-        # below.
-        if entity is not 'nothing':
-            assert uniqueElements(self.createdEntIds)
-            assert entId not in self.createdEntIds
-            self.createdEntIds.append(entId)
-
-        # call the create handler
-        # we used to do this in initializeEntity, but that did not
-        # allow for additional initialization to be performed in
-        # derived entity __init__ funcs before their presence was announced
-        # Note that now DistributedEntity's are responsible for calling
-        # this for themselves
-        self.onEntityCreate(entId)
-
-        return entity
-
-    def initializeEntity(self, entity):
-        """populate an entity with its spec data. This is not done
-        in createEntity in order to allow other pieces of code to create
-        entities; this is called directly by Entity.
-        """
-        entId = entity.entId
-        spec = self.levelSpec.getEntitySpec(entId)
-        # on initialization, set items directly on entity
-        for key,value in spec.items():
-            if key in ('type', 'name', 'comment',):
-                continue
-            entity.setAttribInit(key, value)
-
-        # entity is initialized, add it to the list of entities
-        # if this assert fails, check distributed entities to make sure
-        # they're calling down to Entity.destroy
-        if __debug__:
-            if entId in self.entities:
-                self.notify.warning(
-                    'entity %s already in entity table... '%(entId)+
-                    'make sure distributedEntity is calling down to '
-                    'Entity.destroy!')
-        self.entities[entId] = entity
-
-    def getEntity(self, entId):
-        return self.entities.get(entId)
-
-    def getEntityType(self, entId):
-        return self.levelSpec.getEntityType(entId)
-
-    def getEntityZoneEntId(self, entId):
-        """return entId of zone that contains the entity"""
-        return self.levelSpec.getEntityZoneEntId(entId)
-
-    def getEntityZoneId(self, entId):
-        """return network zoneId of zone that contains the entity"""
-        # this is called during entity creation on the AI; we have to
-        # handle this carefully, since the information required to
-        # produce a zoneId is not available until the level's zone
-        # entities have been instantiated.
-        zoneEntId = self.getEntityZoneEntId(entId)
-        # fundamental entities (levelMgr) are responsible for creating
-        # tables like 'zoneNum2zoneId'; if those tables haven't been
-        # created yet, just return None
-        if not hasattr(self, 'zoneNum2zoneId'):
-            return None
-        # this might return None if all of our zone entities haven't
-        # been created yet. this could be a problem if zone entities
-        # are ever distributed. it also means that no distributed entities
-        # should be created before the zone entities.
-        return self.zoneNum2zoneId.get(zoneEntId)
-
-    def getZoneId(self, zoneEntId):
-        """look up network zoneId by zone entId"""
-        assert zoneEntId in self.zoneNum2zoneId
-        return self.zoneNum2zoneId[zoneEntId]
-
-    def getZoneNumFromId(self, zoneId):
-        """returns the model zoneNum that corresponds to a network zoneId"""
-        return self.zoneId2zoneNum[zoneId]
-
-    def getParentTokenForEntity(self, entId):
-        """returns a unique parent token for this entity"""
-        # default impl
-        # subclasses can override to allow for multiple levels present
-        # on the client simultaneously
-        return entId
-
-    # these events are thrown as the level initializes itself
-    # LEVEL
-    def getLevelPreCreateEvent(self):
-        """This is the event that is thrown immediately before the level
-        creates its entities."""
-        return 'levelPreCreate-%s' % (self.levelId)
-    def getLevelPostCreateEvent(self):
-        """This is the event that is thrown immediately after the level
-        creates its entities."""
-        return 'levelPostCreate-%s' % (self.levelId)
-    # ENTITY TYPE
-    def getEntityTypePreCreateEvent(self, entType):
-        """This is the event that is thrown immediately before the level
-        creates the entities of the given type."""
-        return 'entityTypePreCreate-%s-%s' % (self.levelId, entType)
-    def getEntityTypePostCreateEvent(self, entType):
-        """This is the event that is thrown immediately after the level
-        creates the entities of the given type."""
-        return 'entityTypePostCreate-%s-%s' % (self.levelId, entType)
-    # ENTITY
-    def getEntityCreateEvent(self, entId):
-        """This is the event that is thrown immediately after a
-        particular entity is initialized"""
-        return 'entityCreate-%s-%s' % (self.levelId, entId)
-    def getEntityOfTypeCreateEvent(self, entType):
-        """This event is thrown immediately after each instance of the
-        given entity type is created; handlers must accept an entId"""
-        return 'entityOfTypeCreate-%s-%s' % (self.levelId, entType)
-
-    # these handlers are called as the level initializes itself
-    # LEVEL
-    def onLevelPreCreate(self):
-        """Level is about to create its entities"""
-        messenger.send(self.getLevelPreCreateEvent())
-    def onLevelPostCreate(self):
-        """Level is done creating its entities"""
-        messenger.send(self.getLevelPostCreateEvent())
-    # ENTITY TYPE
-    def onEntityTypePreCreate(self, entType):
-        """Level is about to create these entities"""
-        messenger.send(self.getEntityTypePreCreateEvent(entType))
-    def onEntityTypePostCreate(self, entType):
-        """Level has just created these entities"""
-        messenger.send(self.getEntityTypePostCreateEvent(entType))
-    # ENTITY
-    def onEntityCreate(self, entId):
-        """Level has just created this entity"""
-        # send the entity-create event
-        messenger.send(self.getEntityCreateEvent(entId))
-        # send the entity-of-type create event
-        messenger.send(
-            self.getEntityOfTypeCreateEvent(self.getEntityType(entId)),
-            [entId])
-        # call any callbacks
-        if entId in self.entId2createCallbacks:
-            for callback in self.entId2createCallbacks[entId]:
-                callback()
-            del self.entId2createCallbacks[entId]
-
-    # Use to set a callback to be called when entity is created.
-    # If entity already exists, callback will be called immediately.
-    def setEntityCreateCallback(self, entId, callback):
-        ent = self.getEntity(entId)
-        if ent is not None:
-            callback()
-            return
-        self.entId2createCallbacks.setdefault(entId, [])
-        self.entId2createCallbacks[entId].append(callback)
-
-    # these are events and handlers that are invoked as entities are destroyed
-    def getEntityDestroyEvent(self, entId):
-        """This is the event that is thrown immediately before an
-        entity is destroyed"""
-        return 'entityDestroy-%s-%s' % (self.levelId, entId)
-    def onEntityDestroy(self, entId):
-        """Level is about to destroy this entity"""
-        assert entId in self.entities
-        # send the entity-destroy event
-        messenger.send(self.getEntityDestroyEvent(entId))
-
-        del self.entities[entId]
-        # if we created this entity, remove its entId from the
-        # createdEntIds list
-        if entId in self.createdEntIds:
-            # this should only happen if someone deleted an entity
-            # with an editor
-            self.createdEntIds.remove(entId)
-
-    def handleVisChange(self):
-        """the zone visibility lists have changed"""
-        pass
-    
-    if __dev__:
-        # the level generates these events when the spec changes
-        def getAttribChangeEventName(self):
-            return 'attribChange-%s' % self.levelId
-        def getInsertEntityEventName(self):
-            return 'insertEntity-%s' % self.levelId
-        def getRemoveEntityEventName(self):
-            return 'removeEntity-%s' % self.levelId
-        
-        # these handlers are called directly by our levelSpec
-        def handleAttribChange(self, entId, attrib, value, username=None):
-            entity = self.getEntity(entId)
-            # the entity might be AI- or client-only
-            if entity is not None:
-                entity.handleAttribChange(attrib, value)
-            messenger.send(self.getAttribChangeEventName(),
-                           [entId, attrib, value, username])
-
-        def setEntityCreatorUsername(self, entId, editUsername):
-            # this is called just before an entity is inserted, with the
-            # entId of the new entity and the username of the editor
-            # that requested its creation.
-            pass
-
-        def handleEntityInsert(self, entId):
-            # update our local type->entId table
-            self.entType2ids[self.getEntityType(entId)].append(entId)
-            self.createEntity(entId)
-            messenger.send(self.getInsertEntityEventName(), [entId])
-
-        def handleEntityRemove(self, entId):
-            messenger.send(self.getRemoveEntityEventName(), [entId])
-            # if we didn't create it, don't destroy it (probably a distributed
-            # entity on the client; wait for AI to destroy it)
-            if entId in self.createdEntIds:
-                entity = self.getEntity(entId)
-                entity.destroy()
-            # update our local type->entId table
-            self.entType2ids[self.getEntityType(entId)].remove(entId)

+ 0 - 12
direct/src/level/LevelConstants.py

@@ -1,12 +0,0 @@
-"""LevelConstants module: contains Level-related constants"""
-
-# Zone Num from model is also the Zone Entity's entId
-MinZoneNum = 0
-MaxZoneNum = 999
-
-# zoneNum 0 is reserved for UberZone
-UberZoneEntId = 0
-
-# system-allocated entities start at 1000
-LevelMgrEntId = 1000
-EditMgrEntId  = 1001

+ 0 - 80
direct/src/level/LevelMgr.py

@@ -1,80 +0,0 @@
-"""LevelMgr module: contains the LevelMgr class"""
-
-from direct.showbase.PythonUtil import Functor
-import LevelMgrBase
-
-class LevelMgr(LevelMgrBase.LevelMgrBase):
-    """This class manages editable client-side level attributes"""
-
-    def __init__(self, level, entId):
-        LevelMgrBase.LevelMgrBase.__init__(self, level, entId)
-        
-        # load the model
-        self.geom = loader.loadModel(self.modelFilename)
-
-        # this will hold the zoneNums/entIds for our own bookkeeping
-        self.zoneNums = []
-
-        # zoneNum -> network zoneId
-        self.level.zoneNum2zoneId = {}
-        # network zoneId -> zoneNum
-        self.level.zoneId2zoneNum = {}
-
-        # listen for every zone creation
-        self.accept(self.level.getEntityOfTypeCreateEvent('zone'),
-                    self.handleZoneCreated)
-
-    def destroy(self):
-        del self.level.zoneIds
-        del self.level.zoneId2zoneNum
-        del self.level.zoneNum2zoneId
-        self.geom.removeNode()
-        del self.geom
-        LevelMgrBase.LevelMgrBase.destroy(self)
-
-    def handleZoneCreated(self, entId):
-        zoneEnt = self.level.getEntity(entId)
-
-        # register the zone's info in the tables
-
-        assert (zoneEnt.entId not in self.zoneNums)
-        self.zoneNums.append(zoneEnt.entId)
-        
-        # we can assume that we have a complete list of network zoneIds in
-        # self.level.zoneIds. As each zone entity is created, set up
-        # as if we have all of the zone entities. This allows dynamic
-        # zone entity creation and deletion during editing.
-        # TODO: we should delay this until all zone entities have been
-        # created on level init
-        self.privAssignZoneIds()
-
-        # listen for the zone's destruction
-        self.accept(self.level.getEntityDestroyEvent(entId),
-                    Functor(self.handleZoneDestroy, entId))
-
-    def handleZoneDestroy(self, entId):
-        zoneEnt = self.level.getEntity(entId)
-        # unregister the zone from the maps
-        del self.level.zoneId2zoneNum[
-            self.level.zoneNum2zoneId[zoneEnt.entId]]
-        del self.level.zoneNum2zoneId[zoneEnt.entId]
-        self.zoneNums.remove(zoneEnt.entId)
-        # reassign the zoneIds (we may not need to do this, if all of the
-        # other entities already have their correct zoneId...?)
-        self.privAssignZoneIds()
-
-    def privAssignZoneIds(self):
-        """assign network zoneIds from self.level.zoneIds, according to
-        the zones that are registered so far"""
-        # sort the zoneNums
-        self.zoneNums.sort()
-
-        # dole out the zoneIds, in increasing order of zoneNum
-        for i in range(len(self.zoneNums)):
-            zoneNum = self.zoneNums[i]
-            zoneEnt = self.level.getEntity(zoneNum)
-            zoneId = self.level.zoneIds[i]
-            zoneEnt.setZoneId(zoneId)
-            # the zoneIds have shifted. update the tables
-            self.level.zoneNum2zoneId[zoneNum] = zoneId
-            self.level.zoneId2zoneNum[zoneId] = zoneNum

+ 0 - 59
direct/src/level/LevelMgrAI.py

@@ -1,59 +0,0 @@
-"""LevelMgrAI module: contains the LevelMgrAI class"""
-
-from direct.showbase.PythonUtil import Functor
-import LevelMgrBase
-
-class LevelMgrAI(LevelMgrBase.LevelMgrBase):
-    """This class manages editable AI level attributes"""
-    def __init__(self, level, entId):
-        LevelMgrBase.LevelMgrBase.__init__(self, level, entId)
-
-        # zoneNum -> network zoneId
-        self.level.zoneNum2zoneId = {}
-        # list of network zoneIDs, sorted by zoneNum
-        self.level.zoneIds = []
-
-        # listen for every zone creation
-        self.accept(self.level.getEntityOfTypeCreateEvent('zone'),
-                    self.handleZoneCreated)
-
-    def destroy(self):
-        del self.level.zoneIds
-        del self.level.zoneNum2zoneId
-        LevelMgrBase.LevelMgrBase.destroy(self)
-
-    def handleZoneCreated(self, entId):
-        zoneEnt = self.level.getEntity(entId)
-
-        # register the zone's info in the tables
-        self.level.zoneNum2zoneId[zoneEnt.entId] = zoneEnt.getZoneId()
-
-        # TODO: we should delay this until all zone entities have been
-        # created on level init
-        self.privCreateSortedZoneIdList()
-
-        # listen for the zone's destruction
-        self.accept(self.level.getEntityDestroyEvent(entId),
-                    Functor(self.handleZoneDestroy, entId))
-
-    def handleZoneDestroy(self, entId):
-        zoneEnt = self.level.getEntity(entId)
-        # unregister the zone from the tables
-        del self.level.zoneNum2zoneId[zoneEnt.entId]
-        # recreate the sorted network zoneId list
-        self.privCreateSortedZoneIdList()
-
-    def privCreateSortedZoneIdList(self):
-        # sort the zoneNums
-        zoneNums = self.level.zoneNum2zoneId.keys()
-        zoneNums.sort()
-
-        # create a list of network zoneIds, ordered by their corresponding
-        # sorted model zoneNum values
-        self.level.zoneIds = []
-        for zoneNum in zoneNums:
-            self.level.zoneIds.append(self.level.zoneNum2zoneId[zoneNum])
-
-        # TODO: if we ever allow dynamic insertion and removal of zone
-        # entities, and we just added or removed a zone entity AFTER the level
-        # was initialized, we would need to re-send the zoneId list

+ 0 - 12
direct/src/level/LevelMgrBase.py

@@ -1,12 +0,0 @@
-"""LevelMgrBase module: contains the LevelMgrBase class"""
-
-import Entity
-
-class LevelMgrBase(Entity.Entity):
-    """This class contains LevelMgr code shared by the AI and client"""
-    def __init__(self, level, entId):
-        Entity.Entity.__init__(self, level, entId)
-
-    def destroy(self):
-        Entity.Entity.destroy(self)
-        self.ignoreAll()

+ 0 - 460
direct/src/level/LevelSpec.py

@@ -1,460 +0,0 @@
-"""LevelSpec module: contains the LevelSpec class"""
-
-from direct.directnotify import DirectNotifyGlobal
-from direct.showbase.PythonUtil import list2dict, uniqueElements
-import string
-import LevelConstants
-import types
-if __dev__:
-    import os
-
-class LevelSpec:
-    """contains spec data for a level, is responsible for handing the data
-    out upon request, as well as recording changes made during editing, and
-    saving out modified spec data"""
-    notify = DirectNotifyGlobal.directNotify.newCategory("LevelSpec")
-    
-    def __init__(self, spec=None, scenario=0):
-        """spec must be passed in as a python module or a dictionary.
-        If not passed in, will create a new spec."""
-        newSpec = 0
-        if type(spec) is types.ModuleType:
-            if __dev__:
-                # reload the spec module to pick up changes
-                reload(spec)
-            self.specDict = spec.levelSpec
-            if __dev__:
-                self.setFilename(spec.__file__)
-        elif type(spec) is types.DictType:
-            # we need this for repr/eval-ing LevelSpecs
-            self.specDict = spec
-        elif spec is None:
-            if __dev__:
-                newSpec = 1
-                self.specDict = {
-                    'globalEntities': {},
-                    'scenarios': [{}],
-                    }
-
-        assert hasattr(self, 'specDict')
-
-        # this maps an entId to the dict that holds its spec;
-        # entities are either in the global dict or a scenario dict
-        # update the map of entId to spec dict
-        self.entId2specDict = {}
-        self.entId2specDict.update(
-            list2dict(self.getGlobalEntIds(),
-                      value=self.privGetGlobalEntityDict()))
-        for i in range(self.getNumScenarios()):
-            self.entId2specDict.update(
-                list2dict(self.getScenarioEntIds(i),
-                          value=self.privGetScenarioEntityDict(i)))
-
-        self.setScenario(scenario)
-
-        if __dev__:
-            if newSpec:
-                # add basic required entities
-                import EntityTypes
-                import EntityTypeRegistry
-                etr = EntityTypeRegistry.EntityTypeRegistry(EntityTypes)
-                self.setEntityTypeReg(etr)
-
-                # UberZone
-                entId = LevelConstants.UberZoneEntId
-                self.insertEntity(entId, 'zone')
-                self.doSetAttrib(entId, 'name', 'UberZone')
-                # LevelMgr
-                entId = LevelConstants.LevelMgrEntId
-                self.insertEntity(entId, 'levelMgr')
-                self.doSetAttrib(entId, 'name', 'LevelMgr')
-                # EditMgr
-                entId = LevelConstants.EditMgrEntId
-                self.insertEntity(entId, 'editMgr')
-                self.doSetAttrib(entId, 'name', 'EditMgr')
-                                       
-    def getNumScenarios(self):
-        return len(self.specDict['scenarios'])
-
-    def setScenario(self, scenario):
-        assert scenario in range(0, self.getNumScenarios())
-        self.scenario = scenario
-
-    def getScenario(self):
-        return self.scenario
-
-    def getGlobalEntIds(self):
-        return self.privGetGlobalEntityDict().keys()
-
-    def getScenarioEntIds(self, scenario=None):
-        if scenario is None:
-            scenario = self.scenario
-        return self.privGetScenarioEntityDict(scenario).keys()
-
-    def getAllEntIds(self):
-        """this returns all of the entIds involved in the current scenario"""
-        return self.getGlobalEntIds() + self.getScenarioEntIds()
-
-    def getAllEntIdsFromAllScenarios(self):
-        """this returns all of the entIds involved in all scenarios"""
-        entIds = self.getGlobalEntIds()
-        for scenario in xrange(self.getNumScenarios()):
-            entIds.extend(self.getScenarioEntIds(scenario))
-        return entIds
-
-    def getEntitySpec(self, entId):
-        assert entId in self.entId2specDict
-        specDict = self.entId2specDict[entId]
-        return specDict[entId]
-
-    def getEntityType(self, entId):
-        return self.getEntitySpec(entId)['type']
-
-    def getEntityZoneEntId(self, entId):
-        """ return the entId of the zone that entity is in; if entity
-        is a zone, returns its entId """
-        spec = self.getEntitySpec(entId)
-        type = spec['type']
-        # if it's a zone, this is our entity
-        if type == 'zone':
-            return entId
-        # keep looking up the heirarchy for a zone entity
-        return self.getEntityZoneEntId(spec['parentEntId'])
-
-    def getEntType2ids(self, entIds):
-        """given list of entIds, return dict of entType->entIds"""
-        entType2ids = {}
-        for entId in entIds:
-            type = self.getEntityType(entId)
-            entType2ids.setdefault(type, [])
-            entType2ids[type].append(entId)
-        return entType2ids
-
-    # private support functions to abstract dict structure
-    def privGetGlobalEntityDict(self):
-        return self.specDict['globalEntities']
-
-    def privGetScenarioEntityDict(self, scenario):
-        return self.specDict['scenarios'][scenario]
-
-    def printZones(self):
-        """currently prints list of zoneNum->zone name"""
-        # this could be more efficient
-        allIds = self.getAllEntIds()
-        type2id = self.getEntType2ids(allIds)
-        zoneIds = type2id['zone']
-        # omit the UberZone
-        if 0 in zoneIds:
-            zoneIds.remove(0)
-        zoneIds.sort()
-        for zoneNum in zoneIds:
-            spec = self.getEntitySpec(zoneNum)
-            print 'zone %s : %s' % (zoneNum, spec['name'])
-
-    if __dev__:
-        def setLevel(self, level):
-            self.level = level
-
-        def hasLevel(self):
-            return hasattr(self, 'level')
-
-        def setEntityTypeReg(self, entTypeReg):
-            self.entTypeReg = entTypeReg
-            self.checkSpecIntegrity()
-
-        def hasEntityTypeReg(self):
-            return hasattr(self, 'entTypeReg')
-
-        def setFilename(self, filename):
-            self.filename = filename
-
-        def doSetAttrib(self, entId, attrib, value):
-            """ do the dirty work of changing an attrib value """
-            assert entId in self.entId2specDict
-            specDict = self.entId2specDict[entId]
-            assert specDict[entId].has_key(attrib)
-            specDict[entId][attrib] = value
-
-        def setAttribChange(self, entId, attrib, value, username):
-            """ we're being asked to change an attribute """
-            LevelSpec.notify.info("setAttribChange(%s): %s, %s = %s" %
-                                  (username, entId, attrib, repr(value)))
-            self.doSetAttrib(entId, attrib, value)
-            if self.hasLevel():
-                # let the level know that this attribute value has
-                # officially changed
-                self.level.handleAttribChange(entId, attrib, value, username)
-
-        def insertEntity(self, entId, entType, parentEntId='unspecified'):
-            LevelSpec.notify.info('inserting entity %s (%s)' % (entId, entType))
-            assert entId not in self.entId2specDict
-            assert self.entTypeReg is not None
-            globalEnts = self.privGetGlobalEntityDict()
-            self.entId2specDict[entId] = globalEnts
-
-            # create a new entity spec entry w/ default values
-            globalEnts[entId] = {}
-            spec = globalEnts[entId]
-            attribDescs = self.entTypeReg.getTypeDesc(entType
-                                                      ).getAttribDescDict()
-            for name, desc in attribDescs.items():
-                spec[name] = desc.getDefaultValue()
-            spec['type'] = entType
-            if parentEntId != 'unspecified':
-                spec['parentEntId'] = parentEntId
-
-            if self.hasLevel():
-                # notify the level
-                self.level.handleEntityInsert(entId)
-            else:
-                LevelSpec.notify.warning('no level to be notified of insertion')
-            
-        def removeEntity(self, entId):
-            LevelSpec.notify.info('removing entity %s' % entId)
-            assert entId in self.entId2specDict
-
-            if self.hasLevel():
-                # notify the level
-                self.level.handleEntityRemove(entId)
-            else:
-                LevelSpec.notify.warning('no level to be notified of removal')
-
-            # remove the entity's spec
-            dict = self.entId2specDict[entId]
-            del dict[entId]
-            del self.entId2specDict[entId]
-
-        def removeZoneReferences(self, removedZoneNums):
-            """call with a list of zoneNums of zone entities that have just
-            been removed; will clean up references to those zones"""
-            assert self.hasEntityTypeReg()
-            # get dict of entType->entIds, for ALL scenarios
-            type2ids = self.getEntType2ids(self.getAllEntIdsFromAllScenarios())
-            # figure out which entity types have attributes that need to be
-            # updated
-            for type in type2ids:
-                typeDesc = self.entTypeReg.getTypeDesc(type)
-                visZoneListAttribs = typeDesc.getAttribsOfType('visZoneList')
-                if len(visZoneListAttribs) > 0:
-                    # this entity type has at least one attrib of type
-                    # 'visZoneList'.
-                    # run through all of the existing entities of this type
-                    for entId in type2ids[type]:
-                        spec = self.getEntitySpec(entId)
-                        # for each attrib of type 'visZoneList'...
-                        for attribName in visZoneListAttribs:
-                            # remove each of the removed zoneNums
-                            for zoneNum in removedZoneNums:
-                                while zoneNum in spec[attribName]:
-                                    spec[attribName].remove(zoneNum)
-
-        def getSpecImportsModuleName(self):
-            # name of module that should be imported by spec py file
-            # TODO: make this generic
-            return 'toontown.coghq.SpecImports'
-
-        def getFilename(self):
-            return self.filename
-
-        def privGetBackupFilename(self, filename):
-            return '%s.bak' % filename
-
-        def saveToDisk(self, filename=None, makeBackup=1):
-            """returns zero on failure"""
-            if filename is None:
-                filename = self.filename
-
-            if makeBackup and self.privFileExists(filename):
-                # create a backup
-                try:
-                    backupFilename = self.privGetBackupFilename(filename)
-                    self.privRemoveFile(backupFilename)
-                    os.rename(filename, backupFilename)
-                except OSError, e:
-                    LevelSpec.notify.warning(
-                        'error during backup: %s' % str(e))
-
-            LevelSpec.notify.info("writing to '%s'" % filename)
-            self.privRemoveFile(filename)
-            self.privSaveToDisk(filename)
-
-        def privSaveToDisk(self, filename):
-            """internal. saves spec to file. returns zero on failure"""
-            retval = 1
-            # wb to create a UNIX-format file
-            f = file(filename, 'wb')
-            try:
-                f.write(self.getPrettyString())
-            except IOError:
-                retval = 0
-            f.close()
-            return retval
-
-        def privFileExists(self, filename):
-            try:
-                os.stat(filename)
-                return 1
-            except OSError:
-                return 0
-
-        def privRemoveFile(self, filename):
-            try:
-                os.remove(filename)
-                return 1
-            except OSError:
-                return 0
-
-        def getPrettyString(self):
-            """Returns a string that contains the spec data, nicely formatted.
-            This should be used when writing the spec out to file."""
-            import pprint
-            
-            tabWidth = 4
-            tab = ' ' * tabWidth
-            # structure names
-            globalEntitiesName = 'GlobalEntities'
-            scenarioEntitiesName = 'Scenario%s'
-            topLevelName = 'levelSpec'
-            def getPrettyEntityDictStr(name, dict, tabs=0):
-                def t(n):
-                    return (tabs+n)*tab
-                def sortList(lst, firstElements=[]):
-                    """sort list; elements in firstElements will be put
-                    first, in the order that they appear in firstElements;
-                    rest of elements will follow, sorted"""
-                    elements = list(lst)
-                    # put elements in order
-                    result = []
-                    for el in firstElements:
-                        if el in elements:
-                            result.append(el)
-                            elements.remove(el)
-                    elements.sort()
-                    result.extend(elements)
-                    return result
-   
-                firstTypes = ('levelMgr', 'editMgr', 'zone',)
-                firstAttribs = ('type', 'name', 'comment', 'parentEntId',
-                                'pos', 'x', 'y', 'z',
-                                'hpr', 'h', 'p', 'r',
-                                'scale', 'sx', 'sy', 'sz',
-                                'color',
-                                'model',
-                                )
-                str = t(0)+'%s = {\n' % name
-                # get list of types
-                entIds = dict.keys()
-                entType2ids = self.getEntType2ids(entIds)
-                # put types in order
-                types = sortList(entType2ids.keys(), firstTypes)
-                for type in types:
-                    str += t(1)+'# %s\n' % string.upper(type)
-                    entIds = entType2ids[type]
-                    entIds.sort()
-                    for entId in entIds:
-                        str += t(1)+'%s: {\n' % entId
-                        spec = dict[entId]
-                        attribs = sortList(spec.keys(), firstAttribs)
-                        for attrib in attribs:
-                            str += t(2)+"'%s': %s,\n" % (attrib,
-                                                         repr(spec[attrib]))
-                        # maybe this will help with CVS merges?
-                        str += t(2)+'}, # end entity %s\n' % entId
-                        
-                str += t(1)+'}\n'
-                return str
-            def getPrettyTopLevelDictStr(tabs=0):
-                def t(n):
-                    return (tabs+n)*tab
-                str  = t(0)+'%s = {\n' % topLevelName
-                str += t(1)+"'globalEntities': %s,\n" % globalEntitiesName
-                str += t(1)+"'scenarios': [\n"
-                for i in range(self.getNumScenarios()):
-                    str += t(2)+'%s,\n' % (scenarioEntitiesName % i)
-                str += t(2)+'],\n'
-                str += t(1)+'}\n'
-                return str
-            
-            str  = 'from %s import *\n' % self.getSpecImportsModuleName()
-            str += '\n'
-
-            # add the global entities
-            str += getPrettyEntityDictStr('GlobalEntities',
-                                          self.privGetGlobalEntityDict())
-            str += '\n'
-
-            # add the scenario entities
-            numScenarios = self.getNumScenarios()
-            for i in range(numScenarios):
-                str += getPrettyEntityDictStr('Scenario%s' % i,
-                                              self.privGetScenarioEntityDict(i))
-                str += '\n'
-
-            # add the top-level table
-            str += getPrettyTopLevelDictStr()
-
-            self.testPrettyString(prettyString=str)
-
-            return str
-
-        def testPrettyString(self, prettyString=None):
-            # execute the pretty output in our local scope
-            if prettyString is None:
-                prettyString=self.getPrettyString()
-            exec(prettyString)
-            assert levelSpec == self.specDict, (
-                'LevelSpec pretty string does not match spec data.\n'
-                'pretty=%s\n'
-                'specData=%s' %
-                (levelSpec, self.specDict)
-                )
-
-        def checkSpecIntegrity(self):
-            # make sure there are no duplicate entIds
-            entIds = self.getGlobalEntIds()
-            assert uniqueElements(entIds)
-            entIds = list2dict(entIds)
-            for i in range(self.getNumScenarios()):
-                for id in self.getScenarioEntIds(i):
-                    assert not entIds.has_key(id)
-                    entIds[id] = None
-
-            if self.entTypeReg is not None:
-                # check each spec
-                allEntIds = entIds
-                for entId in allEntIds:
-                    spec = self.getEntitySpec(entId)
-
-                    assert spec.has_key('type')
-                    entType = spec['type']
-                    typeDesc = self.entTypeReg.getTypeDesc(entType)
-                    attribNames = typeDesc.getAttribNames()
-                    attribDescs = typeDesc.getAttribDescDict()
-
-                    # are there any unknown attribs in the spec?
-                    for attrib in spec.keys():
-                        if attrib not in attribNames:
-                            LevelSpec.notify.warning(
-                                "entId %s (%s): unknown attrib '%s', omitting"
-                                % (entId, spec['type'], attrib))
-                            del spec[attrib]
-
-                    # does the spec have all of its attributes?
-                    for attribName in attribNames:
-                        if not spec.has_key(attribName):
-                            default = attribDescs[attribName].getDefaultValue()
-                            LevelSpec.notify.warning(
-                                "entId %s (%s): missing attrib '%s', setting "
-                                "to default (%s)" % (entId, spec['type'],
-                                                     attribName, repr(default)))
-                            spec[attribName] = default
-
-        def __hash__(self):
-            return hash(repr(self))
-
-        def __str__(self):
-            return 'LevelSpec'
-
-        def __repr__(self):
-            return 'LevelSpec(%s, scenario=%s)' % (repr(self.specDict),
-                                                   self.scenario)

+ 0 - 51
direct/src/level/LevelUtil.py

@@ -1,51 +0,0 @@
-"""LevelUtil module: contains Level utility funcs"""
-
-import string
-import LevelConstants
-
-def getZoneNum2Node(levelModel, logFunc=lambda str:str):
-    """ given model, returns dict of ZoneNumber -> ZoneNode """
-    def findNumberedNodes(baseString, model, caseInsens=1):
-        # finds nodes whose name follows the pattern 'baseString#blah'
-        # returns dictionary that maps # to node
-        srch = '**/%s*' % baseString
-        if caseInsens:
-            srch += ';+i'
-        potentialNodes = model.findAllMatches(srch).asList()
-        num2node = {}
-        for potentialNode in potentialNodes:
-            name = potentialNode.getName()
-            logFunc('potential match for %s: %s' % (baseString, name))
-            name = name[len(baseString):]
-            numDigits = 0
-            while numDigits < len(name):
-                if name[numDigits] not in string.digits:
-                    break
-                numDigits += 1
-            if numDigits == 0:
-                continue
-            num = int(name[:numDigits])
-            # is this a valid zoneNum?
-            if num == LevelConstants.UberZoneEntId:
-                logFunc('warning: cannot use UberZone zoneNum (%s). '
-                        'ignoring %s' % (LevelConstants.UberZoneEntId,
-                                         potentialNode))
-                continue
-            if (num < LevelConstants.MinZoneNum) or (
-                num > LevelConstants.MaxZoneNum):
-                logFunc('warning: zone %s is out of range. ignoring %s' %
-                        (num, potentialNode))
-                continue
-            # do we already have a ZoneNode for this zone num?
-            if num in num2node:
-                logFunc('warning: zone %s already assigned to %s. ignoring %s' %
-                        (num, num2node[num], potentialNode))
-                continue
-            num2node[num] = potentialNode
-
-        return num2node
-
-    zoneNum2node = findNumberedNodes('zone', levelModel)
-    # add the UberZone to the table
-    zoneNum2node[LevelConstants.UberZoneEntId] = levelModel
-    return zoneNum2node

+ 0 - 143
direct/src/level/LogicGate.py

@@ -1,143 +0,0 @@
-"""
-LogicGate.py
-
-    Logic Gates:
-
-         and: 0 0 = 0     or: 0 0 = 0    xor: 0 0 = 0
-              0 1 = 0         0 1 = 1         0 1 = 1
-              1 0 = 0         1 0 = 1         1 0 = 1
-              1 1 = 1         1 1 = 1         1 1 = 0
-
-        nand: 0 0 = 1    nor: 0 0 = 1   xnor: 0 0 = 1
-              0 1 = 1         0 1 = 0         0 1 = 0
-              1 0 = 1         1 0 = 0         1 0 = 0
-              1 1 = 0         1 1 = 0         1 1 = 1
-
-    In the following:
-        1: send a true message
-        0: send a false message
-        -: don't send a message
-
-        a b  and  or  xor  nand  nor  xnor
-       (0 0)  (0) (0)  (0)   (1)  (1)   (1)  <--- initial state
-        1 0    -   1    1     -    0     0
-        0 0    -   0    0     -    1     1
-        1 0    -   1    1     -    0     0
-        1 1    1   -    0     0    -     1
-        0 1    0   -    1     1    -     0
-        1 1    1   -    0     0    -     1
-        0 1    0   -    1     1    -     0
-        0 0    -   0    0     -    1     1
-"""
-
-from direct.showbase import PandaObject
-from direct.directnotify import DirectNotifyGlobal
-import Entity
-
-
-def andTest(self, a, b):
-    assert(self.debugPrint("andTest(a=%s, b=%s)"%(a, b)))
-    if b:
-        messenger.send(self.getOutputEventName(), [a])
-
-def orTest(self, a, b):
-    assert(self.debugPrint("orTest(a=%s, b=%s)"%(a, b)))
-    if not b:
-        messenger.send(self.getOutputEventName(), [a])
-    # else: ...we already sent the messege when b was set.
-
-def xorTest(self, a, b):
-    assert(self.debugPrint("xorTest(a=%s, b=%s)"%(a, b)))
-    messenger.send(self.getOutputEventName(), [(not (a and b)) and (a or b)])
-
-def nandTest(self, a, b):
-    assert(self.debugPrint("nandTest(a=%s, b=%s)"%(a, b)))
-    if b:
-        messenger.send(self.getOutputEventName(), [not (a and b)])
-
-def norTest(self, a, b):
-    assert(self.debugPrint("norTest(a=%s, b=%s)"%(a, b)))
-    if not b:
-        messenger.send(self.getOutputEventName(), [not (a or b)])
-    # else: ...we already sent the messege when b was set.
-
-def xnorTest(self, a, b):
-    assert(self.debugPrint("xnorTest(a=%s, b=%s)"%(a, b)))
-    messenger.send(self.getOutputEventName(), [(a and b) or (not (a or b))])
-
-
-class LogicGate(Entity.Entity, PandaObject.PandaObject):
-    if __debug__:
-        notify = DirectNotifyGlobal.directNotify.newCategory(
-                'LogicGate')
-    logicTests={
-        "and": andTest,
-        "or": orTest,
-        "xor": xorTest,
-        "nand": nandTest,
-        "nor": norTest,
-        "xnor": xnorTest,
-    }
-
-    def __init__(self, level, entId):
-        """entId: """
-        assert(self.debugPrint(
-                "LogicGate(entId=%s)"
-                %(entId)))
-        self.input1Event = None
-        self.input2Event = None
-        PandaObject.PandaObject.__init__(self)
-        Entity.Entity.__init__(self, level, entId)
-        self.setLogicType(self.logicType)
-        self.setIsInput1(self.isInput1)
-        self.setIsInput2(self.isInput2)
-        self.setInput1Event(self.input1Event)
-        self.setInput2Event(self.input2Event)
-
-    def destroy(self):
-        assert(self.debugPrint("destroy()"))
-        self.ignore(self.input1Event)
-        self.input1Event = None
-        self.ignore(self.input2Event)
-        self.input2Event = None
-        Entity.Entity.destroy(self)
-    
-    def setLogicType(self, logicType):
-        assert(self.debugPrint("setLogicType(logicType=%s)"%(logicType,)))
-        self.logicType=logicType
-        assert self.logicTests[logicType]
-        self.logicTest=self.logicTests[logicType]
-    
-    def setIsInput1(self, isTrue):
-        assert(self.debugPrint("setIsInput1(isTrue=%s)"%(isTrue,)))
-        if 1 or (not isTrue) != (not self.input1Event):
-            # ...the logical state of self.input1Event has changed.
-            self.isInput1=isTrue
-            self.logicTest(self, isTrue, self.isInput2)
-    
-    def setIsInput2(self, isTrue):
-        assert(self.debugPrint("setIsInput2(isTrue=%s)"%(isTrue,)))
-        if 1 or (not isTrue) != (not self.input2Event):
-            # ...the logical state of self.input2Event has changed.
-            self.isInput2=isTrue
-            self.logicTest(self, isTrue, self.isInput1)
-    
-    def setInput1Event(self, event):
-        assert(self.debugPrint("setInput1Event(event=%s)"%(event,)))
-        if self.input1Event:
-            self.ignore(self.input1Event)
-        self.input1Event = self.getOutputEventName(event)
-        if self.input1Event:
-            self.accept(self.input1Event, self.setIsInput1)
-    
-    def setInput2Event(self, event):
-        assert(self.debugPrint("setInput2Event(event=%s)"%(event,)))
-        if self.input2Event:
-            self.ignore(self.input2Event)
-        self.input2Event = self.getOutputEventName(event)
-        if self.input2Event:
-            self.accept(self.input2Event, self.setIsInput2)
-    
-    def getName(self):
-        #return "logicGate-%s"%(self.entId,)
-        return "switch-%s"%(self.entId,)

+ 0 - 42
direct/src/level/ModelEntity.py

@@ -1,42 +0,0 @@
-from toontown.toonbase.ToontownGlobals import *
-from direct.directnotify import DirectNotifyGlobal
-import BasicEntities
-
-class ModelEntity(BasicEntities.NodePathEntity):
-    def __init__(self, level, entId):
-        BasicEntities.NodePathEntity.__init__(self, level, entId)
-        self.model = None
-        self.loadModel()
-        
-    def destroy(self):
-        if self.model:
-            self.model.removeNode()
-            del self.model
-        BasicEntities.NodePathEntity.destroy(self)
-
-    def loadModel(self):
-        if self.model:
-            self.model.removeNode()
-            self.model = None
-        if self.modelPath:
-            self.model = loader.loadModel(self.modelPath)
-            if self.model:
-                self.model.reparentTo(self)
-
-        # HACK SDN: special code for moving crate wall collisions down
-        if self.modelPath in ("phase_9/models/cogHQ/woodCrateB.bam",
-                              "phase_9/models/cogHQ/metal_crateB.bam"):
-            # move walls down
-            cNode = self.find("**/wall")
-            cNode.setZ(-.75)
-            # duplicate the floor and move it down to crate a
-            # catch effect for low-hopped toons
-            colNode = self.find("**/collision")
-            floor = colNode.find("**/floor")
-            floor2 = floor.copyTo(colNode)
-            floor2.setZ(-.75)
-
-    def setModelPath(self, path):
-        self.modelPath = path
-        self.loadModel()
-    

+ 0 - 57
direct/src/level/PathEntity.py

@@ -1,57 +0,0 @@
-from toontown.toonbase.ToontownGlobals import *
-from direct.interval.IntervalGlobal import *
-from direct.directnotify import DirectNotifyGlobal
-import BasicEntities
-from toontown.suit import GoonPathData
-
-class PathEntity(BasicEntities.NodePathEntity):
-    def __init__(self, level, entId):
-        BasicEntities.NodePathEntity.__init__(self, level, entId)
-        self.path = GoonPathData.Paths[self.level.factoryId][self.pathIndex]
-            
-    def destroy(self):
-        BasicEntities.NodePathEntity.destroy(self)
-
-    def setPathIndex(self, pathIndex):
-        self.pathIndex = pathIndex
-        self.path = GoonPathData.Paths[self.level.factoryId][self.pathIndex]
-    
-    def makePathTrack(self, node, velocity, name, turnTime=1, lookAroundNode=None):
-        track = Sequence(name = name)
-        assert (len(self.path) > 1)
-
-        # end with the starting point at the end, so we have a continuous loop
-        path = self.path + [self.path[0]]
-        for pointIndex in range(len(path) - 1):
-            startPoint = path[pointIndex]
-            endPoint = path[pointIndex + 1]
-            # Face the endpoint
-            v = startPoint - endPoint
-
-            # figure out the angle we have to turn to look at the next point
-            # Note: this will only look right for paths that are defined in a
-            # counterclockwise order.  Otherwise the goon will always turn the
-            # "long" way to look at the next point
-            node.setPos(startPoint[0], startPoint[1],startPoint[2])
-            node.headsUp(endPoint[0], endPoint[1], endPoint[2])
-            theta = node.getH() % 360
-                              
-            track.append(
-                LerpHprInterval(node, # stop and look around
-                                turnTime,
-                                Vec3(theta,0,0)))
-            
-            # Calculate the amount of time we should spend walking
-            distance = Vec3(v).length()
-            duration = distance / velocity
-            
-            # Walk to the end point
-            track.append(
-                LerpPosInterval(node, duration=duration,
-                                pos=Point3(endPoint),
-                                startPos=Point3(startPoint)))
-        return track
-
-    
-        
-        

+ 0 - 53
direct/src/level/PropSpinner.py

@@ -1,53 +0,0 @@
-from direct.interval.IntervalGlobal import * 
-import Entity
-
-class PropSpinner(Entity.Entity):
-    def __init__(self, level, entId):
-        Entity.Entity.__init__(self, level, entId)
-        self.initProps()
-
-    def destroy(self):
-        self.destroyProps()
-        Entity.Entity.destroy(self)        
-
-    def initProps(self):
-        topNode = self.getZoneNode()
-        props = topNode.findAllMatches("**/Prop_*").asList() 
-        spinTracks = Parallel() 
-        for prop in props: 
-            name = prop.getName() 
-            nameParts = name.split('_') 
-            # ['Prop', 'Rotate', 'Y', '15', 'Gear2'] 
-            axis = nameParts[2]
-            rate = 0
-            neg = (string.upper(nameParts[3][0]) == 'N')
-            if neg:
-                nameParts[3] = nameParts[3][1:]
-            try:
-                rate = int(nameParts[3])
-            except:
-                print 'invalid prop rotate string: %s' % name
-            if neg:
-                rate = -rate
-            prop.setHpr(0,0,0) 
-            if axis == "X": 
-                hpr = Vec3(0, rate*360, 0) 
-            elif axis == "Y": 
-                hpr = Vec3(rate*360, 0, 0) 
-            elif axis == "Z": 
-                hpr = Vec3(0, 0, rate*360) 
-            else: 
-                print 'error', axis 
-            spinTracks.append(LerpHprInterval(prop, 60, hpr)) 
-        spinTracks.loop() 
-        self.spinTracks = spinTracks
-
-    def destroyProps(self):
-        if hasattr(self, 'spinTracks'):
-            self.spinTracks.pause()
-            del self.spinTracks
-
-    if __dev__:
-        def attribChanged(self, *args):
-            self.destroyProps()
-            self.initProps()

+ 0 - 3
direct/src/level/Sources.pp

@@ -1,3 +0,0 @@
-// For now, since we are not installing Python files, this file can
-// remain empty.
-

+ 0 - 124
direct/src/level/SpecUtil.py

@@ -1,124 +0,0 @@
-"""SpecUtil module: contains utility functions for creating and managing level specs"""
-
-from direct.showbase.ShowBaseGlobal import *
-import LevelSpec
-import LevelConstants
-import LevelUtil
-from direct.showbase.PythonUtil import list2dict
-import EntityTypes
-import types
-
-"""
-TO CREATE A NEW SPEC:
-from direct.level import SpecUtil
-from toontown.coghq import FactoryEntityTypes
-SpecUtil.makeNewSpec('$TOONTOWN/src/coghq/FactoryMockupSpec.py', 'phase_9/models/cogHQ/SelbotLegFactory', FactoryEntityTypes)
-"""
-def makeNewSpec(filename, modelPath, entTypeModule=EntityTypes):
-    """call this to create a new level spec for the level model at 'modelPath'.
-    Spec will be saved as 'filename'"""
-    spec = LevelSpec.LevelSpec()
-    # make every zone visible from every other zone
-    privUpdateSpec(spec, modelPath, entTypeModule, newZonesGloballyVisible=1)
-    # expand any env vars, then convert to an OS-correct path
-    fname = Filename.expandFrom(filename).toOsSpecific()
-    spec.saveToDisk(fname, makeBackup=0)
-    print 'Done.'
-
-"""
-FOR SAME LEVEL MODEL PATH:
-from direct.level import SpecUtil
-from toontown.coghq import SellbotLegFactorySpec
-from toontown.coghq import FactoryEntityTypes
-SpecUtil.updateSpec(SellbotLegFactorySpec, FactoryEntityTypes)
-
-FOR DIFFERENT LEVEL MODEL PATH:
-from direct.level import SpecUtil
-from toontown.coghq import SellbotLegFactorySpec
-from toontown.coghq import FactoryEntityTypes
-SpecUtil.updateSpec(SellbotLegFactorySpec, FactoryEntityTypes, '/i/beta/toons/maya/work/CogHeadquarters/CogFactoriesInteriors/AllFactories/LegFactory/SelbotLegFactory_v##s#.mb')
-"""
-
-def updateSpec(specModule, entTypeModule=EntityTypes, modelPath=None):
-    """Call this to update an existing levelSpec to work with a new level
-    model. If the level model has a new path, pass it in as 'modelPath'.
-    specModule must be a Python module"""
-    spec = LevelSpec.LevelSpec(specModule)
-    privUpdateSpec(spec, modelPath, entTypeModule)
-    spec.saveToDisk()
-    print 'Done.'
-
-def privUpdateSpec(spec, modelPath, entTypeModule, newZonesGloballyVisible=0):
-    """internal: take a spec and update it to match its level model
-    If newZonesGloballyVisible is true, any new zones will be added to the
-    visibility lists for every zone.
-    """
-    assert __dev__
-    assert type(entTypeModule) is types.ModuleType
-    import EntityTypeRegistry
-    etr = EntityTypeRegistry.EntityTypeRegistry(entTypeModule)
-    spec.setEntityTypeReg(etr)
-
-    if modelPath is None:
-        modelPath = spec.getEntitySpec(
-            LevelConstants.LevelMgrEntId)['modelFilename']
-    else:
-        spec.doSetAttrib(LevelConstants.LevelMgrEntId,
-                         'modelFilename', modelPath)
-
-    # load the model
-    # disable texture loading for speed
-    TexturePool.setFakeTextureImage(
-        '/i/alpha/player/install/ttmodels/src/fonts/ImpressBT.rgb')
-    model = loader.loadModel(modelPath)
-    assert model is not None
-    TexturePool.clearFakeTextureImage()
-    # get the model's zone info
-    zoneNum2node = LevelUtil.getZoneNum2Node(model)
-    zoneNums = zoneNum2node.keys()
-
-    # what zone entities do we have specs for?
-    type2ids = spec.getEntType2ids(spec.getAllEntIds())
-    type2ids.setdefault('zone', [])
-    zoneEntIds = type2ids['zone']
-
-    def removeZoneEntity(entId, spec=spec, zoneEntIds=zoneEntIds):
-        spec.removeEntity(entId)
-        zoneEntIds.remove(entId)
-
-    def insertZoneEntity(zoneNum, spec=spec, zoneEntIds=zoneEntIds):
-        spec.insertEntity(zoneNum, 'zone', LevelConstants.UberZoneEntId)
-        spec.doSetAttrib(zoneNum, 'name', 'zone%s' % zoneNum)
-        zoneEntIds.append(zoneNum)
-
-    # prune zone entities that reference zones that no longer exist
-    removedZoneNums = []
-    for entId in list(zoneEntIds):
-        if entId not in zoneNums:
-            print 'zone %s no longer exists; removing' % entId
-            removeZoneEntity(entId)
-            removedZoneNums.append(entId)
-            
-    # add new zone entities for new zones
-    newZoneNums = []
-    for zoneNum in zoneNums:
-        if zoneNum not in zoneEntIds:
-            newZoneNums.append(zoneNum)
-
-            print 'adding new zone entity %s' % zoneNum
-            insertZoneEntity(zoneNum)
-            # by default, new zone can't see any other zones
-            spec.doSetAttrib(zoneNum, 'visibility', [])
-
-    if newZonesGloballyVisible:
-        for entId in zoneEntIds:
-            visList = list(spec.getEntitySpec(entId)['visibility'])
-            visDict = list2dict(visList)
-            for zoneNum in newZoneNums:
-                visDict[zoneNum] = None
-            visList = visDict.keys()
-            visList.sort()
-            spec.doSetAttrib(entId, 'visibility', visList)
-
-    # make sure none of the zones reference removed zones
-    spec.removeZoneReferences(removedZoneNums)

+ 0 - 52
direct/src/level/VisibilityBlocker.py

@@ -1,52 +0,0 @@
-"""VisibilityBlocker module: contains the VisibilityBlocker class"""
-
-import Entity
-
-class VisibilityBlocker:
-    """This is a mixin class for level entities (see Entity.py) that in some
-    way 'block' visibility (such as doors) -- entities that can completely
-    obscure what's behind them. It provides the blocker with a mechanism
-    whereby they are informed of when it is safe for them to 'unblock' the
-    visibility and show what's behind them. Without this mechanism, the
-    blocker might show what's behind it before all of the distributed objects
-    behind it have been generated."""
-    def __init__(self):
-        self.__nextSetZoneDoneEvent=None
-
-    def destroy(self):
-        self.cancelUnblockVis()
-
-    def requestUnblockVis(self):
-        """derived class should call this before the end of the frame in which
-        they cause the visibility to be extended. okToUnblockVis (see below)
-        will be called when it's safe to show the new zones."""
-        if self.__nextSetZoneDoneEvent is None:
-            self.__nextSetZoneDoneEvent = self.level.cr.getNextSetZoneDoneEvent()
-            self.acceptOnce(self.__nextSetZoneDoneEvent, self.okToUnblockVis)
-            # make sure that a setZone is sent this frame, even if the
-            # visibility list doesn't change
-            self.level.forceSetZoneThisFrame()
-
-    def cancelUnblockVis(self):
-        """
-        derived class should call this if they have called
-        requestUnblockVis, but no longer need that service.  For example
-        the user could have canceled the request that started the
-        visibility change.
-        """
-        if self.__nextSetZoneDoneEvent is not None:
-            self.ignore(self.__nextSetZoneDoneEvent)
-            self.__nextSetZoneDoneEvent = None
-
-    def isWaitingForUnblockVis(self):
-        """
-        returns a boolean for whether there is a requestUnblockVis() pending.
-        """
-        return self.__nextSetZoneDoneEvent is not None
-
-    def okToUnblockVis(self):
-        """
-        derived class should override this func and do the vis unblock
-        (i.e. open the door, etc.)
-        """
-        self.cancelUnblockVis()

+ 0 - 67
direct/src/level/VisibilityExtender.py

@@ -1,67 +0,0 @@
-"""VisibilityExtender module: contains the VisibilityExtender class"""
-
-import Entity
-
-class VisibilityExtender(Entity.Entity):
-    def __init__(self, level, entId):
-        Entity.Entity.__init__(self, level, entId)
-        self.initVisExt()
-
-    def initVisExt(self):
-        self.extended = 0
-        self.zoneEntId = self.getZoneEntId()
-        self.eventName = None
-        if self.event is not None:
-            self.eventName = self.getOutputEventName(self.event)
-            self.accept(self.eventName, self.handleEvent)
-
-    def destroyVisExt(self):
-        if self.eventName is not None:
-            self.ignore(self.eventName)
-        if self.extended:
-            self.retract()
-
-    def handleEvent(self, doExtend):
-        if doExtend:
-            if not self.extended:
-                self.extend()
-        else:
-            if self.extended:
-                self.retract()
-
-    def extend(self):
-        """extend the visibility list"""
-        assert not self.extended
-        zoneEnt = self.level.getEntity(self.getZoneEntId())
-        zoneEnt.incrementRefCounts(self.newZones)
-        self.extended = 1
-        self.level.handleVisChange()
-        
-    def retract(self):
-        """un-extend the visibility list"""
-        assert self.extended
-        zoneEnt = self.level.getEntity(self.getZoneEntId())
-        zoneEnt.decrementRefCounts(self.newZones)
-        self.extended = 0
-        self.level.handleVisChange()
-
-    def destroy(self):
-        self.destroyVisExt()
-        Entity.Entity.destroy(self)
-
-    if __dev__:
-        def setNewZones(self, newZones):
-            # we need to call destroyVisExt before accepting the new zone set
-            extended = self.extended
-            self.destroyVisExt()
-            self.newZones = newZones
-            self.initVisExt()
-            if extended:
-                self.extend()
-            
-        def attribChanged(self, *args):
-            extended = self.extended
-            self.destroyVisExt()
-            self.initVisExt()
-            if extended:
-                self.extend()

+ 0 - 57
direct/src/level/ZoneEntity.py

@@ -1,57 +0,0 @@
-"""ZoneEntity module: contains the ZoneEntity class"""
-
-import ZoneEntityBase
-import BasicEntities
-
-class ZoneEntity(ZoneEntityBase.ZoneEntityBase, BasicEntities.NodePathAttribs):
-    def __init__(self, level, entId):
-        ZoneEntityBase.ZoneEntityBase.__init__(self, level, entId)
-
-        self.nodePath = self.level.getZoneNode(self.entId)
-        if self.nodePath is None:
-            if __dev__:
-                self.level.reportModelSpecSyncError(
-                    'unknown zoneNum %s; zone was removed from model?' %
-                    self.entId)
-            else:
-                self.notify.error('zone %s not found in level model' %
-                                  self.entId)
-        BasicEntities.NodePathAttribs.initNodePathAttribs(self, doReparent=0)
-
-        # dict of zoneNum to 'visible' reference count
-        self.visibleZoneNums = {}
-
-        # inc ref counts for the zones that are always visible from this zone
-        self.incrementRefCounts(self.visibility)
-
-    def destroy(self):
-        # no need to dec our visibility reference counts
-        BasicEntities.NodePathAttribs.destroy(self)
-        ZoneEntityBase.ZoneEntityBase.destroy(self)
-
-    def getNodePath(self):
-        return self.nodePath
-
-    def getVisibleZoneNums(self):
-        return self.visibleZoneNums.keys()
-
-    # call these with lists of zoneNums to increment or decrement their
-    # 'visible' reference counts
-    # zone is visible as long as its ref count is nonzero
-    def incrementRefCounts(self, zoneNumList):
-        for zoneNum in zoneNumList:
-            self.visibleZoneNums.setdefault(zoneNum, 0)
-            self.visibleZoneNums[zoneNum] += 1
-    def decrementRefCounts(self, zoneNumList):
-        for zoneNum in zoneNumList:
-            self.visibleZoneNums[zoneNum] -= 1
-            if self.visibleZoneNums[zoneNum] == 0:
-                del self.visibleZoneNums[zoneNum]
-
-    if __dev__:
-        def setVisibility(self, visibility):
-            self.decrementRefCounts(self.visibility)
-            self.visibility = visibility
-            self.incrementRefCounts(self.visibility)
-
-            self.level.handleVisChange()

+ 0 - 16
direct/src/level/ZoneEntityAI.py

@@ -1,16 +0,0 @@
-"""ZoneEntityAI module: contains the ZoneEntityAI class"""
-
-import ZoneEntityBase
-
-class ZoneEntityAI(ZoneEntityBase.ZoneEntityBase):
-    def __init__(self, level, entId):
-        ZoneEntityBase.ZoneEntityBase.__init__(self, level, entId)
-
-        # allocate a network zoneId for this zone
-        # there is error checking in air.allocateZone
-        self.setZoneId(self.level.air.allocateZone())
-        
-    def destroy(self):
-        if not self.isUberZone():
-            self.level.air.deallocateZone(self.getZoneId())
-        ZoneEntityBase.ZoneEntityBase.destroy(self)

+ 0 - 28
direct/src/level/ZoneEntityBase.py

@@ -1,28 +0,0 @@
-"""ZoneEntityBase module: contains the ZoneEntityBase class"""
-
-import Entity
-import LevelConstants
-
-class ZoneEntityBase(Entity.Entity):
-    def __init__(self, level, entId):
-        Entity.Entity.__init__(self, level, entId)
-        self.zoneId = None
-
-    def destroy(self):
-        del self.zoneId
-        Entity.Entity.destroy(self)
-
-    def isUberZone(self):
-        return self.entId == LevelConstants.UberZoneEntId
-
-    def setZoneId(self, zoneId):
-        """set the network zoneId that this zone entity corresponds to"""
-        self.zoneId = zoneId
-
-    def getZoneId(self):
-        """network zoneId"""
-        return self.zoneId
-
-    def getZoneNum(self):
-        """zoneNum from model / entityId"""
-        return self.entId

+ 0 - 0
direct/src/level/__init__.py