oldschool-toontown/toontown/toon/LocalToon.py
2019-11-17 16:29:23 -05:00

2240 lines
98 KiB
Python

import random
import math
import time
import re
import zlib
from direct.interval.IntervalGlobal import *
from direct.distributed.ClockDelta import *
from direct.showbase.PythonUtil import *
from direct.gui.DirectGui import *
from direct.task import Task
from direct.showbase import PythonUtil
from direct.directnotify import DirectNotifyGlobal
from direct.gui import DirectGuiGlobals
from pandac.PandaModules import *
from libotp import *
from otp.avatar import LocalAvatar
from otp.login import LeaveToPayDialog
from otp.avatar import PositionExaminer
from otp.otpbase import OTPGlobals
from otp.avatar import DistributedPlayer
from toontown.shtiker import ShtikerBook
from toontown.shtiker import InventoryPage
from toontown.shtiker import MapPage
from toontown.shtiker import OptionsPage
from toontown.shtiker import ShardPage
from toontown.shtiker import QuestPage
from toontown.shtiker import TrackPage
from toontown.shtiker import KartPage
from toontown.shtiker import GardenPage
from toontown.shtiker import GolfPage
from toontown.shtiker import SuitPage
from toontown.shtiker import DisguisePage
from toontown.shtiker import PhotoAlbumPage
from toontown.shtiker import FishPage
from toontown.shtiker import NPCFriendPage
from toontown.shtiker import EventsPage
from toontown.shtiker import TIPPage
from toontown.quest import Quests
from toontown.quest import QuestParser
from toontown.toonbase.ToontownGlobals import *
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.catalog import CatalogNotifyDialog
from toontown.chat import ToontownChatManager
from toontown.chat import TTTalkAssistant
from toontown.estate import GardenGlobals
from toontown.battle.BattleSounds import *
from toontown.battle import Fanfare
from toontown.parties import PartyGlobals
from toontown.toon import ElevatorNotifier
from toontown.toon import ToonDNA
import DistributedToon
import Toon
import LaffMeter
from toontown.quest import QuestMap
from toontown.toon.DistributedNPCToonBase import DistributedNPCToonBase
WantNewsPage = base.config.GetBool('want-news-page', ToontownGlobals.DefaultWantNewsPageSetting)
from toontown.toontowngui import NewsPageButtonManager
if WantNewsPage:
from toontown.shtiker import NewsPage
AdjustmentForNewsButton = -0.275
ClaraBaseXPos = 1.45
if (__debug__):
import pdb
class LocalToon(DistributedToon.DistributedToon, LocalAvatar.LocalAvatar):
neverDisable = 1
piePowerSpeed = base.config.GetDouble('pie-power-speed', 0.2)
piePowerExponent = base.config.GetDouble('pie-power-exponent', 0.75)
def __init__(self, cr):
try:
self.LocalToon_initialized
except:
self.LocalToon_initialized = 1
self.numFlowers = 0
self.maxFlowerBasket = 0
DistributedToon.DistributedToon.__init__(self, cr)
chatMgr = ToontownChatManager.ToontownChatManager(cr, self)
talkAssistant = TTTalkAssistant.TTTalkAssistant()
LocalAvatar.LocalAvatar.__init__(self, cr, chatMgr, talkAssistant, passMessagesThrough=True)
self.soundRun = base.loadSfx('phase_3.5/audio/sfx/AV_footstep_runloop.wav')
self.soundWalk = base.loadSfx('phase_3.5/audio/sfx/AV_footstep_walkloop.wav')
self.soundWhisper = base.loadSfx('phase_3.5/audio/sfx/GUI_whisper_3.mp3')
self.soundPhoneRing = base.loadSfx('phase_3.5/audio/sfx/telephone_ring.mp3')
self.soundSystemMessage = base.loadSfx('phase_3/audio/sfx/clock03.mp3')
self.positionExaminer = PositionExaminer.PositionExaminer()
friendsGui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
friendsButtonNormal = friendsGui.find('**/FriendsBox_Closed')
friendsButtonPressed = friendsGui.find('**/FriendsBox_Rollover')
friendsButtonRollover = friendsGui.find('**/FriendsBox_Rollover')
newScale = oldScale = 0.8
if WantNewsPage:
newScale = oldScale * ToontownGlobals.NewsPageScaleAdjust
self.bFriendsList = DirectButton(image=(friendsButtonNormal, friendsButtonPressed, friendsButtonRollover), relief=None, pos=(1.192, 0, 0.875), scale=newScale, text=('', TTLocalizer.FriendsListLabel, TTLocalizer.FriendsListLabel), text_scale=0.09, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.18), text_font=ToontownGlobals.getInterfaceFont(), command=self.sendFriendsListEvent)
self.bFriendsList.hide()
self.friendsListButtonActive = 0
self.friendsListButtonObscured = 0
self.moveFurnitureButtonObscured = 0
self.clarabelleButtonObscured = 0
friendsGui.removeNode()
self.__furnitureGui = None
self.__clarabelleButton = None
self.__clarabelleFlash = None
self.furnitureManager = None
self.furnitureDirector = None
self.gotCatalogNotify = 0
self.__catalogNotifyDialog = None
self.accept('phaseComplete-5.5', self.loadPhase55Stuff)
Toon.loadDialog()
self.isIt = 0
self.cantLeaveGame = 0
self.tunnelX = 0.0
self.estate = None
self.__pieBubble = None
self.allowPies = 0
self.__pieButton = None
self.__piePowerMeter = None
self.__piePowerMeterSequence = None
self.__pieButtonType = None
self.__pieButtonCount = None
self.tossPieStart = None
self.__presentingPie = 0
self.__pieSequence = 0
self.wantBattles = base.config.GetBool('want-battles', 1)
self.seeGhosts = base.config.GetBool('see-ghosts', 0)
wantNameTagAvIds = base.config.GetBool('want-nametag-avids', 0)
if wantNameTagAvIds:
messenger.send('nameTagShowAvId', [])
base.idTags = 1
self.glitchX = 0
self.glitchY = 0
self.glitchZ = 0
self.glitchCount = 0
self.ticker = 0
self.glitchOkay = 1
self.tempGreySpacing = 0
self.wantStatePrint = base.config.GetBool('want-statePrint', 0)
self.__gardeningGui = None
self.__gardeningGuiFake = None
self.__shovelButton = None
self.shovelRelatedDoId = 0
self.shovelAbility = ''
self.plantToWater = 0
self.shovelButtonActiveCount = 0
self.wateringCanButtonActiveCount = 0
self.showingWateringCan = 0
self.showingShovel = 0
self.touchingPlantList = []
self.inGardenAction = None
self.guiConflict = 0
self.lastElevatorLeft = 0
self.elevatorNotifier = ElevatorNotifier.ElevatorNotifier()
self.accept(OTPGlobals.AvatarFriendAddEvent, self.sbFriendAdd)
self.accept(OTPGlobals.AvatarFriendUpdateEvent, self.sbFriendUpdate)
self.accept(OTPGlobals.AvatarFriendRemoveEvent, self.sbFriendRemove)
self._zoneId = None
self.accept('system message aknowledge', self.systemWarning)
self.systemMsgAckGuiDoneEvent = 'systemMsgAckGuiDoneEvent'
self.accept(self.systemMsgAckGuiDoneEvent, self.hideSystemMsgAckGui)
self.systemMsgAckGui = None
self.createSystemMsgAckGui()
if not hasattr(base.cr, 'lastLoggedIn'):
base.cr.lastLoggedIn = self.cr.toontownTimeManager.convertStrToToontownTime('')
self.setLastTimeReadNews(base.cr.lastLoggedIn)
self.acceptingNewFriends = Settings.getAcceptingNewFriends() and base.config.GetBool('accepting-new-friends-default', True)
self.acceptingNonFriendWhispers = Settings.getAcceptingNonFriendWhispers() and base.config.GetBool('accepting-non-friend-whispers-default', True)
self.physControls.event.addAgainPattern('again%in')
self.oldPos = None
self.questMap = None
self.prevToonIdx = 0
def wantLegacyLifter(self):
return True
def startGlitchKiller(self):
if localAvatar.getZoneId() not in GlitchKillerZones:
return
if __dev__:
self.glitchMessage = 'START GLITCH KILLER'
randChoice = random.randint(0, 3)
if randChoice == 0:
self.glitchMessage = 'START GLITCH KILLER'
elif randChoice == 1:
self.glitchMessage = 'GLITCH KILLER ENGAGED'
elif randChoice == 2:
self.glitchMessage = 'GLITCH KILLER GO!'
elif randChoice == 3:
self.glitchMessage = 'GLITCH IN YO FACE FOOL!'
self.notify.debug(self.glitchMessage)
taskMgr.remove(self.uniqueName('glitchKiller'))
taskMgr.add(self.glitchKiller, self.uniqueName('glitchKiller'))
self.glitchOkay = 1
def pauseGlitchKiller(self):
self.tempGreySpacing = 1
def unpauseGlitchKiller(self):
self.tempGreySpacing = 0
def stopGlitchKiller(self):
if __dev__ and hasattr(self, 'glitchMessage'):
if self.glitchMessage == 'START GLITCH KILLER':
self.notify.debug('STOP GLITCH KILLER')
elif self.glitchMessage == 'GLITCH KILLER ENGAGED':
self.notify.debug('GLITCH KILLER DISENGAGED')
elif self.glitchMessage == 'GLITCH KILLER GO!':
self.notify.debug('GLITCH KILLER NO GO!')
elif self.glitchMessage == 'GLITCH IN YO FACE FOOL!':
self.notify.debug('GLITCH OFF YO FACE FOOL!')
taskMgr.remove(self.uniqueName('glitchKiller'))
self.glitchOkay = 1
def glitchKiller(self, taskFooler = 0):
if base.greySpacing or self.tempGreySpacing:
return Task.cont
self.ticker += 1
if not self.physControls.lifter.hasContact() and not self.glitchOkay:
self.glitchCount += 1
else:
self.glitchX = self.getX()
self.glitchY = self.getY()
self.glitchZ = self.getZ()
self.glitchCount = 0
if self.physControls.lifter.hasContact():
self.glitchOkay = 0
if hasattr(self, 'physControls'):
if self.ticker >= 10:
self.ticker = 0
if self.glitchCount >= 7:
print 'GLITCH MAXED!!! resetting pos'
self.setX(self.glitchX - 1 * (self.getX() - self.glitchX))
self.setY(self.glitchY - 1 * (self.getY() - self.glitchY))
self.glitchCount = 0
return Task.cont
def announceGenerate(self):
self.startLookAround()
if base.wantNametags:
self.nametag.manage(base.marginManager)
self.startHackObservation()
DistributedToon.DistributedToon.announceGenerate(self)
from otp.friends import FriendInfo
def toonPosCheck(self, task = None):
toon = random.choice(self.cr.toons.values())
if toon and toon is not self and not isinstance(toon, DistributedNPCToonBase):
self.notify.debug('checking position for %s' % toon.doId)
realTimeStart = globalClock.getRealTime()
numOtherToons = len(self.cr.toons.values())
for otherToonIdxBase in range(numOtherToons):
otherToonIdx = otherToonIdxBase + self.prevToonIdx
if otherToonIdx >= numOtherToons:
otherToonIdx = otherToonIdx % numOtherToons
if globalClock.getRealTime() > realTimeStart + AV_TOUCH_CHECK_TIMELIMIT_CL:
self.notify.debug('too much time, exiting at index %s' % otherToonIdx)
self.prevToonIdx = otherToonIdx
break
otherToon = self.cr.toons.values()[otherToonIdx]
self.notify.debug('comparing with toon %s at index %s' % (otherToon.doId, otherToonIdx))
if otherToon and otherToon is not toon and otherToon is not self and not isinstance(otherToon, DistributedNPCToonBase):
toonPos = toon.getPos(render)
otherToonPos = otherToon.getPos(render)
self.notify.debug('pos1: %s pos2: %s' % (toonPos, otherToonPos))
zDist = otherToonPos.getZ() - toonPos.getZ()
toonPos.setZ(0)
otherToonPos.setZ(0)
moveVec = otherToonPos - toonPos
dist = moveVec.length()
self.notify.debug('distance to %s is %s %s' % (otherToon.doId, dist, zDist))
if dist < AV_TOUCH_CHECK_DIST and zDist < AV_TOUCH_CHECK_DIST_Z:
self.notify.debug('inappropriate touching!!!')
if toon.getParent() == render:
toonToMoveId = toon.doId
toonToNotMoveId = otherToon.doId
else:
toonToMoveId = otherToon.doId
toonToNotMoveId = toon.doId
self.sendUpdate('flagAv', [toonToMoveId, AV_FLAG_REASON_TOUCH, [str(toonToNotMoveId)]])
self.prevToonIdx = otherToonIdx
break
self.notify.debug('spent %s seconds doing pos check for %s' % (globalClock.getRealTime() - realTimeStart, toon.doId))
return Task.again
def tmdcc(self, task = None):
toon = random.choice(self.cr.toons.values())
result = self._tmdcc(toon)
if task:
if result:
task.setDelay(5.0)
else:
task.setDelay(1.5)
return Task.again
def _tmdcc(self, toon, checks = []):
result = None
if isinstance(toon, DistributedNPCToonBase) or toon is localAvatar or toon.isEmpty() or toon.bFake or toon._delayDeleteForceAllow:
return result
startTime = globalClock.getRealTime()
def delayedSend(toon, msg):
if toon:
toon.sendLogSuspiciousEvent(msg)
return Task.done
def sendT(header, msg, sToon, sendFooter = False, sendLs = True):
uid = '[' + str(globalClock.getRealTime()) + ']'
msgSize = 800 - (len(header) + len(uid) + 1)
uname = self.uniqueName('ioorrd234')
currCounter = 0
def sendAsParts(message, counter):
for currBlock in range(0, len(message) / msgSize + 1):
fmsg = '%s %02d: ' % (uid, currBlock + counter) + header + ': "%s"' % message[currBlock * msgSize:currBlock * msgSize + msgSize]
taskMgr.doMethodLater(0.08 * (currBlock + counter), delayedSend, uname + str(currBlock + counter), extraArgs=[sToon, fmsg])
return currBlock + counter + 1
currCounter = sendAsParts(msg, currCounter)
if sendLs:
sstream = StringStream.StringStream()
sToon.ls(sstream)
sdata = sstream.getData()
currCounter = sendAsParts(sdata, currCounter)
if sendFooter:
sstream.clearData()
if hasattr(sToon, 'suitGeom'):
sToon.suitGeom.ls(sstream)
bs = ''
nodeNames = config.GetString('send-suspicious-bam', 'to_head')
if nodeNames != '':
bs = ' bam ' + nodeNames + ': '
nodesToLog = []
for currName in nodeNames.split():
nodesToLog.append(sToon.find('**/' + currName))
for currNode in nodesToLog:
bs += zlib.compress(currNode.encodeToBamStream()).encode('hex') + '_'
footer = 'loc: %s dna: %s gmname: %s ntag: %s ceffect: %s disguise: %s sstyle: %s sgeom: %s %s' % (str(sToon.getLocation()),
str(sToon.style.asTuple()),
sToon.gmNameTagEnabled,
str(sToon.nametag and sToon.nametag.getContents()),
str(sToon.cheesyEffect),
sToon.isDisguised,
hasattr(sToon, 'suit') and str(sToon.suit.style),
hasattr(sToon, 'suitGeom') and sstream.getData(),
bs)
currCounter = sendAsParts(footer, currCounter)
self.sendUpdate('requestPing', [toon.doId])
if not checks:
numChecks = 6
checks = [random.choice(range(1, numChecks + 1))]
def findParentAv(node):
avId = 0
topParent = node
while topParent and not topParent.getTag('avatarDoId'):
topParent = topParent.getParent()
if topParent:
avIdStr = topParent.getTag('avatarDoId')
if avIdStr:
avId = int(avIdStr)
return (self.cr.getDo(avId), avId)
msgHeader = 'AvatarHackWarning!'
def hacker_detect_immediate(cbdata):
action = cbdata.getAction()
node = cbdata.getNode()
np = NodePath(node)
if not self.cr or not self.cr.distributedDistrict or not self.cr.distributedDistrict.getAllowAHNNLog():
if self.cr and self.cr.distributedDistrict:
sToon, avId = findParentAv(np)
if sToon is localAvatar:
return
if sToon and isinstance(sToon, DistributedToon.DistributedToon):
msg = "Blocking '%s' '%s' '%s'" % (self.cr.distributedDistrict.getAllowAHNNLog(), np, re.sub('<', '[', StackTrace(start=1).compact()))
sendT(msgHeader, msg, sToon, sendFooter=False, sendLs=False)
return
try:
parentNames = ['__Actor_modelRoot', 'to_head']
newParent = np.getParent()
if newParent and newParent.getName() in parentNames:
newParentParent = newParent.getParent()
parentParentNames = ['actorGeom', '__Actor_modelRoot']
if newParentParent and newParentParent.getName() in parentParentNames:
sToon, avId = findParentAv(newParentParent.getParent())
if sToon is localAvatar:
return
header = msgHeader + ' nodename'
avInfo = "hacker activity '%s' avatar %s node name '%s' with parents '%s' and '%s'!" % (action,
avId,
np.getName(),
newParent.getName(),
newParentParent.getName())
if sToon and isinstance(sToon, DistributedToon.DistributedToon):
avInfo += ' trace: '
avInfo += re.sub('<', '[', StackTrace(start=1).compact())
sendT(header, avInfo, sToon=sToon, sendFooter=True)
else:
sendLogSuspiciousEvent(header, 'got non-toon or missing parent %s...' % sToon + avInfo)
except:
pass
if config.GetBool('detect-suspicious-nodename', True):
PandaNode.setDetectCallback(PythonCallbackObject(hacker_detect_immediate))
def trackChat(chattingToon):
def _spoke(cbdata):
avId = cbdata.getId()
av = self.cr.getDo(avId)
chat = cbdata.getChat()
if avId != localAvatar.doId and av:
avInfo = 'suspicious chat "%s" trace: ' % chat
avInfo += re.sub('<', '[', StackTrace(start=1).compact())
sendT(msgHeader + ' chat', avInfo, chattingToon, sendFooter=False, sendLs=False)
chattingToon.nametag.setChatCallback(PythonCallbackObject(_spoke))
chattingToon.nametag.setChatCallbackId(chattingToon.doId)
if 1 in checks:
if base.config.GetBool('tmdcc-headcheck', 1):
headNodes = toon.findAllMatches('**/__Actor_head')
if len(headNodes) != 3 or not toon.getGeomNode().isHidden() and filter(lambda x: x.isHidden(), headNodes):
sendT(msgHeader, 'missing head node', toon)
result = toon
if base.config.GetBool('tmdcc-chatcheck', 1):
trackChat(toon)
else:
checks.append(2)
if 2 in checks:
if base.config.GetBool('tmdcc-handcheck', 1):
if not toon.getGeomNode().isHidden():
handNodes = toon.findAllMatches('**/hands')
for currHandNode in handNodes:
if currHandNode.hasColor() and currHandNode.getColor() != VBase4(1, 1, 1, 1):
sendT(msgHeader, 'invalid hand color: %s' % currHandNode.getColor(), toon)
result = toon
break
else:
checks.append(3)
if 3 in checks:
if base.config.GetBool('tmdcc-namecheck', 1):
nameNode = toon.find('**/nametag3d')
if not nameNode or nameNode.isHidden() and not toon.getGeomNode().isHidden() and toon.ghostMode == 0:
sendT(msgHeader, 'missing nametag for name: %s' % toon.getName(), toon)
result = toon
else:
checks.append(4)
if 4 in checks:
if base.config.GetBool('tmdcc-animcheck', 1):
if toon.zoneId in [ToontownGlobals.DonaldsDock,
ToontownGlobals.OutdoorZone,
ToontownGlobals.ToontownCentral,
ToontownGlobals.TheBrrrgh,
ToontownGlobals.MinniesMelodyland,
ToontownGlobals.DaisyGardens,
ToontownGlobals.FunnyFarm,
ToontownGlobals.GoofySpeedway,
ToontownGlobals.DonaldsDreamland]:
currAnim = toon.animFSM.getCurrentState().getName()
if currAnim != None and currAnim not in ['neutral',
'Happy',
'off',
'Sad',
'TeleportIn',
'jumpAirborne',
'CloseBook',
'run',
'OpenBook',
'TeleportOut',
'TeleportedOut',
'ReadBook',
'walk',
'Sit',
'jumpLand',
'Sleep',
'cringe',
'jumpSquat',
'Died']:
sendT(msgHeader, 'invalid animation playing: %s' % currAnim, toon)
result = toon
else:
checks.append(5)
if 5 in checks:
if base.config.GetBool('tmdcc-cogsuit', 1):
if toon.zoneId in [ToontownGlobals.DonaldsDock,
ToontownGlobals.OutdoorZone,
ToontownGlobals.ToontownCentral,
ToontownGlobals.TheBrrrgh,
ToontownGlobals.MinniesMelodyland,
ToontownGlobals.DaisyGardens,
ToontownGlobals.FunnyFarm,
ToontownGlobals.GoofySpeedway,
ToontownGlobals.DonaldsDreamland]:
if toon.isDisguised:
sendT(msgHeader, 'toon %s is in a cog suit' % toon.getName(), toon)
result = toon
else:
checks.append(6)
if 6 in checks:
if base.config.GetBool('tmdcc-colorcheck', 1):
torsoPieces = toon.getPieces(('torso', ('arms', 'neck')))
legPieces = toon.getPieces(('legs', ('legs', 'feet')))
headPieces = toon.getPieces(('head', '*head*'))
if (filter(lambda x: x.hasColor() and x.getColor() not in ToonDNA.allowedColors,
torsoPieces) or
filter(lambda x: x.hasColor() and x.getColor() not in ToonDNA.allowedColors,
legPieces) or
filter(lambda x: x.hasColor() and x.getColor() not in ToonDNA.allowedColors,
headPieces)) and toon.cheesyEffect == ToontownGlobals.CENormal:
torsoColors = str(map(lambda x: not x.hasColor() and 'clear' or x.getColor() in ToonDNA.allowedColors and 'ok' or x.getColor(), torsoPieces))
legColors = str(map(lambda x: not x.hasColor() and 'clear' or x.getColor() in ToonDNA.allowedColors and 'ok' or x.getColor(), legPieces))
headColors = str(map(lambda x: not x.hasColor() and 'clear' or x.getColor() in ToonDNA.allowedColors and 'ok' or x.getColor(), headPieces))
sendT(msgHeader, 'invalid color...arm: %s leg: %s head: %s' % (torsoColors, legColors, headColors), toon)
result = toon
else:
checks.append(7)
endTime = globalClock.getRealTime()
return result
def startHackObservation(self):
taskMgr.doMethodLater(AV_TOUCH_CHECK_DELAY_CL, self.toonPosCheck, self.uniqueName('toonPosCheck'))
taskMgr.doMethodLater(config.GetDouble('tmdcc-delay', 5.0), self.tmdcc, self.uniqueName('tmdcc'))
if __dev__ and base.config.GetBool('tmdcc-keys', 0):
from toontown.testenv import safezoneAutoVisit
safezoneAutoVisit.setupKeys()
from toontown.testenv import watchDistObj
watchDistObj.watchObj.setupKeys()
def stopHackObservation(self):
taskMgr.remove(self.uniqueName('toonPosCheck'))
taskMgr.remove(self.uniqueName('tmdcc'))
def disable(self):
self.stopHackObservation()
self.laffMeter.destroy()
del self.laffMeter
self.questMap.destroy()
self.questMap = None
if hasattr(self, 'purchaseButton'):
self.purchaseButton.destroy()
del self.purchaseButton
self.newsButtonMgr.request('Off')
base.whiteList.unload()
self.book.unload()
del self.optionsPage
del self.shardPage
del self.mapPage
del self.invPage
del self.questPage
del self.suitPage
del self.sosPage
del self.disguisePage
del self.fishPage
del self.gardenPage
del self.trackPage
del self.book
if base.wantKarts:
if hasattr(self, 'kartPage'):
del self.kartPage
if base.wantNametags:
self.nametag.unmanage(base.marginManager)
taskMgr.removeTasksMatching('*ioorrd234*')
self.ignoreAll()
DistributedToon.DistributedToon.disable(self)
return
def disableBodyCollisions(self):
pass
def delete(self):
try:
self.LocalToon_deleted
except:
self.LocalToon_deleted = 1
Toon.unloadDialog()
QuestParser.clear()
DistributedToon.DistributedToon.delete(self)
LocalAvatar.LocalAvatar.delete(self)
self.bFriendsList.destroy()
del self.bFriendsList
if self.__pieButton:
self.__pieButton.destroy()
self.__pieButton = None
if self.__piePowerMeter:
self.__piePowerMeter.destroy()
self.__piePowerMeter = None
taskMgr.remove('unlockGardenButtons')
taskMgr.remove('lerpFurnitureButton')
if self.__furnitureGui:
self.__furnitureGui.destroy()
del self.__furnitureGui
if self.__gardeningGui:
self.__gardeningGui.destroy()
del self.__gardeningGui
if self.__gardeningGuiFake:
self.__gardeningGuiFake.destroy()
del self.__gardeningGuiFake
if self.__clarabelleButton:
self.__clarabelleButton.destroy()
del self.__clarabelleButton
if self.__clarabelleFlash:
self.__clarabelleFlash.finish()
del self.__clarabelleFlash
if self.__catalogNotifyDialog:
self.__catalogNotifyDialog.cleanup()
del self.__catalogNotifyDialog
return
def initInterface(self):
self.newsButtonMgr = NewsPageButtonManager.NewsPageButtonManager()
self.newsButtonMgr.request('Hidden')
self.book = ShtikerBook.ShtikerBook('bookDone')
self.book.load()
self.book.hideButton()
self.optionsPage = OptionsPage.OptionsPage()
self.optionsPage.load()
self.book.addPage(self.optionsPage, pageName=TTLocalizer.OptionsPageTitle)
self.shardPage = ShardPage.ShardPage()
self.shardPage.load()
self.book.addPage(self.shardPage, pageName=TTLocalizer.ShardPageTitle)
self.mapPage = MapPage.MapPage()
self.mapPage.load()
self.book.addPage(self.mapPage, pageName=TTLocalizer.MapPageTitle)
self.invPage = InventoryPage.InventoryPage()
self.invPage.load()
self.book.addPage(self.invPage, pageName=TTLocalizer.InventoryPageTitle)
self.questPage = QuestPage.QuestPage()
self.questPage.load()
self.book.addPage(self.questPage, pageName=TTLocalizer.QuestPageToonTasks)
self.trackPage = TrackPage.TrackPage()
self.trackPage.load()
self.book.addPage(self.trackPage, pageName=TTLocalizer.TrackPageShortTitle)
self.suitPage = SuitPage.SuitPage()
self.suitPage.load()
self.book.addPage(self.suitPage, pageName=TTLocalizer.SuitPageTitle)
if base.config.GetBool('want-photo-album', 0):
self.photoAlbumPage = PhotoAlbumPage.PhotoAlbumPage()
self.photoAlbumPage.load()
self.book.addPage(self.photoAlbumPage, pageName=TTLocalizer.PhotoPageTitle)
self.fishPage = FishPage.FishPage()
self.fishPage.setAvatar(self)
self.fishPage.load()
self.book.addPage(self.fishPage, pageName=TTLocalizer.FishPageTitle)
if base.wantKarts:
self.addKartPage()
if self.disguisePageFlag:
self.loadDisguisePages()
if self.sosPageFlag:
self.loadSosPages()
if self.gardenStarted:
self.loadGardenPages()
self.addGolfPage()
self.addEventsPage()
if WantNewsPage:
self.addNewsPage()
self.book.setPage(self.mapPage, enterPage=False)
self.laffMeter = LaffMeter.LaffMeter(self.style, self.hp, self.maxHp)
self.laffMeter.setAvatar(self)
self.laffMeter.setScale(0.075)
if self.style.getAnimal() == 'monkey':
self.laffMeter.setPos(-1.18, 0.0, -0.87)
else:
self.laffMeter.setPos(-1.2, 0.0, -0.87)
self.laffMeter.stop()
self.questMap = QuestMap.QuestMap(self)
self.questMap.stop()
if not base.cr.isPaid():
guiButton = loader.loadModel('phase_3/models/gui/quit_button')
self.purchaseButton = DirectButton(parent=aspect2d, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=0.9, text=TTLocalizer.OptionsPagePurchase, text_scale=0.05, text_pos=(0, -0.01), textMayChange=0, pos=(0.885, 0, -0.94), sortOrder=100, command=self.__handlePurchase)
base.setCellsAvailable([base.bottomCells[4]], 0)
self.accept('time-insert', self.__beginTossPie)
self.accept('time-insert-up', self.__endTossPie)
self.accept('time-delete', self.__beginTossPie)
self.accept('time-delete-up', self.__endTossPie)
self.accept('pieHit', self.__pieHit)
self.accept('interrupt-pie', self.interruptPie)
self.accept('InputState-jump', self.__toonMoved)
self.accept('InputState-forward', self.__toonMoved)
self.accept('InputState-reverse', self.__toonMoved)
self.accept('InputState-turnLeft', self.__toonMoved)
self.accept('InputState-turnRight', self.__toonMoved)
self.accept('InputState-slide', self.__toonMoved)
QuestParser.init()
return
def __handlePurchase(self):
self.purchaseButton.hide()
if (base.cr.isWebPlayToken() or __dev__):
if base.cr.isPaid():
if base.cr.productName in ['DisneyOnline-UK', 'DisneyOnline-AP', 'JP', 'DE', 'BR', 'FR']:
paidNoParentPassword = launcher and launcher.getParentPasswordSet()
else:
paidNoParentPassword = launcher and not launcher.getParentPasswordSet()
else:
paidNoParentPassword = 0
self.leaveToPayDialog = LeaveToPayDialog.LeaveToPayDialog(paidNoParentPassword, self.purchaseButton.show)
self.leaveToPayDialog.show()
else:
self.notify.error('You should not get here without a PlayToken')
if base.wantKarts:
def addKartPage(self):
if self.hasKart():
if hasattr(self, 'kartPage') and self.kartPage != None:
return
if not launcher.getPhaseComplete(6):
self.acceptOnce('phaseComplete-6', self.addKartPage)
return
self.kartPage = KartPage.KartPage()
self.kartPage.setAvatar(self)
self.kartPage.load()
self.book.addPage(self.kartPage, pageName=TTLocalizer.KartPageTitle)
return
def setWantBattles(self, wantBattles):
self.wantBattles = wantBattles
def loadDisguisePages(self):
if self.disguisePage != None:
return
if not launcher.getPhaseComplete(9):
self.acceptOnce('phaseComplete-9', self.loadDisguisePages)
return
self.disguisePage = DisguisePage.DisguisePage()
self.disguisePage.load()
self.book.addPage(self.disguisePage, pageName=TTLocalizer.DisguisePageTitle)
self.loadSosPages()
return
def loadSosPages(self):
if self.sosPage != None:
return
self.sosPage = NPCFriendPage.NPCFriendPage()
self.sosPage.load()
self.book.addPage(self.sosPage, pageName=TTLocalizer.NPCFriendPageTitle)
return
def loadGardenPages(self):
if self.gardenPage != None:
return
if not launcher.getPhaseComplete(5.5):
self.acceptOnce('phaseComplete-5.5', self.loadPhase55Stuff)
return
self.gardenPage = GardenPage.GardenPage()
self.gardenPage.load()
self.book.addPage(self.gardenPage, pageName=TTLocalizer.GardenPageTitle)
return
def loadPhase55Stuff(self):
if self.gardenPage == None:
self.gardenPage = GardenPage.GardenPage()
self.gardenPage.load()
self.book.addPage(self.gardenPage, pageName=TTLocalizer.GardenPageTitle)
elif not launcher.getPhaseComplete(5.5):
self.acceptOnce('phaseComplete-5.5', self.loadPhase55Stuff)
self.refreshOnscreenButtons()
return
def setAsGM(self, state):
self.notify.debug('Setting GM State: %s in LocalToon' % state)
DistributedToon.DistributedToon.setAsGM(self, state)
if self.gmState:
if base.config.GetString('gm-nametag-string', '') != '':
self.gmNameTagString = base.config.GetString('gm-nametag-string')
if base.config.GetString('gm-nametag-color', '') != '':
self.gmNameTagColor = base.config.GetString('gm-nametag-color')
if base.config.GetInt('gm-nametag-enabled', 0):
self.gmNameTagEnabled = 1
self.d_updateGMNameTag()
def displayTalkWhisper(self, fromId, avatarName, rawString, mods):
sender = base.cr.identifyAvatar(fromId)
if sender:
chatString, scrubbed = sender.scrubTalk(rawString, mods)
else:
chatString, scrubbed = self.scrubTalk(rawString, mods)
sender = self
sfx = self.soundWhisper
chatString = avatarName + ': ' + chatString
whisper = WhisperPopup(chatString, OTPGlobals.getInterfaceFont(), WhisperPopup.WTNormal)
whisper.setClickable(avatarName, fromId)
whisper.manage(base.marginManager)
base.playSfx(sfx)
def displayTalkAccount(self, fromId, senderName, rawString, mods):
sender = None
playerInfo = None
sfx = self.soundWhisper
playerInfo = base.cr.playerFriendsManager.playerId2Info.get(fromId, None)
if playerInfo == None:
return
senderAvId = base.cr.playerFriendsManager.findAvIdFromPlayerId(fromId)
if not senderName and base.cr.playerFriendsManager.playerId2Info.get(fromId):
senderName = base.cr.playerFriendsManager.playerId2Info.get(fromId).playerName
senderAvatar = base.cr.identifyAvatar(senderAvId)
if sender:
chatString, scrubbed = senderAvatar.scrubTalk(rawString, mods)
else:
chatString, scrubbed = self.scrubTalk(rawString, mods)
chatString = senderName + ': ' + chatString
whisper = WhisperPopup(chatString, OTPGlobals.getInterfaceFont(), WhisperPopup.WTNormal)
if playerInfo != None:
whisper.setClickable(senderName, fromId, 1)
whisper.manage(base.marginManager)
base.playSfx(sfx)
return
def isLocal(self):
return 1
def canChat(self):
if not self.cr.allowAnyTypedChat():
return 0
if self.commonChatFlags & (ToontownGlobals.CommonChat | ToontownGlobals.SuperChat):
return 1
if base.cr.whiteListChatEnabled:
return 1
for friendId, flags in self.friendsList:
if flags & ToontownGlobals.FriendChat:
return 1
return 0
def startChat(self):
if self.tutorialAck:
self.notify.info('calling LocalAvatar.startchat')
LocalAvatar.LocalAvatar.startChat(self)
self.accept('chatUpdateSCToontask', self.b_setSCToontask)
self.accept('chatUpdateSCResistance', self.d_reqSCResistance)
self.accept('chatUpdateSCSinging', self.b_setSCSinging)
self.accept('whisperUpdateSCToontask', self.whisperSCToontaskTo)
else:
self.notify.info('NOT calling LocalAvatar.startchat, in tutorial')
def stopChat(self):
LocalAvatar.LocalAvatar.stopChat(self)
self.ignore('chatUpdateSCToontask')
self.ignore('chatUpdateSCResistance')
self.ignore('chatUpdateSCSinging')
self.ignore('whisperUpdateSCToontask')
def tunnelIn(self, tunnelOrigin):
self.b_setTunnelIn(self.tunnelX * 0.8, tunnelOrigin)
def tunnelOut(self, tunnelOrigin):
self.tunnelX = self.getX(tunnelOrigin)
tunnelY = self.getY(tunnelOrigin)
self.b_setTunnelOut(self.tunnelX * 0.95, tunnelY, tunnelOrigin)
def handleTunnelIn(self, startTime, endX, x, y, z, h):
self.notify.debug('LocalToon.handleTunnelIn')
tunnelOrigin = render.attachNewNode('tunnelOrigin')
tunnelOrigin.setPosHpr(x, y, z, h, 0, 0)
self.b_setAnimState('run', self.animMultiplier)
self.stopLookAround()
self.reparentTo(render)
self.runSound()
camera.reparentTo(render)
camera.setPosHpr(tunnelOrigin, 0, 20, 12, 180, -20, 0)
base.transitions.irisIn(0.4)
toonTrack = self.getTunnelInToonTrack(endX, tunnelOrigin)
def cleanup(self = self, tunnelOrigin = tunnelOrigin):
self.stopSound()
tunnelOrigin.removeNode()
messenger.send('tunnelInMovieDone')
self.tunnelTrack = Sequence(toonTrack, Func(cleanup))
self.tunnelTrack.start(globalClock.getFrameTime() - startTime)
def handleTunnelOut(self, startTime, startX, startY, x, y, z, h):
self.notify.debug('LocalToon.handleTunnelOut')
tunnelOrigin = render.attachNewNode('tunnelOrigin')
tunnelOrigin.setPosHpr(x, y, z, h, 0, 0)
self.b_setAnimState('run', self.animMultiplier)
self.runSound()
self.stopLookAround()
tracks = Parallel()
camera.wrtReparentTo(render)
startPos = camera.getPos(tunnelOrigin)
startHpr = camera.getHpr(tunnelOrigin)
camLerpDur = 1.0
reducedCamH = fitDestAngle2Src(startHpr[0], 180)
tracks.append(LerpPosHprInterval(camera, camLerpDur, pos=Point3(0, 20, 12), hpr=Point3(reducedCamH, -20, 0), startPos=startPos, startHpr=startHpr, other=tunnelOrigin, blendType='easeInOut', name='tunnelOutLerpCamPos'))
toonTrack = self.getTunnelOutToonTrack(startX, startY, tunnelOrigin)
tracks.append(toonTrack)
irisDur = 0.4
tracks.append(Sequence(Wait(toonTrack.getDuration() - (irisDur + 0.1)), Func(base.transitions.irisOut, irisDur)))
def cleanup(self = self, tunnelOrigin = tunnelOrigin):
self.stopSound()
self.detachNode()
tunnelOrigin.removeNode()
messenger.send('tunnelOutMovieDone')
self.tunnelTrack = Sequence(tracks, Func(cleanup))
self.tunnelTrack.start(globalClock.getFrameTime() - startTime)
def getPieBubble(self):
if self.__pieBubble == None:
bubble = CollisionSphere(0, 0, 0, 1)
node = CollisionNode('pieBubble')
node.addSolid(bubble)
node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask)
node.setIntoCollideMask(BitMask32.allOff())
self.__pieBubble = NodePath(node)
self.pieHandler = CollisionHandlerEvent()
self.pieHandler.addInPattern('pieHit')
self.pieHandler.addInPattern('pieHit-%in')
return self.__pieBubble
def __beginTossPieMouse(self, mouseParam):
self.__beginTossPie(globalClock.getFrameTime())
def __endTossPieMouse(self, mouseParam):
self.__endTossPie(globalClock.getFrameTime())
def __beginTossPie(self, time):
if self.tossPieStart != None:
return
if not self.allowPies:
return
if self.numPies == 0:
messenger.send('outOfPies')
return
if self.__pieInHand():
return
if getattr(self.controlManager.currentControls, 'isAirborne', 0):
return
messenger.send('wakeup')
self.localPresentPie(time)
taskName = self.uniqueName('updatePiePower')
taskMgr.add(self.__updatePiePower, taskName)
return
def __endTossPie(self, time):
if self.tossPieStart == None:
return
taskName = self.uniqueName('updatePiePower')
taskMgr.remove(taskName)
messenger.send('wakeup')
power = self.__getPiePower(time)
self.tossPieStart = None
self.localTossPie(power)
return
def localPresentPie(self, time):
import TTEmote
from otp.avatar import Emote
self.__stopPresentPie()
if self.tossTrack:
tossTrack = self.tossTrack
self.tossTrack = None
tossTrack.finish()
self.interruptPie()
self.tossPieStart = time
self.__pieSequence = self.__pieSequence + 1 & 255
sequence = self.__pieSequence
self.__presentingPie = 1
pos = self.getPos()
hpr = self.getHpr()
timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32)
self.sendUpdate('presentPie', [pos[0],
pos[1],
pos[2],
hpr[0] % 360.0,
hpr[1],
hpr[2],
timestamp32])
Emote.globalEmote.disableBody(self)
messenger.send('begin-pie')
ival = self.getPresentPieInterval(pos[0], pos[1], pos[2], hpr[0], hpr[1], hpr[2])
ival = Sequence(ival, name=self.uniqueName('localPresentPie'))
self.tossTrack = ival
ival.start()
self.makePiePowerMeter()
self.__piePowerMeter.show()
self.__piePowerMeterSequence = sequence
self.__piePowerMeter['value'] = 0
return
def __stopPresentPie(self):
if self.__presentingPie:
import TTEmote
from otp.avatar import Emote
Emote.globalEmote.releaseBody(self)
messenger.send('end-pie')
self.__presentingPie = 0
taskName = self.uniqueName('updatePiePower')
taskMgr.remove(taskName)
def __getPiePower(self, time):
elapsed = max(time - self.tossPieStart, 0.0)
t = elapsed / self.piePowerSpeed
t = math.pow(t, self.piePowerExponent)
power = int(t * 100) % 200
if power > 100:
power = 200 - power
return power
def __updatePiePower(self, task):
if not self.__piePowerMeter:
return Task.done
self.__piePowerMeter['value'] = self.__getPiePower(globalClock.getFrameTime())
return Task.cont
def interruptPie(self):
self.cleanupPieInHand()
self.__stopPresentPie()
if self.__piePowerMeter:
self.__piePowerMeter.hide()
pie = self.pieTracks.get(self.__pieSequence)
if pie and pie.getT() < 14.0 / 24.0:
del self.pieTracks[self.__pieSequence]
pie.pause()
def __pieInHand(self):
pie = self.pieTracks.get(self.__pieSequence)
return pie and pie.getT() < 15.0 / 24.0
def __toonMoved(self, isSet):
if isSet:
self.interruptPie()
def localTossPie(self, power):
if not self.__presentingPie:
return
pos = self.getPos()
hpr = self.getHpr()
timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32)
sequence = self.__pieSequence
if self.tossTrack:
tossTrack = self.tossTrack
self.tossTrack = None
tossTrack.finish()
if self.pieTracks.has_key(sequence):
pieTrack = self.pieTracks[sequence]
del self.pieTracks[sequence]
pieTrack.finish()
if self.splatTracks.has_key(sequence):
splatTrack = self.splatTracks[sequence]
del self.splatTracks[sequence]
splatTrack.finish()
self.makePiePowerMeter()
self.__piePowerMeter['value'] = power
self.__piePowerMeter.show()
self.__piePowerMeterSequence = sequence
pieBubble = self.getPieBubble().instanceTo(NodePath())
def pieFlies(self = self, pos = pos, hpr = hpr, sequence = sequence, power = power, timestamp32 = timestamp32, pieBubble = pieBubble):
self.sendUpdate('tossPie', [pos[0],
pos[1],
pos[2],
hpr[0] % 360.0,
hpr[1],
hpr[2],
sequence,
power,
timestamp32])
if self.numPies != ToontownGlobals.FullPies:
self.setNumPies(self.numPies - 1)
base.cTrav.addCollider(pieBubble, self.pieHandler)
toss, pie, flyPie = self.getTossPieInterval(pos[0], pos[1], pos[2], hpr[0], hpr[1], hpr[2], power, beginFlyIval=Func(pieFlies))
pieBubble.reparentTo(flyPie)
flyPie.setTag('pieSequence', str(sequence))
toss = Sequence(toss)
self.tossTrack = toss
toss.start()
pie = Sequence(pie, Func(base.cTrav.removeCollider, pieBubble), Func(self.pieFinishedFlying, sequence))
self.pieTracks[sequence] = pie
pie.start()
return
def pieFinishedFlying(self, sequence):
DistributedToon.DistributedToon.pieFinishedFlying(self, sequence)
if self.__piePowerMeterSequence == sequence:
self.__piePowerMeter.hide()
def __finishPieTrack(self, sequence):
if self.pieTracks.has_key(sequence):
pieTrack = self.pieTracks[sequence]
del self.pieTracks[sequence]
pieTrack.finish()
def __pieHit(self, entry):
if not entry.hasSurfacePoint() or not entry.hasInto():
return
if not entry.getInto().isTangible():
return
sequence = int(entry.getFromNodePath().getNetTag('pieSequence'))
self.__finishPieTrack(sequence)
if self.splatTracks.has_key(sequence):
splatTrack = self.splatTracks[sequence]
del self.splatTracks[sequence]
splatTrack.finish()
pieCode = 0
pieCodeStr = entry.getIntoNodePath().getNetTag('pieCode')
if pieCodeStr:
pieCode = int(pieCodeStr)
pos = entry.getSurfacePoint(render)
timestamp32 = globalClockDelta.getFrameNetworkTime(bits=32)
self.sendUpdate('pieSplat', [pos[0],
pos[1],
pos[2],
sequence,
pieCode,
timestamp32])
splat = self.getPieSplatInterval(pos[0], pos[1], pos[2], pieCode)
splat = Sequence(splat, Func(self.pieFinishedSplatting, sequence))
self.splatTracks[sequence] = splat
splat.start()
messenger.send('pieSplat', [self, pieCode])
messenger.send('localPieSplat', [pieCode, entry])
def beginAllowPies(self):
self.allowPies = 1
self.updatePieButton()
def endAllowPies(self):
self.allowPies = 0
self.updatePieButton()
def makePiePowerMeter(self):
from direct.gui.DirectGui import DirectWaitBar, DGG
if self.__piePowerMeter == None:
self.__piePowerMeter = DirectWaitBar(frameSize=(-0.2,
0.2,
-0.03,
0.03), relief=DGG.SUNKEN, borderWidth=(0.005, 0.005), barColor=(0.4, 0.6, 1.0, 1), pos=(0, 0.1, 0.8))
self.__piePowerMeter.hide()
return
def updatePieButton(self):
from toontown.toonbase import ToontownBattleGlobals
from direct.gui.DirectGui import DirectButton, DGG
wantButton = 0
if self.allowPies and self.numPies > 0:
wantButton = 1
if not launcher.getPhaseComplete(5):
wantButton = 0
haveButton = self.__pieButton != None
if not haveButton and not wantButton:
return
if haveButton and not wantButton:
self.__pieButton.destroy()
self.__pieButton = None
self.__pieButtonType = None
self.__pieButtonCount = None
return
if self.__pieButtonType != self.pieType:
if self.__pieButton:
self.__pieButton.destroy()
self.__pieButton = None
if self.__pieButton == None:
inv = self.inventory
if self.pieType >= len(inv.invModels[ToontownBattleGlobals.THROW_TRACK]):
gui = loader.loadModel('phase_3.5/models/gui/stickerbook_gui')
pieGui = gui.find('**/summons')
pieScale = 0.1
else:
gui = None
pieGui = (inv.invModels[ToontownBattleGlobals.THROW_TRACK][self.pieType],)
pieScale = 0.85
self.__pieButton = DirectButton(image=(inv.upButton, inv.downButton, inv.rolloverButton), geom=pieGui, text='50', text_scale=0.04, text_align=TextNode.ARight, geom_scale=pieScale, geom_pos=(-0.01, 0, 0), text_fg=Vec4(1, 1, 1, 1), text_pos=(0.07, -0.04), relief=None, image_color=(0, 0.6, 1, 1), pos=(0, 0.1, 0.9))
self.__pieButton.bind(DGG.B1PRESS, self.__beginTossPieMouse)
self.__pieButton.bind(DGG.B1RELEASE, self.__endTossPieMouse)
self.__pieButtonType = self.pieType
self.__pieButtonCount = None
if gui:
del gui
if self.__pieButtonCount != self.numPies:
if self.numPies == ToontownGlobals.FullPies:
self.__pieButton['text'] = ''
else:
self.__pieButton['text'] = str(self.numPies)
self.__pieButtonCount = self.numPies
return
def displayWhisper(self, fromId, chatString, whisperType):
sender = None
sfx = self.soundWhisper
if fromId == TTLocalizer.Clarabelle:
chatString = TTLocalizer.Clarabelle + ': ' + chatString
sfx = self.soundPhoneRing
elif fromId != 0:
sender = base.cr.identifyAvatar(fromId)
if whisperType == WhisperPopup.WTNormal or whisperType == WhisperPopup.WTQuickTalker:
if sender == None:
return
chatString = sender.getName() + ': ' + chatString
elif whisperType == WhisperPopup.WTSystem:
sfx = self.soundSystemMessage
whisper = WhisperPopup(chatString, OTPGlobals.getInterfaceFont(), whisperType)
if sender != None:
whisper.setClickable(sender.getName(), fromId)
whisper.manage(base.marginManager)
base.playSfx(sfx)
return
def displaySystemClickableWhisper(self, fromId, chatString, whisperType):
sender = None
sfx = self.soundWhisper
if fromId == TTLocalizer.Clarabelle:
chatString = TTLocalizer.Clarabelle + ': ' + chatString
sfx = self.soundPhoneRing
elif fromId != 0:
sender = base.cr.identifyAvatar(fromId)
if whisperType == WhisperPopup.WTNormal or whisperType == WhisperPopup.WTQuickTalker:
if sender == None:
return
chatString = sender.getName() + ': ' + chatString
elif whisperType == WhisperPopup.WTSystem:
sfx = self.soundSystemMessage
whisper = WhisperPopup(chatString, OTPGlobals.getInterfaceFont(), whisperType)
whisper.setClickable('', fromId)
whisper.manage(base.marginManager)
base.playSfx(sfx)
return
def clickedWhisper(self, doId, isPlayer = None):
if doId > 0:
LocalAvatar.LocalAvatar.clickedWhisper(self, doId, isPlayer)
else:
foundCanStart = False
for partyInfo in self.hostedParties:
if partyInfo.status == PartyGlobals.PartyStatus.CanStart:
foundCanStart = True
break
if base.cr and base.cr.playGame and base.cr.playGame.getPlace() and base.cr.playGame.getPlace().fsm:
fsm = base.cr.playGame.getPlace().fsm
curState = fsm.getCurrentState().getName()
if curState == 'walk':
if hasattr(self, 'eventsPage'):
desiredMode = -1
if doId == -1:
desiredMode = EventsPage.EventsPage_Invited
elif foundCanStart:
desiredMode = EventsPage.EventsPage_Host
if desiredMode >= 0:
self.book.setPage(self.eventsPage)
self.eventsPage.setMode(desiredMode)
fsm.request('stickerBook')
def loadFurnitureGui(self):
if self.__furnitureGui:
return
guiModels = loader.loadModel('phase_5.5/models/gui/house_design_gui')
self.__furnitureGui = DirectFrame(relief=None, pos=(-1.19, 0.0, 0.33), scale=0.04, image=guiModels.find('**/attic'))
DirectLabel(parent=self.__furnitureGui, relief=None, image=guiModels.find('**/rooftile'))
bMoveStartUp = guiModels.find('**/bu_attic/bu_attic_up')
bMoveStartDown = guiModels.find('**/bu_attic/bu_attic_down')
bMoveStartRollover = guiModels.find('**/bu_attic/bu_attic_rollover')
DirectButton(parent=self.__furnitureGui, relief=None, image=[bMoveStartUp,
bMoveStartDown,
bMoveStartRollover,
bMoveStartUp], text=['', TTLocalizer.HDMoveFurnitureButton, TTLocalizer.HDMoveFurnitureButton], text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), pos=(-0.3, 0, 9.4), command=self.__startMoveFurniture)
self.__furnitureGui.hide()
guiModels.removeNode()
return
def showFurnitureGui(self):
self.loadFurnitureGui()
self.__furnitureGui.show()
def hideFurnitureGui(self):
if self.__furnitureGui:
self.__furnitureGui.hide()
def clarabelleNewsPageCollision(self, show = True):
if self.__clarabelleButton == None:
return
claraXPos = ClaraBaseXPos
notifyXPos = CatalogNotifyDialog.CatalogNotifyBaseXPos
if show:
claraXPos += AdjustmentForNewsButton
notifyXPos += AdjustmentForNewsButton
newPos = (claraXPos - 0.1, 1.0, 0.45)
self.__clarabelleButton.setPos(newPos)
if self.__catalogNotifyDialog == None or self.__catalogNotifyDialog.frame == None:
return
notifyPos = self.__catalogNotifyDialog.frame.getPos()
notifyPos[0] = notifyXPos
self.__catalogNotifyDialog.frame.setPos(notifyPos)
return
def loadClarabelleGui(self):
if self.__clarabelleButton:
return
guiItems = loader.loadModel('phase_5.5/models/gui/catalog_gui')
circle = guiItems.find('**/cover/blue_circle')
icon = guiItems.find('**/cover/clarabelle')
icon.reparentTo(circle)
rgba = VBase4(0.71589, 0.784547, 0.974, 1.0)
white = VBase4(1.0, 1.0, 1.0, 1.0)
icon.setColor(white)
claraXPos = ClaraBaseXPos
newScale = oldScale = 0.5
newPos = (claraXPos, 1.0, 0.37)
if WantNewsPage:
claraXPos += AdjustmentForNewsButton
oldPos = ((claraXPos, 1.0, 0.37),)
newScale = oldScale * ToontownGlobals.NewsPageScaleAdjust
newPos = (claraXPos - 0.1, 1.0, 0.45)
self.__clarabelleButton = DirectButton(relief=None, image=circle, text='', text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_scale=0.1, text_pos=(-1.06, 1.06), text_font=ToontownGlobals.getInterfaceFont(), pos=newPos, scale=newScale, command=self.__handleClarabelleButton)
self.__clarabelleButton.reparentTo(aspect2d, DGG.BACKGROUND_SORT_INDEX - 1)
button = self.__clarabelleButton.stateNodePath[0]
self.__clarabelleFlash = Sequence(LerpColorInterval(button, 2, white, blendType='easeInOut'), LerpColorInterval(button, 2, rgba, blendType='easeInOut'))
self.__clarabelleFlash.loop()
self.__clarabelleFlash.pause()
return
def showClarabelleGui(self, mailboxItems):
self.loadClarabelleGui()
if mailboxItems:
self.__clarabelleButton['text'] = ['', TTLocalizer.CatalogNewDeliveryButton, TTLocalizer.CatalogNewDeliveryButton]
else:
self.__clarabelleButton['text'] = ['', TTLocalizer.CatalogNewCatalogButton, TTLocalizer.CatalogNewCatalogButton]
if not self.mailboxNotify and not self.awardNotify and self.catalogNotify == ToontownGlobals.OldItems and (self.simpleMailNotify != ToontownGlobals.NoItems or self.inviteMailNotify != ToontownGlobals.NoItems):
self.__clarabelleButton['text'] = ['', TTLocalizer.MailNewMailButton, TTLocalizer.MailNewMailButton]
if self.newsButtonMgr.isNewIssueButtonShown():
self.clarabelleNewsPageCollision(True)
self.__clarabelleButton.show()
self.__clarabelleFlash.resume()
def hideClarabelleGui(self):
if self.__clarabelleButton:
self.__clarabelleButton.hide()
self.__clarabelleFlash.pause()
def __handleClarabelleButton(self):
self.stopMoveFurniture()
place = base.cr.playGame.getPlace()
if place == None:
self.notify.warning('Tried to go home, but place is None.')
return
if self.__catalogNotifyDialog:
self.__catalogNotifyDialog.cleanup()
self.__catalogNotifyDialog = None
if base.config.GetBool('want-qa-regression', 0):
self.notify.info('QA-REGRESSION: VISITESTATE: Visit estate')
place.goHomeNow(self.lastHood)
return
def __startMoveFurniture(self):
self.oldPos = self.getPos()
if base.config.GetBool('want-qa-regression', 0):
self.notify.info('QA-REGRESSION: ESTATE: Furniture Placement')
if self.cr.furnitureManager != None:
self.cr.furnitureManager.d_suggestDirector(self.doId)
elif self.furnitureManager != None:
self.furnitureManager.d_suggestDirector(self.doId)
return
def stopMoveFurniture(self):
if self.oldPos:
self.setPos(self.oldPos)
if self.furnitureManager != None:
self.furnitureManager.d_suggestDirector(0)
return
def setFurnitureDirector(self, avId, furnitureManager):
if avId == 0:
if self.furnitureManager == furnitureManager:
messenger.send('exitFurnitureMode', [furnitureManager])
self.furnitureManager = None
self.furnitureDirector = None
elif avId != self.doId:
if self.furnitureManager == None or self.furnitureDirector != avId:
self.furnitureManager = furnitureManager
self.furnitureDirector = avId
messenger.send('enterFurnitureMode', [furnitureManager, 0])
else:
if self.furnitureManager != None:
messenger.send('exitFurnitureMode', [self.furnitureManager])
self.furnitureManager = None
self.furnitureManager = furnitureManager
self.furnitureDirector = avId
messenger.send('enterFurnitureMode', [furnitureManager, 1])
self.refreshOnscreenButtons()
return
def getAvPosStr(self):
pos = self.getPos()
hpr = self.getHpr()
serverVersion = base.cr.getServerVersion()
districtName = base.cr.getShardName(base.localAvatar.defaultShard)
if hasattr(base.cr.playGame.hood, 'loader') and hasattr(base.cr.playGame.hood.loader, 'place') and base.cr.playGame.getPlace() != None:
zoneId = base.cr.playGame.getPlace().getZoneId()
else:
zoneId = '?'
strPosCoordText = 'X: %.3f' % pos[0] + ', Y: %.3f' % pos[1] + '\nZ: %.3f' % pos[2] + ', H: %.3f' % hpr[0] + '\nZone: %s' % str(zoneId) + ', Ver: %s, ' % serverVersion + 'District: %s' % districtName
return strPosCoordText
self.refreshOnscreenButtons()
return
def thinkPos(self):
pos = self.getPos()
hpr = self.getHpr()
serverVersion = base.cr.getServerVersion()
districtName = base.cr.getShardName(base.localAvatar.defaultShard)
if hasattr(base.cr.playGame.hood, 'loader') and hasattr(base.cr.playGame.hood.loader, 'place') and base.cr.playGame.getPlace() != None:
zoneId = base.cr.playGame.getPlace().getZoneId()
else:
zoneId = '?'
strPos = '(%.3f' % pos[0] + '\n %.3f' % pos[1] + '\n %.3f)' % pos[2] + '\nH: %.3f' % hpr[0] + '\nZone: %s' % str(zoneId) + ',\nVer: %s, ' % serverVersion + '\nDistrict: %s' % districtName
print 'Current position=', strPos.replace('\n', ', ')
self.setChatAbsolute(strPos, CFThought | CFTimeout)
return
def __placeMarker(self):
pos = self.getPos()
hpr = self.getHpr()
chest = loader.loadModel('phase_4/models/props/coffin')
chest.reparentTo(render)
chest.setColor(1, 0, 0, 1)
chest.setPosHpr(pos, hpr)
chest.setScale(0.5)
def setFriendsListButtonActive(self, active):
self.friendsListButtonActive = active
self.refreshOnscreenButtons()
def obscureFriendsListButton(self, increment):
self.friendsListButtonObscured += increment
self.refreshOnscreenButtons()
def obscureMoveFurnitureButton(self, increment):
self.moveFurnitureButtonObscured += increment
self.refreshOnscreenButtons()
def obscureClarabelleButton(self, increment):
self.clarabelleButtonObscured += increment
self.refreshOnscreenButtons()
def refreshOnscreenButtons(self):
self.bFriendsList.hide()
self.hideFurnitureGui()
self.hideClarabelleGui()
clarabelleHidden = 1
self.ignore(ToontownGlobals.FriendsListHotkey)
if self.friendsListButtonActive and self.friendsListButtonObscured <= 0:
self.bFriendsList.show()
self.accept(ToontownGlobals.FriendsListHotkey, self.sendFriendsListEvent)
if self.clarabelleButtonObscured <= 0 and self.isTeleportAllowed():
if self.catalogNotify == ToontownGlobals.NewItems or self.mailboxNotify == ToontownGlobals.NewItems or self.simpleMailNotify == ToontownGlobals.NewItems or self.inviteMailNotify == ToontownGlobals.NewItems or self.awardNotify == ToontownGlobals.NewItems:
showClarabelle = not launcher or launcher.getPhaseComplete(5.5)
for quest in self.quests:
if quest[0] in Quests.PreClarabelleQuestIds and self.mailboxNotify != ToontownGlobals.NewItems and self.awardNotify != ToontownGlobals.NewItems:
showClarabelle = 0
if base.cr.playGame.getPlace().getState() == 'stickerBook':
showClarabelle = 0
if showClarabelle:
newItemsInMailbox = self.mailboxNotify == ToontownGlobals.NewItems or self.awardNotify == ToontownGlobals.NewItems
self.showClarabelleGui(newItemsInMailbox)
clarabelleHidden = 0
if clarabelleHidden:
if self.__catalogNotifyDialog:
self.__catalogNotifyDialog.cleanup()
self.__catalogNotifyDialog = None
else:
self.newCatalogNotify()
if self.moveFurnitureButtonObscured <= 0:
if self.furnitureManager != None and self.furnitureDirector == self.doId:
self.loadFurnitureGui()
self.__furnitureGui.setPos(-1.16, 0, -0.03)
self.__furnitureGui.setScale(0.06)
elif self.cr.furnitureManager != None:
self.showFurnitureGui()
taskMgr.remove('lerpFurnitureButton')
self.__furnitureGui.lerpPosHprScale(pos=Point3(-1.19, 0.0, 0.33), hpr=Vec3(0.0, 0.0, 0.0), scale=Vec3(0.04, 0.04, 0.04), time=1.0, blendType='easeInOut', task='lerpFurnitureButton')
if hasattr(self, 'inEstate') and self.inEstate:
self.loadGardeningGui()
self.hideGardeningGui()
else:
self.hideGardeningGui()
return
def setGhostMode(self, flag):
if flag == 2:
self.seeGhosts = 1
DistributedToon.DistributedToon.setGhostMode(self, flag)
def newCatalogNotify(self):
if not self.gotCatalogNotify:
return
hasPhase = not launcher or launcher.getPhaseComplete(5.5)
if not hasPhase:
return
if not self.friendsListButtonActive or self.friendsListButtonObscured > 0:
return
self.gotCatalogNotify = 0
currentWeek = self.catalogScheduleCurrentWeek - 1
if currentWeek < 57:
seriesNumber = currentWeek / ToontownGlobals.CatalogNumWeeksPerSeries + 1
weekNumber = currentWeek % ToontownGlobals.CatalogNumWeeksPerSeries + 1
elif currentWeek < 65:
seriesNumber = 6
weekNumber = currentWeek - 56
else:
seriesNumber = currentWeek / ToontownGlobals.CatalogNumWeeksPerSeries + 2
weekNumber = currentWeek % ToontownGlobals.CatalogNumWeeksPerSeries + 1
message = None
if self.mailboxNotify == ToontownGlobals.NoItems:
if self.catalogNotify == ToontownGlobals.NewItems:
if self.catalogScheduleCurrentWeek == 1:
message = (TTLocalizer.CatalogNotifyFirstCatalog, TTLocalizer.CatalogNotifyInstructions)
else:
message = (TTLocalizer.CatalogNotifyNewCatalog % weekNumber,)
elif self.mailboxNotify == ToontownGlobals.NewItems:
if self.catalogNotify == ToontownGlobals.NewItems:
message = (TTLocalizer.CatalogNotifyNewCatalogNewDelivery % weekNumber,)
else:
message = (TTLocalizer.CatalogNotifyNewDelivery,)
elif self.mailboxNotify == ToontownGlobals.OldItems:
if self.catalogNotify == ToontownGlobals.NewItems:
message = (TTLocalizer.CatalogNotifyNewCatalogOldDelivery % weekNumber,)
else:
message = (TTLocalizer.CatalogNotifyOldDelivery,)
if self.awardNotify == ToontownGlobals.NoItems:
pass
elif self.awardNotify == ToontownGlobals.NewItems:
oldStr = ''
if message:
oldStr = message[0] + ' '
oldStr += TTLocalizer.AwardNotifyNewItems
message = (oldStr,)
elif self.awardNotify == ToontownGlobals.OldItems:
oldStr = ''
if message:
oldStr = message[0] + ' '
oldStr += TTLocalizer.AwardNotifyOldItems
message = (oldStr,)
if self.simpleMailNotify == ToontownGlobals.NewItems or self.inviteMailNotify == ToontownGlobals.NewItems:
oldStr = ''
if message:
oldStr = message[0] + ' '
oldStr += TTLocalizer.MailNotifyNewItems
message = (oldStr,)
if message == None:
return
if self.__catalogNotifyDialog:
self.__catalogNotifyDialog.cleanup()
self.__catalogNotifyDialog = CatalogNotifyDialog.CatalogNotifyDialog(message)
base.playSfx(self.soundPhoneRing)
return
def allowHardLand(self):
retval = LocalAvatar.LocalAvatar.allowHardLand(self)
return retval and not self.isDisguised
def setShovelGuiLevel(self, level = 0):
pass
def setWateringCanGuiLevel(self, level = 0):
pass
def loadGardeningGui(self):
if self.__gardeningGui:
return
gardenGuiCard = loader.loadModel('phase_5.5/models/gui/planting_gui')
self.__gardeningGui = DirectFrame(relief=None, geom=gardenGuiCard, geom_color=GlobalDialogColor, geom_scale=(0.17, 1.0, 0.3), pos=(-1.2, 0, 0.5), scale=1.0)
self.__gardeningGui.setName('gardeningFrame')
self.__gardeningGuiFake = DirectFrame(relief=None, geom=None, geom_color=GlobalDialogColor, geom_scale=(0.17, 1.0, 0.3), pos=(-1.2, 0, 0.5), scale=1.0)
self.__gardeningGuiFake.setName('gardeningFrameFake')
iconScale = 1
iconColorWhite = Vec4(1.0, 1.0, 1.0, 1.0)
iconColorGrey = Vec4(0.7, 0.7, 0.7, 1.0)
iconColorBrown = Vec4(0.7, 0.4, 0.3, 1.0)
iconColorBlue = Vec4(0.2, 0.3, 1.0, 1.0)
shovelCardP = loader.loadModel('phase_5.5/models/gui/planting_but_shovel_P')
shovelCardY = loader.loadModel('phase_5.5/models/gui/planting_but_shovel_Y')
wateringCanCardP = loader.loadModel('phase_5.5/models/gui/planting_but_can_P')
wateringCanCardY = loader.loadModel('phase_5.5/models/gui/planting_but_can_Y')
backCard = loader.loadModel('phase_5.5/models/gui/planting_gui')
iconImage = None
iconModels = loader.loadModel('phase_3.5/models/gui/sos_textures')
iconGeom = iconModels.find('**/fish')
buttonText = TTLocalizer.GardeningPlant
self.shovelText = ('',
'',
buttonText,
'')
self.__shovelButtonFake = DirectLabel(parent=self.__gardeningGuiFake, relief=None, text=self.shovelText, text_align=TextNode.ALeft, text_pos=(0.0, -0.0), text_scale=0.07, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image_scale=(0.18, 1.0, 0.36), geom=None, geom_scale=iconScale, geom_color=iconColorWhite, pos=(0.15, 0, 0.2), scale=0.775)
self.shovelButtonFake = self.__shovelButtonFake
self.shovelText = ('',
'',
buttonText,
'')
self.__shovelButton = DirectButton(parent=self.__gardeningGui, relief=None, text=self.shovelText, text_align=TextNode.ACenter, text_pos=(0.0, -0.0), text_scale=0.1, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image=(shovelCardP,
shovelCardY,
shovelCardY,
shovelCardY), image_scale=(0.18, 1.0, 0.36), geom=None, geom_scale=iconScale, geom_color=iconColorWhite, pos=(0, 0, 0.2), scale=0.775, command=self.__shovelButtonClicked)
self.shovelButton = self.__shovelButton
iconGeom = iconModels.find('**/teleportIcon')
buttonText = TTLocalizer.GardeningWater
self.waterText = (buttonText,
buttonText,
buttonText,
'')
self.__wateringCanButtonFake = DirectLabel(parent=self.__gardeningGuiFake, relief=None, text=self.waterText, text_align=TextNode.ALeft, text_pos=(0.0, -0.0), text_scale=0.07, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image_scale=(0.18, 1.0, 0.36), geom=None, geom_scale=iconScale, geom_color=iconColorWhite, pos=(0.15, 0, 0.01), scale=0.775)
self.wateringCanButtonFake = self.__wateringCanButtonFake
self.__wateringCanButton = DirectButton(parent=self.__gardeningGui, relief=None, text=self.waterText, text_align=TextNode.ACenter, text_pos=(0.0, -0.0), text_scale=0.1, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image=(wateringCanCardP,
wateringCanCardY,
wateringCanCardY,
wateringCanCardY), image_scale=(0.18, 1.0, 0.36), geom=None, geom_scale=iconScale, geom_color=iconColorWhite, pos=(0, 0, 0.01), scale=0.775, command=self.__wateringCanButtonClicked)
self.wateringCanButton = self.__wateringCanButton
self.basketText = '%s / %s' % (self.numFlowers, self.maxFlowerBasket)
self.basketButton = DirectLabel(parent=self.__gardeningGui, relief=None, text=self.basketText, text_align=TextNode.ALeft, text_pos=(0.82, -1.4), text_scale=0.2, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image=None, image_scale=iconScale, geom=None, geom_scale=iconScale, geom_color=iconColorWhite, pos=(-0.34, 0, 0.16), scale=0.3, textMayChange=1)
if hasattr(self, 'shovel'):
self.setShovelGuiLevel(self.shovel)
if hasattr(self, 'wateringCan'):
self.setWateringCanGuiLevel(self.wateringCan)
self.__shovelButton.hide()
self.__wateringCanButton.hide()
self.__shovelButtonFake.hide()
self.__wateringCanButtonFake.hide()
return
def changeButtonText(self, button, text):
button['text'] = text
def resetWaterText(self):
self.wateringCanButton['text'] = self.waterText
def resetShovelText(self):
self.shovelButton['text'] = self.holdShovelText
def showGardeningGui(self):
self.loadGardeningGui()
self.__gardeningGui.show()
base.setCellsAvailable([base.leftCells[2]], 0)
def hideGardeningGui(self):
if self.__gardeningGui:
self.__gardeningGui.hide()
base.setCellsAvailable([base.leftCells[2]], 1)
def showShovelButton(self, add = 0):
if add:
self.shovelButtonActiveCount += add
else:
self.showingShovel = 1
self.notify.debug('showing shovel %s' % self.shovelButtonActiveCount)
self.__gardeningGui.show()
self.__shovelButton.show()
def hideShovelButton(self, deduct = 0):
self.shovelButtonActiveCount -= deduct
if deduct == 0:
self.showingShovel = 0
if self.shovelButtonActiveCount < 1:
self.shovelButtonActiveCount = 0
if self.showingShovel == 0:
self.__shovelButton.hide()
self.handleAllGardeningButtonsHidden()
self.notify.debug('hiding shovel %s' % self.shovelButtonActiveCount)
def showWateringCanButton(self, add = 0):
if add:
self.wateringCanButtonActiveCount += add
else:
self.showingWateringCan = 1
self.__gardeningGui.show()
self.__wateringCanButton.show()
self.basketButton.show()
def hideWateringCanButton(self, deduct = 0):
self.wateringCanButtonActiveCount -= deduct
if deduct == 0:
self.showingWateringCan = 0
if self.wateringCanButtonActiveCount < 1:
wateringCanButtonActiveCount = 0
if self.showingWateringCan == 0:
self.__wateringCanButton.hide()
self.handleAllGardeningButtonsHidden()
def showWateringCanButtonFake(self, add = 0):
self.__wateringCanButtonFake.show()
def hideWateringCanButtonFake(self, deduct = 0):
self.__wateringCanButtonFake.hide()
def showShovelButtonFake(self, add = 0):
self.__shovelButtonFake.show()
def hideShovelButtonFake(self, deduct = 0):
self.__shovelButtonFake.hide()
def levelWater(self, change = 1):
if change < 0:
return
self.showWateringCanButtonFake(1)
if change < 1:
changeString = TTLocalizer.GardeningNoSkill
else:
changeString = '+%s %s' % (change, TTLocalizer.GardeningWaterSkill)
self.waterTrack = Sequence(Wait(0.0), Func(self.changeButtonText, self.wateringCanButtonFake, changeString), SoundInterval(globalBattleSoundCache.getSound('GUI_balloon_popup.mp3'), node=self), Wait(1.0), Func(self.hideWateringCanButtonFake, 1))
self.waterTrack.start()
def levelShovel(self, change = 1):
if change < 1:
return
self.showShovelButtonFake(1)
if change < 1:
changeString = TTLocalizer.GardeningNoSkill
else:
changeString = '+%s %s' % (change, TTLocalizer.GardeningShovelSkill)
plant = base.cr.doId2do.get(self.shovelRelatedDoId)
if plant:
self.holdShovelText = plant.getShovelAction()
self.shovelTrack = Sequence(Wait(0.0), Func(self.changeButtonText, self.shovelButtonFake, changeString), SoundInterval(globalBattleSoundCache.getSound('GUI_balloon_popup.mp3'), node=self), Wait(1.0), Func(self.hideShovelButtonFake, 1))
self.shovelTrack.start()
def setGuiConflict(self, con):
self.guiConflict = con
def getGuiConflict(self, con):
return self.guiConflict
def verboseState(self):
self.lastPlaceState = 'None'
taskMgr.add(self.__expressState, 'expressState', extraArgs=[])
def __expressState(self, task = None):
place = base.cr.playGame.getPlace()
if place:
state = place.fsm.getCurrentState()
if state.getName() != self.lastPlaceState:
print 'Place State Change From %s to %s' % (self.lastPlaceState, state.getName())
self.lastPlaceState = state.getName()
return Task.cont
def addShovelRelatedDoId(self, doId):
if hasattr(base.cr.playGame.getPlace(), 'detectedGardenPlotDone'):
place = base.cr.playGame.getPlace()
state = place.fsm.getCurrentState()
if state.getName() == 'stopped':
return
self.touchingPlantList.append(doId)
self.autoSetActivePlot()
def removeShovelRelatedDoId(self, doId):
if doId in self.touchingPlantList:
self.touchingPlantList.remove(doId)
self.autoSetActivePlot()
def autoSetActivePlot(self):
if self.guiConflict:
return
if len(self.touchingPlantList) > 0:
minDist = 10000
minDistPlot = 0
for plot in self.touchingPlantList:
plant = base.cr.doId2do.get(plot)
if plant:
if self.getDistance(plant) < minDist:
minDist = self.getDistance(plant)
minDistPlot = plot
else:
self.touchingPlantList.remove(plot)
if len(self.touchingPlantList) == 0:
self.setActivePlot(None)
else:
self.setActivePlot(minDistPlot)
else:
self.setActivePlot(None)
return
def setActivePlot(self, doId):
if not self.gardenStarted:
return
self.shovelRelatedDoId = doId
plant = base.cr.doId2do.get(doId)
if plant:
self.startStareAt(plant, Point3(0, 0, 1))
self.__shovelButton['state'] = DGG.NORMAL
if not plant.canBePicked():
self.hideShovelButton()
else:
self.showShovelButton()
self.setShovelAbility(TTLocalizer.GardeningPlant)
if plant.getShovelAction():
self.setShovelAbility(plant.getShovelAction())
if plant.getShovelAction() == TTLocalizer.GardeningPick:
if not plant.unlockPick():
self.__shovelButton['state'] = DGG.DISABLED
self.setShovelAbility(TTLocalizer.GardeningFull)
self.notify.debug('self.shovelRelatedDoId = %d' % self.shovelRelatedDoId)
if plant.getShovelCommand():
self.extraShovelCommand = plant.getShovelCommand()
self.__shovelButton['command'] = self.__shovelButtonClicked
if plant.canBeWatered():
self.showWateringCanButton()
else:
self.hideWateringCanButton()
else:
self.stopStareAt()
self.shovelRelatedDoId = 0
if self.__shovelButton:
self.__shovelButton['command'] = None
self.hideShovelButton()
self.hideWateringCanButton()
self.handleAllGardeningButtonsHidden()
if not self.inGardenAction:
if hasattr(base.cr.playGame.getPlace(), 'detectedGardenPlotDone'):
place = base.cr.playGame.getPlace()
if place:
place.detectedGardenPlotDone()
return
def setPlantToWater(self, plantId):
import pdb
pdb.set_trace()
if self.plantToWater == None:
self.plantToWater = plantId
self.notify.debug('setting plant to water %s' % plantId)
return
def clearPlantToWater(self, plantId):
if not hasattr(self, 'secondaryPlant'):
self.secondaryWaterPlant = None
if self.plantToWater == plantId:
self.plantToWater = None
self.hideWateringCanButton()
return
def hasPlant(self):
if self.plantToWater != None:
return 1
else:
return 0
return
def handleAllGardeningButtonsHidden(self):
somethingVisible = False
if not self.__shovelButton.isHidden():
somethingVisible = True
if not self.__wateringCanButton.isHidden():
somethingVisible = True
if not somethingVisible:
self.hideGardeningGui()
def setShovelAbility(self, ability):
self.shovelAbility = ability
if self.__shovelButton:
self.__shovelButton['text'] = ability
def setFlowerBasket(self, speciesList, varietyList):
DistributedToon.DistributedToon.setFlowerBasket(self, speciesList, varietyList)
self.numFlowers = len(self.flowerBasket.flowerList)
self.maxFlowerBasket
if hasattr(self, 'basketButton'):
self.basketText = '%s / %s' % (self.numFlowers, self.maxFlowerBasket)
self.basketButton['text'] = self.basketText
def setShovelSkill(self, skillLevel):
if hasattr(self, 'shovelSkill') and hasattr(self, 'shovelButton'):
if self.shovelSkill != None:
self.levelShovel(skillLevel - self.shovelSkill)
oldShovelSkill = self.shovelSkill
DistributedToon.DistributedToon.setShovelSkill(self, skillLevel)
if hasattr(self, 'shovel'):
oldShovelPower = GardenGlobals.getShovelPower(self.shovel, oldShovelSkill)
newShovelPower = GardenGlobals.getShovelPower(self.shovel, self.shovelSkill)
almostMaxedSkill = GardenGlobals.ShovelAttributes[GardenGlobals.MAX_SHOVELS - 1]['skillPts'] - 2
if skillLevel >= GardenGlobals.ShovelAttributes[self.shovel]['skillPts']:
self.promoteShovel()
elif oldShovelSkill and oldShovelPower < newShovelPower:
self.promoteShovelSkill(self.shovel, self.shovelSkill)
elif oldShovelSkill == almostMaxedSkill and newShovelPower == GardenGlobals.getNumberOfShovelBoxes():
self.promoteShovelSkill(self.shovel, self.shovelSkill)
return
def setWateringCanSkill(self, skillLevel):
skillDelta = skillLevel - self.wateringCanSkill
if skillDelta or 1:
if hasattr(self, 'wateringCanSkill') and hasattr(self, 'wateringCanButton'):
if self.wateringCanSkill != None:
self.levelWater(skillDelta)
DistributedToon.DistributedToon.setWateringCanSkill(self, skillLevel)
if hasattr(self, 'wateringCan'):
if skillLevel >= GardenGlobals.WateringCanAttributes[self.wateringCan]['skillPts']:
self.promoteWateringCan()
return
def unlockGardeningButtons(self, task = None):
if hasattr(self, '_LocalToon__shovelButton'):
try:
self.__shovelButton['state'] = DGG.NORMAL
except TypeError:
self.notify.warning('Could not unlock the shovel button- Type Error')
if hasattr(self, '_LocalToon__wateringCanButton'):
try:
self.__wateringCanButton['state'] = DGG.NORMAL
except TypeError:
self.notify.warning('Could not unlock the watering can button - Type Error')
taskMgr.remove('unlockGardenButtons')
return None
def lockGardeningButtons(self, task = None):
if hasattr(self, '_LocalToon__shovelButton'):
try:
self.__shovelButton['state'] = DGG.DISABLED
except TypeError:
self.notify.warning('Could not lock the shovel button- Type Error')
if hasattr(self, '_LocalToon__wateringCanButton'):
try:
self.__wateringCanButton['state'] = DGG.DISABLED
except TypeError:
self.notify.warning('Could not lock the watering can button - Type Error')
self.accept('endPlantInteraction', self.__handleEndPlantInteraction)
return None
def reactivateShovel(self, task = None):
if hasattr(self, '_LocalToon__shovelButton'):
self.__shovelButton['state'] = DGG.NORMAL
taskMgr.remove('reactShovel')
return None
def reactivateWater(self, task = None):
if hasattr(self, '_LocalToon__wateringCanButton'):
self.__wateringCanButton['state'] = DGG.NORMAL
taskMgr.remove('reactWater')
return None
def handleEndPlantInteraction(self, object = None, replacement = 0):
if not replacement:
self.setInGardenAction(None, object)
self.autoSetActivePlot()
return
def __handleEndPlantInteraction(self, task = None):
self.setInGardenAction(None)
self.autoSetActivePlot()
return
def promoteShovelSkill(self, shovelLevel, shovelSkill):
shovelName = GardenGlobals.ShovelAttributes[shovelLevel]['name']
shovelBeans = GardenGlobals.getShovelPower(shovelLevel, shovelSkill)
oldShovelBeans = GardenGlobals.getShovelPower(shovelLevel, shovelSkill - 1)
doPartyBall = False
message = TTLocalizer.GardenShovelSkillLevelUp % {'shovel': shovelName,
'oldbeans': oldShovelBeans,
'newbeans': shovelBeans}
if shovelBeans == GardenGlobals.getNumberOfShovelBoxes():
if shovelSkill == GardenGlobals.ShovelAttributes[shovelLevel]['skillPts'] - 1:
doPartyBall = True
message = TTLocalizer.GardenShovelSkillMaxed % {'shovel': shovelName,
'oldbeans': oldShovelBeans,
'newbeans': shovelBeans}
messagePos = Vec2(0, 0.2)
messageScale = 0.07
image = loader.loadModel('phase_5.5/models/gui/planting_but_shovel_P')
imagePos = Vec3(0, 0, -0.13)
imageScale = Vec3(0.28, 0, 0.56)
if doPartyBall:
go = Fanfare.makeFanfareWithMessageImage(0, base.localAvatar, 1, message, Vec2(0, 0.2), 0.08, image, Vec3(0, 0, -0.1), Vec3(0.35, 0, 0.7), wordwrap=23)
Sequence(go[0], Func(go[1].show), LerpColorScaleInterval(go[1], duration=0.5, startColorScale=Vec4(1, 1, 1, 0), colorScale=Vec4(1, 1, 1, 1)), Wait(10), LerpColorScaleInterval(go[1], duration=0.5, startColorScale=Vec4(1, 1, 1, 1), colorScale=Vec4(1, 1, 1, 0)), Func(go[1].remove)).start()
else:
go = Fanfare.makePanel(base.localAvatar, 1)
Fanfare.makeMessageBox(go, message, messagePos, messageScale, wordwrap=24)
Fanfare.makeImageBox(go.itemFrame, image, imagePos, imageScale)
Sequence(Func(go.show), LerpColorScaleInterval(go, duration=0.5, startColorScale=Vec4(1, 1, 1, 0), colorScale=Vec4(1, 1, 1, 1)), Wait(10), LerpColorScaleInterval(go, duration=0.5, startColorScale=Vec4(1, 1, 1, 1), colorScale=Vec4(1, 1, 1, 0)), Func(go.remove)).start()
def promoteShovel(self, shovelLevel = 0):
shovelName = GardenGlobals.ShovelAttributes[shovelLevel]['name']
shovelBeans = GardenGlobals.getShovelPower(shovelLevel, 0)
message = TTLocalizer.GardenShovelLevelUp % {'shovel': shovelName,
'oldbeans': shovelBeans - 1,
'newbeans': shovelBeans}
messagePos = Vec2(0, 0.2)
messageScale = 0.07
image = loader.loadModel('phase_5.5/models/gui/planting_but_shovel_P')
imagePos = Vec3(0, 0, -0.13)
imageScale = Vec3(0.28, 0, 0.56)
go = Fanfare.makePanel(base.localAvatar, 1)
Fanfare.makeMessageBox(go, message, messagePos, messageScale, wordwrap=24)
Fanfare.makeImageBox(go.itemFrame, image, imagePos, imageScale)
Sequence(Func(go.show), LerpColorScaleInterval(go, duration=0.5, startColorScale=Vec4(1, 1, 1, 0), colorScale=Vec4(1, 1, 1, 1)), Wait(10), LerpColorScaleInterval(go, duration=0.5, startColorScale=Vec4(1, 1, 1, 1), colorScale=Vec4(1, 1, 1, 0)), Func(go.remove)).start()
def promoteWateringCan(self, wateringCanlevel = 0):
message = TTLocalizer.GardenWateringCanLevelUp + ' \n' + GardenGlobals.WateringCanAttributes[wateringCanlevel]['name']
messagePos = Vec2(0, 0.2)
messageScale = 0.08
image = loader.loadModel('phase_5.5/models/gui/planting_but_can_P')
imagePos = Vec3(0, 0, -0.1)
imageScale = Vec3(0.35, 0, 0.7)
if wateringCanlevel >= GardenGlobals.MAX_WATERING_CANS - 1:
go = Fanfare.makeFanfareWithMessageImage(0, base.localAvatar, 1, message, Vec2(0, 0.2), 0.08, image, Vec3(0, 0, -0.1), Vec3(0.35, 0, 0.7))
Sequence(go[0], Func(go[1].show), LerpColorScaleInterval(go[1], duration=0.5, startColorScale=Vec4(1, 1, 1, 0), colorScale=Vec4(1, 1, 1, 1)), Wait(5), LerpColorScaleInterval(go[1], duration=0.5, startColorScale=Vec4(1, 1, 1, 1), colorScale=Vec4(1, 1, 1, 0)), Func(go[1].remove)).start()
else:
go = Fanfare.makePanel(base.localAvatar, 1)
Fanfare.makeMessageBox(go, message, messagePos, messageScale)
Fanfare.makeImageBox(go.itemFrame, image, imagePos, imageScale)
Sequence(Func(go.show), LerpColorScaleInterval(go, duration=0.5, startColorScale=Vec4(1, 1, 1, 0), colorScale=Vec4(1, 1, 1, 1)), Wait(5), LerpColorScaleInterval(go, duration=0.5, startColorScale=Vec4(1, 1, 1, 1), colorScale=Vec4(1, 1, 1, 0)), Func(go.remove)).start()
def setInGardenAction(self, actionObject, fromObject = None):
if actionObject:
self.lockGardeningButtons()
elif fromObject:
self.unlockGardeningButtons()
else:
self.unlockGardeningButtons()
self.inGardenAction = actionObject
def __wateringCanButtonClicked(self):
self.notify.debug('wateringCanButtonClicked')
if self.inGardenAction:
return
plant = base.cr.doId2do.get(self.shovelRelatedDoId)
if plant:
if hasattr(plant, 'handleWatering'):
plant.handleWatering()
messenger.send('wakeup')
def __shovelButtonClicked(self):
if self.inGardenAction:
return
self.notify.debug('shovelButtonClicked')
messenger.send('wakeup')
thingId = self.shovelRelatedDoId
thing = base.cr.doId2do.get(thingId)
if hasattr(self, 'extraShovelCommand'):
self.extraShovelCommand()
self.setActivePlot(thingId)
def setShovel(self, shovelId):
DistributedToon.DistributedToon.setShovel(self, shovelId)
if self.__gardeningGui:
self.setShovelGuiLevel(shovelId)
def setWateringCan(self, wateringCanId):
DistributedToon.DistributedToon.setWateringCan(self, wateringCanId)
if self.__gardeningGui:
self.setWateringCanGuiLevel(wateringCanId)
def setGardenStarted(self, bStarted):
self.gardenStarted = bStarted
if self.gardenStarted and not self.gardenPage and hasattr(self, 'book'):
self.loadGardenPages()
def b_setAnimState(self, animName, animMultiplier = 1.0, callback = None, extraArgs = []):
if self.wantStatePrint:
print 'Local Toon Anim State %s' % animName
DistributedToon.DistributedToon.b_setAnimState(self, animName, animMultiplier, callback, extraArgs)
def swimTimeoutAction(self):
self.ignore('wakeup')
self.takeOffSuit()
base.cr.playGame.getPlace().fsm.request('final')
self.b_setAnimState('TeleportOut', 1, self.__handleSwimExitTeleport, [0])
return Task.done
def __handleSwimExitTeleport(self, requestStatus):
self.notify.info('closing shard...')
base.cr.gameFSM.request('closeShard', ['afkTimeout'])
def sbFriendAdd(self, id, info):
print 'sbFriendAdd'
def sbFriendUpdate(self, id, info):
print 'sbFriendUpdate'
def sbFriendRemove(self, id):
print 'sbFriendRemove'
def addGolfPage(self):
if self.hasPlayedGolf():
if hasattr(self, 'golfPage') and self.golfPage != None:
return
if not launcher.getPhaseComplete(6):
self.acceptOnce('phaseComplete-6', self.addGolfPage)
return
self.golfPage = GolfPage.GolfPage()
self.golfPage.setAvatar(self)
self.golfPage.load()
self.book.addPage(self.golfPage, pageName=TTLocalizer.GolfPageTitle)
return
def addEventsPage(self):
if hasattr(self, 'eventsPage') and self.eventsPage != None:
return
if not launcher.getPhaseComplete(4):
self.acceptOnce('phaseComplete-4', self.addEventsPage)
return
self.eventsPage = EventsPage.EventsPage()
self.eventsPage.load()
self.book.addPage(self.eventsPage, pageName=TTLocalizer.EventsPageName)
return
def addNewsPage(self):
self.newsPage = NewsPage.NewsPage()
self.newsPage.load()
self.book.addPage(self.newsPage, pageName=TTLocalizer.NewsPageName)
def addTIPPage(self):
self.tipPage = TIPPage.TIPPage()
self.tipPage.load()
self.book.addPage(self.tipPage, pageName=TTLocalizer.TIPPageTitle)
def setPinkSlips(self, pinkSlips):
DistributedToon.DistributedToon.setPinkSlips(self, pinkSlips)
self.inventory.updateTotalPropsText()
def getAccountDays(self):
days = 0
defaultDays = base.cr.config.GetInt('account-days', -1)
if defaultDays >= 0:
days = defaultDays
elif hasattr(base.cr, 'accountDays'):
days = base.cr.accountDays
return days
def hasActiveBoardingGroup(self):
if hasattr(localAvatar, 'boardingParty') and localAvatar.boardingParty:
return localAvatar.boardingParty.hasActiveGroup(localAvatar.doId)
else:
return False
def getZoneId(self):
return self._zoneId
def setZoneId(self, value):
if value == -1:
self.notify.error('zoneId should not be set to -1, tell Redmond')
self._zoneId = value
zoneId = property(getZoneId, setZoneId)
def systemWarning(self, warningText = 'Acknowledge this system message.'):
self.createSystemMsgAckGui()
self.systemMsgAckGui['text'] = warningText
self.systemMsgAckGui.show()
def createSystemMsgAckGui(self):
if self.systemMsgAckGui == None or self.systemMsgAckGui.isEmpty():
message = 'o' * 100
self.systemMsgAckGui = TTDialog.TTGlobalDialog(doneEvent=self.systemMsgAckGuiDoneEvent, message=message, style=TTDialog.Acknowledge)
self.systemMsgAckGui.hide()
return
def hideSystemMsgAckGui(self):
if self.systemMsgAckGui != None and not self.systemMsgAckGui.isEmpty():
self.systemMsgAckGui.hide()
return
def setSleepAutoReply(self, fromId):
av = base.cr.identifyAvatar(fromId)
if isinstance(av, DistributedToon.DistributedToon):
base.localAvatar.setSystemMessage(0, TTLocalizer.sleep_auto_reply % av.getName(), WhisperPopup.WTToontownBoardingGroup)
elif av is not None:
self.notify.warning('setSleepAutoReply from non-toon %s' % fromId)
return
def setLastTimeReadNews(self, newTime):
self.lastTimeReadNews = newTime
def getLastTimeReadNews(self):
return self.lastTimeReadNews
def cheatCogdoMazeGame(self, kindOfCheat = 0):
if base.config.GetBool('allow-cogdo-maze-suit-hit-cheat'):
maze = base.cr.doFind('DistCogdoMazeGame')
if maze:
if kindOfCheat == 0:
for suitNum in maze.game.suitsById.keys():
suit = maze.game.suitsById[suitNum]
maze.sendUpdate('requestSuitHitByGag', [suit.type, suitNum])
elif kindOfCheat == 1:
for joke in maze.game.pickups:
maze.sendUpdate('requestPickUp', [joke.serialNum])
else:
self.sendUpdate('logSuspiciousEvent', ['cheatCogdoMazeGame'])
def isReadingNews(self):
result = False
if base.cr and base.cr.playGame and base.cr.playGame.getPlace() and hasattr(base.cr.playGame.getPlace(), 'fsm') and base.cr.playGame.getPlace().fsm:
fsm = base.cr.playGame.getPlace().fsm
curState = fsm.getCurrentState().getName()
if curState == 'stickerBook' and WantNewsPage:
if hasattr(self, 'newsPage'):
if self.book.isOnPage(self.newsPage):
result = True
return result
def doTeleportResponse(self, fromAvatar, toAvatar, avId, available, shardId, hoodId, zoneId, sendToId):
localAvatar.d_teleportResponse(avId, available, shardId, hoodId, zoneId, sendToId)
def d_teleportResponse(self, avId, available, shardId, hoodId, zoneId, sendToId = None):
if base.config.GetBool('want-tptrack', False):
if available == 1:
self.notify.debug('sending teleportResponseToAI')
self.sendUpdate('teleportResponseToAI', [avId,
available,
shardId,
hoodId,
zoneId,
sendToId])
else:
self.sendUpdate('teleportResponse', [avId,
available,
shardId,
hoodId,
zoneId], sendToId)
else:
DistributedPlayer.DistributedPlayer.d_teleportResponse(self, avId, available, shardId, hoodId, zoneId, sendToId)
def startQuestMap(self):
if self.questMap:
self.questMap.start()
def stopQuestMap(self):
if self.questMap:
self.questMap.stop()
def _startZombieCheck(self):
pass
def _stopZombieCheck(self):
pass