From 405c4bed63799639a54dc3c04a1c8f585cbb0e6c Mon Sep 17 00:00:00 2001 From: Darren Ranalli Date: Fri, 19 Sep 2003 22:32:53 +0000 Subject: [PATCH] fixed zone detection logic --- direct/src/level/DistributedLevel.py | 87 ++++++++++++++++++---------- direct/src/level/LevelBase.py | 9 +++ 2 files changed, 64 insertions(+), 32 deletions(-) diff --git a/direct/src/level/DistributedLevel.py b/direct/src/level/DistributedLevel.py index 2958654f24..12747d551f 100755 --- a/direct/src/level/DistributedLevel.py +++ b/direct/src/level/DistributedLevel.py @@ -16,6 +16,8 @@ class DistributedLevel(DistributedObject.DistributedObject, WantVisibility = config.GetBool('level-visibility', 1) HideZones = config.GetBool('level-hidezones', 1) + FloorCollPrefix = 'zoneFloor' + def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) LevelBase.LevelBase.__init__(self) @@ -66,6 +68,7 @@ class DistributedLevel(DistributedObject.DistributedObject, LevelBase.LevelBase.initializeLevel(self, self.doId, spec, self.scenarioIndex) + # all of the entities have been created now. # there should not be any pending reparents left at this point assert len(self.parent2ChildIds) == 0 # make sure the zoneNums from the model match the zoneNums from @@ -73,31 +76,6 @@ class DistributedLevel(DistributedObject.DistributedObject, assert sameElements(self.zoneNums, self.zoneNum2entId.keys()) # load stuff - - # fix up the floor collisions for walkable zones - for zoneNum in self.zoneNums: - zoneNode = self.zoneNum2node[zoneNum] - - # if this is a walkable zone, fix up the model - floorColls = zoneNode.findAllMatches('**/+CollisionNode').asList() - if len(floorColls) > 0: - # rename the floor collision nodes, and make sure no other - # nodes under the ZoneNode have that name - floorCollName = '%s' % 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): - # eat the collisionEntry - self.toonEnterZone(zoneNum) - self.accept('enter%s' % floorCollName, handleZoneEnter) - self.initVisibility() def createEntityCreator(self): @@ -110,6 +88,13 @@ class DistributedLevel(DistributedObject.DistributedObject, # load up the model ASAP so that we can get zone info out of it self.acceptOnce(self.getEntityTypeCreateEvent('levelMgr'), self.handleLevelMgrCreated) + """ it would be nice to be able to do this, but this overrides the + handler in LevelBase. For now, just override the LevelBase handler + and call down. + # fix up the model wrt zone collisions + self.acceptOnce(self.getEntityTypeCreateEvent('zone'), + self.handleAllZonesCreated) + """ def removeEntityCreationHandlers(self): LevelBase.LevelBase.removeEntityCreationHandlers(self) @@ -156,6 +141,41 @@ class DistributedLevel(DistributedObject.DistributedObject, # find the doorway nodes self.doorwayNum2Node = findNumberedNodes('Doorway') + def handleAllZonesCreated(self): + LevelBase.LevelBase.handleAllZonesCreated(self) + + # fix up the floor collisions for walkable zones before + # any entities get put under the model + for zoneNum in self.zoneNums: + zoneNode = self.zoneNum2node[zoneNum] + + # 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): + # eat the collisionEntry + self.toonEnterZone(zoneNum) + self.accept('enter%s' % floorCollName, handleZoneEnter) + def announceGenerate(self): self.notify.debug('announceGenerate') DistributedObject.DistributedObject.announceGenerate(self) @@ -231,7 +251,7 @@ class DistributedLevel(DistributedObject.DistributedObject, # been hidden self.curVisibleZoneNums = list2dict(self.zoneNums) # the UberZone is always visible, so it's not included in the - # viz lists + # zones' viz lists del self.curVisibleZoneNums[0] # we have not entered any zone yet self.curZoneNum = None @@ -239,12 +259,15 @@ class DistributedLevel(DistributedObject.DistributedObject, # listen for camera-ray/floor collision events def handleCameraRayFloorCollision(collEntry, self=self): name = collEntry.getIntoNode().getName() - try: - zoneNum = int(name) - except: - self.notify.warning('Invalid floor collision node: %s' % name) - else: - self.camEnterZone(zoneNum) + prefixLen = len(DistributedLevel.FloorCollPrefix) + if (name[:prefixLen] == DistributedLevel.FloorCollPrefix): + try: + zoneNum = int(name[prefixLen:]) + except: + self.notify.debug('Invalid zone floor collision node: %s' + % name) + else: + self.camEnterZone(zoneNum) self.accept('on-floor', handleCameraRayFloorCollision) # if no viz, listen to all the zones diff --git a/direct/src/level/LevelBase.py b/direct/src/level/LevelBase.py index 2260a4b5c0..2fc03e70e4 100755 --- a/direct/src/level/LevelBase.py +++ b/direct/src/level/LevelBase.py @@ -88,6 +88,15 @@ class LevelBase: def setupEntityCreationHandlers(self): # set up any handlers for entity creation events # override if desired, but be sure to call down + + # NOTE: we currently don't support a single object listening + # multiple times to a single event; therefore, anything that + # is listened for here cannot be listened for in a subclass + # as well; one will stomp the other. Therefore, until we figure + # out a better way to handle it, override any handlers defined + # in LevelBase and call down, instead of installing your own + # handler. + self.acceptOnce( self.getEntityTypeCreateEvent('zone'), self.handleAllZonesCreated)