from panda3d.core import * from direct.directnotify import DirectNotifyGlobal from direct.showbase import DirectObject from otp.ai.AIZoneData import AIZoneData from toontown.toonbase import ToontownGlobals from toontown.pets import PetConstants def getStartLookingAtOtherEvent(lookingAvId): return 'PetLookerAI-%s-startLookingAtOther' % lookingAvId def getStopLookingAtOtherEvent(lookingAvId): return 'PetLookerAI-%s-stopLookingAtOther' % lookingAvId def getStartLookedAtByOtherEvent(lookedAtAvId): return 'PetLookerAI-%s-startLookedAtByOther' % lookedAtAvId def getStopLookedAtByOtherEvent(lookedAtAvId): return 'PetLookerAI-%s-stopLookedAtByOther' % lookedAtAvId class PetLookerAI: notify = DirectNotifyGlobal.directNotify.newCategory('PetLookerAI') def __init__(self): self.__active = 0 self.others = {} def destroy(self): if self.__active: self.exitPetLook() if len(self.others): PetLookerAI.notify.warning('%s: self.others not empty: %s' % (self.doId, list(self.others.keys()))) self.others = {} def _getPetLookerBodyNode(self): return self def _isPet(self): return 0 def enterPetLook(self): PetLookerAI.notify.debug('enterPetLook: %s' % self.doId) if self.__active: PetLookerAI.notify.warning('enterPetLook: %s already active!' % self.doId) return if len(self.others): PetLookerAI.notify.warning('%s: len(self.others) != 0: %s' % (self.doId, list(self.others.keys()))) self.others = {} self.__active = 1 self.__collNode = self._getPetLookerBodyNode().attachNewNode('PetLookerCollNode') self._createPetLookSphere() def exitPetLook(self): PetLookerAI.notify.debug('exitPetLook: %s' % self.doId) if not self.__active: PetLookerAI.notify.warning('exitPetLook: %s not active!' % self.doId) return if len(self.others): otherIds = list(self.others.keys()) PetLookerAI.notify.warning('%s: still in otherIds: %s' % (self.doId, otherIds)) for otherId in otherIds: self._handleLookingAtOtherStop(otherId) if len(self.others): PetLookerAI.notify.warning('%s: self.others still not empty: %s' % (self.doId, list(self.others.keys()))) self.others = {} self._destroyPetLookSphere() self.__collNode.removeNode() del self.__collNode self.__active = 0 def _createPetLookSphere(self): isPet = self._isPet() if isPet: radius = PetConstants.PetSphereRadius else: radius = PetConstants.NonPetSphereRadius lookSphere = CollisionSphere(0, 0, 0, radius) lookSphereNode = CollisionNode('petLookSphere-%s' % self.doId) lookSphereNode.addSolid(lookSphere) lookSphereNode.setFromCollideMask(BitMask32.allOff()) if isPet: intoCollideMask = ToontownGlobals.PetLookatPetBitmask fromCollideMask = ToontownGlobals.PetLookatPetBitmask | ToontownGlobals.PetLookatNonPetBitmask else: intoCollideMask = ToontownGlobals.PetLookatNonPetBitmask fromCollideMask = ToontownGlobals.PetLookatPetBitmask lookSphereNode.setIntoCollideMask(intoCollideMask) lookSphereNode.setFromCollideMask(fromCollideMask) self.lookSphereNodePath = self.__collNode.attachNewNode(lookSphereNode) self.lookSphereNodePath.setTag('petLooker', '%s' % self.doId) self._cHandler = CollisionHandlerEvent() self._cHandler.addInPattern(self._getLookingStartEvent()) self._cHandler.addOutPattern(self._getLookingStopEvent()) collTrav = self.getCollTrav() if collTrav: collTrav.addCollider(self.lookSphereNodePath, self._cHandler) self.accept(self._getLookingStartEvent(), self._handleLookingAtOtherStart) self.accept(self._getLookingStopEvent(), self._handleLookingAtOtherStop) if hasattr(self, 'eventProxy'): PetLookerAI.notify.warning('%s: already have an eventProxy!' % self.doId) else: self.eventProxy = DirectObject.DirectObject() self.eventProxy.accept(self.getZoneChangeEvent(), self._handleZoneChange) def _destroyPetLookSphere(self): collTrav = self.getCollTrav() if collTrav: collTrav.removeCollider(self.lookSphereNodePath) del self._cHandler self.lookSphereNodePath.removeNode() del self.lookSphereNodePath self.ignore(self._getLookingStartEvent()) self.ignore(self._getLookingStopEvent()) self.eventProxy.ignoreAll() del self.eventProxy def _handleZoneChange(self, newZoneId, oldZoneId): PetLookerAI.notify.debug('_handleZoneChange: %s' % self.doId) if not self.__active: PetLookerAI.notify.warning('%s: _handleZoneChange: not active!' % self.doId) return oldZoneData = AIZoneData(self.air, self.parentId, oldZoneId) if oldZoneData.hasCollTrav(): oldZoneData.getCollTrav().removeCollider(self.lookSphereNodePath) oldZoneData.destroy() newZoneData = AIZoneData(self.air, self.parentId, newZoneId) if newZoneData.hasCollTrav(): newZoneData.getCollTrav().addCollider(self.lookSphereNodePath, self._cHandler) newZoneData.destroy() def _getLookingStartEvent(self): return 'PetLookerAI-lookingStart-%s' % self.doId def _getLookingStopEvent(self): return 'PetLookerAI-lookingStop-%s' % self.doId def __getOtherLookerDoIdFromCollEntry(self, collEntry): into = collEntry.getIntoNodePath() if not into.hasTag('petLooker'): return 0 return int(into.getTag('petLooker')) def _handleLookingAtOtherStart(self, other): if not self.__active: PetLookerAI.notify.warning('%s: _handleLookingAtOtherStart: not active!' % self.doId) return if isinstance(other, CollisionEntry): other = self.__getOtherLookerDoIdFromCollEntry(other) if other == 0: PetLookerAI.notify.warning('%s: looking at unknown other avatar' % self.doId) return PetLookerAI.notify.debug('_handleLookingAtOtherStart: %s looking at %s' % (self.doId, other)) if other in self.others: PetLookerAI.notify.warning('%s: other (%s) is already in self.others!' % (self.doId, other)) if not hasattr(self, '_cHandler'): PetLookerAI.notify.warning('-->The looker sphere has already been destroyed') else: self.others[other] = None messenger.send(getStartLookingAtOtherEvent(self.doId), [other]) messenger.send(getStartLookedAtByOtherEvent(other), [self.doId]) return def _handleLookingAtOtherStop(self, other): if not self.__active: PetLookerAI.notify.warning('%s: _handleLookingAtOtherStop: not active!' % self.doId) return if isinstance(other, CollisionEntry): other = self.__getOtherLookerDoIdFromCollEntry(other) if other == 0: PetLookerAI.notify.warning('%s: stopped looking at unknown other avatar' % self.doId) return PetLookerAI.notify.debug('_handleLookingAtOtherStop: %s no longer looking at %s' % (self.doId, other)) if other not in self.others: PetLookerAI.notify.warning('%s: other (%s) is not in self.others!' % (self.doId, other)) if not hasattr(self, '_cHandler'): PetLookerAI.notify.warning('-->The looker sphere has already been destroyed') else: del self.others[other] messenger.send(getStopLookingAtOtherEvent(self.doId), [other]) messenger.send(getStopLookedAtByOtherEvent(other), [self.doId])