from otp.ai.AIBaseGlobal import * from direct.distributed.ClockDelta import * from otp.avatar import DistributedAvatarAI from otp.avatar.DistributedPlayerAI import DistributedPlayerAI from direct.directnotify import DirectNotifyGlobal from toontown.toonbase import ToontownGlobals import random class DistributedCCharBaseAI(DistributedAvatarAI.DistributedAvatarAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCCharBaseAI') def __init__(self, air, name): DistributedAvatarAI.DistributedAvatarAI.__init__(self, air) self.setName(name) self.exitOff() self.transitionToCostume = 0 self.diffPath = None return def generate(self): DistributedAvatarAI.DistributedAvatarAI.generate(self) if config.GetBool('classic-char-client-spam', 0): self._ccharSpamTask = taskMgr.add(self._simSpam, 'cchar-spam-%s' % serialNum()) def _simSpam(self, task): AvEnter = 'avatarEnter' AvExit = 'avatarExit' SetChat = 'setNearbyAvatarChat' SetSC = 'setNearbyAvatarSC' SetSCCustom = 'setNearbyAvatarSCCustom' SetSCToontask = 'setNearbyAvatarSCToontask' msgs = (AvEnter, AvExit, SetChat, SetSC, SetSCCustom, SetSCToontask) msg = random.choice(msgs) r = random.random() fixedAvId = 1000000006 if r < 0.3: avId = random.randrange(1 << 32) else: if r < 0.6: players = self.air.doFindAllOfType('DistributedToonAI')[0] if len(players): player = random.choice(players) avId = player.doId else: avId = fixedAvId else: avId = fixedAvId savedIdFunc = self.air.getAvatarIdFromSender self.air.getAvatarIdFromSender = lambda : avId rrange = random.randrange if msg is AvEnter: self.avatarEnter() elif msg is AvExit: self.avatarExit() else: if msg is SetChat: length = rrange(1024) s = '' for i in range(length): s += chr(rrange(1 << 8)) self.setNearbyAvatarChat(s) else: if msg is SetSC: self.setNearbyAvatarSC(rrange(1 << 16)) else: if msg is SetSCCustom: self.setNearbyAvatarSCCustom(rrange(1 << 16)) else: if msg is SetSCToontask: self.setNearbyAvatarSCToontask(rrange(1 << 32), rrange(1 << 32), rrange(1 << 32), rrange(1 << 8)) self.air.getAvatarIdFromSender = savedIdFunc return task.cont def delete(self): self.ignoreAll() if hasattr(self, '_ccharSpamTask'): taskMgr.remove(self._ccharSpamTask) self._ccharSpamTask = None DistributedAvatarAI.DistributedAvatarAI.delete(self) return def exitOff(self): self.__initAttentionSpan() self.__clearNearbyAvatars() def avatarEnter(self): avId = self.air.getAvatarIdFromSender() if avId not in self.air.doId2do: self.air.writeServerEvent('suspicious', avId, 'CCharBaseAI.avatarEnter from unknown avId') return av = self.air.getDo(avId) if not isinstance(av, DistributedPlayerAI): self.air.writeServerEvent('suspicious', avId, 'CCharBaseAI.avatarEnter from non-player object to cchar %s' % self.doId) return if av.zoneId != self.zoneId: self.air.writeServerEvent('suspicious', avId, 'CCharBaseAI.avatarEnter from av in zone %s, my zone is %s' % (av.zoneId, self.zoneId)) return self.notify.debug('adding avatar ' + str(avId) + ' to the nearby avatar list') if avId not in self.nearbyAvatars: self.nearbyAvatars.append(avId) else: self.air.writeServerEvent('suspicious', avId, 'CCharBase.avatarEnter') self.notify.warning('Avatar %s already in nearby avatars!' % avId) self.nearbyAvatarInfoDict[avId] = {} self.nearbyAvatarInfoDict[avId]['enterTime'] = globalClock.getRealTime() self.nearbyAvatarInfoDict[avId]['lastChatTime'] = 0 self.sortNearbyAvatars() self.__interestingAvatarEventOccured() avExitEvent = self.air.getAvatarExitEvent(avId) self.acceptOnce(avExitEvent, self.__handleExitedAvatar, [avId]) self.avatarEnterNextState() def avatarExit(self): avId = self.air.getAvatarIdFromSender() self.__doAvatarExit(avId) def __doAvatarExit(self, avId): avId = self.air.getAvatarIdFromSender() self.notify.debug('removing avatar ' + str(avId) + ' from the nearby avatar list') if avId not in self.nearbyAvatars: self.notify.debug('avatar ' + str(avId) + ' not in the nearby avatar list') else: avExitEvent = self.air.getAvatarExitEvent(avId) self.ignore(avExitEvent) del self.nearbyAvatarInfoDict[avId] self.nearbyAvatars.remove(avId) def avatarEnterNextState(): pass def avatarExitNextState(): pass def __clearNearbyAvatars(self): self.nearbyAvatars = [] self.nearbyAvatarInfoDict = {} def sortNearbyAvatars(self): def nAv_compare(a, b, nAvIDict=self.nearbyAvatarInfoDict): tsA = nAvIDict[a]['enterTime'] tsB = nAvIDict[b]['enterTime'] if tsA == tsB: return 0 else: if tsA < tsB: return -1 else: return 1 self.nearbyAvatars.sort(nAv_compare) def getNearbyAvatars(self): return self.nearbyAvatars def __avatarSpoke(self, avId): now = globalClock.getRealTime() if avId in self.nearbyAvatarInfoDict: self.nearbyAvatarInfoDict[avId]['lastChatTime'] = now self.__interestingAvatarEventOccured() def __initAttentionSpan(self): self.__avatarTimeoutBase = 0 def __interestingAvatarEventOccured(self, t=None): if t == None: t = globalClock.getRealTime() self.__avatarTimeoutBase = t return def lostInterest(self): now = globalClock.getRealTime() if now > self.__avatarTimeoutBase + 50.0: return 1 return 0 def __handleExitedAvatar(self, avId): self.__doAvatarExit(avId) def setNearbyAvatarChat(self, msg): avId = self.air.getAvatarIdFromSender() self.notify.debug('setNearbyAvatarChat: avatar ' + str(avId) + ' said ' + str(msg)) self.__avatarSpoke(avId) def setNearbyAvatarSC(self, msgIndex): avId = self.air.getAvatarIdFromSender() self.notify.debug('setNearbyAvatarSC: avatar %s said SpeedChat phrase %s' % (avId, msgIndex)) self.__avatarSpoke(avId) def setNearbyAvatarSCCustom(self, msgIndex): avId = self.air.getAvatarIdFromSender() self.notify.debug('setNearbyAvatarSCCustom: avatar %s said custom SpeedChat phrase %s' % (avId, msgIndex)) self.__avatarSpoke(avId) def setNearbyAvatarSCToontask(self, taskId, toNpcId, toonProgress, msgIndex): avId = self.air.getAvatarIdFromSender() self.notify.debug('setNearbyAvatarSCToontask: avatar %s said %s' % (avId, (taskId, toNpcId, toonProgress, msgIndex))) self.__avatarSpoke(avId) def getWalk(self): return ('', '', 0) def walkSpeed(self): return 0.1 def handleHolidays(self): self.CCChatter = 0 if hasattr(simbase.air, 'holidayManager'): if ToontownGlobals.CRASHED_LEADERBOARD in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.CRASHED_LEADERBOARD elif ToontownGlobals.CIRCUIT_RACING_EVENT in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.CIRCUIT_RACING_EVENT elif ToontownGlobals.WINTER_CAROLING in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.WINTER_CAROLING elif ToontownGlobals.WINTER_DECORATIONS in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.WINTER_DECORATIONS elif ToontownGlobals.VALENTINES_DAY in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.VALENTINES_DAY elif ToontownGlobals.APRIL_FOOLS_COSTUMES in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.APRIL_FOOLS_COSTUMES elif ToontownGlobals.SILLY_CHATTER_ONE in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.SILLY_CHATTER_ONE elif ToontownGlobals.SILLY_CHATTER_TWO in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.SILLY_CHATTER_TWO elif ToontownGlobals.SILLY_CHATTER_THREE in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.SILLY_CHATTER_THREE elif ToontownGlobals.SILLY_CHATTER_FOUR in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.SILLY_CHATTER_FOUR elif ToontownGlobals.SILLY_CHATTER_FIVE in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.SILLY_CHATTER_FOUR elif ToontownGlobals.HALLOWEEN_COSTUMES in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.HALLOWEEN_COSTUMES elif ToontownGlobals.SELLBOT_FIELD_OFFICE in simbase.air.holidayManager.currentHolidays: self.CCChatter = ToontownGlobals.SELLBOT_FIELD_OFFICE def getCCLocation(self): return 0 def getCCChatter(self): self.handleHolidays() return self.CCChatter def fadeAway(self): self.sendUpdate('fadeAway', []) def transitionCostume(self): self.transitionToCostume = 1