import copy from direct.controls.ControlManager import CollisionHandlerRayStart from direct.directnotify import DirectNotifyGlobal from direct.fsm import ClassicFSM from direct.fsm import State from direct.interval.IntervalGlobal import * from pandac.PandaModules import * import string import CCharChatter import CCharPaths from otp.avatar import Avatar from toontown.char import CharDNA from toontown.char import DistributedChar from toontown.chat.ChatGlobals import * from toontown.effects import DustCloud from toontown.toonbase import ToontownGlobals from toontown.toonbase.TTLocalizer import Donald, DonaldDock, WesternPluto, Pluto class DistributedCCharBase(DistributedChar.DistributedChar): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCCharBase') def __init__(self, cr, name, dnaName): try: self.DistributedCCharBase_initialized return except: self.DistributedCCharBase_initialized = 1 DistributedChar.DistributedChar.__init__(self, cr) dna = CharDNA.CharDNA() dna.newChar(dnaName) self.setDNA(dna) self.setName(name) self.setTransparency(TransparencyAttrib.MDual, 1) fadeIn = self.colorScaleInterval(0.5, Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0), blendType='easeInOut') fadeIn.start() self.diffPath = None self.transitionToCostume = 0 self.__initCollisions() return def __initCollisions(self): self.cSphere = CollisionSphere(0.0, 0.0, 0.0, 8.0) self.cSphere.setTangible(0) self.cSphereNode = CollisionNode(self.getName() + 'BlatherSphere') self.cSphereNode.addSolid(self.cSphere) self.cSphereNodePath = self.attachNewNode(self.cSphereNode) self.cSphereNodePath.hide() self.cSphereNode.setCollideMask(ToontownGlobals.WallBitmask) self.acceptOnce('enter' + self.cSphereNode.getName(), self.__handleCollisionSphereEnter) self.cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0) self.cRayNode = CollisionNode(self.getName() + 'cRay') self.cRayNode.addSolid(self.cRay) self.cRayNodePath = self.attachNewNode(self.cRayNode) self.cRayNodePath.hide() self.cRayBitMask = ToontownGlobals.FloorBitmask self.cRayNode.setFromCollideMask(self.cRayBitMask) self.cRayNode.setIntoCollideMask(BitMask32.allOff()) self.lifter = CollisionHandlerFloor() self.lifter.setOffset(ToontownGlobals.FloorOffset) self.lifter.setReach(10.0) self.lifter.setMaxVelocity(0.0) self.lifter.addCollider(self.cRayNodePath, self) self.cTrav = base.localAvatar.cTrav def __deleteCollisions(self): del self.cSphere del self.cSphereNode self.cSphereNodePath.removeNode() del self.cSphereNodePath self.cRay = None self.cRayNode = None self.cRayNodePath = None self.lifter = None self.cTrav = None return def disable(self): self.stopBlink() self.ignoreAll() self.chatTrack.finish() del self.chatTrack if self.chatterDialogue: self.chatterDialogue.stop() del self.chatterDialogue DistributedChar.DistributedChar.disable(self) self.stopEarTask() def delete(self): try: self.DistributedCCharBase_deleted except: self.setParent(NodePath('Temp')) self.DistributedCCharBase_deleted = 1 self.__deleteCollisions() DistributedChar.DistributedChar.delete(self) def generate(self, diffPath = None): DistributedChar.DistributedChar.generate(self) if diffPath == None: self.setPos(CCharPaths.getNodePos(CCharPaths.startNode, CCharPaths.getPaths(self.getName(), self.getCCLocation()))) else: self.setPos(CCharPaths.getNodePos(CCharPaths.startNode, CCharPaths.getPaths(diffPath, self.getCCLocation()))) self.setHpr(0, 0, 0) self.setParent(ToontownGlobals.SPRender) self.startBlink() self.startEarTask() self.chatTrack = Sequence() self.chatterDialogue = None self.acceptOnce('enter' + self.cSphereNode.getName(), self.__handleCollisionSphereEnter) self.accept('exitSafeZone', self.__handleExitSafeZone) return def __handleExitSafeZone(self): self.__handleCollisionSphereExit(None) return def __handleCollisionSphereEnter(self, collEntry): self.notify.debug('Entering collision sphere...') self.sendUpdate('avatarEnter', []) self.accept('chatUpdate', self.__handleChatUpdate) self.accept('chatUpdateSC', self.__handleChatUpdateSC) self.accept('chatUpdateSCCustom', self.__handleChatUpdateSCCustom) self.accept('chatUpdateSCToontask', self.__handleChatUpdateSCToontask) self.nametag3d.setBin('transparent', 100) self.acceptOnce('exit' + self.cSphereNode.getName(), self.__handleCollisionSphereExit) def __handleCollisionSphereExit(self, collEntry): self.notify.debug('Exiting collision sphere...') self.sendUpdate('avatarExit', []) self.ignore('chatUpdate') self.ignore('chatUpdateSC') self.ignore('chatUpdateSCCustom') self.ignore('chatUpdateSCToontask') self.acceptOnce('enter' + self.cSphereNode.getName(), self.__handleCollisionSphereEnter) def __handleChatUpdate(self, msg, chatFlags): self.sendUpdate('setNearbyAvatarChat', [msg]) def __handleChatUpdateSC(self, msgIndex): self.sendUpdate('setNearbyAvatarSC', [msgIndex]) def __handleChatUpdateSCCustom(self, msgIndex): self.sendUpdate('setNearbyAvatarSCCustom', [msgIndex]) def __handleChatUpdateSCToontask(self, taskId, toNpcId, toonProgress, msgIndex): self.sendUpdate('setNearbyAvatarSCToontask', [taskId, toNpcId, toonProgress, msgIndex]) def makeTurnToHeadingTrack(self, heading): curHpr = self.getHpr() destHpr = self.getHpr() destHpr.setX(heading) if destHpr[0] - curHpr[0] > 180.0: destHpr.setX(destHpr[0] - 360) elif destHpr[0] - curHpr[0] < -180.0: destHpr.setX(destHpr[0] + 360) turnSpeed = 180.0 time = abs(destHpr[0] - curHpr[0]) / turnSpeed turnTracks = Parallel() if time > 0.2: turnTracks.append(Sequence(Func(self.loop, 'walk'), Wait(time), Func(self.loop, 'neutral'))) turnTracks.append(LerpHprInterval(self, time, destHpr, name='lerp' + self.getName() + 'Hpr')) return turnTracks def setChat(self, category, msg, avId): if avId in self.cr.doId2do: avatar = self.cr.doId2do[avId] chatter = CCharChatter.getChatter(self.getName(), self.getCCChatter()) if category >= len(chatter): self.notify.debug("Chatter's changed") return elif len(chatter[category]) <= msg: self.notify.debug("Chatter's changed") return str = chatter[category][msg] if '%' in str: str = copy.deepcopy(str) avName = avatar.getName() str = str.replace('%', avName) track = Sequence() if category != CCharChatter.GOODBYE: curHpr = self.getHpr() self.headsUp(avatar) destHpr = self.getHpr() self.setHpr(curHpr) track.append(self.makeTurnToHeadingTrack(destHpr[0])) if self.getName() == Donald or self.getName() == WesternPluto or self.getName() == Pluto: chatFlags = CFThought | CFTimeout if hasattr(base.cr, 'newsManager') and base.cr.newsManager: holidayIds = base.cr.newsManager.getHolidayIdList() if ToontownGlobals.APRIL_FOOLS_COSTUMES in holidayIds: if self.getName() == Pluto: chatFlags = CFTimeout | CFSpeech elif self.getName() == DonaldDock: chatFlags = CFTimeout | CFSpeech self.nametag3d.hide() else: chatFlags = CFTimeout | CFSpeech self.chatterDialogue = self.getChatterDialogue(category, msg) track.append(Func(self.setChatAbsolute, str, chatFlags, self.chatterDialogue)) self.chatTrack.finish() self.chatTrack = track self.chatTrack.start() def setWalk(self, srcNode, destNode, timestamp): pass def walkSpeed(self): return 0.1 def enableRaycast(self, enable = 1): if not self.cTrav or not hasattr(self, 'cRayNode') or not self.cRayNode: self.notify.debug('raycast info not found for ' + self.getName()) return self.cTrav.removeCollider(self.cRayNodePath) if enable: if self.notify.getDebug(): self.notify.debug('enabling raycast for ' + self.getName()) self.cTrav.addCollider(self.cRayNodePath, self.lifter) elif self.notify.getDebug(): self.notify.debug('disabling raycast for ' + self.getName()) def getCCLocation(self): return 0 def getCCChatter(self): self.handleHolidays() return self.CCChatter def handleHolidays(self): self.CCChatter = 0 if hasattr(base.cr, 'newsManager') and base.cr.newsManager: holidayIds = base.cr.newsManager.getHolidayIdList() if ToontownGlobals.CRASHED_LEADERBOARD in holidayIds: self.CCChatter = ToontownGlobals.CRASHED_LEADERBOARD elif ToontownGlobals.CIRCUIT_RACING_EVENT in holidayIds: self.CCChatter = ToontownGlobals.CIRCUIT_RACING_EVENT elif ToontownGlobals.WINTER_CAROLING in holidayIds: self.CCChatter = ToontownGlobals.WINTER_CAROLING elif ToontownGlobals.WINTER_DECORATIONS in holidayIds: self.CCChatter = ToontownGlobals.WINTER_DECORATIONS elif ToontownGlobals.WACKY_WINTER_CAROLING in holidayIds: self.CCChatter = ToontownGlobals.WACKY_WINTER_CAROLING elif ToontownGlobals.WACKY_WINTER_DECORATIONS in holidayIds: self.CCChatter = ToontownGlobals.WACKY_WINTER_DECORATIONS elif ToontownGlobals.VALENTINES_DAY in holidayIds: self.CCChatter = ToontownGlobals.VALENTINES_DAY elif ToontownGlobals.APRIL_FOOLS_COSTUMES in holidayIds: self.CCChatter = ToontownGlobals.APRIL_FOOLS_COSTUMES elif ToontownGlobals.SILLY_CHATTER_ONE in holidayIds: self.CCChatter = ToontownGlobals.SILLY_CHATTER_ONE elif ToontownGlobals.SILLY_CHATTER_TWO in holidayIds: self.CCChatter = ToontownGlobals.SILLY_CHATTER_TWO elif ToontownGlobals.SILLY_CHATTER_THREE in holidayIds: self.CCChatter = ToontownGlobals.SILLY_CHATTER_THREE elif ToontownGlobals.SILLY_CHATTER_FOUR in holidayIds: self.CCChatter = ToontownGlobals.SILLY_CHATTER_FOUR elif ToontownGlobals.SILLY_CHATTER_FIVE in holidayIds: self.CCChatter = ToontownGlobals.SILLY_CHATTER_FOUR elif ToontownGlobals.HALLOWEEN_COSTUMES in holidayIds: self.CCChatter = ToontownGlobals.HALLOWEEN_COSTUMES elif ToontownGlobals.SPOOKY_COSTUMES in holidayIds: self.CCChatter = ToontownGlobals.SPOOKY_COSTUMES elif ToontownGlobals.SELLBOT_FIELD_OFFICE in holidayIds: self.CCChatter = ToontownGlobals.SELLBOT_FIELD_OFFICE def fadeAway(self): fadeOut = self.colorScaleInterval(0.5, Vec4(1, 1, 1, 0.5), startColorScale=Vec4(1, 1, 1, 1), blendType='easeInOut') fadeOut.start() self.loop('neutral') if self.fsm: self.fsm.addState(State.State('TransitionToCostume', self.enterTransitionToCostume, self.exitTransitionToCostume, ['Off'])) self.fsm.request('TransitionToCostume', force=1) self.ignoreAll() def enterTransitionToCostume(self): def getDustCloudIval(): dustCloud = DustCloud.DustCloud(fBillboard=0, wantSound=1) dustCloud.setBillboardAxis(2.0) dustCloud.setZ(4) dustCloud.setScale(0.6) dustCloud.createTrack() return Sequence(Func(dustCloud.reparentTo, self), dustCloud.track, Func(dustCloud.destroy), name='dustCloadIval') dust = getDustCloudIval() dust.start() def exitTransitionToCostume(self): pass