diff --git a/etc/toon.dc b/etc/toon.dc index 083bcb9..b4b29ed 100755 --- a/etc/toon.dc +++ b/etc/toon.dc @@ -619,6 +619,7 @@ dclass DistributedToon : DistributedPlayer { setNeverStartedPartyRefunded(uint64, int8, uint16) ownrecv; setDISLname(string) ram; setDISLid(uint32) ram db airecv; + toggleSleep() ownrecv; }; dclass DistributedCCharBase : DistributedObject { @@ -2873,6 +2874,9 @@ dclass ToontownFriendsManager : DistributedObject { makeFriendsResponse(uint32, uint32, uint8, uint32) airecv; removeFriend(uint32) clsend; requestSecret(uint32); + submitSecret(uint32, string); + requestSecretResponse(uint8, string, uint32) airecv; + submitSecretResponse(uint8, uint32, uint32) airecv; }; dclass TTSpeedchatRelay : SpeedchatRelay { diff --git a/otp/avatar/LocalAvatar.py b/otp/avatar/LocalAvatar.py index 2b689cc..8af6d4b 100644 --- a/otp/avatar/LocalAvatar.py +++ b/otp/avatar/LocalAvatar.py @@ -61,6 +61,7 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis self.soundRun = None self.soundWalk = None self.sleepFlag = 0 + self.noSleep = 0 self.isDisguised = 0 self.movingFlag = 0 self.swimmingFlag = 0 @@ -984,7 +985,7 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis return def gotoSleep(self): - if not self.sleepFlag: + if not self.sleepFlag and not self.noSleep: self.b_setAnimState('Sleep', self.animMultiplier) self.sleepFlag = 1 diff --git a/otp/friends/FriendManagerAI.py b/otp/friends/FriendManagerAI.py index ab4a1e0..b3c3bcd 100644 --- a/otp/friends/FriendManagerAI.py +++ b/otp/friends/FriendManagerAI.py @@ -18,6 +18,11 @@ class FriendManagerAI(DistributedObjectGlobalAI): # forget who has declined friendships from whom. DeclineFriendshipTimeout = 600.0 + # This is the length of time, in seconds, to sit on a secret guess + # # before processing it. This serves to make it difficult to guess + # # passwords at random. + SecretDelay = 1.0 + # This subclass is used to record currently outstanding # in-the-game invitation requests. class Invite: @@ -50,9 +55,13 @@ class FriendManagerAI(DistributedObjectGlobalAI): # will be sent in response to secret requests to the database, # via the AIR. self.accept("makeFriendsReply", self.makeFriendsReply) + self.accept("requestSecretReply", self.requestSecretReply) + self.accept('submitSecretReply', self.submitSecretReply) def delete(self): self.ignore("makeFriendsReply") + self.ignore("requestSecretReply") + self.ignore('submitSecretReply') DistributedObjectGlobalAI.delete(self) ### Messages sent from inviter client to AI @@ -221,6 +230,51 @@ class FriendManagerAI(DistributedObjectGlobalAI): self.sendUpdateToAvatarId(recipient, "friendResponse", [yesNoMaybe, context]) self.notify.debug("AI: friendResponse(%d, %d)" % (yesNoMaybe, context)) + def submitSecret(self, secret): + """submitSecret(self, string secret) + + Sent by the client to the AI to submit a "secret" typed in by + the user. + """ + avId = self.air.getAvatarIdFromSender() + + # We have to sit on this request for a few seconds before + # processing it. This delay is solely to discourage password + # guessing. + taskName = "secret-" + str(avId) + taskMgr.remove(taskName) + if FriendManagerAI.SecretDelay: + taskMgr.doMethodLater(FriendManagerAI.SecretDelay, + self.continueSubmission, + taskName, + extraArgs = (avId, secret)) + else: + # No delay + self.continueSubmission(avId, secret) + + def continueSubmission(self, avId, secret): + """continueSubmission(self, avId, secret) + Finishes the work of submitSecret, a short time later. + """ + self.air.submitSecret(avId, secret) + + def submitSecretReply(self, result, recipient, avId): + self.down_submitSecretResponse(recipient, result, avId) + + def down_submitSecretResponse(self, recipient, result, avId): + """submitSecret(self, int8 result, int32 avId) + + Sent by the AI to the client in response to submitSecret(). + result is one of: + + 0 - Failure. The secret is unknown or has timed out. + 1 - Success. You are now friends with the indicated avId. + 2 - Failure. One of the avatars has too many friends already. + 3 - Failure. You just used up your own secret. + + """ + self.sendUpdateToAvatarId(recipient, 'submitSecretResponse', [result, avId]) + ### Support methods def newInvite(self, inviterId, inviteeId): @@ -409,3 +463,18 @@ class FriendManagerAI(DistributedObjectGlobalAI): avatar.d_friendsNotify(invite.inviterId, 2) self.clearInvite(invite) + + def requestSecretReply(self, result, secret, requesterId): + self.down_requestSecretResponse(requesterId, result, secret) + + def down_requestSecretResponse(self, recipient, result, secret): + """requestSecret(self, int8 result, string secret) + + Sent by the AI to the client in response to requestSecret(). + result is one of: + + 0 - Too many secrets outstanding. Try again later. + 1 - Success. The new secret is supplied. + + """ + self.sendUpdateToAvatarId(recipient, 'requestSecretResponse', [result, secret]) \ No newline at end of file diff --git a/otp/friends/FriendSecret.py b/otp/friends/FriendSecret.py index 0b01bd2..3eaefc8 100644 --- a/otp/friends/FriendSecret.py +++ b/otp/friends/FriendSecret.py @@ -1,59 +1,67 @@ -from panda3d.core import * -from panda3d.otp import * -from direct.gui.DirectGui import * from direct.directnotify import DirectNotifyGlobal from direct.fsm import StateData -from otp.otpbase import OTPLocalizer +from direct.gui.DirectGui import * +from panda3d.core import * +from panda3d.otp import NametagGlobals + from otp.otpbase import OTPGlobals +from otp.otpbase import OTPLocalizer from otp.uberdog import RejectCode + globalFriendSecret = None AccountSecret = 0 AvatarSecret = 1 BothSecrets = 2 -def showFriendSecret(secretType = AvatarSecret): + +def showFriendSecret(secretType=AvatarSecret): + """ + Added optional parameter to offer the choice between account and avatar friend tokens. + """ + # A module function to open the global secret panel. global globalFriendSecret if not base.cr.isPaid(): + # bring up teaser panel chatMgr = base.localAvatar.chatMgr - chatMgr.fsm.request('trueFriendTeaserPanel') + chatMgr.fsm.request("trueFriendTeaserPanel") elif not base.cr.isParentPasswordSet(): + # non-COPPA gamecard user: prompt to leave game and set parent password chatMgr = base.localAvatar.chatMgr - if base.cr.productName in ['DisneyOnline-AP', - 'DisneyOnline-UK', - 'JP', - 'DE', - 'BR', - 'FR']: + if base.cr.productName in ['DisneyOnline-AP', 'DisneyOnline-UK', 'JP', 'DE', 'BR', 'FR']: chatMgr = base.localAvatar.chatMgr if not base.cr.isPaid(): - chatMgr.fsm.request('unpaidChatWarning') + chatMgr.fsm.request("unpaidChatWarning") else: chatMgr.paidNoParentPassword = 1 - chatMgr.fsm.request('unpaidChatWarning') + chatMgr.fsm.request("unpaidChatWarning") else: chatMgr.paidNoParentPassword = 1 - chatMgr.fsm.request('noSecretChatAtAll') + chatMgr.fsm.request("noSecretChatAtAll") # bring up dialog for true friends # open chat with true friends + elif not base.cr.allowSecretChat(): + # If we're paid but have not yet activated secrets, pop up the + # dialog to do this. chatMgr = base.localAvatar.chatMgr - if base.cr.productName in ['DisneyOnline-AP', - 'DisneyOnline-UK', - 'JP', - 'DE', - 'BR', - 'FR']: + if base.cr.productName in ['DisneyOnline-AP', 'DisneyOnline-UK', 'JP', 'DE', 'BR', 'FR']: chatMgr = base.localAvatar.chatMgr if not base.cr.isPaid(): - chatMgr.fsm.request('unpaidChatWarning') + chatMgr.fsm.request("unpaidChatWarning") else: chatMgr.paidNoParentPassword = 1 - chatMgr.fsm.request('unpaidChatWarning') + chatMgr.fsm.request("unpaidChatWarning") else: - chatMgr.fsm.request('noSecretChatAtAll') + # we no longer offer the ability to enable chat in game + # chatMgr.fsm.request("noSecretChatWarning") + chatMgr.fsm.request("noSecretChatAtAll") elif base.cr.needParentPasswordForSecretChat(): + # If we're paid but have the flag set to require the Parent Password to be + # entered to get or use a Secret Friends password, pop up the + # dialog to get the Parent Password. unloadFriendSecret() globalFriendSecret = FriendSecretNeedsParentLogin(secretType) globalFriendSecret.enter() else: + # Otherwise, actually open the secrets panel. openFriendSecret(secretType) @@ -63,53 +71,60 @@ def openFriendSecret(secretType): globalFriendSecret.unload() globalFriendSecret = FriendSecret(secretType) globalFriendSecret.enter() - return def hideFriendSecret(): + # A module function to close the global secret panel if it is open. if globalFriendSecret != None: globalFriendSecret.exit() - return def unloadFriendSecret(): + # A module function to completely unload the global secret panel. global globalFriendSecret if globalFriendSecret != None: globalFriendSecret.unload() globalFriendSecret = None - return class FriendSecretNeedsParentLogin(StateData.StateData): - notify = DirectNotifyGlobal.directNotify.newCategory('FriendSecretNeedsParentLogin') + notify = DirectNotifyGlobal.directNotify.newCategory("FriendSecretNeedsParentLogin") def __init__(self, secretType): - StateData.StateData.__init__(self, 'friend-secret-needs-parent-login-done') + StateData.StateData.__init__(self, "friend-secret-needs-parent-login-done") self.dialog = None self.secretType = secretType - return def enter(self): StateData.StateData.enter(self) - base.localAvatar.chatMgr.fsm.request('otherDialog') + base.localAvatar.chatMgr.fsm.request("otherDialog") + # Pop up a dialog indicating the parent account needs to login + # in order to get to the Secret Friends chat: if self.dialog == None: - guiButton = loader.loadModel('phase_3/models/gui/quit_button') + guiButton = loader.loadModel("phase_3/models/gui/quit_button") buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') - nameBalloon = loader.loadModel('phase_3/models/props/chatbox_input') - optionsButtonImage = (guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')) - okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')) - cancelButtonImage = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')) + nameBalloon = loader.loadModel("phase_3/models/props/chatbox_input") + optionsButtonImage = ( + guiButton.find("**/QuitBtn_UP"), guiButton.find("**/QuitBtn_DN"), guiButton.find("**/QuitBtn_RLVR")) + okButtonImage = ( + buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')) + cancelButtonImage = ( + buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')) + + # The Castillian (and all foreign) version relies on a seperate parent + # password system. Omit the the password entry field and cancel button. withParentAccount = False try: withParentAccount = base.cr.withParentAccount except: - self.notify.warning('withParentAccount not found in base.cr') + self.notify.warning("withParentAccount not found in base.cr") + pass if withParentAccount: okPos = (-0.22, 0.0, -0.5) textPos = (0, 0.25) okCommand = self.__handleOKWithParentAccount - elif base.cr.productName != 'Terra-DMC': + elif base.cr.productName != "Terra-DMC": okPos = (-0.22, 0.0, -0.5) textPos = (0, 0.25) okCommand = self.__oldHandleOK @@ -118,24 +133,48 @@ class FriendSecretNeedsParentLogin(StateData.StateData): okPos = (0, 0, -0.35) textPos = (0, 0.125) okCommand = self.__handleCancel - self.dialog = DirectFrame(parent=aspect2dp, pos=(0.0, 0.1, 0.2), relief=None, image=DGG.getDefaultDialogGeom(), image_color=OTPGlobals.GlobalDialogColor, image_scale=(1.4, 1.0, 1.25), image_pos=(0, 0, -0.1), text=OTPLocalizer.FriendSecretNeedsParentLoginWarning, text_wordwrap=21.5, text_scale=0.055, text_pos=textPos, textMayChange=1) - DirectButton(self.dialog, image=okButtonImage, relief=None, text=OTPLocalizer.FriendSecretNeedsPasswordWarningOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=okPos, command=okCommand) - DirectLabel(parent=self.dialog, relief=None, pos=(0, 0, 0.35), text=OTPLocalizer.FriendSecretNeedsPasswordWarningTitle, textMayChange=0, text_scale=0.08) - if base.cr.productName != 'Terra-DMC': - self.usernameLabel = DirectLabel(parent=self.dialog, relief=None, pos=(-0.07, 0.0, -0.1), text=OTPLocalizer.ParentLogin, text_scale=0.06, text_align=TextNode.ARight, textMayChange=0) - self.usernameEntry = DirectEntry(parent=self.dialog, relief=None, image=nameBalloon, image1_color=(0.8, 0.8, 0.8, 1.0), scale=0.064, pos=(0.0, 0.0, -0.1), width=OTPGlobals.maxLoginWidth, numLines=1, focus=1, cursorKeys=1, obscured=1, command=self.__handleUsername) - self.passwordLabel = DirectLabel(parent=self.dialog, relief=None, pos=(-0.02, 0.0, -0.3), text=OTPLocalizer.ParentPassword, text_scale=0.06, text_align=TextNode.ARight, textMayChange=0) - self.passwordEntry = DirectEntry(parent=self.dialog, relief=None, image=nameBalloon, image1_color=(0.8, 0.8, 0.8, 1.0), scale=0.064, pos=(0.04, 0.0, -0.3), width=OTPGlobals.maxLoginWidth, numLines=1, focus=1, cursorKeys=1, obscured=1, command=okCommand) - DirectButton(self.dialog, image=cancelButtonImage, relief=None, text=OTPLocalizer.FriendSecretNeedsPasswordWarningCancel, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=1, pos=(0.2, 0.0, -0.5), command=self.__handleCancel) + + # make the common gui elements + self.dialog = DirectFrame(parent=aspect2dp, pos=(0.0, 0.1, 0.2), relief=None, + image=DGG.getDefaultDialogGeom(), image_color=OTPGlobals.GlobalDialogColor, + image_scale=(1.4, 1.0, 1.25), image_pos=(0, 0, -0.1), + text=OTPLocalizer.FriendSecretNeedsParentLoginWarning, text_wordwrap=21.5, text_scale=0.055, + text_pos=textPos, textMayChange=1) + DirectButton(self.dialog, image=okButtonImage, relief=None, + text=OTPLocalizer.FriendSecretNeedsPasswordWarningOK, text_scale=0.05, text_pos=(0.0, -0.1), + textMayChange=0, pos=okPos, command=okCommand) + DirectLabel(parent=self.dialog, relief=None, pos=(0, 0, 0.35), + text=OTPLocalizer.FriendSecretNeedsPasswordWarningTitle, textMayChange=0, text_scale=0.08) + + # if not foreign, make the domestic only password entry elements + if base.cr.productName != "Terra-DMC": + self.usernameLabel = DirectLabel(parent=self.dialog, relief=None, pos=(-0.07, 0.0, -0.1), + text=OTPLocalizer.ParentLogin, text_scale=0.06, text_align=TextNode.ARight, textMayChange=0) + self.usernameEntry = DirectEntry(parent=self.dialog, relief=None, image=nameBalloon, + image1_color=(0.8, 0.8, 0.8, 1.0), scale=0.064, pos=(0.0, 0.0, -0.1), + width=OTPGlobals.maxLoginWidth, numLines=1, focus=1, cursorKeys=1, obscured=1, + command=self.__handleUsername) + self.passwordLabel = DirectLabel(parent=self.dialog, relief=None, pos=(-0.02, 0.0, -0.3), + text=OTPLocalizer.ParentPassword, text_scale=0.06, text_align=TextNode.ARight, textMayChange=0) + self.passwordEntry = DirectEntry(parent=self.dialog, relief=None, image=nameBalloon, + image1_color=(0.8, 0.8, 0.8, 1.0), scale=0.064, pos=(0.04, 0.0, -0.3), + width=OTPGlobals.maxLoginWidth, numLines=1, focus=1, cursorKeys=1, obscured=1, command=okCommand) + DirectButton(self.dialog, image=cancelButtonImage, relief=None, + text=OTPLocalizer.FriendSecretNeedsPasswordWarningCancel, text_scale=0.05, text_pos=(0.0, -0.1), + textMayChange=1, pos=(0.2, 0.0, -0.5), command=self.__handleCancel) + + # hide the parent login as it's not valid yet if withParentAccount: self.usernameEntry.enterText('') self.usernameEntry['focus'] = 1 self.passwordEntry.enterText('') + else: self.usernameEntry.hide() self.usernameLabel.hide() self.passwordEntry['focus'] = 1 self.passwordEntry.enterText('') + guiButton.removeNode() buttons.removeNode() nameBalloon.removeNode() @@ -147,8 +186,8 @@ class FriendSecretNeedsParentLogin(StateData.StateData): elif self.passwordEntry: self.passwordEntry['focus'] = 1 self.passwordEntry.enterText('') + self.dialog.show() - return def exit(self): self.ignoreAll() @@ -156,11 +195,11 @@ class FriendSecretNeedsParentLogin(StateData.StateData): self.dialog.destroy() self.dialog = None if self.isEntered: - base.localAvatar.chatMgr.fsm.request('mainMenu') + base.localAvatar.chatMgr.fsm.request("mainMenu") StateData.StateData.exit(self) - return def __handleUsername(self, *args): + # activate password entry if self.passwordEntry: self.passwordEntry['focus'] = 1 self.passwordEntry.enterText('') @@ -168,17 +207,29 @@ class FriendSecretNeedsParentLogin(StateData.StateData): def __handleOKWithParentAccount(self, *args): username = self.usernameEntry.get() password = self.passwordEntry.get() + # we need to store these in base.cr for __enterSecret base.cr.parentUsername = username base.cr.parentPassword = password tt = base.cr.loginInterface - okflag, message = tt.authenticateParentUsernameAndPassword(localAvatar.DISLid, base.cr.password, username, password) + try: + DISLIdFromLogin = base.cr.DISLIdFromLogin + except: + DISLIdFromLogin = 0 + if DISLIdFromLogin and (DISLIdFromLogin != localAvatar.DISLid): + # we only expect to have 1 DISLId per player, we're screwed if this happens + self.notify.error( + "Mismatched DISLIds, fromLogin=%s, localAvatar.dislId=%s" % (DISLIdFromLogin, localAvatar.DISLid)) + okflag, message = tt.authenticateParentUsernameAndPassword(localAvatar.DISLid, base.cr.password, username, + password) if okflag: self.exit() openFriendSecret(self.secretType) elif message: - base.localAvatar.chatMgr.fsm.request('problemActivatingChat') - base.localAvatar.chatMgr.problemActivatingChat['text'] = OTPLocalizer.ProblemActivatingChat % message + # Error connecting. + base.localAvatar.chatMgr.fsm.request("problemActivatingChat") + base.localAvatar.chatMgr.problemActivatingChat['text'] = OTPLocalizer.ProblemActivatingChat % (message) else: + # Wrong password. self.dialog['text'] = OTPLocalizer.FriendSecretNeedsPasswordWarningWrongPassword self.passwordEntry['focus'] = 1 self.passwordEntry.enterText('') @@ -186,6 +237,7 @@ class FriendSecretNeedsParentLogin(StateData.StateData): def __oldHandleOK(self, *args): username = self.usernameEntry.get() password = self.passwordEntry.get() + # we need to store these in base.cr for __enterSecret base.cr.parentUsername = username base.cr.parentPassword = password tt = base.cr.loginInterface @@ -194,59 +246,83 @@ class FriendSecretNeedsParentLogin(StateData.StateData): self.exit() openFriendSecret(self.secretType) elif message: - base.localAvatar.chatMgr.fsm.request('problemActivatingChat') - base.localAvatar.chatMgr.problemActivatingChat['text'] = OTPLocalizer.ProblemActivatingChat % message + # Error connecting. + base.localAvatar.chatMgr.fsm.request("problemActivatingChat") + base.localAvatar.chatMgr.problemActivatingChat['text'] = OTPLocalizer.ProblemActivatingChat % (message) else: + # Wrong password. self.dialog['text'] = OTPLocalizer.FriendSecretNeedsPasswordWarningWrongPassword self.passwordEntry['focus'] = 1 self.passwordEntry.enterText('') def __handleOK(self, *args): + base.cr.parentUsername = self.usernameEntry.get() base.cr.parentPassword = self.passwordEntry.get() + # we don't have a request for this yet, so pretend we are submitting a limited secret base.cr.playerFriendsManager.sendRequestUseLimitedSecret('', base.cr.parentUsername, base.cr.parentPassword) self.accept(OTPGlobals.PlayerFriendRejectUseSecretEvent, self.__handleParentLogin) + # we won't get an answer yet, so spoof a return code + # self.__handleParentLogin(0) + # that doesn't work, just immediately close the panel self.exit() def __handleParentLogin(self, reason): + # don't know reason codes yet, spoof something if reason == 0: self.exit() openFriendSecret(self.secretType) elif reason == 1: + # Wrong username self.dialog['text'] = OTPLocalizer.FriendSecretNeedsPasswordWarningWrongUsername self.usernameEntry['focus'] = 1 self.usernameEntry.enterText('') elif reason == 2: + # Wrong password self.dialog['text'] = OTPLocalizer.FriendSecretNeedsPasswordWarningWrongPassword self.passwordEntry['focus'] = 1 self.passwordEntry.enterText('') else: - base.localAvatar.chatMgr.fsm.request('problemActivatingChat') - base.localAvatar.chatMgr.problemActivatingChat['text'] = OTPLocalizer.ProblemActivatingChat % message + # Error connecting (fall through case) + base.localAvatar.chatMgr.fsm.request("problemActivatingChat") + base.localAvatar.chatMgr.problemActivatingChat['text'] = OTPLocalizer.ProblemActivatingChat % (message) def __handleCancel(self): self.exit() class FriendSecret(DirectFrame, StateData.StateData): - notify = DirectNotifyGlobal.directNotify.newCategory('FriendSecret') + """ + This is a panel that allows the user to manage 'secrets' that is, + code words that identify people who are actually friends in real + life (and thus are entitled to use full chat with each other). + + This panel is the place the user will come to either get a new + 'secret' to give to someone else, or to enter the 'secret' they + got from someone. + """ + notify = DirectNotifyGlobal.directNotify.newCategory("FriendSecret") def __init__(self, secretType): - DirectFrame.__init__(self, parent=aspect2dp, pos=(0, 0, 0.3), relief=None, image=DGG.getDefaultDialogGeom(), image_scale=(1.6, 1, 1.4), image_pos=(0, 0, -0.05), image_color=OTPGlobals.GlobalDialogColor, borderWidth=(0.01, 0.01)) - StateData.StateData.__init__(self, 'friend-secret-done') + DirectFrame.__init__(self, parent=aspect2dp, pos=(0, 0, 0.30), relief=None, image=DGG.getDefaultDialogGeom(), + image_scale=(1.6, 1, 1.4), image_pos=(0, 0, -0.05), + image_color=OTPGlobals.GlobalDialogColor, borderWidth=(0.01, 0.01), ) + StateData.StateData.__init__(self, "friend-secret-done") self.initialiseoptions(FriendSecret) self.prefix = OTPGlobals.getDefaultProductPrefix() + # what types of secret friends will we offer self.secretType = secretType - self.notify.debug('### secretType = %s' % self.secretType) + self.notify.debug("### secretType = %s" % self.secretType) + # what type of secret friend has the user chosen self.requestedSecretType = secretType - self.notify.debug('### requestedSecretType = %s' % self.requestedSecretType) - return + self.notify.debug("### requestedSecretType = %s" % self.requestedSecretType) def unload(self): if self.isLoaded == 0: return None self.isLoaded = 0 self.exit() + del self.introText del self.getSecret del self.enterSecretText @@ -259,34 +335,48 @@ class FriendSecret(DirectFrame, StateData.StateData): del self.accountButton DirectFrame.destroy(self) self.ignore('clientCleanup') - return None def load(self): if self.isLoaded == 1: return None self.isLoaded = 1 - self.introText = DirectLabel(parent=self, relief=None, pos=(0, 0, 0.4), scale=0.05, text=OTPLocalizer.FriendSecretIntro, text_fg=(0, 0, 0, 1), text_wordwrap=30) + + self.introText = DirectLabel(parent=self, relief=None, pos=(0, 0, 0.4), scale=0.05, + text=OTPLocalizer.FriendSecretIntro, text_fg=(0, 0, 0, 1), text_wordwrap=30, ) self.introText.hide() - guiButton = loader.loadModel('phase_3/models/gui/quit_button') - self.getSecret = DirectButton(parent=self, relief=None, pos=(0, 0, -0.11), image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=OTPLocalizer.FSgetSecret, text=OTPLocalizer.FriendSecretGetSecret, text_scale=OTPLocalizer.FSgetSecretButton, text_pos=(0, -0.02), command=self.__determineSecret) + + guiButton = loader.loadModel("phase_3/models/gui/quit_button") + + self.getSecret = DirectButton(parent=self, relief=None, pos=(0, 0, -0.11), image=( + guiButton.find("**/QuitBtn_UP"), guiButton.find("**/QuitBtn_DN"), guiButton.find("**/QuitBtn_RLVR"),), + image_scale=OTPLocalizer.FSgetSecret, text=OTPLocalizer.FriendSecretGetSecret, + text_scale=OTPLocalizer.FSgetSecretButton, text_pos=(0, -0.02), command=self.__determineSecret, ) self.getSecret.hide() - self.enterSecretText = DirectLabel(parent=self, relief=None, pos=OTPLocalizer.FSenterSecretTextPos, scale=0.05, text=OTPLocalizer.FriendSecretEnterSecret, text_fg=(0, 0, 0, 1), text_wordwrap=30) + + self.enterSecretText = DirectLabel(parent=self, relief=None, pos=OTPLocalizer.FSenterSecretTextPos, scale=0.05, + text=OTPLocalizer.FriendSecretEnterSecret, text_fg=(0, 0, 0, 1), text_wordwrap=30, ) self.enterSecretText.hide() - self.enterSecret = DirectEntry(parent=self, relief=DGG.SUNKEN, scale=0.06, pos=(-0.6, 0, -0.38), frameColor=(0.8, 0.8, 0.5, 1), borderWidth=(0.1, 0.1), numLines=1, width=20, frameSize=(-0.4, - 20.4, - -0.4, - 1.1), command=self.__enterSecret) + + self.enterSecret = DirectEntry(parent=self, relief=DGG.SUNKEN, scale=0.06, pos=(-0.60, 0, -0.38), + frameColor=(0.8, 0.8, 0.5, 1), borderWidth=(0.1, 0.1), numLines=1, width=20, + frameSize=(-0.4, 20.4, -0.4, 1.1), command=self.__enterSecret) + + # This fixes a little problem with the initial frame size. self.enterSecret.resetFrameSize() self.enterSecret.hide() - self.ok1 = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=OTPLocalizer.FSok1, text=OTPLocalizer.FriendSecretEnter, text_scale=0.06, text_pos=(0, -0.02), pos=(0, 0, -0.5), command=self.__ok1) + + self.ok1 = DirectButton(parent=self, relief=None, image=( + guiButton.find("**/QuitBtn_UP"), guiButton.find("**/QuitBtn_DN"), guiButton.find("**/QuitBtn_RLVR"),), + image_scale=OTPLocalizer.FSok1, text=OTPLocalizer.FriendSecretEnter, text_scale=0.06, text_pos=(0, -0.02), + pos=(0, 0, -0.5), command=self.__ok1, ) self.ok1.hide() - if base.cr.productName in ['JP', - 'DE', - 'BR', - 'FR']: + if base.cr.productName in ['JP', 'DE', 'BR', 'FR']: + # There should be no 'change secret friends options' button in + # the UK version. + # the only thing we do to self.changeOptions is show and hide it; + # avoid adding a bunch of 'if' statements class ShowHide: - def show(self): pass @@ -294,16 +384,32 @@ class FriendSecret(DirectFrame, StateData.StateData): pass self.changeOptions = ShowHide() - self.ok2 = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=OTPLocalizer.FSok2, text=OTPLocalizer.FriendSecretOK, text_scale=0.06, text_pos=(0, -0.02), pos=(0, 0, -0.57), command=self.__ok2) + + self.ok2 = DirectButton(parent=self, relief=None, image=( + guiButton.find("**/QuitBtn_UP"), guiButton.find("**/QuitBtn_DN"), guiButton.find("**/QuitBtn_RLVR"),), + image_scale=OTPLocalizer.FSok2, text=OTPLocalizer.FriendSecretOK, text_scale=0.06, text_pos=(0, -0.02), + pos=(0, 0, -0.57), command=self.__ok2, ) self.ok2.hide() - self.cancel = DirectButton(parent=self, relief=None, text=OTPLocalizer.FriendSecretCancel, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=OTPLocalizer.FScancel, text_scale=0.06, text_pos=(0, -0.02), pos=(0, 0, -0.57), command=self.__cancel) + + self.cancel = DirectButton(parent=self, relief=None, text=OTPLocalizer.FriendSecretCancel, image=( + guiButton.find("**/QuitBtn_UP"), guiButton.find("**/QuitBtn_DN"), guiButton.find("**/QuitBtn_RLVR"),), + image_scale=OTPLocalizer.FScancel, text_scale=0.06, text_pos=(0, -0.02), pos=(0, 0, -0.57), + command=self.__cancel, ) self.cancel.hide() - self.nextText = DirectLabel(parent=self, relief=None, pos=(0, 0, 0.3), scale=0.06, text='', text_scale=OTPLocalizer.FSnextText, text_fg=(0, 0, 0, 1), text_wordwrap=25.5) + + self.nextText = DirectLabel(parent=self, relief=None, pos=(0, 0, 0.30), scale=0.06, text="", + text_scale=OTPLocalizer.FSnextText, text_fg=(0, 0, 0, 1), text_wordwrap=25.5, ) self.nextText.hide() - self.secretText = DirectLabel(parent=self, relief=None, pos=(0, 0, -0.42), scale=0.1, text='', text_fg=(0, 0, 0, 1), text_wordwrap=30) + + self.secretText = DirectLabel(parent=self, relief=None, pos=(0, 0, -0.42), scale=0.1, text="", + text_fg=(0, 0, 0, 1), text_wordwrap=30, ) self.secretText.hide() + guiButton.removeNode() + + # moved into it's own method to make overloading easier self.makeFriendTypeButtons() + self.accept('clientCleanup', self.__handleCleanup) self.accept('walkDone', self.__handleStop) @@ -314,59 +420,100 @@ class FriendSecret(DirectFrame, StateData.StateData): self.unload() def makeFriendTypeButtons(self): + # NOTE: this uses generic text, if you want game-specific text, please inherit and override + # (see $TOONTOWN/src/friends/ToontownFriendSecret.py for an example) buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') - self.avatarButton = DirectButton(self, image=(buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), relief=None, text=OTPLocalizer.FriendSecretDetermineSecretAvatar, text_scale=0.07, text_pos=(0.0, -0.1), pos=(-0.35, 0.0, -0.05), command=self.__handleAvatar) - avatarText = DirectLabel(parent=self, relief=None, pos=Vec3(0.35, 0, -0.3), text=OTPLocalizer.FriendSecretDetermineSecretAvatarRollover, text_fg=(0, 0, 0, 1), text_pos=(0, 0), text_scale=0.055, text_align=TextNode.ACenter) + + # make an avatar friend + self.avatarButton = DirectButton(self, image=( + buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), + relief=None, text=OTPLocalizer.FriendSecretDetermineSecretAvatar, text_scale=0.07, text_pos=(0.0, -0.1), + pos=(-0.35, 0.0, -0.05), command=self.__handleAvatar) + # make a label to show avatar friend desc on rollover + avatarText = DirectLabel(parent=self, relief=None, pos=Vec3(0.35, 0, -0.3), + text=OTPLocalizer.FriendSecretDetermineSecretAvatarRollover, text_fg=(0, 0, 0, 1), text_pos=(0, 0), + text_scale=0.055, text_align=TextNode.ACenter, ) avatarText.reparentTo(self.avatarButton.stateNodePath[2]) self.avatarButton.hide() - self.accountButton = DirectButton(self, image=(buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), relief=None, text=OTPLocalizer.FriendSecretDetermineSecretAccount, text_scale=0.07, text_pos=(0.0, -0.1), pos=(0.35, 0.0, -0.05), command=self.__handleAccount) - accountText = DirectLabel(parent=self, relief=None, pos=Vec3(-0.35, 0, -0.3), text=OTPLocalizer.FriendSecretDetermineSecretAccountRollover, text_fg=(0, 0, 0, 1), text_pos=(0, 0), text_scale=0.055, text_align=TextNode.ACenter) + + # make an account friend + self.accountButton = DirectButton(self, image=( + buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), + relief=None, text=OTPLocalizer.FriendSecretDetermineSecretAccount, text_scale=0.07, text_pos=(0.0, -0.1), + pos=(0.35, 0.0, -0.05), command=self.__handleAccount) + # make a label to show feature desc on rollover + accountText = DirectLabel(parent=self, relief=None, pos=Vec3(-0.35, 0, -0.3), + text=OTPLocalizer.FriendSecretDetermineSecretAccountRollover, text_fg=(0, 0, 0, 1), text_pos=(0, 0), + text_scale=0.055, text_align=TextNode.ACenter, ) accountText.reparentTo(self.accountButton.stateNodePath[2]) self.accountButton.hide() + buttons.removeNode() - return def enter(self): if self.isEntered == 1: return self.isEntered = 1 + # Use isLoaded to avoid redundant loading if self.isLoaded == 0: self.load() + self.show() + + # Set us up on the first page. self.introText.show() self.getSecret.show() self.enterSecretText.show() self.enterSecret.show() self.ok1.show() + self.ok2.hide() self.cancel.hide() self.nextText.hide() self.secretText.hide() - base.localAvatar.chatMgr.fsm.request('otherDialog') + + # While the entry's on the screen, we have to turn off the + # background focus on the normal chat entry. Otherwise, + # keypresses would start chatting! + base.localAvatar.chatMgr.fsm.request("otherDialog") + + # And now we can set the focus on our entry. self.enterSecret['focus'] = 1 + + # The secret panel uses up a lot of space onscreen; in + # particular, it will hide most of the chat balloons. Force + # these to go to the margins. NametagGlobals.setOnscreenChatForced(1) def exit(self): if self.isEntered == 0: return self.isEntered = 0 + + # Restore the normal chat behavior. NametagGlobals.setOnscreenChatForced(0) + self.__cleanupFirstPage() self.ignoreAll() self.accept('clientCleanup', self.unload) self.hide() def __determineSecret(self): + # If we support both types of secrets... if self.secretType == BothSecrets: + # ask the player what type they want self.__cleanupFirstPage() self.ok1.hide() + # NOTE: this uses generic text, if you want game-specific text, please inherit and override + # (see $TOONTOWN/src/friends/ToontownFriendSecret.py for an example) self.nextText['text'] = OTPLocalizer.FriendSecretDetermineSecret - self.nextText.setPos(0, 0, 0.3) + self.nextText.setPos(0, 0, 0.30) self.nextText.show() self.avatarButton.show() self.accountButton.show() self.cancel.show() else: + # or just get the secret self.__getSecret() def __handleAvatar(self): @@ -383,39 +530,36 @@ class FriendSecret(DirectFrame, StateData.StateData): def __getSecret(self): self.__cleanupFirstPage() self.nextText['text'] = OTPLocalizer.FriendSecretGettingSecret - self.nextText.setPos(0, 0, 0.3) + self.nextText.setPos(0, 0, 0.30) self.nextText.show() self.avatarButton.hide() self.accountButton.hide() self.ok1.hide() self.cancel.show() - if self.requestedSecretType == AvatarSecret: - if not base.cr.friendManager: - self.notify.warning('No FriendManager available.') - self.exit() - return - base.cr.friendManager.up_requestSecret() - self.accept('requestSecretResponse', self.__gotAvatarSecret) - else: - if base.cr.needParentPasswordForSecretChat(): - self.notify.info('### requestLimitedSecret') - base.cr.playerFriendsManager.sendRequestLimitedSecret(base.cr.parentUsername, base.cr.parentPassword) - else: - base.cr.playerFriendsManager.sendRequestUnlimitedSecret() - self.notify.info('### requestUnlimitedSecret') - self.accept(OTPGlobals.PlayerFriendNewSecretEvent, self.__gotAccountSecret) - self.accept(OTPGlobals.PlayerFriendRejectNewSecretEvent, self.__rejectAccountSecret) + # If we don't have a FriendManager, something's badly wrong. + # Most likely we're running in a development environment + # without an AI client. + if not base.cr.friendManager: + self.notify.warning("No FriendManager available.") + self.exit() + return + base.cr.friendManager.up_requestSecret() + self.accept('requestSecretResponse', + self.__gotAvatarSecret) # else: # if base.cr.needParentPasswordForSecretChat(): # self.notify.info("### requestLimitedSecret") # base.cr.playerFriendsManager.sendRequestLimitedSecret(base.cr.parentUsername, base.cr.parentPassword) # else: # base.cr.playerFriendsManager.sendRequestUnlimitedSecret() # self.notify.info("### requestUnlimitedSecret") # self.accept(OTPGlobals.PlayerFriendNewSecretEvent, self.__gotAccountSecret) # self.accept(OTPGlobals.PlayerFriendRejectNewSecretEvent, self.__rejectAccountSecret) def __gotAvatarSecret(self, result, secret): self.ignore('requestSecretResponse') + if result == 1: self.nextText['text'] = OTPLocalizer.FriendSecretGotSecret self.nextText.setPos(*OTPLocalizer.FSgotSecretPos) - if self.prefix: - self.secretText['text'] = self.prefix + ' ' + secret - else: - self.secretText['text'] = secret + # always append the prefix + self.secretText['text'] = self.prefix + ' ' + secret + elif result == 2: + self.nextText['text'] = OTPLocalizer.FriendSecretTooManyFriends + else: + # Oops, too many secrets. self.nextText['text'] = OTPLocalizer.FriendSecretTooMany self.nextText.show() self.secretText.show() @@ -423,133 +567,148 @@ class FriendSecret(DirectFrame, StateData.StateData): self.ok1.hide() self.ok2.show() - def __gotAccountSecret(self, secret): - self.ignore(OTPGlobals.PlayerFriendNewSecretEvent) - self.ignore(OTPGlobals.PlayerFriendRejectNewSecretEvent) - self.nextText['text'] = OTPLocalizer.FriendSecretGotSecret - self.nextText.setPos(0, 0, 0.47) - self.secretText['text'] = secret - self.nextText.show() - self.secretText.show() - self.cancel.hide() - self.ok1.hide() - self.ok2.show() - - def __rejectAccountSecret(self, reason): - print('## rejectAccountSecret: reason = ', reason) - self.ignore(OTPGlobals.PlayerFriendNewSecretEvent) - self.ignore(OTPGlobals.PlayerFriendRejectNewSecretEvent) - self.nextText['text'] = OTPLocalizer.FriendSecretTooMany - self.nextText.show() - self.secretText.show() - self.cancel.hide() - self.ok1.hide() - self.ok2.show() - def __enterSecret(self, secret): - self.enterSecret.set('') + # Empty the entry for next time. + self.enterSecret.set("") + secret = secret.strip() if not secret: + # If the secret is empty, it just means to close down + # the dialog. self.exit() return + + # If we don't have a FriendManager, something's badly wrong. + # Most likely we're running in a development environment + # without an AI client. if not base.cr.friendManager: - self.notify.warning('No FriendManager available.') + self.notify.warning("No FriendManager available.") self.exit() return + self.__cleanupFirstPage() + + # The client can now prepend a product prefix to all secrets - strip this off if present if self.prefix: if secret[0:2] == self.prefix: secret = secret[3:] - self.notify.info('### use TT secret') + self.notify.info("### use TT secret") self.accept('submitSecretResponse', self.__enteredSecret) base.cr.friendManager.up_submitSecret(secret) - else: - self.accept(OTPGlobals.PlayerFriendUpdateEvent, self.__useAccountSecret) - self.accept(OTPGlobals.PlayerFriendRejectUseSecretEvent, self.__rejectUseAccountSecret) - if base.cr.needParentPasswordForSecretChat(): - self.notify.info('### useLimitedSecret') - base.cr.playerFriendsManager.sendRequestUseLimitedSecret(secret, base.cr.parentUsername, base.cr.parentPassword) - else: - self.notify.info('### useUnlimitedSecret') - base.cr.playerFriendsManager.sendRequestUseUnlimitedSecret(secret) + self.nextText['text'] = OTPLocalizer.FriendSecretTryingSecret - self.nextText.setPos(0, 0, 0.3) + self.nextText.setPos(0, 0, 0.30) self.nextText.show() self.ok1.hide() self.cancel.show() def __enteredSecret(self, result, avId): self.ignore('submitSecretResponse') + if result == 1: + # We made it! handle = base.cr.identifyAvatar(avId) if handle != None: - self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretSuccess % handle.getName() + self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretSuccess % (handle.getName()) else: + # Shoot. We just made friends with someone, but we + # don't know who it is yet. We'll have to ask the + # server who this is, and wait for the response before + # we can continue. self.accept('friendsMapComplete', self.__nowFriends, [avId]) ready = base.cr.fillUpFriendsMap() if ready: self.__nowFriends(avId) return + elif result == 0: + # Unknown secret. self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretUnknown + elif result == 2: + # Friends list full. handle = base.cr.identifyAvatar(avId) if handle != None: - self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretFull % handle.getName() + self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretFull % (handle.getName()) else: self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretFullNoName + elif result == 3: + # Self match. self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretSelf + elif result == 4: - self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretWrongProduct % self.prefix + # This doesn't look like our secret friend code - wrong prefix + self.nextText['text'] = OTPLocalizer.FriendSecretEnteredSecretWrongProduct % (self.prefix) + self.nextText.show() self.cancel.hide() self.ok1.hide() self.ok2.show() - return def __useAccountSecret(self, avId, friendInfo): self.ignore(OTPGlobals.PlayerFriendUpdateEvent) self.ignore(OTPGlobals.PlayerFriendRejectUseSecretEvent) + + # todo - pass an avId? self.__enteredSecret(1, 0) def __rejectUseAccountSecret(self, reason): - print('## rejectUseAccountSecret: reason = ', reason) + print("## rejectUseAccountSecret: reason = ", reason) self.ignore(OTPGlobals.PlayerFriendUpdateEvent) self.ignore(OTPGlobals.PlayerFriendRejectUseSecretEvent) - if reason == RejectCode.RejectCode.FRIENDS_LIST_FULL: + + if (reason == RejectCode.RejectCode.FRIENDS_LIST_FULL): self.__enteredSecret(2, 0) - elif reason == RejectCode.RejectCode.ALREADY_FRIENDS_WITH_SELF: + elif (reason == RejectCode.RejectCode.ALREADY_FRIENDS_WITH_SELF): self.__enteredSecret(3, 0) else: + # todo: this shouldn't be the fall thru self.__enteredSecret(0, 0) def __nowFriends(self, avId): + # This is called only from enteredSecret(), after the friend + # transaction has completed. This will be called only if the + # client didn't know the identity of the friend at the time, + # but it should know now. + self.ignore('friendsMapComplete') + handle = base.cr.identifyAvatar(avId) if handle != None: - self.nextText['text'] = OTPLocalizer.FriendSecretNowFriends % handle.getName() + self.nextText['text'] = OTPLocalizer.FriendSecretNowFriends % (handle.getName()) else: + # This really shouldn't be possible. self.nextText['text'] = OTPLocalizer.FriendSecretNowFriendsNoName + self.nextText.show() self.cancel.hide() self.ok1.hide() self.ok2.show() - return def __ok1(self): + # Clicking "ok" from the front screen is the same thing as + # pressing Enter in the entry. secret = self.enterSecret.get() self.__enterSecret(secret) def __ok2(self): + # Clicking "ok" from a finished screen just makes the thing go + # away. self.exit() def __cancel(self): + # Clicking "cancel" makes the panel close too. self.exit() def __cleanupFirstPage(self): + # Removes all the widgets etc. that were created for the + # welcome page, except the introText. + self.introText.hide() self.getSecret.hide() self.enterSecretText.hide() self.enterSecret.hide() - base.localAvatar.chatMgr.fsm.request('mainMenu') + + # Restore the background focus on the chat entry. + base.localAvatar.chatMgr.fsm.request("mainMenu") diff --git a/otp/login/AstronLoginManagerUD.py b/otp/login/AstronLoginManagerUD.py index d1d1c5a..360e53b 100644 --- a/otp/login/AstronLoginManagerUD.py +++ b/otp/login/AstronLoginManagerUD.py @@ -5,7 +5,17 @@ from datetime import datetime from direct.directnotify import DirectNotifyGlobal from direct.distributed.DistributedObjectGlobalUD import DistributedObjectGlobalUD -from direct.distributed.PyDatagram import * +from direct.distributed.PyDatagram import PyDatagram +from direct.distributed.MsgTypes import ( + CLIENTAGENT_ADD_POST_REMOVE, + CLIENTAGENT_CLEAR_POST_REMOVES, + CLIENTAGENT_CLOSE_CHANNEL, + CLIENTAGENT_EJECT, + CLIENTAGENT_OPEN_CHANNEL, + CLIENTAGENT_REMOVE_SESSION_OBJECT, + CLIENTAGENT_SET_CLIENT_ID, + STATESERVER_OBJECT_DELETE_RAM +) from otp.otpbase import OTPGlobals diff --git a/toontown/ai/ToontownAIRepository.py b/toontown/ai/ToontownAIRepository.py index d83d6fa..4349269 100644 --- a/toontown/ai/ToontownAIRepository.py +++ b/toontown/ai/ToontownAIRepository.py @@ -37,12 +37,14 @@ from toontown.hood.TTHoodDataAI import TTHoodDataAI from toontown.pets.PetManagerAI import PetManagerAI from toontown.quest.QuestManagerAI import QuestManagerAI from toontown.racing import RaceGlobals +from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI from toontown.racing.DistributedLeaderBoardAI import DistributedLeaderBoardAI from toontown.racing.DistributedRacePadAI import DistributedRacePadAI from toontown.racing.DistributedStartingBlockAI import DistributedStartingBlockAI from toontown.racing.DistributedStartingBlockAI import DistributedViewingBlockAI from toontown.racing.DistributedViewPadAI import DistributedViewPadAI from toontown.racing.RaceManagerAI import RaceManagerAI +from toontown.uberdog.DistributedPartyManagerAI import DistributedPartyManagerAI from toontown.safezone.SafeZoneManagerAI import SafeZoneManagerAI from toontown.shtiker.CogPageManagerAI import CogPageManagerAI from toontown.spellbook.ToontownMagicWordManagerAI import ToontownMagicWordManagerAI @@ -95,6 +97,7 @@ class ToontownAIRepository(ToontownInternalRepository): self.friendManager = None self.toontownFriendsManager = None self.estateMgr = None + self.partyManager = None self.zoneTable = {} self.dnaStoreMap = {} self.dnaDataMap = {} @@ -242,6 +245,10 @@ class ToontownAIRepository(ToontownInternalRepository): self.tutorialManager = TutorialManagerAI(self) self.tutorialManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT) + # Generate our party manager... + self.partyManager = DistributedPartyManagerAI(self) + self.partyManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT) + def generateHood(self, hoodConstructor, zoneId): # Bossbot HQ doesn't use DNA, so we skip over that. if zoneId != ToontownGlobals.BossbotHQ: @@ -391,7 +398,29 @@ class ToontownAIRepository(ToontownInternalRepository): return loadDNAFileAI(dnaStore, dnaFileName) def findFishingPonds(self, dnaData, zoneId, area): - return [], [] # TODO + fishingPonds, fishingPondGroups = [], [] + + if "fishing_pond" in dnaData.getName(): + fishingPondGroups.append(dnaData) + pond = DistributedFishingPondAI(self) + pond.setArea(area) + pond.generateWithRequired(zoneId) + fishingPonds.append(pond) + else: + if isinstance(dnaData, DNAVisGroup): + name = dnaData.getName() + visId = int(name.split(":", 1)[0]) % 1000 + zoneId = ZoneUtil.getHoodId(zoneId) + visId + + for i in range(dnaData.getNumChildren()): + foundFishingPonds, foundFishingPondGroups = self.findFishingPonds(dnaData.at(i), zoneId, area) + fishingPonds.extend(foundFishingPonds) + fishingPondGroups.extend(foundFishingPondGroups) + + return fishingPonds, fishingPondGroups + + def findFishingSpots(self, dnaData, pond): + return [] # TODO def findPartyHats(self, dnaData, zoneId): return [] # TODO @@ -518,6 +547,19 @@ class ToontownAIRepository(ToontownInternalRepository): if __astron__: self.toontownFriendsManager.sendRequestSecret(requesterId) + def submitSecret(self, avId, secret): + """ + avId: the avatar id of the friend who requested the secret + secret: the secret that was requested + Submits a secret that was previously requested. + Will submit through the friends manager. + When the secret is submitted, a "submitSecretReply" message will + be thrown with two parameters: the result code (0 or 1, + indicating failure or success), and the requesterId again. + """ + if __astron__: + self.toontownFriendsManager.sendSubmitSecret(avId, secret) + def setupFiles(self): if not os.path.exists(self.dataFolder): os.mkdir(self.dataFolder) diff --git a/toontown/battle/BattleCalculatorAI.py b/toontown/battle/BattleCalculatorAI.py index d76ea92..0ed39aa 100644 --- a/toontown/battle/BattleCalculatorAI.py +++ b/toontown/battle/BattleCalculatorAI.py @@ -74,7 +74,8 @@ class BattleCalculatorAI: return (1, 95) else: return (0, 0) - if self.toonsAlwaysHit: + toon = self.battle.getToon(attackIndex) + if self.toonsAlwaysHit or toon.instantKillMode: return (1, 95) elif self.toonsAlwaysMiss: return (0, 0) @@ -529,6 +530,9 @@ class BattleCalculatorAI: if attackLevel == -1 and not atkTrack == FIRE: result = LURE_SUCCEEDED elif atkTrack != TRAP: + toon = self.battle.getToon(toonId) + if atkTrack != HEAL and toon.instantKillMode: + attackDamage = 32767 result = attackDamage if atkTrack == HEAL: if not self.__attackHasHit(attack, suit=0): @@ -747,11 +751,15 @@ class BattleCalculatorAI: toonId = self.toonAtkOrder[attackIndex] attack = self.battle.toonAttacks[toonId] atkTrack = self.__getActualTrack(attack) + TTOStyle = simbase.config.GetBool('want-tto-style-knockback', False) if atkTrack == HEAL or atkTrack == PETSOS: return tgts = self.__createToonTargetList(toonId) for currTgt in tgts: - tgtPos = self.battle.suits.index(currTgt) + if not TTOStyle: + tgtPos = self.battle.activeSuits.index(currTgt) + else: + tgtPos = self.battle.suits.index(currTgt) attackerId = self.toonAtkOrder[attackIndex] attack = self.battle.toonAttacks[attackerId] track = self.__getActualTrack(attack) diff --git a/toontown/battle/BattleProps.py b/toontown/battle/BattleProps.py index d4033fb..aa29387 100644 --- a/toontown/battle/BattleProps.py +++ b/toontown/battle/BattleProps.py @@ -324,12 +324,12 @@ class PropPool: lips.setPos(0, 0, -3.04) lips.flattenMedium() elif name == '5dollar': - tex = loader.loadTexture('phase_5/maps/dollar_5.jpg') + tex = loader.loadTexture('phase_5/maps/dollar_5.png') tex.setMinfilter(Texture.FTLinearMipmapLinear) tex.setMagfilter(Texture.FTLinear) self.props[name].setTexture(tex, 1) elif name == '10dollar': - tex = loader.loadTexture('phase_5/maps/dollar_10.jpg') + tex = loader.loadTexture('phase_5/maps/dollar_10.png') tex.setMinfilter(Texture.FTLinearMipmapLinear) tex.setMagfilter(Texture.FTLinear) self.props[name].setTexture(tex, 1) diff --git a/toontown/battle/DistributedBattleBase.py b/toontown/battle/DistributedBattleBase.py index 9716ede..5e886b1 100644 --- a/toontown/battle/DistributedBattleBase.py +++ b/toontown/battle/DistributedBattleBase.py @@ -1,28 +1,55 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from direct.interval.IntervalGlobal import * -from .BattleBase import * -from direct.distributed.ClockDelta import * -from toontown.toonbase import ToontownBattleGlobals -from direct.distributed import DistributedNode -from direct.fsm import ClassicFSM, State -from direct.fsm import State -from direct.task.Task import Task -from direct.directnotify import DirectNotifyGlobal -from . import Movie -from . import MovieUtil -from toontown.suit import Suit -from direct.actor import Actor -from . import BattleProps -from direct.particles import ParticleEffect -from . import BattleParticles -from toontown.hood import ZoneUtil -from toontown.distributed import DelayDelete -from toontown.toon import TTEmote -from otp.avatar import Emote +from panda3d.core import CollisionNode, CollisionTube, LineSegs, NodePath, Point3, VBase3 +from panda3d.otp import NametagGlobals -class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): - notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBattleBase') +from direct.actor.Actor import Actor +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.distributed.ClockDelta import globalClockDelta +from direct.distributed.DistributedNode import DistributedNode +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.interval.IntervalGlobal import Func, LerpPosInterval, Parallel, Sequence +from direct.showbase.MessengerGlobal import messenger +from direct.task.Task import Task +from direct.task.TaskManagerGlobal import taskMgr +from direct.task.Timer import Timer + +from otp.avatar.Emote import globalEmote + +from toontown.battle import BattleParticles +from toontown.battle import MovieUtil +from toontown.battle.BattleBase import ( + attackAffectsGroup, + BattleBase, + BATTLE_SMALL_VALUE, + CLIENT_INPUT_TIMEOUT, + FIRE, + HEAL, + levelAffectsGroup, + LURE, + MAX_JOIN_T, + NO_ATTACK, + NO_TRAP, + NPCSOS, + PASS, + PASS_ATTACK, + PETSOS, + SOS, + TRAP, + UN_ATTACK +) + +from toontown.battle.BattleProps import globalPropPool +from toontown.battle.Movie import Movie +from toontown.distributed.DelayDelete import DelayDelete, cleanupDelayDeletes +from toontown.hood import ZoneUtil +from toontown.suit.Suit import Suit +from toontown.toonbase import ToontownBattleGlobals +from toontown.toonbase import ToontownGlobals +from toontown.toonbase.ToonBaseGlobal import base + + +class DistributedBattleBase(DistributedNode, BattleBase): + notify = directNotify.newCategory('DistributedBattleBase') id = 0 camPos = ToontownBattleGlobals.BattleCamDefaultPos camHpr = ToontownBattleGlobals.BattleCamDefaultHpr @@ -32,9 +59,9 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): camJoinHpr = ToontownBattleGlobals.BattleCamJoinHpr def __init__(self, cr, townBattle): - DistributedNode.DistributedNode.__init__(self, cr) + DistributedNode.__init__(self, cr) NodePath.__init__(self) - self.assign(render.attachNewNode(self.uniqueBattleName('distributed-battle'))) + self.assign(base.render.attachNewNode(self.uniqueBattleName('distributed-battle'))) BattleBase.__init__(self) self.bossBattle = 0 self.townBattle = townBattle @@ -50,35 +77,34 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.localToonBattleEvent = self.uniqueBattleName('localtoon-battle-event') self.adjustName = self.uniqueBattleName('adjust') self.timerCountdownTaskName = self.uniqueBattleName('timer-countdown') - self.movie = Movie.Movie(self) + self.movie = Movie(self) self.timer = Timer() self.needAdjustTownBattle = 0 self.streetBattle = 1 self.levelBattle = 0 - self.localToonFsm = ClassicFSM.ClassicFSM('LocalToon', [State.State('HasLocalToon', self.enterHasLocalToon, self.exitHasLocalToon, ['NoLocalToon', 'WaitForServer']), State.State('NoLocalToon', self.enterNoLocalToon, self.exitNoLocalToon, ['HasLocalToon', 'WaitForServer']), State.State('WaitForServer', self.enterWaitForServer, self.exitWaitForServer, ['HasLocalToon', 'NoLocalToon'])], 'WaitForServer', 'WaitForServer') + self.localToonFsm = ClassicFSM('LocalToon', [State('HasLocalToon', self.enterHasLocalToon, self.exitHasLocalToon, ['NoLocalToon', 'WaitForServer']), State('NoLocalToon', self.enterNoLocalToon, self.exitNoLocalToon, ['HasLocalToon', 'WaitForServer']), State('WaitForServer', self.enterWaitForServer, self.exitWaitForServer, ['HasLocalToon', 'NoLocalToon'])], 'WaitForServer', 'WaitForServer') self.localToonFsm.enterInitialState() - self.fsm = ClassicFSM.ClassicFSM('DistributedBattle', [State.State('Off', self.enterOff, self.exitOff, ['FaceOff', + self.fsm = ClassicFSM('DistributedBattle', [State('Off', self.enterOff, self.exitOff, ['FaceOff', 'WaitForInput', 'WaitForJoin', 'MakeMovie', 'PlayMovie', 'Reward', 'Resume']), - State.State('FaceOff', self.enterFaceOff, self.exitFaceOff, ['WaitForInput']), - State.State('WaitForJoin', self.enterWaitForJoin, self.exitWaitForJoin, ['WaitForInput', 'Resume']), - State.State('WaitForInput', self.enterWaitForInput, self.exitWaitForInput, ['WaitForInput', 'PlayMovie', 'Resume']), - State.State('MakeMovie', self.enterMakeMovie, self.exitMakeMovie, ['PlayMovie', 'Resume']), - State.State('PlayMovie', self.enterPlayMovie, self.exitPlayMovie, ['WaitForInput', + State('FaceOff', self.enterFaceOff, self.exitFaceOff, ['WaitForInput']), + State('WaitForJoin', self.enterWaitForJoin, self.exitWaitForJoin, ['WaitForInput', 'Resume']), + State('WaitForInput', self.enterWaitForInput, self.exitWaitForInput, ['WaitForInput', 'PlayMovie', 'Resume']), + State('MakeMovie', self.enterMakeMovie, self.exitMakeMovie, ['PlayMovie', 'Resume']), + State('PlayMovie', self.enterPlayMovie, self.exitPlayMovie, ['WaitForInput', 'WaitForJoin', 'Reward', 'Resume']), - State.State('Reward', self.enterReward, self.exitReward, ['Resume']), - State.State('Resume', self.enterResume, self.exitResume, [])], 'Off', 'Off') + State('Reward', self.enterReward, self.exitReward, ['Resume']), + State('Resume', self.enterResume, self.exitResume, [])], 'Off', 'Off') self.fsm.enterInitialState() - self.adjustFsm = ClassicFSM.ClassicFSM('Adjust', [State.State('Adjusting', self.enterAdjusting, self.exitAdjusting, ['NotAdjusting']), State.State('NotAdjusting', self.enterNotAdjusting, self.exitNotAdjusting, ['Adjusting'])], 'NotAdjusting', 'NotAdjusting') + self.adjustFsm = ClassicFSM('Adjust', [State('Adjusting', self.enterAdjusting, self.exitAdjusting, ['NotAdjusting']), State('NotAdjusting', self.enterNotAdjusting, self.exitNotAdjusting, ['Adjusting'])], 'NotAdjusting', 'NotAdjusting') self.adjustFsm.enterInitialState() self.interactiveProp = None - return def uniqueBattleName(self, name): DistributedBattleBase.id += 1 @@ -86,9 +112,9 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def generate(self): self.notify.debug('generate(%s)' % self.doId) - DistributedNode.DistributedNode.generate(self) + DistributedNode.generate(self) self.__battleCleanedUp = 0 - self.reparentTo(render) + self.reparentTo(base.render) self._skippingRewardMovie = False def storeInterval(self, interval, name): @@ -96,12 +122,13 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): ival = self.activeIntervals[name] if hasattr(ival, 'delayDelete') or hasattr(ival, 'delayDeletes'): self.clearInterval(name, finish=1) + self.activeIntervals[name] = interval def __cleanupIntervals(self): for interval in list(self.activeIntervals.values()): interval.finish() - DelayDelete.cleanupDelayDeletes(interval) + cleanupDelayDeletes(interval) self.activeIntervals = {} @@ -112,8 +139,9 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): ival.finish() else: ival.pause() + if name in self.activeIntervals: - DelayDelete.cleanupDelayDeletes(ival) + cleanupDelayDeletes(ival) if name in self.activeIntervals: del self.activeIntervals[name] else: @@ -127,7 +155,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def disable(self): self.notify.debug('disable(%s)' % self.doId) self.cleanupBattle() - DistributedNode.DistributedNode.disable(self) + DistributedNode.disable(self) def battleCleanedUp(self): return self.__battleCleanedUp @@ -135,6 +163,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def cleanupBattle(self): if self.__battleCleanedUp: return + self.notify.debug('cleanupBattle(%s)' % self.doId) self.__battleCleanedUp = 1 self.__cleanupIntervals() @@ -142,12 +171,14 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if self.hasLocalToon(): self.removeLocalToon() base.camLens.setFov(ToontownGlobals.DefaultCameraFov) + self.localToonFsm.request('WaitForServer') self.ignoreAll() for suit in self.suits: if suit.battleTrap != NO_TRAP: self.notify.debug('250 calling self.removeTrap, suit=%d' % suit.doId) self.removeTrap(suit) + suit.battleTrap = NO_TRAP suit.battleTrapProp = None self.notify.debug('253 suit.battleTrapProp = None') @@ -166,7 +197,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.__stopTimer() self.__cleanupIntervals() self._removeMembersKeep() - return def delete(self): self.notify.debug('delete(%s)' % self.doId) @@ -180,13 +210,12 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.adjustFsm = None self.__stopTimer() self.timer = None - DistributedNode.DistributedNode.delete(self) - return + DistributedNode.delete(self) def loadTrap(self, suit, trapid): self.notify.debug('loadTrap() trap: %d suit: %d' % (trapid, suit.doId)) - trapName = AvProps[TRAP][trapid] - trap = BattleProps.globalPropPool.getProp(trapName) + trapName = ToontownBattleGlobals.AvProps[TRAP][trapid] + trap = globalPropPool.getProp(trapName) suit.battleTrap = trapid suit.battleTrapIsFresh = 0 suit.battleTrapProp = trap @@ -195,6 +224,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): pass else: trap.wrtReparentTo(suit) + distance = MovieUtil.SUIT_TRAP_DISTANCE if trapName == 'rake': distance = MovieUtil.SUIT_TRAP_RAKE_DISTANCE @@ -212,8 +242,9 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): sparks = BattleParticles.createParticleEffect(file='tnt') trap.sparksEffect = sparks sparks.start(tip) + trap.setPos(0, distance, 0) - if isinstance(trap, Actor.Actor): + if isinstance(trap, Actor): frame = trap.getNumFrames(trapName) - 1 trap.pose(trapName, frame) @@ -223,7 +254,8 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.notify.debug('suit.battleTrapProp == None, suit.battleTrap=%s setting to NO_TRAP, returning' % suit.battleTrap) suit.battleTrap = NO_TRAP return - if suit.battleTrap == UBER_GAG_LEVEL_INDEX: + + if suit.battleTrap == ToontownBattleGlobals.UBER_GAG_LEVEL_INDEX: if removeTrainTrack: self.notify.debug('doing removeProp on traintrack') MovieUtil.removeProp(suit.battleTrapProp) @@ -233,17 +265,16 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.notify.debug('351 otherSuit=%d otherSuit.battleTrapProp = None' % otherSuit.doId) otherSuit.battleTrap = NO_TRAP otherSuit.battleTrapIsFresh = 0 - else: self.notify.debug('deliberately not doing removeProp on traintrack') else: self.notify.debug('suit.battleTrap != UBER_GAG_LEVEL_INDEX') MovieUtil.removeProp(suit.battleTrapProp) + suit.battleTrapProp = None self.notify.debug('360 suit.battleTrapProp = None') suit.battleTrap = NO_TRAP suit.battleTrapIsFresh = 0 - return def pause(self): self.timer.stop() @@ -256,21 +287,19 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if s.doId == id: return s - return None - def findToon(self, id): toon = self.getToon(id) if toon == None: return + for t in self.toons: if t == toon: return t - return - def isSuitLured(self, suit): if self.luredSuits.count(suit) != 0: return 1 + return 0 def unlureSuit(self, suit): @@ -278,19 +307,18 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if self.luredSuits.count(suit) != 0: self.luredSuits.remove(suit) self.needAdjustTownBattle = 1 - return None def lureSuit(self, suit): self.notify.debug('movie luring suit %s' % suit.doId) if self.luredSuits.count(suit) == 0: self.luredSuits.append(suit) self.needAdjustTownBattle = 1 - return None def getActorPosHpr(self, actor, actorList = []): - if isinstance(actor, Suit.Suit): + if isinstance(actor, Suit): if actorList == []: actorList = self.activeSuits + if actorList.count(actor) != 0: numSuits = len(actorList) - 1 index = actorList.index(actor) @@ -301,6 +329,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): else: if actorList == []: actorList = self.activeToons + if actorList.count(actor) != 0: numToons = len(actorList) - 1 index = actorList.index(actor) @@ -339,12 +368,14 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def setState(self, state, timestamp): if self.__battleCleanedUp: return + self.notify.debug('setState(%s)' % state) self.fsm.request(state, [globalClockDelta.localElapsedTime(timestamp)]) def setMembers(self, suits, suitsJoining, suitsPending, suitsActive, suitsLured, suitTraps, toons, toonsJoining, toonsPending, toonsActive, toonsRunning, timestamp): if self.__battleCleanedUp: return + self.notify.debug('setMembers() - suits: %s suitsJoining: %s suitsPending: %s suitsActive: %s suitsLured: %s suitTraps: %s toons: %s toonsJoining: %s toonsPending: %s toonsActive: %s toonsRunning: %s' % (suits, suitsJoining, suitsPending, @@ -373,7 +404,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): suit.battleTrapProp = None self.notify.debug('496 suit.battleTrapProp = None') suit.battleTrapIsFresh = 0 - else: self.notify.warning('setMembers() - no suit in repository: %d' % s) self.suits.append(None) @@ -391,6 +421,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if not trainTrap.isEmpty(): self.notify.debug('removing old train trap when 4 suits died') trainTrap.removeNode() + for s in suitsJoining: suit = self.suits[int(s)] if suit != None and self.joiningSuits.count(suit) == 0: @@ -428,12 +459,14 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): trapid = int(s) if trapid == 9: trapid = -1 + suit = self.suits[index] index += 1 if suit != None: if (trapid == NO_TRAP or trapid != suit.battleTrap) and suit.battleTrapProp != None: self.notify.debug('569 calling self.removeTrap, suit=%d' % suit.doId) self.removeTrap(suit) + if trapid != NO_TRAP and suit.battleTrapProp == None: if self.fsm.getCurrentState().getName() != 'PlayMovie': self.loadTrap(suit, trapid) @@ -454,6 +487,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.suits = validSuits self.needAdjustTownBattle = 1 + oldtoons = self.toons self.toons = [] toonGone = 0 @@ -464,6 +498,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.toons.append(None) toonGone = 1 continue + self.toons.append(toon) if oldtoons.count(toon) == 0: self.notify.debug('setMembers() - add toon: %d' % toon.doId) @@ -506,6 +541,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if len(activeSuits) > 0 or len(activeToons) > 0: self.__makeAvsActive(activeSuits, activeToons) + if toonGone == 1: validToons = [] for toon in self.toons: @@ -513,15 +549,19 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): validToons.append(toon) self.toons = validToons + if len(self.activeToons) > 0: self.__requestAdjustTownBattle() + currStateName = self.localToonFsm.getCurrentState().getName() if self.toons.count(base.localAvatar): if oldtoons.count(base.localAvatar) == 0: self.notify.debug('setMembers() - local toon just joined') if self.streetBattle == 1: base.cr.playGame.getPlace().enterZone(self.zoneId) + self.localToonJustJoined = 1 + if currStateName != 'HasLocalToon': self.localToonFsm.request('HasLocalToon') else: @@ -529,19 +569,23 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.notify.debug('setMembers() - local toon just ran') if self.levelBattle: self.unlockLevelViz() + if currStateName != 'NoLocalToon': self.localToonFsm.request('NoLocalToon') + return oldtoons def adjust(self, timestamp): if self.__battleCleanedUp: return + self.notify.debug('adjust(%f) from server' % globalClockDelta.localElapsedTime(timestamp)) self.adjustFsm.request('Adjusting', [globalClockDelta.localElapsedTime(timestamp)]) def setMovie(self, active, toons, suits, id0, tr0, le0, tg0, hp0, ac0, hpb0, kbb0, died0, revive0, id1, tr1, le1, tg1, hp1, ac1, hpb1, kbb1, died1, revive1, id2, tr2, le2, tg2, hp2, ac2, hpb2, kbb2, died2, revive2, id3, tr3, le3, tg3, hp3, ac3, hpb3, kbb3, died3, revive3, sid0, at0, stg0, dm0, sd0, sb0, st0, sid1, at1, stg1, dm1, sd1, sb1, st1, sid2, at2, stg2, dm2, sd2, sb2, st2, sid3, at3, stg3, dm3, sd3, sb3, st3): if self.__battleCleanedUp: return + self.notify.debug('setMovie()') if int(active) == 1: self.notify.debug('setMovie() - movie is active') @@ -550,6 +594,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def setChosenToonAttacks(self, ids, tracks, levels, targets): if self.__battleCleanedUp: return + self.notify.debug('setChosenToonAttacks() - (%s), (%s), (%s), (%s)' % (ids, tracks, levels, @@ -569,8 +614,10 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): levels.append(-1) targetIndices.append(-1) continue + if toon == base.localAvatar: localToonInList = 1 + toonIndices.append(self.activeToons.index(toon)) if track == SOS: targetIndex = -1 @@ -603,6 +650,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): targetIndex = self.activeSuits.index(target) else: targetIndex = -1 + targetIndices.append(targetIndex) for i in range(4 - len(ids)): @@ -619,12 +667,13 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if unAttack == 1 and self.fsm.getCurrentState().getName() == 'WaitForInput': if self.townBattle.fsm.getCurrentState().getName() != 'Attack': self.townBattle.setState('Attack') + self.townBattle.updateChosenAttacks(self.townBattleAttacks[0], self.townBattleAttacks[1], self.townBattleAttacks[2], self.townBattleAttacks[3]) - return def setBattleExperience(self, id0, origExp0, earnedExp0, origQuests0, items0, missedItems0, origMerits0, merits0, parts0, id1, origExp1, earnedExp1, origQuests1, items1, missedItems1, origMerits1, merits1, parts1, id2, origExp2, earnedExp2, origQuests2, items2, missedItems2, origMerits2, merits2, parts2, id3, origExp3, earnedExp3, origQuests3, items3, missedItems3, origMerits3, merits3, parts3, deathList, uberList, helpfulToonsList): if self.__battleCleanedUp: return + self.movie.genRewardDicts(id0, origExp0, earnedExp0, origQuests0, items0, missedItems0, origMerits0, merits0, parts0, id1, origExp1, earnedExp1, origQuests1, items1, missedItems1, origMerits1, merits1, parts1, id2, origExp2, earnedExp2, origQuests2, items2, missedItems2, origMerits2, merits2, parts2, id3, origExp3, earnedExp3, origQuests3, items3, missedItems3, origMerits3, merits3, parts3, deathList, uberList, helpfulToonsList) def __listenForUnexpectedExit(self, toon): @@ -644,10 +693,10 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def delayDeleteMembers(self): membersKeep = [] for t in self.toons: - membersKeep.append(DelayDelete.DelayDelete(t, 'delayDeleteMembers')) + membersKeep.append(DelayDelete(t, 'delayDeleteMembers')) for s in self.suits: - membersKeep.append(DelayDelete.DelayDelete(s, 'delayDeleteMembers')) + membersKeep.append(DelayDelete(s, 'delayDeleteMembers')) self._removeMembersKeep() self.membersKeep = membersKeep @@ -658,45 +707,53 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): delayDelete.destroy() self.membersKeep = None - return def __removeSuit(self, suit): self.notify.debug('__removeSuit(%d)' % suit.doId) if self.suits.count(suit) != 0: self.suits.remove(suit) + if self.joiningSuits.count(suit) != 0: self.joiningSuits.remove(suit) + if self.pendingSuits.count(suit) != 0: self.pendingSuits.remove(suit) + if self.activeSuits.count(suit) != 0: self.activeSuits.remove(suit) + self.suitGone = 1 if suit.battleTrap != NO_TRAP: self.notify.debug('882 calling self.removeTrap, suit=%d' % suit.doId) self.removeTrap(suit) + suit.battleTrap = NO_TRAP suit.battleTrapProp = None self.notify.debug('883 suit.battleTrapProp = None') suit.battleTrapIsFresh = 0 - return def __removeToon(self, toon, unexpected = 0): self.notify.debug('__removeToon(%d)' % toon.doId) self.exitedToons.append(toon) if self.toons.count(toon) != 0: self.toons.remove(toon) + if self.joiningToons.count(toon) != 0: self.clearInterval(self.taskName('to-pending-toon-%d' % toon.doId)) if toon in self.joiningToons: self.joiningToons.remove(toon) + if self.pendingToons.count(toon) != 0: self.pendingToons.remove(toon) + if self.activeToons.count(toon) != 0: self.activeToons.remove(toon) + if self.runningToons.count(toon) != 0: self.clearInterval(self.taskName('running-%d' % toon.doId), finish=1) if toon in self.runningToons: self.runningToons.remove(toon) + self.ignore(toon.uniqueName('disable')) self.ignore(toon.uniqueName('died')) self.toonGone = 1 @@ -704,28 +761,33 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.removeLocalToon() self.__teleportToSafeZone(toon) return 1 + return 0 def removeLocalToon(self): if self._skippingRewardMovie: return + if base.cr.playGame.getPlace() != None: base.cr.playGame.getPlace().setState('walk') + base.localAvatar.earnedExperience = None self.localToonFsm.request('NoLocalToon') - return def removeInactiveLocalToon(self, toon): self.notify.debug('removeInactiveLocalToon(%d)' % toon.doId) self.exitedToons.append(toon) if self.toons.count(toon) != 0: self.toons.remove(toon) + if self.joiningToons.count(toon) != 0: self.clearInterval(self.taskName('to-pending-toon-%d' % toon.doId), finish=1) if toon in self.joiningToons: self.joiningToons.remove(toon) + if self.pendingToons.count(toon) != 0: self.pendingToons.remove(toon) + self.ignore(toon.uniqueName('disable')) self.ignore(toon.uniqueName('died')) base.cr.playGame.getPlace().setState('walk') @@ -733,7 +795,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def __createJoinInterval(self, av, destPos, destHpr, name, ts, callback, toon = 0): joinTrack = Sequence() - joinTrack.append(Func(Emote.globalEmote.disableAll, av, 'dbattlebase, createJoinInterval')) + joinTrack.append(Func(globalEmote.disableAll, av, 'dbattlebase, createJoinInterval')) avPos = av.getPos(self) avPos = Point3(avPos[0], avPos[1], 0.0) av.setShadowHeight(0) @@ -746,6 +808,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): else: timeToDest = self.calcToonMoveTime(avPos, destPos) joinTrack.append(Func(av.loop, 'run')) + if timeToDest > BATTLE_SMALL_VALUE: joinTrack.append(LerpPosInterval(av, timeToDest, destPos, other=self)) totalTime = timeToDest @@ -761,14 +824,17 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): timeToPerimeter = self.calcToonMoveTime(plist[0], avPos) timePerSegment = 10.0 / BattleBase.toonSpeed timeToDest = self.calcToonMoveTime(BattleBase.posE, destPos) + totalTime = timeToPerimeter + (len(plist) - 1) * timePerSegment + timeToDest if totalTime > MAX_JOIN_T: self.notify.warning('__createJoinInterval() - time: %f' % totalTime) + joinTrack.append(Func(av.headsUp, self, plist[0])) if toon == 0: joinTrack.append(Func(av.loop, 'walk')) else: joinTrack.append(Func(av.loop, 'run')) + joinTrack.append(LerpPosInterval(av, timeToPerimeter, plist[0], other=self)) for p in plist[1:]: joinTrack.append(Func(av.headsUp, self, p)) @@ -776,12 +842,14 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): joinTrack.append(Func(av.headsUp, self, destPos)) joinTrack.append(LerpPosInterval(av, timeToDest, destPos, other=self)) + joinTrack.append(Func(av.loop, 'neutral')) joinTrack.append(Func(av.headsUp, self, Point3(0, 0, 0))) tval = totalTime - ts if tval < 0: tval = totalTime - joinTrack.append(Func(Emote.globalEmote.releaseAll, av, 'dbattlebase, createJoinInterval')) + + joinTrack.append(Func(globalEmote.releaseAll, av, 'dbattlebase, createJoinInterval')) joinTrack.append(Func(callback, av, tval)) if av == base.localAvatar: camTrack = Sequence() @@ -790,9 +858,9 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): base.camLens.setFov(fov) camTrack.append(Func(setCamFov, self.camFov)) - camTrack.append(Func(camera.wrtReparentTo, self)) - camTrack.append(Func(camera.setPos, self.camJoinPos)) - camTrack.append(Func(camera.setHpr, self.camJoinHpr)) + camTrack.append(Func(base.camera.wrtReparentTo, self)) + camTrack.append(Func(base.camera.setPos, self.camJoinPos)) + camTrack.append(Func(base.camera.setHpr, self.camJoinHpr)) return Parallel(joinTrack, camTrack, name=name) else: return Sequence(joinTrack, name=name) @@ -808,7 +876,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): trackName = self.taskName('to-pending-suit-%d' % suit.doId) track = self.__createJoinInterval(suit, pos, hpr, trackName, ts, self.__handleSuitJoinDone) track.start(ts) - track.delayDelete = DelayDelete.DelayDelete(suit, 'makeSuitJoin') + track.delayDelete = DelayDelete(suit, 'makeSuitJoin') self.storeInterval(track, trackName) if ToontownBattleGlobals.SkipMovie: track.finish() @@ -823,6 +891,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.clearInterval(self.taskName('to-pending-suit-%d' % suit.doId), finish=1) if self.joiningSuits.count(suit): self.joiningSuits.remove(suit) + self.pendingSuits.append(suit) def __teleportToSafeZone(self, toon): @@ -832,6 +901,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): target_sz = ZoneUtil.getSafeZoneId(self.zoneId) else: target_sz = ZoneUtil.getSafeZoneId(base.localAvatar.defaultZone) + base.cr.playGame.getPlace().fsm.request('teleportOut', [{'loader': ZoneUtil.getLoaderName(target_sz), 'where': ZoneUtil.getWhereName(target_sz, 1), 'how': 'teleportIn', @@ -840,7 +910,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): 'shardId': None, 'avId': -1, 'battle': 1}]) - return def __makeToonJoin(self, toon, pendingToons, ts): self.notify.debug('__makeToonJoin(%d)' % toon.doId) @@ -853,8 +922,9 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): track = self.__createJoinInterval(toon, pos, hpr, trackName, ts, self.__handleToonJoinDone, toon=1) if toon != base.localAvatar: toon.animFSM.request('off') + track.start(ts) - track.delayDelete = DelayDelete.DelayDelete(toon, '__makeToonJoin') + track.delayDelete = DelayDelete(toon, '__makeToonJoin') self.storeInterval(track, trackName) def __handleToonJoinDone(self, toon, ts): @@ -867,6 +937,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.clearInterval(self.taskName('to-pending-toon-%d' % toon.doId), finish=1) if self.joiningToons.count(toon): self.joiningToons.remove(toon) + spotIndex = len(self.pendingToons) self.pendingToons.append(toon) openSpot = self.toonPendingPoints[spotIndex] @@ -874,8 +945,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): hpr = VBase3(openSpot[1], 0.0, 0.0) toon.loop('neutral') toon.setPosHpr(self, pos, hpr) - if base.localAvatar == toon: - currStateName = self.fsm.getCurrentState().getName() def __makeAvsActive(self, suits, toons): self.notify.debug('__makeAvsActive()') @@ -884,8 +953,10 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if self.joiningSuits.count(s): self.notify.warning('suit: %d was in joining list!' % s.doId) self.joiningSuits.remove(s) + if self.pendingSuits.count(s): self.pendingSuits.remove(s) + self.notify.debug('__makeAvsActive() - suit: %d' % s.doId) self.activeSuits.append(s) @@ -897,14 +968,17 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): else: spos = Point3(suitPos[0], suitPos[1] - MovieUtil.SUIT_LURE_DISTANCE, suitPos[2]) suit.setPosHpr(self, spos, suitHpr) + suit.loop('neutral') for toon in toons: if self.joiningToons.count(toon): self.notify.warning('toon: %d was in joining list!' % toon.doId) self.joiningToons.remove(toon) + if self.pendingToons.count(toon): self.pendingToons.remove(toon) + self.notify.debug('__makeAvsActive() - toon: %d' % toon.doId) if self.activeToons.count(toon) == 0: self.activeToons.append(toon) @@ -927,16 +1001,18 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.notify.debug('__makeToonRun(%d)' % toon.doId) if self.activeToons.count(toon): self.activeToons.remove(toon) + self.runningToons.append(toon) self.toonGone = 1 self.__stopTimer() if self.localToonRunning(): self.townBattle.setState('Off') + runMTrack = MovieUtil.getToonTeleportOutInterval(toon) runName = self.taskName('running-%d' % toon.doId) self.notify.debug('duration: %f' % runMTrack.getDuration()) runMTrack.start(ts) - runMTrack.delayDelete = DelayDelete.DelayDelete(toon, '__makeToonRun') + runMTrack.delayDelete = DelayDelete(toon, '__makeToonRun') self.storeInterval(runMTrack, runName) def getToon(self, toonId): @@ -944,8 +1020,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): return self.cr.doId2do[toonId] else: self.notify.warning('getToon() - toon: %d not in repository!' % toonId) - return None - return None def d_toonRequestJoin(self, toonId, pos): self.notify.debug('network:toonRequestJoin()') @@ -993,27 +1067,25 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def enterOff(self, ts = 0): self.localToonFsm.requestFinalState() - return None def exitOff(self): - return None + pass def enterFaceOff(self, ts = 0): - return None + pass def exitFaceOff(self): - return None + pass def enterWaitForJoin(self, ts = 0): self.notify.debug('enterWaitForJoin()') - return None def exitWaitForJoin(self): - return None + pass def __enterLocalToonWaitForInput(self): self.notify.debug('enterLocalToonWaitForInput()') - camera.setPosHpr(self.camPos, self.camHpr) + base.camera.setPosHpr(self.camPos, self.camHpr) base.camLens.setFov(self.camMenuFov) NametagGlobals.setMasterArrowsOn(0) self.townBattle.setState('Attack') @@ -1025,6 +1097,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.notify.warning('startTimer() - ts: %f timeout: %f' % (ts, CLIENT_INPUT_TIMEOUT)) self.__timedOut() return + self.timer.startCallback(CLIENT_INPUT_TIMEOUT - ts, self.__timedOut) timeTask = Task.loop(Task(self.__countdown), Task.pause(0.2)) taskMgr.add(timeTask, self.timerCountdownTaskName) @@ -1040,19 +1113,21 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): else: self.notify.warning('__countdown has tried to update a timer that has been deleted. Stopping timer') self.__stopTimer() - return Task.done + + return task.done def enterWaitForInput(self, ts = 0): self.notify.debug('enterWaitForInput()') if self.interactiveProp: self.interactiveProp.gotoBattleCheer() + self.choseAttackAlready = 0 if self.localToonActive(): self.__enterLocalToonWaitForInput() self.startTimer(ts) + if self.needAdjustTownBattle == 1: self.__adjustTownBattle() - return None def exitWaitForInput(self): self.notify.debug('exitWaitForInput()') @@ -1061,7 +1136,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): base.camLens.setFov(self.camFov) self.ignore(self.localToonBattleEvent) self.__stopTimer() - return None def __handleLocalToonBattleEvent(self, response): mode = response['mode'] @@ -1089,6 +1163,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): targetId = self.activeSuits[target].doId else: target = -1 + if len(self.luredSuits) > 0: if track == TRAP or track == LURE and not levelAffectsGroup(LURE, level): if target != -1: @@ -1104,6 +1179,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): track = -1 level = -1 targetId = -1 + if track == TRAP: if target != -1: if attackAffectsGroup(track, level): @@ -1115,6 +1191,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): track = -1 level = -1 targetId = -1 + self.d_requestAttack(base.localAvatar.doId, track, level, targetId) elif mode == 'Run': self.notify.debug('got a run') @@ -1141,6 +1218,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): messenger.send(proxyGenerateMessage) else: self.d_requestPetProxy(base.localAvatar.doId, petProxyId) + noAttack = 1 elif mode == 'Pass': targetId = response['id'] @@ -1156,6 +1234,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): else: self.notify.warning('unknown battle response') return + if noAttack == 1: self.choseAttackAlready = 0 else: @@ -1164,6 +1243,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def __timedOut(self): if self.choseAttackAlready == 1: return + self.notify.debug('WaitForInput timed out') if self.localToonActive(): self.notify.debug('battle timed out') @@ -1171,27 +1251,27 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): def enterMakeMovie(self, ts = 0): self.notify.debug('enterMakeMovie()') - return None def exitMakeMovie(self): - return None + pass def enterPlayMovie(self, ts): self.notify.debug('enterPlayMovie()') self.delayDeleteMembers() if self.hasLocalToon(): NametagGlobals.setMasterArrowsOn(0) + if ToontownBattleGlobals.SkipMovie: self.movie.play(ts, self.__handleMovieDone) self.movie.finish() else: self.movie.play(ts, self.__handleMovieDone) - return None def __handleMovieDone(self): self.notify.debug('__handleMovieDone()') if self.hasLocalToon(): self.d_movieDone(base.localAvatar.doId) + self.movie.reset() def exitPlayMovie(self): @@ -1214,7 +1294,6 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): 0, 0, 0]) - return None def hasLocalToon(self): return self.toons.count(base.localAvatar) > 0 @@ -1235,59 +1314,61 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.notify.debug('enterHasLocalToon()') if base.cr.playGame.getPlace() != None: base.cr.playGame.getPlace().setState('battle', self.localToonBattleEvent) - if localAvatar and hasattr(localAvatar, 'inventory') and localAvatar.inventory: - localAvatar.inventory.setInteractivePropTrackBonus(self.interactivePropTrackBonus) - camera.wrtReparentTo(self) + if base.localAvatar and hasattr(base.localAvatar, 'inventory') and base.localAvatar.inventory: + base.localAvatar.inventory.setInteractivePropTrackBonus(self.interactivePropTrackBonus) + + base.camera.wrtReparentTo(self) base.camLens.setFov(self.camFov) - return def exitHasLocalToon(self): self.ignore(self.localToonBattleEvent) self.__stopTimer() - if localAvatar and hasattr(localAvatar, 'inventory') and localAvatar.inventory: - localAvatar.inventory.setInteractivePropTrackBonus(-1) + if base.localAvatar and hasattr(base.localAvatar, 'inventory') and base.localAvatar.inventory: + base.localAvatar.inventory.setInteractivePropTrackBonus(-1) + stateName = None place = base.cr.playGame.getPlace() if place: stateName = place.fsm.getCurrentState().getName() + if stateName == 'died': self.movie.reset() - camera.reparentTo(render) - camera.setPosHpr(localAvatar, 5.2, 5.45, localAvatar.getHeight() * 0.66, 131.5, 3.6, 0) + base.camera.reparentTo(base.render) + base.camera.setPosHpr(base.localAvatar, 5.2, 5.45, base.localAvatar.getHeight() * 0.66, 131.5, 3.6, 0) else: - camera.wrtReparentTo(base.localAvatar) + base.camera.wrtReparentTo(base.localAvatar) messenger.send('localToonLeftBattle') + base.camLens.setFov(ToontownGlobals.DefaultCameraFov) - return def enterNoLocalToon(self): self.notify.debug('enterNoLocalToon()') - return None def exitNoLocalToon(self): - return None + pass def setSkippingRewardMovie(self): self._skippingRewardMovie = True def enterWaitForServer(self): self.notify.debug('enterWaitForServer()') - return None def exitWaitForServer(self): - return None + pass def createAdjustInterval(self, av, destPos, destHpr, toon = 0, run = 0): if run == 1: adjustTime = self.calcToonMoveTime(destPos, av.getPos(self)) else: adjustTime = self.calcSuitMoveTime(destPos, av.getPos(self)) + self.notify.debug('creating adjust interval for: %d' % av.doId) adjustTrack = Sequence() if run == 1: adjustTrack.append(Func(av.loop, 'run')) else: adjustTrack.append(Func(av.loop, 'walk')) + adjustTrack.append(Func(av.headsUp, self, destPos)) adjustTrack.append(LerpPosInterval(av, adjustTime, destPos, other=self)) adjustTrack.append(Func(av.setHpr, self, destHpr)) @@ -1307,9 +1388,11 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): destPos = point[0] if self.isSuitLured(suit) == 1: destPos = Point3(destPos[0], destPos[1] - MovieUtil.SUIT_LURE_DISTANCE, destPos[2]) + if pos != destPos: destHpr = VBase3(point[1], 0.0, 0.0) adjustTrack.append(self.createAdjustInterval(suit, destPos, destHpr)) + index += 1 for suit in self.pendingSuits: @@ -1330,6 +1413,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if pos != destPos: destHpr = VBase3(point[1], 0.0, 0.0) adjustTrack.append(self.createAdjustInterval(toon, destPos, destHpr)) + index += 1 for toon in self.pendingToons: @@ -1377,6 +1461,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): for suit in self.luredSuits: if suit not in self.activeSuits: self.notify.error('lured suit not in self.activeSuits') + luredSuits.append(self.activeSuits.index(suit)) trappedSuits = [] @@ -1387,21 +1472,23 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): self.townBattle.adjustCogsAndToons(self.activeSuits, luredSuits, trappedSuits, self.activeToons) if hasattr(self, 'townBattleAttacks'): self.townBattle.updateChosenAttacks(self.townBattleAttacks[0], self.townBattleAttacks[1], self.townBattleAttacks[2], self.townBattleAttacks[3]) + self.needAdjustTownBattle = 0 def __adjustDone(self): self.notify.debug('__adjustDone()') if self.hasLocalToon(): self.d_adjustDone(base.localAvatar.doId) + self.adjustFsm.request('NotAdjusting') def enterAdjusting(self, ts): self.notify.debug('enterAdjusting()') if self.localToonActive(): self.__stopTimer() + self.delayDeleteMembers() self.__adjust(ts, self.__handleAdjustDone) - return None def exitAdjusting(self): self.notify.debug('exitAdjusting()') @@ -1410,14 +1497,12 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): currStateName = self.fsm.getCurrentState().getName() if currStateName == 'WaitForInput' and self.localToonActive(): self.startTimer() - return None def enterNotAdjusting(self): self.notify.debug('enterNotAdjusting()') - return None def exitNotAdjusting(self): - return None + pass def visualize(self): try: @@ -1440,7 +1525,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): p = BattleBase.allPoints[0] lsegs.drawTo(p[0], p[1], p[2]) self.vis = self.attachNewNode(lsegs.create()) - self.reparentTo(render) + self.reparentTo(base.render) self.isVisualized = 1 def setupCollisions(self, name): @@ -1466,14 +1551,17 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): if self.fsm.getCurrentState().getName() == 'Off': self.notify.debug('ignoring collision in Off state') return + if not base.localAvatar.wantBattles: return + if self._skippingRewardMovie: return + base.cr.playGame.getPlace().setState('WaitForBattle') toon = base.localAvatar self.d_toonRequestJoin(toon.doId, toon.getPos(self)) - base.localAvatar.preBattleHpr = base.localAvatar.getHpr(render) + base.localAvatar.preBattleHpr = base.localAvatar.getHpr(base.render) self.localToonFsm.request('WaitForServer') self.onWaitingForJoin() @@ -1485,6 +1573,7 @@ class DistributedBattleBase(DistributedNode.DistributedNode, BattleBase): place = self.cr.playGame.getPlace() if place.fsm.getCurrentState().getName() == 'WaitForBattle': place.setState('walk') + self.localToonFsm.request('NoLocalToon') def disableCollision(self): diff --git a/toontown/battle/MovieLure.py b/toontown/battle/MovieLure.py index 378b0aa..d7dafef 100644 --- a/toontown/battle/MovieLure.py +++ b/toontown/battle/MovieLure.py @@ -98,10 +98,10 @@ def __createFishingPoleMultiTrack(lure, dollar, dollarName): suitTrack.append(Func(suit.loop, 'neutral')) suitTrack.append(Wait(3.5)) suitName = suit.getStyleName() - retardPos, retardHpr = battle.getActorPosHpr(suit) - retardPos.setY(retardPos.getY() + MovieUtil.SUIT_EXTRA_REACH_DISTANCE) + luredPos, luredHpr = battle.getActorPosHpr(suit) + luredPos.setY(luredPos.getY() + MovieUtil.SUIT_EXTRA_REACH_DISTANCE) if suitName in MovieUtil.largeSuits: - moveTrack = lerpSuit(suit, 0.0, reachAnimDuration / 2.5, retardPos, battle, trapProp) + moveTrack = lerpSuit(suit, 0.0, reachAnimDuration / 2.5, luredPos, battle, trapProp) reachTrack = ActorInterval(suit, 'reach', duration=reachAnimDuration) suitTrack.append(Parallel(moveTrack, reachTrack)) else: diff --git a/toontown/building/DistributedDoor.py b/toontown/building/DistributedDoor.py index 42c27e1..fa6af36 100644 --- a/toontown/building/DistributedDoor.py +++ b/toontown/building/DistributedDoor.py @@ -1,48 +1,66 @@ -from toontown.toonbase.ToonBaseGlobal import * -from panda3d.core import * -from direct.interval.IntervalGlobal import * -from direct.distributed.ClockDelta import * -from toontown.toonbase import ToontownGlobals -from direct.directnotify import DirectNotifyGlobal -from direct.fsm import ClassicFSM, State -from direct.distributed import DistributedObject -from toontown.hood import ZoneUtil -from toontown.suit import Suit -from toontown.distributed import DelayDelete -from . import FADoorCodes -from direct.task.Task import Task -from . import DoorTypes -from toontown.toontowngui import TTDialog -from toontown.toonbase import TTLocalizer -from toontown.toontowngui import TeaserPanel -from toontown.distributed.DelayDeletable import DelayDeletable -if (__debug__): - import pdb +from panda3d.core import NodePath, Point3, VBase3, Vec3 +from panda3d.otp import Nametag, NametagGroup -class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.distributed.ClockDelta import globalClockDelta +from direct.distributed.DistributedObject import DistributedObject +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.interval.IntervalGlobal import ( + ActorInterval, + Func, + HprInterval, + LerpHprInterval, + LerpPosHprInterval, + LerpPosInterval, + Parallel, + PosHprInterval, + Sequence, + SoundInterval, + Wait +) + +from direct.showbase.MessengerGlobal import messenger +from direct.task.TaskManagerGlobal import taskMgr + +from toontown.building import DoorTypes +from toontown.building import FADoorCodes +from toontown.distributed.DelayDeletable import DelayDeletable +from toontown.distributed.DelayDelete import DelayDelete, cleanupDelayDeletes +from toontown.hood import ZoneUtil +from toontown.suit.Suit import Suit +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base +from toontown.toontowngui import TTDialog +from toontown.toontowngui.TeaserPanel import TeaserPanel + + +class DistributedDoor(DistributedObject, DelayDeletable): + notify = directNotify.newCategory('DistributedDoor') def __init__(self, cr): - DistributedObject.DistributedObject.__init__(self, cr) + DistributedObject.__init__(self, cr) self.openSfx = base.loader.loadSfx('phase_3.5/audio/sfx/Door_Open_1.ogg') self.closeSfx = base.loader.loadSfx('phase_3.5/audio/sfx/Door_Close_1.ogg') self.nametag = None - self.fsm = ClassicFSM.ClassicFSM('DistributedDoor_right', [State.State('off', self.enterOff, self.exitOff, ['closing', + self.fsm = ClassicFSM('DistributedDoor_right', [State('off', self.enterOff, self.exitOff, ['closing', 'closed', 'opening', 'open']), - State.State('closing', self.enterClosing, self.exitClosing, ['closed', 'opening']), - State.State('closed', self.enterClosed, self.exitClosed, ['opening']), - State.State('opening', self.enterOpening, self.exitOpening, ['open']), - State.State('open', self.enterOpen, self.exitOpen, ['closing', 'open'])], 'off', 'off') + State('closing', self.enterClosing, self.exitClosing, ['closed', 'opening']), + State('closed', self.enterClosed, self.exitClosed, ['opening']), + State('opening', self.enterOpening, self.exitOpening, ['open']), + State('open', self.enterOpen, self.exitOpen, ['closing', 'open'])], 'off', 'off') self.fsm.enterInitialState() - self.exitDoorFSM = ClassicFSM.ClassicFSM('DistributedDoor_left', [State.State('off', self.exitDoorEnterOff, self.exitDoorExitOff, ['closing', + self.exitDoorFSM = ClassicFSM('DistributedDoor_left', [State('off', self.exitDoorEnterOff, self.exitDoorExitOff, ['closing', 'closed', 'opening', 'open']), - State.State('closing', self.exitDoorEnterClosing, self.exitDoorExitClosing, ['closed', 'opening']), - State.State('closed', self.exitDoorEnterClosed, self.exitDoorExitClosed, ['opening']), - State.State('opening', self.exitDoorEnterOpening, self.exitDoorExitOpening, ['open']), - State.State('open', self.exitDoorEnterOpen, self.exitDoorExitOpen, ['closing', 'open'])], 'off', 'off') + State('closing', self.exitDoorEnterClosing, self.exitDoorExitClosing, ['closed', 'opening']), + State('closed', self.exitDoorEnterClosed, self.exitDoorExitClosed, ['opening']), + State('opening', self.exitDoorEnterOpening, self.exitDoorExitOpening, ['open']), + State('open', self.exitDoorEnterOpen, self.exitDoorExitOpen, ['closing', 'open'])], 'off', 'off') self.exitDoorFSM.enterInitialState() self.specialDoorTypes = {DoorTypes.EXT_HQ: 0, DoorTypes.EXT_COGHQ: 0, @@ -50,17 +68,15 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): DoorTypes.EXT_KS: 0, DoorTypes.INT_KS: 0} self.doorX = 1.5 - return def generate(self): - DistributedObject.DistributedObject.generate(self) + DistributedObject.generate(self) self.avatarTracks = [] self.avatarExitTracks = [] self.avatarIDList = [] self.avatarExitIDList = [] self.doorTrack = None self.doorExitTrack = None - return def disable(self): self.clearNametag() @@ -72,20 +88,22 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.exitDoorFSM.request('off') if 'building' in self.__dict__: del self.building + self.finishAllTracks() self.avatarIDList = [] self.avatarExitIDList = [] if hasattr(self, 'tempDoorNodePath'): self.tempDoorNodePath.removeNode() del self.tempDoorNodePath - DistributedObject.DistributedObject.disable(self) + + DistributedObject.disable(self) def delete(self): del self.fsm del self.exitDoorFSM del self.openSfx del self.closeSfx - DistributedObject.DistributedObject.delete(self) + DistributedObject.delete(self) def wantsNametag(self): return not ZoneUtil.isInterior(self.zoneId) @@ -93,11 +111,13 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def setupNametag(self): if not self.wantsNametag(): return + if self.nametag == None: self.nametag = NametagGroup() self.nametag.setFont(ToontownGlobals.getBuildingNametagFont()) if TTLocalizer.BuildingNametagShadow: self.nametag.setShadow(*TTLocalizer.BuildingNametagShadow) + self.nametag.setContents(Nametag.CName) self.nametag.setColorCode(NametagGroup.CCToonBuilding) self.nametag.setActive(0) @@ -106,14 +126,12 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): name = self.cr.playGame.dnaStore.getTitleFromBlockNumber(self.block) self.nametag.setName(name) self.nametag.manage(base.marginManager) - return def clearNametag(self): if self.nametag != None: self.nametag.unmanage(base.marginManager) self.nametag.setAvatar(NodePath()) self.nametag = None - return def getTriggerName(self): if self.doorType == DoorTypes.INT_HQ or self.doorType in self.specialDoorTypes: @@ -137,26 +155,25 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.hideIfHasFlat(self.findDoorNode('leftDoor')) self.findDoorNode('doorFrameHoleRight').hide() self.findDoorNode('doorFrameHoleLeft').hide() - else: - return def setTriggerName(self): if self.doorType in self.specialDoorTypes: building = self.getBuilding() doorTrigger = building.find('**/door_' + str(self.doorIndex) + '/**/door_trigger*') doorTrigger.node().setName(self.getTriggerName()) - else: - return def setTriggerName_wip(self): building = self.getBuilding() doorTrigger = building.find('**/door_%d/**/door_trigger_%d' % (self.doorIndex, self.block)) if doorTrigger.isEmpty(): doorTrigger = building.find('**/door_trigger_%d' % (self.block,)) + if doorTrigger.isEmpty(): doorTrigger = building.find('**/door_%d/**/door_trigger_*' % (self.doorIndex,)) + if doorTrigger.isEmpty(): doorTrigger = building.find('**/door_trigger_*') + doorTrigger.node().setName(self.getTriggerName()) def setZoneIdAndBlock(self, zoneId, block): @@ -185,7 +202,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.exitDoorFSM.request(state, [globalClockDelta.localElapsedTime(timestamp)]) def announceGenerate(self): - DistributedObject.DistributedObject.announceGenerate(self) + DistributedObject.announceGenerate(self) self.doPostAnnounceGenerate() def doPostAnnounceGenerate(self): @@ -193,6 +210,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.bHasFlat = True else: self.bHasFlat = not self.findDoorNode('door*flat', True).isEmpty() + self.hideDoorParts() self.setTriggerName() self.accept(self.getEnterTriggerEvent(), self.doorTrigger) @@ -202,13 +220,13 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def getBuilding(self): if 'building' not in self.__dict__: if self.doorType == DoorTypes.INT_STANDARD: - door = render.find('**/leftDoor;+s') + door = base.render.find('**/leftDoor;+s') self.building = door.getParent() elif self.doorType == DoorTypes.INT_HQ: - door = render.find('**/door_0') + door = base.render.find('**/door_0') self.building = door.getParent() elif self.doorType == DoorTypes.INT_KS: - self.building = render.find('**/KartShop_Interior*') + self.building = base.render.find('**/KartShop_Interior*') elif self.doorType == DoorTypes.EXT_STANDARD or self.doorType == DoorTypes.EXT_HQ or self.doorType == DoorTypes.EXT_KS: self.building = self.cr.playGame.hood.loader.geom.find('**/??' + str(self.block) + ':*_landmark_*_DNARoot;+s') if self.building.isEmpty(): @@ -217,6 +235,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.building = self.cr.playGame.hood.loader.geom else: self.notify.error('No such door type as ' + str(self.doorType)) + return self.building def getBuilding_wip(self): @@ -226,6 +245,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): else: self.building = self.cr.playGame.hood.loader.geom print('---------------- door is interior -------') + return self.building def readyToExit(self): @@ -238,33 +258,38 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): otherNP = self.getDoorNodePath() if hasattr(avatar, 'stopSmooth'): avatar.stopSmooth() + if avatar.doId == base.localAvatar.doId: - track.append(LerpPosHprInterval(nodePath=camera, other=avatar, duration=duration, pos=Point3(0, -8, avatar.getHeight()), hpr=VBase3(0, 0, 0), blendType='easeInOut')) + track.append(LerpPosHprInterval(nodePath=base.camera, other=avatar, duration=duration, pos=Point3(0, -8, avatar.getHeight()), hpr=VBase3(0, 0, 0), blendType='easeInOut')) + finalPos = avatar.getParent().getRelativePoint(otherNP, Point3(self.doorX, 2, ToontownGlobals.FloorOffset)) moveHere = Sequence(self.getAnimStateInterval(avatar, 'walk'), LerpPosInterval(nodePath=avatar, duration=duration, pos=finalPos, blendType='easeIn')) track.append(moveHere) if avatar.doId == base.localAvatar.doId: track.append(Sequence(Wait(duration * 0.5), Func(base.transitions.irisOut, duration * 0.5), Wait(duration * 0.5), Func(avatar.b_setParent, ToontownGlobals.SPHidden))) - track.delayDelete = DelayDelete.DelayDelete(avatar, 'avatarEnterDoorTrack') + + track.delayDelete = DelayDelete(avatar, 'avatarEnterDoorTrack') return track def avatarEnqueueTrack(self, avatar, duration): if hasattr(avatar, 'stopSmooth'): avatar.stopSmooth() + back = -5.0 - 2.0 * len(self.avatarIDList) if back < -9.0: back = -9.0 + offset = Point3(self.doorX, back, ToontownGlobals.FloorOffset) otherNP = self.getDoorNodePath() walkLike = ActorInterval(avatar, 'walk', startTime=1, duration=duration, endTime=0.0001) standHere = Sequence(LerpPosHprInterval(nodePath=avatar, other=otherNP, duration=duration, pos=offset, hpr=VBase3(0, 0, 0), blendType='easeInOut'), self.getAnimStateInterval(avatar, 'neutral')) trackName = 'avatarEnqueueDoor-%d-%d' % (self.doId, avatar.doId) track = Parallel(walkLike, standHere, name=trackName) - track.delayDelete = DelayDelete.DelayDelete(avatar, 'avatarEnqueueTrack') + track.delayDelete = DelayDelete(avatar, 'avatarEnqueueTrack') return track def getAnimStateInterval(self, avatar, animName): - isSuit = isinstance(avatar, Suit.Suit) + isSuit = isinstance(avatar, Suit) if isSuit: return Func(avatar.loop, animName, 0) else: @@ -284,7 +309,8 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): place = base.cr.playGame.getPlace() if place: place.fsm.request('stopped') - self.dialog = TeaserPanel.TeaserPanel(pageName='otherHoods', doneFunc=self.handleOkTeaser) + + self.dialog = TeaserPanel(pageName='otherHoods', doneFunc=self.handleOkTeaser) def handleOkTeaser(self): self.accept(self.getEnterTriggerEvent(), self.doorTrigger) @@ -301,6 +327,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): allowed = base.ttAccess.canAccess(zoneId) else: allowed = base.ttAccess.canAccess() + return allowed def checkIsDoorHitTaskName(self): @@ -311,8 +338,9 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.ignore(self.checkIsDoorHitTaskName()) self.ignore(self.getExitTriggerEvent()) self.enterDoor() - return Task.done - return Task.cont + return task.done + + return task.cont def cancelCheckIsDoorHitTask(self, args): taskMgr.remove(self.checkIsDoorHitTaskName()) @@ -333,7 +361,6 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): else: self.accept(self.getExitTriggerEvent(), self.cancelCheckIsDoorHitTask) taskMgr.add(self.checkIsDoorHitTask, self.checkIsDoorHitTaskName()) - return def avatarEnter(self, avatarID): avatar = self.cr.doId2do.get(avatarID, None) @@ -343,7 +370,6 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): track.start() self.avatarTracks.append(track) self.avatarIDList.append(avatarID) - return def rejectEnter(self, reason): message = FADoorCodes.reasonDict[reason] @@ -360,7 +386,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def __faRejectEnter(self, message): self.rejectDialog = TTDialog.TTGlobalDialog(message=message, doneEvent='doorRejectAck', style=TTDialog.Acknowledge) self.rejectDialog.show() - self.rejectDialog.delayDelete = DelayDelete.DelayDelete(self, '__faRejectEnter') + self.rejectDialog.delayDelete = DelayDelete(self, '__faRejectEnter') event = 'clientCleanup' self.acceptOnce(event, self.__handleClientCleanup) base.cr.playGame.getPlace().setState('stopped') @@ -370,6 +396,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def __handleClientCleanup(self): if hasattr(self, 'rejectDialog') and self.rejectDialog: self.rejectDialog.doneStatus = 'ok' + self.__handleRejectAck() def __handleFallAsleepDoor(self): @@ -383,6 +410,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): doneStatus = self.rejectDialog.doneStatus if doneStatus != 'ok': self.notify.error('Unrecognized doneStatus: ' + str(doneStatus)) + self.__basicRejectEnter() self.rejectDialog.delayDelete.destroy() self.rejectDialog.cleanup() @@ -390,7 +418,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def getDoorNodePath(self): if self.doorType == DoorTypes.INT_STANDARD: - otherNP = render.find('**/door_origin') + otherNP = base.render.find('**/door_origin') elif self.doorType == DoorTypes.EXT_STANDARD: if hasattr(self, 'tempDoorNodePath'): return self.tempDoorNodePath @@ -404,14 +432,16 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): building = self.getBuilding() otherNP = building.find('**/door_origin_' + str(self.doorIndex)) elif self.doorType == DoorTypes.INT_HQ: - otherNP = render.find('**/door_origin_' + str(self.doorIndex)) + otherNP = base.render.find('**/door_origin_' + str(self.doorIndex)) else: self.notify.error('No such door type as ' + str(self.doorType)) + return otherNP def avatarExitTrack(self, avatar, duration): if hasattr(avatar, 'stopSmooth'): avatar.stopSmooth() + otherNP = self.getDoorNodePath() trackName = 'avatarExitDoor-%d-%d' % (self.doId, avatar.doId) track = Sequence(name=trackName) @@ -419,18 +449,22 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): track.append(PosHprInterval(avatar, Point3(-self.doorX, 0, ToontownGlobals.FloorOffset), VBase3(179, 0, 0), other=otherNP)) track.append(Func(avatar.setParent, ToontownGlobals.SPRender)) if avatar.doId == base.localAvatar.doId: - track.append(PosHprInterval(camera, VBase3(-self.doorX, 5, avatar.getHeight()), VBase3(180, 0, 0), other=otherNP)) + track.append(PosHprInterval(base.camera, VBase3(-self.doorX, 5, avatar.getHeight()), VBase3(180, 0, 0), other=otherNP)) + if avatar.doId == base.localAvatar.doId: - finalPos = render.getRelativePoint(otherNP, Point3(-self.doorX, -6, ToontownGlobals.FloorOffset)) + finalPos = base.render.getRelativePoint(otherNP, Point3(-self.doorX, -6, ToontownGlobals.FloorOffset)) else: - finalPos = render.getRelativePoint(otherNP, Point3(-self.doorX, -3, ToontownGlobals.FloorOffset)) + finalPos = base.render.getRelativePoint(otherNP, Point3(-self.doorX, -3, ToontownGlobals.FloorOffset)) + track.append(LerpPosInterval(nodePath=avatar, duration=duration, pos=finalPos, blendType='easeInOut')) if avatar.doId == base.localAvatar.doId: track.append(Func(self.exitCompleted)) track.append(Func(base.transitions.irisIn)) + if hasattr(avatar, 'startSmooth'): track.append(Func(avatar.startSmooth)) - track.delayDelete = DelayDelete.DelayDelete(avatar, 'DistributedDoor.avatarExitTrack') + + track.delayDelete = DelayDelete(avatar, 'DistributedDoor.avatarExitTrack') return track def exitCompleted(self): @@ -438,6 +472,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): place = self.cr.playGame.getPlace() if place: place.setState('walk') + base.localAvatar.d_setParent(ToontownGlobals.SPRender) def avatarExit(self, avatarID): @@ -451,26 +486,26 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def finishDoorTrack(self): if self.doorTrack: self.doorTrack.finish() + self.doorTrack = None - return def finishDoorExitTrack(self): if self.doorExitTrack: self.doorExitTrack.finish() + self.doorExitTrack = None - return def finishAllTracks(self): self.finishDoorTrack() self.finishDoorExitTrack() for t in self.avatarTracks: t.finish() - DelayDelete.cleanupDelayDeletes(t) + cleanupDelayDeletes(t) self.avatarTracks = [] for t in self.avatarExitTracks: t.finish() - DelayDelete.cleanupDelayDeletes(t) + cleanupDelayDeletes(t) self.avatarExitTracks = [] @@ -498,16 +533,19 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): if doorFrameHoleRight.isEmpty(): self.notify.warning('enterClosing(): did not find doorFrameHoleRight') return + rightDoor = self.findDoorNode('rightDoor') if rightDoor.isEmpty(): self.notify.warning('enterClosing(): did not find rightDoor') return + otherNP = self.getDoorNodePath() trackName = 'doorClose-%d' % self.doId if self.rightSwing: h = 100 else: h = -100 + self.finishDoorTrack() self.doorTrack = Sequence(LerpHprInterval(nodePath=rightDoor, duration=1.0, hpr=VBase3(0, 0, 0), startHpr=VBase3(h, 0, 0), other=otherNP, blendType='easeInOut'), Func(doorFrameHoleRight.hide), Func(self.hideIfHasFlat, rightDoor), SoundInterval(self.closeSfx, node=rightDoor), name=trackName) self.doorTrack.start(ts) @@ -529,16 +567,19 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): if doorFrameHoleRight.isEmpty(): self.notify.warning('enterOpening(): did not find doorFrameHoleRight') return + rightDoor = self.findDoorNode('rightDoor') if rightDoor.isEmpty(): self.notify.warning('enterOpening(): did not find rightDoor') return + otherNP = self.getDoorNodePath() trackName = 'doorOpen-%d' % self.doId if self.rightSwing: h = 100 else: h = -100 + self.finishDoorTrack() self.doorTrack = Parallel(SoundInterval(self.openSfx, node=rightDoor), Sequence(HprInterval(rightDoor, VBase3(0, 0, 0), other=otherNP), Wait(0.4), Func(rightDoor.show), Func(doorFrameHoleRight.show), LerpHprInterval(nodePath=rightDoor, duration=0.6, hpr=VBase3(h, 0, 0), startHpr=VBase3(0, 0, 0), other=otherNP, blendType='easeInOut')), name=trackName) self.doorTrack.start(ts) @@ -553,6 +594,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): track = self.avatarEnterDoorTrack(avatar, 1.0) track.start(ts) self.avatarTracks.append(track) + if avatarID == base.localAvatar.doId: self.done = 1 @@ -561,7 +603,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def exitOpen(self): for track in self.avatarTracks: track.finish() - DelayDelete.cleanupDelayDeletes(track) + cleanupDelayDeletes(track) self.avatarTracks = [] @@ -576,10 +618,12 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): if doorFrameHoleLeft.isEmpty(): self.notify.warning('enterOpening(): did not find flatDoors') return + if self.leftSwing: h = -100 else: h = 100 + leftDoor = self.findDoorNode('leftDoor') if not leftDoor.isEmpty(): otherNP = self.getDoorNodePath() @@ -602,11 +646,13 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): if doorFrameHoleLeft.isEmpty(): self.notify.warning('enterOpening(): did not find flatDoors') return + leftDoor = self.findDoorNode('leftDoor') if self.leftSwing: h = -100 else: h = 100 + if not leftDoor.isEmpty(): otherNP = self.getDoorNodePath() trackName = 'doorDoorExitTrack-%d' % self.doId @@ -632,7 +678,7 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): def exitDoorExitOpen(self): for track in self.avatarExitTracks: track.finish() - DelayDelete.cleanupDelayDeletes(track) + cleanupDelayDeletes(track) self.avatarExitTracks = [] @@ -645,8 +691,10 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): foundNode = building.find('**/door_' + str(self.doorIndex) + '/**/' + string + '*;+s+i') if foundNode.isEmpty(): foundNode = building.find('**/' + string + '*;+s+i') + if allowEmpty: return foundNode + return foundNode def hideIfHasFlat(self, node): diff --git a/toontown/building/DistributedHQInterior.py b/toontown/building/DistributedHQInterior.py index 7cf0e7f..466e797 100644 --- a/toontown/building/DistributedHQInterior.py +++ b/toontown/building/DistributedHQInterior.py @@ -1,19 +1,24 @@ -from toontown.toonbase.ToonBaseGlobal import * -from panda3d.core import * -from panda3d.toontown import * -from toontown.toonbase.ToontownGlobals import * -import random -from direct.task.Task import Task -from direct.distributed import DistributedObject -from direct.directnotify import DirectNotifyGlobal -from . import ToonInteriorColors -import pickle -from toontown.toonbase import TTLocalizer +from panda3d.core import ModelNode, NodePath, TextNode +from panda3d.toontown import DNADoor -class DistributedHQInterior(DistributedObject.DistributedObject): +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.distributed.DistributedObject import DistributedObject +from direct.task.TaskManagerGlobal import taskMgr + +from toontown.building import ToonInteriorColors +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base + +import pickle +from random import Random + + +class DistributedHQInterior(DistributedObject): + notify = directNotify.newCategory('DistributedHQInterior') def __init__(self, cr): - DistributedObject.DistributedObject.__init__(self, cr) + DistributedObject.__init__(self, cr) self.dnaStore = cr.playGame.dnaStore self.leaderAvIds = [] self.leaderNames = [] @@ -22,15 +27,15 @@ class DistributedHQInterior(DistributedObject.DistributedObject): self.tutorial = 0 def generate(self): - DistributedObject.DistributedObject.generate(self) - self.interior = loader.loadModel('phase_3.5/models/modules/HQ_interior') - self.interior.reparentTo(render) + DistributedObject.generate(self) + self.interior = base.loader.loadModel('phase_3.5/models/modules/HQ_interior') + self.interior.reparentTo(base.render) self.interior.find('**/cream').hide() self.interior.find('**/crashed_piano').hide() self.buildLeaderBoard() def announceGenerate(self): - DistributedObject.DistributedObject.announceGenerate(self) + DistributedObject.announceGenerate(self) self.setupDoors() self.interior.flattenMedium() emptyBoard = self.interior.find('**/empty_board') @@ -41,6 +46,7 @@ class DistributedHQInterior(DistributedObject.DistributedObject): return else: self.tutorial = flag + if self.tutorial: self.interior.find('**/periscope').hide() self.interior.find('**/speakers').hide() @@ -53,7 +59,7 @@ class DistributedHQInterior(DistributedObject.DistributedObject): self.block = block def buildLeaderBoard(self): - self.leaderBoard = hidden.attachNewNode('leaderBoard') + self.leaderBoard = base.hidden.attachNewNode('leaderBoard') self.leaderBoard.setPosHprScale(0.1, 0, 4.5, 90, 0, 0, 0.9, 0.9, 0.9) z = 0 row = self.buildTitleRow() @@ -63,7 +69,7 @@ class DistributedHQInterior(DistributedObject.DistributedObject): self.nameTextNodes = [] self.scoreTextNodes = [] self.trophyStars = [] - for i in range(self.numLeaders): + for _ in range(self.numLeaders): row, nameText, scoreText, trophyStar = self.buildLeaderRow() self.nameTextNodes.append(nameText) self.scoreTextNodes.append(scoreText) @@ -87,7 +93,7 @@ class DistributedHQInterior(DistributedObject.DistributedObject): self.trophyStars[i].hide() def buildTitleRow(self): - row = hidden.attachNewNode('leaderRow') + row = base.hidden.attachNewNode('leaderRow') nameText = TextNode('titleRow') nameText.setFont(ToontownGlobals.getSignFont()) nameText.setAlign(TextNode.ACenter) @@ -98,7 +104,7 @@ class DistributedHQInterior(DistributedObject.DistributedObject): return row def buildLeaderRow(self): - row = hidden.attachNewNode('leaderRow') + row = base.hidden.attachNewNode('leaderRow') nameText = TextNode('nameText') nameText.setFont(ToontownGlobals.getToonFont()) nameText.setAlign(TextNode.ALeft) @@ -135,15 +141,16 @@ class DistributedHQInterior(DistributedObject.DistributedObject): doorModelName = doorModelName[:-1] + 'l' else: doorModelName = doorModelName[:-1] + 'r' + door = self.dnaStore.findNode(doorModelName) return door def setupDoors(self): - self.randomGenerator = random.Random() + self.randomGenerator = Random() self.randomGenerator.seed(self.zoneId) - self.colors = ToonInteriorColors.colors[ToontownCentral] + self.colors = ToonInteriorColors.colors[ToontownGlobals.ToontownCentral] door = self.chooseDoor() - doorOrigins = render.findAllMatches('**/door_origin*') + doorOrigins = base.render.findAllMatches('**/door_origin*') numDoorOrigins = doorOrigins.getNumPaths() for npIndex in range(numDoorOrigins): doorOrigin = doorOrigins[npIndex] @@ -173,10 +180,10 @@ class DistributedHQInterior(DistributedObject.DistributedObject): del self.scoreTextNodes del self.trophyStars taskMgr.remove(self.uniqueName('starSpinHQ')) - DistributedObject.DistributedObject.disable(self) + DistributedObject.disable(self) def buildTrophyStar(self): - trophyStar = loader.loadModel('phase_3.5/models/gui/name_star') + trophyStar = base.loader.loadModel('phase_3.5/models/gui/name_star') trophyStar.hide() trophyStar.setPos(*TTLocalizer.DHQItrophyStarPos) return trophyStar @@ -211,7 +218,7 @@ class DistributedHQInterior(DistributedObject.DistributedObject): trophyStar.hide() def __starSpin(self, task): - now = globalClock.getFrameTime() + now = base.clock.getFrameTime() r = now * task.trophyStarSpeed % 360.0 task.trophyStar.setR(r) - return Task.cont + return task.cont diff --git a/toontown/building/DistributedToonHallInterior.py b/toontown/building/DistributedToonHallInterior.py index cfbee85..1fb9d16 100644 --- a/toontown/building/DistributedToonHallInterior.py +++ b/toontown/building/DistributedToonHallInterior.py @@ -1,3 +1,4 @@ +from panda3d.core import * from panda3d.toontown import * from toontown.toonbase.ToonBaseGlobal import * from direct.interval.IntervalGlobal import * diff --git a/toontown/building/ToonInterior.py b/toontown/building/ToonInterior.py index c39acd4..69229ae 100644 --- a/toontown/building/ToonInterior.py +++ b/toontown/building/ToonInterior.py @@ -1,31 +1,33 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from direct.directnotify import DirectNotifyGlobal -from toontown.hood import Place -from toontown.hood import ZoneUtil -from direct.showbase import DirectObject -from direct.fsm import StateData -from direct.fsm import ClassicFSM, State -from direct.fsm import State -from direct.task import Task -from otp.distributed.TelemetryLimiter import RotationLimitToH, TLGatherAllAvs -from toontown.toonbase import ToontownGlobals -from toontown.toonbase import TTLocalizer -from toontown.toon import NPCForceAcknowledge -from toontown.toon import HealthForceAcknowledge +from panda3d.core import ModelPool, TexturePool +from panda3d.otp import NametagGlobals -class ToonInterior(Place.Place): - notify = DirectNotifyGlobal.directNotify.newCategory('ToonInterior') +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.showbase.MessengerGlobal import messenger + +from otp.distributed.TelemetryLimiter import RotationLimitToH, TLGatherAllAvs + +from toontown.hood import ZoneUtil +from toontown.hood.Place import Place +from toontown.toon.HealthForceAcknowledge import HealthForceAcknowledge +from toontown.toon.NPCForceAcknowledge import NPCForceAcknowledge +from toontown.toonbase import ToontownGlobals +from toontown.toonbase.ToonBaseGlobal import base + + +class ToonInterior(Place): + notify = directNotify.newCategory('ToonInterior') def __init__(self, loader, parentFSMState, doneEvent): - Place.Place.__init__(self, loader, doneEvent) + Place.__init__(self, loader, doneEvent) self.dnaFile = 'phase_7/models/modules/toon_interior' self.isInterior = 1 self.tfaDoneEvent = 'tfaDoneEvent' self.hfaDoneEvent = 'hfaDoneEvent' self.npcfaDoneEvent = 'npcfaDoneEvent' - self.fsm = ClassicFSM.ClassicFSM('ToonInterior', [State.State('start', self.enterStart, self.exitStart, ['doorIn', 'teleportIn', 'tutorial']), - State.State('walk', self.enterWalk, self.exitWalk, ['sit', + self.fsm = ClassicFSM('ToonInterior', [State('start', self.enterStart, self.exitStart, ['doorIn', 'teleportIn', 'tutorial']), + State('walk', self.enterWalk, self.exitWalk, ['sit', 'stickerBook', 'doorOut', 'DFA', @@ -36,8 +38,8 @@ class ToonInterior(Place.Place): 'phone', 'stopped', 'pet']), - State.State('sit', self.enterSit, self.exitSit, ['walk']), - State.State('stickerBook', self.enterStickerBook, self.exitStickerBook, ['walk', + State('sit', self.enterSit, self.exitSit, ['walk']), + State('stickerBook', self.enterStickerBook, self.exitStickerBook, ['walk', 'DFA', 'trialerFA', 'sit', @@ -48,37 +50,37 @@ class ToonInterior(Place.Place): 'phone', 'stopped', 'pet']), - State.State('trialerFA', self.enterTrialerFA, self.exitTrialerFA, ['trialerFAReject', 'DFA']), - State.State('trialerFAReject', self.enterTrialerFAReject, self.exitTrialerFAReject, ['walk']), - State.State('DFA', self.enterDFA, self.exitDFA, ['DFAReject', + State('trialerFA', self.enterTrialerFA, self.exitTrialerFA, ['trialerFAReject', 'DFA']), + State('trialerFAReject', self.enterTrialerFAReject, self.exitTrialerFAReject, ['walk']), + State('DFA', self.enterDFA, self.exitDFA, ['DFAReject', 'HFA', 'NPCFA', 'teleportOut', 'doorOut']), - State.State('DFAReject', self.enterDFAReject, self.exitDFAReject, ['walk']), - State.State('NPCFA', self.enterNPCFA, self.exitNPCFA, ['NPCFAReject', 'HFA', 'teleportOut']), - State.State('NPCFAReject', self.enterNPCFAReject, self.exitNPCFAReject, ['walk']), - State.State('HFA', self.enterHFA, self.exitHFA, ['HFAReject', 'teleportOut', 'tunnelOut']), - State.State('HFAReject', self.enterHFAReject, self.exitHFAReject, ['walk']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), - State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk']), - State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn']), - State.State('quest', self.enterQuest, self.exitQuest, ['walk', 'doorOut']), - State.State('tutorial', self.enterTutorial, self.exitTutorial, ['walk', 'quest']), - State.State('purchase', self.enterPurchase, self.exitPurchase, ['walk', 'doorOut']), - State.State('pet', self.enterPet, self.exitPet, ['walk']), - State.State('phone', self.enterPhone, self.exitPhone, ['walk', 'doorOut']), - State.State('stopped', self.enterStopped, self.exitStopped, ['walk', 'doorOut']), - State.State('final', self.enterFinal, self.exitFinal, ['start'])], 'start', 'final') + State('DFAReject', self.enterDFAReject, self.exitDFAReject, ['walk']), + State('NPCFA', self.enterNPCFA, self.exitNPCFA, ['NPCFAReject', 'HFA', 'teleportOut']), + State('NPCFAReject', self.enterNPCFAReject, self.exitNPCFAReject, ['walk']), + State('HFA', self.enterHFA, self.exitHFA, ['HFAReject', 'teleportOut', 'tunnelOut']), + State('HFAReject', self.enterHFAReject, self.exitHFAReject, ['walk']), + State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), + State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), + State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk']), + State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn']), + State('quest', self.enterQuest, self.exitQuest, ['walk', 'doorOut']), + State('tutorial', self.enterTutorial, self.exitTutorial, ['walk', 'quest']), + State('purchase', self.enterPurchase, self.exitPurchase, ['walk', 'doorOut']), + State('pet', self.enterPet, self.exitPet, ['walk']), + State('phone', self.enterPhone, self.exitPhone, ['walk', 'doorOut']), + State('stopped', self.enterStopped, self.exitStopped, ['walk', 'doorOut']), + State('final', self.enterFinal, self.exitFinal, ['start'])], 'start', 'final') self.parentFSMState = parentFSMState def load(self): - Place.Place.load(self) + Place.load(self) self.parentFSMState.addChild(self.fsm) def unload(self): - Place.Place.unload(self) + Place.unload(self) self.parentFSMState.removeChild(self.fsm) del self.parentFSMState del self.fsm @@ -111,7 +113,7 @@ class ToonInterior(Place.Place): def enterTutorial(self, requestStatus): self.fsm.request('walk') base.localAvatar.b_setParent(ToontownGlobals.SPRender) - globalClock.tick() + base.clock.tick() base.transitions.irisIn() messenger.send('enterTutorialInterior') @@ -134,7 +136,7 @@ class ToonInterior(Place.Place): def enterNPCFA(self, requestStatus): self.acceptOnce(self.npcfaDoneEvent, self.enterNPCFACallback, [requestStatus]) - self.npcfa = NPCForceAcknowledge.NPCForceAcknowledge(self.npcfaDoneEvent) + self.npcfa = NPCForceAcknowledge(self.npcfaDoneEvent) self.npcfa.enter() def exitNPCFA(self): @@ -161,7 +163,7 @@ class ToonInterior(Place.Place): def enterHFA(self, requestStatus): self.acceptOnce(self.hfaDoneEvent, self.enterHFACallback, [requestStatus]) - self.hfa = HealthForceAcknowledge.HealthForceAcknowledge(self.hfaDoneEvent) + self.hfa = HealthForceAcknowledge(self.hfaDoneEvent) self.hfa.enter(1) def exitHFA(self): @@ -191,10 +193,11 @@ class ToonInterior(Place.Place): base.localAvatar.setPosHpr(0, 0, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0) else: base.localAvatar.setPosHpr(2.5, 11.5, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0) - Place.Place.enterTeleportIn(self, requestStatus) + + Place.enterTeleportIn(self, requestStatus) def enterTeleportOut(self, requestStatus): - Place.Place.enterTeleportOut(self, requestStatus, self.__teleportOutDone) + Place.enterTeleportOut(self, requestStatus, self.__teleportOutDone) def __teleportOutDone(self, requestStatus): hoodId = requestStatus['hoodId'] @@ -207,7 +210,6 @@ class ToonInterior(Place.Place): else: self.doneStatus = requestStatus messenger.send(self.doneEvent) - return def goHomeFailed(self, task): self.notifyUserGoHomeFailed() @@ -215,7 +217,7 @@ class ToonInterior(Place.Place): self.doneStatus['avId'] = -1 self.doneStatus['zoneId'] = self.getZoneId() self.fsm.request('teleportIn', [self.doneStatus]) - return Task.done + return task.done def exitTeleportOut(self): - Place.Place.exitTeleportOut(self) + Place.exitTeleportOut(self) diff --git a/toontown/catalog/CatalogFlooringItem.py b/toontown/catalog/CatalogFlooringItem.py index 664a7d1..bf23940 100644 --- a/toontown/catalog/CatalogFlooringItem.py +++ b/toontown/catalog/CatalogFlooringItem.py @@ -2,30 +2,30 @@ from .CatalogSurfaceItem import * FTTextureName = 0 FTColor = 1 FTBasePrice = 2 -FlooringTypes = {1000: ('phase_5.5/maps/floor_wood_neutral.jpg', CTBasicWoodColorOnWhite, 150), - 1010: ('phase_5.5/maps/flooring_carpetA_neutral.jpg', CTFlatColorDark, 150), - 1020: ('phase_4/maps/flooring_tile_neutral.jpg', CTFlatColorDark, 150), - 1030: ('phase_5.5/maps/flooring_tileB2.jpg', None, 150), - 1040: ('phase_4/maps/grass.jpg', None, 150), - 1050: ('phase_4/maps/floor_tile_brick_diagonal2.jpg', None, 150), - 1060: ('phase_4/maps/floor_tile_brick_diagonal.jpg', None, 150), - 1070: ('phase_4/maps/plazz_tile.jpg', None, 150), - 1080: ('phase_4/maps/sidewalk.jpg', CTFlatColorDark, 150), - 1090: ('phase_3.5/maps/boardwalk_floor.jpg', None, 150), - 1100: ('phase_3.5/maps/dustroad.jpg', None, 150), - 1110: ('phase_5.5/maps/floor_woodtile_neutral.jpg', CTBasicWoodColorOnWhite, 150), - 1120: ('phase_5.5/maps/floor_tile_neutral.jpg', CTBasicWoodColorOnWhite + CTFlatColorDark, 150), - 1130: ('phase_5.5/maps/floor_tile_honeycomb_neutral.jpg', CTBasicWoodColorOnWhite, 150), - 1140: ('phase_5.5/maps/UWwaterFloor1.jpg', None, 150), - 1150: ('phase_5.5/maps/UWtileFloor4.jpg', None, 150), - 1160: ('phase_5.5/maps/UWtileFloor3.jpg', None, 150), - 1170: ('phase_5.5/maps/UWtileFloor2.jpg', None, 150), - 1180: ('phase_5.5/maps/UWtileFloor1.jpg', None, 150), - 1190: ('phase_5.5/maps/UWsandyFloor1.jpg', None, 150), - 10000: ('phase_5.5/maps/floor_icecube.jpg', CTWhite, 225), - 10010: ('phase_5.5/maps/floor_snow.jpg', CTWhite, 225), - 11000: ('phase_5.5/maps/StPatsFloor1.jpg', CTWhite, 225), - 11010: ('phase_5.5/maps/StPatsFloor2.jpg', CTWhite, 225)} +FlooringTypes = {1000: ('phase_5.5/maps/floor_wood_neutral.png', CTBasicWoodColorOnWhite, 150), + 1010: ('phase_5.5/maps/flooring_carpetA_neutral.png', CTFlatColorDark, 150), + 1020: ('phase_4/maps/flooring_tile_neutral.png', CTFlatColorDark, 150), + 1030: ('phase_5.5/maps/flooring_tileB2.png', None, 150), + 1040: ('phase_4/maps/grass.png', None, 150), + 1050: ('phase_4/maps/floor_tile_brick_diagonal2.png', None, 150), + 1060: ('phase_4/maps/floor_tile_brick_diagonal.png', None, 150), + 1070: ('phase_4/maps/plazz_tile.png', None, 150), + 1080: ('phase_4/maps/sidewalk.png', CTFlatColorDark, 150), + 1090: ('phase_3.5/maps/boardwalk_floor.png', None, 150), + 1100: ('phase_3.5/maps/dustroad.png', None, 150), + 1110: ('phase_5.5/maps/floor_woodtile_neutral.png', CTBasicWoodColorOnWhite, 150), + 1120: ('phase_5.5/maps/floor_tile_neutral.png', CTBasicWoodColorOnWhite + CTFlatColorDark, 150), + 1130: ('phase_5.5/maps/floor_tile_honeycomb_neutral.png', CTBasicWoodColorOnWhite, 150), + 1140: ('phase_5.5/maps/UWwaterFloor1.png', None, 150), + 1150: ('phase_5.5/maps/UWtileFloor4.png', None, 150), + 1160: ('phase_5.5/maps/UWtileFloor3.png', None, 150), + 1170: ('phase_5.5/maps/UWtileFloor2.png', None, 150), + 1180: ('phase_5.5/maps/UWtileFloor1.png', None, 150), + 1190: ('phase_5.5/maps/UWsandyFloor1.png', None, 150), + 10000: ('phase_5.5/maps/floor_icecube.png', CTWhite, 225), + 10010: ('phase_5.5/maps/floor_snow.png', CTWhite, 225), + 11000: ('phase_5.5/maps/StPatsFloor1.png', CTWhite, 225), + 11010: ('phase_5.5/maps/StPatsFloor2.png', CTWhite, 225)} class CatalogFlooringItem(CatalogSurfaceItem): diff --git a/toontown/catalog/CatalogMouldingItem.py b/toontown/catalog/CatalogMouldingItem.py index 1341a14..c4b289f 100644 --- a/toontown/catalog/CatalogMouldingItem.py +++ b/toontown/catalog/CatalogMouldingItem.py @@ -2,20 +2,20 @@ from .CatalogSurfaceItem import * MTTextureName = 0 MTColor = 1 MTBasePrice = 2 -MouldingTypes = {1000: ('phase_3.5/maps/molding_wood1.jpg', CTBasicWoodColorOnWhite, 150), - 1010: ('phase_5.5/maps/bd_grey_border1.jpg', CTFlatColorDark, 150), - 1020: ('phase_5.5/maps/dental_Border_wood_neutral.jpg', CTFlatColorDark, 150), - 1030: ('phase_5.5/maps/littleFlowers_border.jpg', CTWhite, 150), - 1040: ('phase_5.5/maps/littleFlowers_border_neutral.jpg', CTFlatColorDark, 150), - 1050: ('phase_5.5/maps/ladybugs2_Border.jpg', CTFlatColorDark, 150), - 1060: ('phase_5.5/maps/bd_grey_border1.jpg', CTValentinesColors, 150), - 1070: ('phase_5.5/maps/bd_grey_border1.jpg', CTUnderwaterColors, 150), - 1080: ('phase_5.5/maps/tt_t_ara_int_border_winterLights1.jpg', CTWhite, 150), - 1085: ('phase_5.5/maps/tt_t_ara_int_border_winterLights2.jpg', CTWhite, 150), - 1090: ('phase_5.5/maps/tt_t_ara_int_border_winterLights3.jpg', CTWhite, 150), - 1100: ('phase_5.5/maps/tt_t_ara_int_border_valentine_cupid.jpg', CTWhite, 150), - 1110: ('phase_5.5/maps/tt_t_ara_int_border_valentine_heart1.jpg', CTWhite, 150), - 1120: ('phase_5.5/maps/tt_t_ara_int_border_valentine_heart2.jpg', CTWhite, 150)} +MouldingTypes = {1000: ('phase_3.5/maps/molding_wood1.png', CTBasicWoodColorOnWhite, 150), + 1010: ('phase_5.5/maps/bd_grey_border1.png', CTFlatColorDark, 150), + 1020: ('phase_5.5/maps/dental_Border_wood_neutral.png', CTFlatColorDark, 150), + 1030: ('phase_5.5/maps/littleFlowers_border.png', CTWhite, 150), + 1040: ('phase_5.5/maps/littleFlowers_border_neutral.png', CTFlatColorDark, 150), + 1050: ('phase_5.5/maps/ladybugs2_Border.png', CTFlatColorDark, 150), + 1060: ('phase_5.5/maps/bd_grey_border1.png', CTValentinesColors, 150), + 1070: ('phase_5.5/maps/bd_grey_border1.png', CTUnderwaterColors, 150), + 1080: ('phase_5.5/maps/tt_t_ara_int_border_winterLights1.png', CTWhite, 150), + 1085: ('phase_5.5/maps/tt_t_ara_int_border_winterLights2.png', CTWhite, 150), + 1090: ('phase_5.5/maps/tt_t_ara_int_border_winterLights3.png', CTWhite, 150), + 1100: ('phase_5.5/maps/tt_t_ara_int_border_valentine_cupid.png', CTWhite, 150), + 1110: ('phase_5.5/maps/tt_t_ara_int_border_valentine_heart1.png', CTWhite, 150), + 1120: ('phase_5.5/maps/tt_t_ara_int_border_valentine_heart2.png', CTWhite, 150)} class CatalogMouldingItem(CatalogSurfaceItem): diff --git a/toontown/catalog/CatalogWainscotingItem.py b/toontown/catalog/CatalogWainscotingItem.py index 462571d..9915e5c 100644 --- a/toontown/catalog/CatalogWainscotingItem.py +++ b/toontown/catalog/CatalogWainscotingItem.py @@ -2,11 +2,11 @@ from .CatalogSurfaceItem import * WSTTextureName = 0 WSTColor = 1 WSTBasePrice = 2 -WainscotingTypes = {1000: ('phase_3.5/maps/wall_paper_b3.jpg', CTFlatColorDark, 200), - 1010: ('phase_5.5/maps/wall_paper_b4_greyscale.jpg', CTBasicWoodColorOnWhite, 200), - 1020: ('phase_5.5/maps/wainscotings_neutral.jpg', CTBasicWoodColorOnWhite, 200), - 1030: ('phase_3.5/maps/wall_paper_b3.jpg', CTValentinesColors, 200), - 1040: ('phase_3.5/maps/wall_paper_b3.jpg', CTUnderwaterColors, 200)} +WainscotingTypes = {1000: ('phase_3.5/maps/wall_paper_b3.png', CTFlatColorDark, 200), + 1010: ('phase_5.5/maps/wall_paper_b4_greyscale.png', CTBasicWoodColorOnWhite, 200), + 1020: ('phase_5.5/maps/wainscotings_neutral.png', CTBasicWoodColorOnWhite, 200), + 1030: ('phase_3.5/maps/wall_paper_b3.png', CTValentinesColors, 200), + 1040: ('phase_3.5/maps/wall_paper_b3.png', CTUnderwaterColors, 200)} class CatalogWainscotingItem(CatalogSurfaceItem): diff --git a/toontown/catalog/CatalogWallpaperItem.py b/toontown/catalog/CatalogWallpaperItem.py index 77802ed..a9b8949 100644 --- a/toontown/catalog/CatalogWallpaperItem.py +++ b/toontown/catalog/CatalogWallpaperItem.py @@ -13,242 +13,242 @@ All = (1000, 1050, 1060, 1070) -WallpaperTypes = {1000: ('phase_5.5/maps/flat_wallpaper1.jpg', +WallpaperTypes = {1000: ('phase_5.5/maps/flat_wallpaper1.png', CTFlatColor, (0, 1000), 180), - 1100: ('phase_5.5/maps/big_stripes1.jpg', + 1100: ('phase_5.5/maps/big_stripes1.png', CTWhite, (0, 1010), 180), - 1110: ('phase_5.5/maps/big_stripes2.jpg', + 1110: ('phase_5.5/maps/big_stripes2.png', CTWhite, (0, 1040), 180), - 1120: ('phase_5.5/maps/big_stripes3.jpg', + 1120: ('phase_5.5/maps/big_stripes3.png', CTWhite, (0, 1030), 180), - 1130: ('phase_5.5/maps/big_stripes4.jpg', + 1130: ('phase_5.5/maps/big_stripes4.png', CTWhite, (0, 1010), 180), - 1140: ('phase_5.5/maps/big_stripes5.jpg', + 1140: ('phase_5.5/maps/big_stripes5.png', CTWhite, (0, 1020), 180), - 1150: ('phase_5.5/maps/big_stripes6.jpg', + 1150: ('phase_5.5/maps/big_stripes6.png', CTWhite, (0, 1020), 180), - 1200: ('phase_5.5/maps/stripeB1.jpg', + 1200: ('phase_5.5/maps/stripeB1.png', CTWhite, (0, 1000), 180), - 1210: ('phase_5.5/maps/stripeB2.jpg', + 1210: ('phase_5.5/maps/stripeB2.png', CTWhite, (0, 1000), 180), - 1220: ('phase_5.5/maps/stripeB3.jpg', + 1220: ('phase_5.5/maps/stripeB3.png', CTWhite, (0, 1000), 180), - 1230: ('phase_5.5/maps/stripeB4.jpg', + 1230: ('phase_5.5/maps/stripeB4.png', CTWhite, (0, 1000), 180), - 1240: ('phase_3.5/maps/stripeB5.jpg', + 1240: ('phase_3.5/maps/stripeB5.png', CTWhite, (0, 1000), 180), - 1250: ('phase_5.5/maps/stripeB6.jpg', + 1250: ('phase_5.5/maps/stripeB6.png', CTWhite, (0, 1000), 180), - 1260: ('phase_5.5/maps/stripeB7.jpg', + 1260: ('phase_5.5/maps/stripeB7.png', CTWhite, (0, 1000), 180), - 1300: ('phase_5.5/maps/squiggle1.jpg', + 1300: ('phase_5.5/maps/squiggle1.png', CTWhite, (0,), 180), - 1310: ('phase_5.5/maps/squiggle2.jpg', + 1310: ('phase_5.5/maps/squiggle2.png', CTWhite, (0,), 180), - 1320: ('phase_5.5/maps/squiggle3.jpg', + 1320: ('phase_5.5/maps/squiggle3.png', CTWhite, (0,), 180), - 1330: ('phase_5.5/maps/squiggle4.jpg', + 1330: ('phase_5.5/maps/squiggle4.png', CTWhite, (0,), 180), - 1340: ('phase_5.5/maps/squiggle5.jpg', + 1340: ('phase_5.5/maps/squiggle5.png', CTWhite, (0,), 180), - 1350: ('phase_5.5/maps/squiggle6.jpg', + 1350: ('phase_5.5/maps/squiggle6.png', CTWhite, (0,), 180), - 1400: ('phase_5.5/maps/stripes_cyan.jpg', + 1400: ('phase_5.5/maps/stripes_cyan.png', CTWhite, (0, 1000), 180), - 1410: ('phase_5.5/maps/stripes_green.jpg', + 1410: ('phase_5.5/maps/stripes_green.png', CTWhite, (0, 1000), 180), - 1420: ('phase_5.5/maps/stripes_magenta.jpg', + 1420: ('phase_5.5/maps/stripes_magenta.png', CTWhite, (0, 1000), 180), - 1430: ('phase_5.5/maps/two_stripes1.jpg', + 1430: ('phase_5.5/maps/two_stripes1.png', CTWhite, (0, 1000), 180), - 1440: ('phase_5.5/maps/two_stripes2.jpg', + 1440: ('phase_5.5/maps/two_stripes2.png', CTWhite, (0, 1000), 180), - 1450: ('phase_5.5/maps/two_stripes3.jpg', + 1450: ('phase_5.5/maps/two_stripes3.png', CTWhite, (0, 1000), 180), - 1500: ('phase_5.5/maps/leaves1.jpg', + 1500: ('phase_5.5/maps/leaves1.png', CTWhite, (0,), 180), - 1510: ('phase_5.5/maps/leaves2.jpg', + 1510: ('phase_5.5/maps/leaves2.png', CTWhite, (0,), 180), - 1520: ('phase_5.5/maps/leaves3.jpg', + 1520: ('phase_5.5/maps/leaves3.png', CTWhite, (0,), 180), - 1600: ('phase_5.5/maps/diamonds2_cherries.jpg', + 1600: ('phase_5.5/maps/diamonds2_cherries.png', CTWhite, (0, 1000), 180), - 1610: ('phase_5.5/maps/diamonds3_cherries.jpg', + 1610: ('phase_5.5/maps/diamonds3_cherries.png', CTWhite, (0, 1000), 180), - 1620: ('phase_5.5/maps/diamonds3_cherry.jpg', + 1620: ('phase_5.5/maps/diamonds3_cherry.png', CTWhite, (0, 1000), 180), - 1630: ('phase_5.5/maps/diamonds4_cherries.jpg', + 1630: ('phase_5.5/maps/diamonds4_cherries.png', CTWhite, (0, 1000), 180), - 1640: ('phase_5.5/maps/diamonds4_cherry.jpg', + 1640: ('phase_5.5/maps/diamonds4_cherry.png', CTWhite, (0, 1000), 180), - 1650: ('phase_5.5/maps/diamonds5_cherries.jpg', + 1650: ('phase_5.5/maps/diamonds5_cherries.png', CTWhite, (0, 1000), 180), - 1660: ('phase_5.5/maps/diamonds6_cherry.jpg', + 1660: ('phase_5.5/maps/diamonds6_cherry.png', CTWhite, (0, 1000), 180), - 1700: ('phase_5.5/maps/moon1.jpg', + 1700: ('phase_5.5/maps/moon1.png', CTWhite, (0,), 180), - 1710: ('phase_5.5/maps/moon2.jpg', + 1710: ('phase_5.5/maps/moon2.png', CTWhite, (0,), 180), - 1720: ('phase_5.5/maps/moon3.jpg', + 1720: ('phase_5.5/maps/moon3.png', CTWhite, (0,), 180), - 1730: ('phase_5.5/maps/moon4.jpg', + 1730: ('phase_5.5/maps/moon4.png', CTWhite, (0,), 180), - 1740: ('phase_5.5/maps/moon5.jpg', + 1740: ('phase_5.5/maps/moon5.png', CTWhite, (0,), 180), - 1750: ('phase_5.5/maps/moon6.jpg', + 1750: ('phase_5.5/maps/moon6.png', CTWhite, (0,), 180), - 1760: ('phase_5.5/maps/moon7.jpg', + 1760: ('phase_5.5/maps/moon7.png', CTWhite, (0,), 180), - 1800: ('phase_5.5/maps/stars1.jpg', + 1800: ('phase_5.5/maps/stars1.png', CTWhite, (0,), 180), - 1810: ('phase_5.5/maps/stars2.jpg', + 1810: ('phase_5.5/maps/stars2.png', (CT_BLUE2, CT_PINK2, CT_RED), (0,), 180), - 1820: ('phase_5.5/maps/stars3.jpg', + 1820: ('phase_5.5/maps/stars3.png', (CT_BLUE2, CT_PINK2, CT_RED, CT_WHITE), (0,), 180), - 1830: ('phase_5.5/maps/stars4.jpg', + 1830: ('phase_5.5/maps/stars4.png', CTWhite, (0,), 180), - 1840: ('phase_5.5/maps/stars5.jpg', + 1840: ('phase_5.5/maps/stars5.png', CTWhite, (0,), 180), - 1850: ('phase_5.5/maps/stars6.jpg', + 1850: ('phase_5.5/maps/stars6.png', CTWhite, (0,), 180), - 1860: ('phase_5.5/maps/stars7.jpg', + 1860: ('phase_5.5/maps/stars7.png', (CT_BEIGE2, CT_WHITE), (0,), 180), - 1900: ('phase_5.5/maps/wall_paper_flower1.jpg', + 1900: ('phase_5.5/maps/wall_paper_flower1.png', CTWhite, (0, 1000), 180), - 1910: ('phase_5.5/maps/wall_paper_flower2.jpg', + 1910: ('phase_5.5/maps/wall_paper_flower2.png', CTWhite, (0, 1000), 180), - 1920: ('phase_5.5/maps/wall_paper_flower3.jpg', + 1920: ('phase_5.5/maps/wall_paper_flower3.png', CTWhite, (0, 1000), 180), - 1930: ('phase_5.5/maps/wall_paper_flower4.jpg', + 1930: ('phase_5.5/maps/wall_paper_flower4.png', CTWhite, (0, 1000), 180), - 1940: ('phase_5.5/maps/wall_paper_flower5.jpg', + 1940: ('phase_5.5/maps/wall_paper_flower5.png', CTWhite, (0, 1000), 180), - 1950: ('phase_5.5/maps/wall_paper_flower6.jpg', + 1950: ('phase_5.5/maps/wall_paper_flower6.png', CTWhite, (0, 1000), 180), - 2000: ('phase_5.5/maps/flat_wallpaper1.jpg', + 2000: ('phase_5.5/maps/flat_wallpaper1.png', (CT_BEIGE, CT_BEIGE2, CT_RED), (1050,), 180), - 2010: ('phase_5.5/maps/flat_wallpaper1.jpg', + 2010: ('phase_5.5/maps/flat_wallpaper1.png', (CT_BLUE2, CT_PINK2), (1060,), 180), - 2020: ('phase_5.5/maps/flat_wallpaper1.jpg', + 2020: ('phase_5.5/maps/flat_wallpaper1.png', (CT_BEIGE2, CT_BLUE2, CT_PINK2, @@ -256,207 +256,207 @@ WallpaperTypes = {1000: ('phase_5.5/maps/flat_wallpaper1.jpg', CT_RED), (1070,), 180), - 2100: ('phase_5.5/maps/big_stripes1.jpg', + 2100: ('phase_5.5/maps/big_stripes1.png', CTWhite, (1050,), 180), - 2110: ('phase_5.5/maps/big_stripes2.jpg', + 2110: ('phase_5.5/maps/big_stripes2.png', CTWhite, (1050,), 180), - 2120: ('phase_5.5/maps/big_stripes3.jpg', + 2120: ('phase_5.5/maps/big_stripes3.png', CTWhite, (1060,), 180), - 2130: ('phase_5.5/maps/big_stripes3.jpg', + 2130: ('phase_5.5/maps/big_stripes3.png', CTWhite, (1070,), 180), - 2140: ('phase_5.5/maps/big_stripes6.jpg', + 2140: ('phase_5.5/maps/big_stripes6.png', CTWhite, (1070,), 180), - 2200: ('phase_5.5/maps/wall_paper_car.jpg', + 2200: ('phase_5.5/maps/wall_paper_car.png', CTWhite, (0, 1000), 180), - 2210: ('phase_5.5/maps/wall_paper_car_neutral.jpg', + 2210: ('phase_5.5/maps/wall_paper_car_neutral.png', CTFlatColor, (0, 1000), 180), - 2300: ('phase_5.5/maps/wall_paper_football_neutral.jpg', + 2300: ('phase_5.5/maps/wall_paper_football_neutral.png', CTFlatColor, (0, 1080), 180), - 2400: ('phase_5.5/maps/wall_paper_clouds.jpg', + 2400: ('phase_5.5/maps/wall_paper_clouds.png', CTWhite, (0, 1000), 180), - 2500: ('phase_5.5/maps/wall_paper_vine_neutral.jpg', + 2500: ('phase_5.5/maps/wall_paper_vine_neutral.png', CTFlatColorAll, (0, 1090), 180), - 2600: ('phase_5.5/maps/basket.jpg', + 2600: ('phase_5.5/maps/basket.png', CTWhite, (0, 1000), 180), - 2610: ('phase_5.5/maps/basket_neutral.jpg', + 2610: ('phase_5.5/maps/basket_neutral.png', CTFlatColor, (0, 1000), 180), - 2700: ('phase_5.5/maps/doll.jpg', + 2700: ('phase_5.5/maps/doll.png', CTWhite, (0, 1000, 1110), 180), - 2710: ('phase_5.5/maps/doll_neutral.jpg', + 2710: ('phase_5.5/maps/doll_neutral.png', CTFlatColor, (0, 1100, 1110), 180), - 2800: ('phase_5.5/maps/littleFlowers.jpg', + 2800: ('phase_5.5/maps/littleFlowers.png', CTWhite, (0, 1000), 180), - 2810: ('phase_5.5/maps/littleFlowers_neutral.jpg', + 2810: ('phase_5.5/maps/littleFlowers_neutral.png', CTFlatColor, (0, 1000), 180), - 2900: ('phase_5.5/maps/UWwallPaperAngelFish.jpg', + 2900: ('phase_5.5/maps/UWwallPaperAngelFish.png', CTWhite, (0, 1120, 1160), 180), - 2910: ('phase_5.5/maps/UWwallPaperAngelFishColor.jpg', + 2910: ('phase_5.5/maps/UWwallPaperAngelFishColor.png', CTWhite, (0, 1120, 1160), 180), - 2920: ('phase_5.5/maps/UWwallPaperBubbles.jpg', + 2920: ('phase_5.5/maps/UWwallPaperBubbles.png', CTWhite, (0, 1120, 1160), 180), - 2930: ('phase_5.5/maps/UWwallPaperBubbles2.jpg', + 2930: ('phase_5.5/maps/UWwallPaperBubbles2.png', CTWhite, (0, 1120, 1160), 180), - 2940: ('phase_5.5/maps/UWwallPaperGreenFish.jpg', + 2940: ('phase_5.5/maps/UWwallPaperGreenFish.png', CTWhite, (0, 1120, 1160), 180), - 2950: ('phase_5.5/maps/UWwallPaperRedFish.jpg', + 2950: ('phase_5.5/maps/UWwallPaperRedFish.png', CTWhite, (0, 1120, 1160), 180), - 2960: ('phase_5.5/maps/UWwallPaperSea_horse.jpg', + 2960: ('phase_5.5/maps/UWwallPaperSea_horse.png', CTWhite, (0, 1120, 1160), 180), - 2970: ('phase_5.5/maps/UWwallPaperShells.jpg', + 2970: ('phase_5.5/maps/UWwallPaperShells.png', CTWhite, (0, 1140, 1150), 180), - 2980: ('phase_5.5/maps/UWwaterFloor1.jpg', + 2980: ('phase_5.5/maps/UWwaterFloor1.png', (CT_WHITE, CT_PALE_GREEN, CT_LIGHT_BLUE), (0,), 180), - 3000: ('phase_5.5/maps/UWwallPaperBubbles.jpg', + 3000: ('phase_5.5/maps/UWwallPaperBubbles.png', CTWhite, (0, 1120, 1160), 180), - 3100: ('phase_5.5/maps/UWwallPaperBubbles2.jpg', + 3100: ('phase_5.5/maps/UWwallPaperBubbles2.png', CTWhite, (0, 1120, 1160), 180), - 3200: ('phase_5.5/maps/UWwallPaperGreenFish.jpg', + 3200: ('phase_5.5/maps/UWwallPaperGreenFish.png', CTWhite, (0, 1120, 1160), 180), - 3300: ('phase_5.5/maps/UWwallPaperRedFish.jpg', + 3300: ('phase_5.5/maps/UWwallPaperRedFish.png', CTWhite, (0, 1120, 1160), 180), - 3400: ('phase_5.5/maps/UWwallPaperSea_horse.jpg', + 3400: ('phase_5.5/maps/UWwallPaperSea_horse.png', CTWhite, (0, 1120, 1160), 180), - 3500: ('phase_5.5/maps/UWwallPaperShells.jpg', + 3500: ('phase_5.5/maps/UWwallPaperShells.png', (CT_WHITE, CT_SEA_GREEN, CT_LIGHT_BLUE), (0, 1140, 1150), 180), - 3600: ('phase_5.5/maps/UWwaterFloor1.jpg', + 3600: ('phase_5.5/maps/UWwaterFloor1.png', (CT_WHITE, CT_PALE_GREEN, CT_LIGHT_BLUE), (0,), 180), - 3700: ('phase_5.5/maps/WesternBootWallpaper1.jpg', + 3700: ('phase_5.5/maps/WesternBootWallpaper1.png', CTWhite, (0, 1170, 1180), 180), - 3800: ('phase_5.5/maps/WesternCactusWallpaper1.jpg', + 3800: ('phase_5.5/maps/WesternCactusWallpaper1.png', CTWhite, (0, 1170, 1180), 180), - 3900: ('phase_5.5/maps/WesternHatWallpaper1.jpg', + 3900: ('phase_5.5/maps/WesternHatWallpaper1.png', CTWhite, (0, 1170, 1180), 180), - 10100: ('phase_5.5/maps/cats1.jpg', + 10100: ('phase_5.5/maps/cats1.png', CTWhite, (0, 10010, 10020), 400), - 10200: ('phase_5.5/maps/bats2.jpg', + 10200: ('phase_5.5/maps/bats2.png', CTWhite, (0, 10010, 10020), 400), - 11000: ('phase_5.5/maps/wall_paper_snowflakes.jpg', + 11000: ('phase_5.5/maps/wall_paper_snowflakes.png', CTWhite, (0, 11000, 11010), 400), - 11100: ('phase_5.5/maps/wall_paper_hollyleaf.jpg', + 11100: ('phase_5.5/maps/wall_paper_hollyleaf.png', CTWhite, (0, 11000, 11010), 400), - 11200: ('phase_5.5/maps/wall_paper_snowman.jpg', + 11200: ('phase_5.5/maps/wall_paper_snowman.png', CTWhite, (0, 11000, 11010), 400), - 12000: ('phase_5.5/maps/VdayWall1.jpg', + 12000: ('phase_5.5/maps/VdayWall1.png', CTWhite, (0, 12000, 12010, 12020), 400), - 12100: ('phase_5.5/maps/VdayWall2.jpg', + 12100: ('phase_5.5/maps/VdayWall2.png', CTWhite, (0, 12000, 12010, 12020), 400), - 12200: ('phase_5.5/maps/VdayWall3.jpg', + 12200: ('phase_5.5/maps/VdayWall3.png', CTWhite, (0, 12000, 12010, 12020), 400), - 12300: ('phase_5.5/maps/VdayWall4.jpg', + 12300: ('phase_5.5/maps/VdayWall4.png', CTWhite, (0, 12000, 12010, 12020), 400), - 13000: ('phase_5.5/maps/StPatWallpaper1.jpg', + 13000: ('phase_5.5/maps/StPatWallpaper1.png', CTWhite, (0, 13000), 400), - 13100: ('phase_5.5/maps/StPatWallpaper2.jpg', + 13100: ('phase_5.5/maps/StPatWallpaper2.png', CTWhite, (0, 13000), 400), - 13200: ('phase_5.5/maps/StPatWallpaper3.jpg', + 13200: ('phase_5.5/maps/StPatWallpaper3.png', CTWhite, (0, 13000), 400), - 13300: ('phase_5.5/maps/StPatWallpaper4.jpg', + 13300: ('phase_5.5/maps/StPatWallpaper4.png', CTWhite, (0, 13000), 400)} @@ -524,33 +524,33 @@ WallpaperGroups = {1100: (1100, 2700: (2700, 2710), 2800: (2800, 2810), 2900: (2900, 2910)} -BorderTypes = {1000: ('phase_5.5/maps/bd_grey_border1.jpg', CTFlatColorDark), - 1010: ('phase_5.5/maps/diamonds_border2.jpg', CTWhite), - 1020: ('phase_5.5/maps/diamonds_border2ch.jpg', CTWhite), - 1030: ('phase_5.5/maps/diamonds_border3ch.jpg', CTWhite), - 1040: ('phase_5.5/maps/diamonds_border4ch.jpg', CTWhite), - 1050: ('phase_5.5/maps/flower_border2.jpg', CTWhite), - 1060: ('phase_5.5/maps/flower_border5.jpg', CTWhite), - 1070: ('phase_5.5/maps/flower_border6.jpg', CTWhite), - 1080: ('phase_5.5/maps/football_border_neutral.jpg', CTFlatColorDark), - 1090: ('phase_5.5/maps/vine_border1.jpg', CTFlatColorDark), - 1100: ('phase_5.5/maps/doll_board.jpg', CTWhite), - 1110: ('phase_5.5/maps/doll_board_neutral.jpg', CTFlatColorDark), - 1120: ('phase_5.5/maps/UWwallPaperPlantBorder.jpg', CTWhite), - 1130: ('phase_5.5/maps/UWwallPaperSea_horseBorder.jpg', CTWhite), - 1140: ('phase_5.5/maps/UWwallPaperShellBorder1.jpg', CTWhite), - 1150: ('phase_5.5/maps/UWwallPaperShellBorder2.jpg', CTWhite), - 1160: ('phase_5.5/maps/UWwallPaperWaveBorder.jpg', CTWhite), - 1170: ('phase_5.5/maps/WesternSkullBorder.jpg', CTWhite), - 1180: ('phase_5.5/maps/WesternStarBorder.jpg', CTWhite), - 10010: ('phase_5.5/maps/border_ScarryMoon1.jpg', CTWhite), - 10020: ('phase_5.5/maps/border_candy1.jpg', CTWhite), - 11000: ('phase_5.5/maps/flakes_border.jpg', CTWhite), - 11010: ('phase_5.5/maps/hollyleaf_border.jpg', CTWhite), - 12000: ('phase_5.5/maps/Vborder1a.jpg', CTWhite), - 12010: ('phase_5.5/maps/Vborder1b.jpg', CTWhite), - 12020: ('phase_5.5/maps/Vborder2b.jpg', CTWhite), - 13000: ('phase_5.5/maps/StPatBorder1.jpg', CTWhite)} +BorderTypes = {1000: ('phase_5.5/maps/bd_grey_border1.png', CTFlatColorDark), + 1010: ('phase_5.5/maps/diamonds_border2.png', CTWhite), + 1020: ('phase_5.5/maps/diamonds_border2ch.png', CTWhite), + 1030: ('phase_5.5/maps/diamonds_border3ch.png', CTWhite), + 1040: ('phase_5.5/maps/diamonds_border4ch.png', CTWhite), + 1050: ('phase_5.5/maps/flower_border2.png', CTWhite), + 1060: ('phase_5.5/maps/flower_border5.png', CTWhite), + 1070: ('phase_5.5/maps/flower_border6.png', CTWhite), + 1080: ('phase_5.5/maps/football_border_neutral.png', CTFlatColorDark), + 1090: ('phase_5.5/maps/vine_border1.png', CTFlatColorDark), + 1100: ('phase_5.5/maps/doll_board.png', CTWhite), + 1110: ('phase_5.5/maps/doll_board_neutral.png', CTFlatColorDark), + 1120: ('phase_5.5/maps/UWwallPaperPlantBorder.png', CTWhite), + 1130: ('phase_5.5/maps/UWwallPaperSea_horseBorder.png', CTWhite), + 1140: ('phase_5.5/maps/UWwallPaperShellBorder1.png', CTWhite), + 1150: ('phase_5.5/maps/UWwallPaperShellBorder2.png', CTWhite), + 1160: ('phase_5.5/maps/UWwallPaperWaveBorder.png', CTWhite), + 1170: ('phase_5.5/maps/WesternSkullBorder.png', CTWhite), + 1180: ('phase_5.5/maps/WesternStarBorder.png', CTWhite), + 10010: ('phase_5.5/maps/border_ScarryMoon1.png', CTWhite), + 10020: ('phase_5.5/maps/border_candy1.png', CTWhite), + 11000: ('phase_5.5/maps/flakes_border.png', CTWhite), + 11010: ('phase_5.5/maps/hollyleaf_border.png', CTWhite), + 12000: ('phase_5.5/maps/Vborder1a.png', CTWhite), + 12010: ('phase_5.5/maps/Vborder1b.png', CTWhite), + 12020: ('phase_5.5/maps/Vborder2b.png', CTWhite), + 13000: ('phase_5.5/maps/StPatBorder1.png', CTWhite)} class CatalogWallpaperItem(CatalogSurfaceItem): diff --git a/toontown/char/Char.py b/toontown/char/Char.py index 8d42300..3910dbc 100644 --- a/toontown/char/Char.py +++ b/toontown/char/Char.py @@ -252,8 +252,8 @@ class Char(Avatar.Avatar): self.eyesOpen = None self.eyesClosed = None if self._name == 'mickey' or self._name == 'minnie': - self.eyesOpen = loader.loadTexture('phase_3/maps/eyes1.jpg', 'phase_3/maps/eyes1_a.rgb') - self.eyesClosed = loader.loadTexture('phase_3/maps/mickey_eyes_closed.jpg', 'phase_3/maps/mickey_eyes_closed_a.rgb') + self.eyesOpen = loader.loadTexture('phase_3/maps/eyes1.png') + self.eyesClosed = loader.loadTexture('phase_3/maps/mickey_eyes_closed.png') self.eyes = self.find('**/1200/**/eyes') self.eyes.setBin('transparent', 0) self.lpupil = self.find('**/1200/**/joint_pupilL') @@ -285,8 +285,8 @@ class Char(Avatar.Avatar): part.hide() elif self._name == 'pluto': - self.eyesOpen = loader.loadTexture('phase_6/maps/plutoEyesOpen.jpg', 'phase_6/maps/plutoEyesOpen_a.rgb') - self.eyesClosed = loader.loadTexture('phase_6/maps/plutoEyesClosed.jpg', 'phase_6/maps/plutoEyesClosed_a.rgb') + self.eyesOpen = loader.loadTexture('phase_6/maps/plutoEyesOpen.png') + self.eyesClosed = loader.loadTexture('phase_6/maps/plutoEyesClosed.png') self.eyes = self.find('**/1000/**/eyes') self.lpupil = self.find('**/1000/**/joint_pupilL') self.rpupil = self.find('**/1000/**/joint_pupilR') @@ -317,8 +317,8 @@ class Char(Avatar.Avatar): self.rpupil = self.find('**/joint_pupilR') self.drawInFront('joint_pupil?', 'eyes*', -3) elif self._name == 'chip' or self._name == 'dale': - self.eyesOpen = loader.loadTexture('phase_6/maps/dale_eye1.jpg', 'phase_6/maps/dale_eye1_a.rgb') - self.eyesClosed = loader.loadTexture('phase_6/maps/chip_dale_eye1_blink.jpg', 'phase_6/maps/chip_dale_eye1_blink_a.rgb') + self.eyesOpen = loader.loadTexture('phase_6/maps/dale_eye1.png') + self.eyesClosed = loader.loadTexture('phase_6/maps/chip_dale_eye1_blink.png') self.eyes = self.find('**/eyes') self.lpupil = self.find('**/pupil_left') self.rpupil = self.find('**/pupil_right') diff --git a/toontown/cogdominium/CogdoElevatorMovie.py b/toontown/cogdominium/CogdoElevatorMovie.py index c76972f..269b3d8 100644 --- a/toontown/cogdominium/CogdoElevatorMovie.py +++ b/toontown/cogdominium/CogdoElevatorMovie.py @@ -1,6 +1,5 @@ -from panda3d.core import NodePath, Point3, PlaneNode, TextNode +from panda3d.core import NodePath, Point3, Plane, PlaneNode, TextNode from direct.interval.IntervalGlobal import * -from direct.showbase.ShowBase import Plane from direct.directnotify import DirectNotifyGlobal from direct.showbase.RandomNumGen import RandomNumGen from direct.interval.MetaInterval import Sequence, Parallel diff --git a/toontown/cogdominium/CogdoExecutiveSuiteMovies.py b/toontown/cogdominium/CogdoExecutiveSuiteMovies.py index 0558ba0..9868269 100644 --- a/toontown/cogdominium/CogdoExecutiveSuiteMovies.py +++ b/toontown/cogdominium/CogdoExecutiveSuiteMovies.py @@ -1,6 +1,5 @@ -from panda3d.core import NodePath, Point3, PlaneNode, TextNode +from panda3d.core import NodePath, Point3, Plane, PlaneNode, TextNode from direct.interval.IntervalGlobal import * -from direct.showbase.ShowBase import Plane from direct.directnotify import DirectNotifyGlobal from direct.showbase.RandomNumGen import RandomNumGen from direct.interval.MetaInterval import Sequence, Parallel diff --git a/toontown/cogdominium/CogdoFlyingGameMovies.py b/toontown/cogdominium/CogdoFlyingGameMovies.py index 64378a5..3ce87ca 100644 --- a/toontown/cogdominium/CogdoFlyingGameMovies.py +++ b/toontown/cogdominium/CogdoFlyingGameMovies.py @@ -1,5 +1,4 @@ -from panda3d.core import Point3, PlaneNode -from direct.showbase.ShowBase import Plane +from panda3d.core import Point3, Plane, PlaneNode from direct.showbase.RandomNumGen import RandomNumGen from direct.interval.MetaInterval import Sequence, Parallel from direct.interval.FunctionInterval import Func, Wait diff --git a/toontown/cogdominium/CogdoMazeGameMovies.py b/toontown/cogdominium/CogdoMazeGameMovies.py index e3b45e5..20e6874 100644 --- a/toontown/cogdominium/CogdoMazeGameMovies.py +++ b/toontown/cogdominium/CogdoMazeGameMovies.py @@ -1,5 +1,4 @@ -from panda3d.core import NodePath, Point3, PlaneNode -from direct.showbase.ShowBase import Plane +from panda3d.core import NodePath, Point3, Plane, PlaneNode from direct.showbase.RandomNumGen import RandomNumGen from direct.interval.MetaInterval import Sequence, Parallel from direct.interval.FunctionInterval import Func, Wait diff --git a/toontown/cogdominium/DistributedCogdoBarrel.py b/toontown/cogdominium/DistributedCogdoBarrel.py index 6a5b0d9..6b37fc1 100644 --- a/toontown/cogdominium/DistributedCogdoBarrel.py +++ b/toontown/cogdominium/DistributedCogdoBarrel.py @@ -34,8 +34,8 @@ class DistributedCogdoBarrel(DistributedObject.DistributedObject): cogdoBarrelsNode = render.attachNewNode('CogdoBarrels') cogdoBarrelsNode.stash() self.model.reparentTo(cogdoBarrelsNode) - self.availableTex = loader.loadTexture('phase_5/maps/tt_t_ara_cbr_Barrel_notUsed.jpg') - self.usedTex = loader.loadTexture('phase_5/maps/tt_t_ara_cbr_Barrel_Used.jpg') + self.availableTex = loader.loadTexture('phase_5/maps/tt_t_ara_cbr_Barrel_notUsed.png') + self.usedTex = loader.loadTexture('phase_5/maps/tt_t_ara_cbr_Barrel_Used.png') self.model.setTexture(self.availableTex, 100) def __addCollision(self): diff --git a/toontown/estate/DistributedToonStatuary.py b/toontown/estate/DistributedToonStatuary.py index c89989d..b418317 100644 --- a/toontown/estate/DistributedToonStatuary.py +++ b/toontown/estate/DistributedToonStatuary.py @@ -98,10 +98,10 @@ class DistributedToonStatuary(DistributedStatuary.DistributedStatuary): for node in self.toon.findAllMatches('**/*'): node.setState(RenderState.makeEmpty()) - desatShirtTex = loader.loadTexture('phase_3/maps/desat_shirt_1.jpg') - desatSleeveTex = loader.loadTexture('phase_3/maps/desat_sleeve_1.jpg') - desatShortsTex = loader.loadTexture('phase_3/maps/desat_shorts_1.jpg') - desatSkirtTex = loader.loadTexture('phase_3/maps/desat_skirt_1.jpg') + desatShirtTex = loader.loadTexture('phase_3/maps/desat_shirt_1.png') + desatSleeveTex = loader.loadTexture('phase_3/maps/desat_sleeve_1.png') + desatShortsTex = loader.loadTexture('phase_3/maps/desat_shorts_1.png') + desatSkirtTex = loader.loadTexture('phase_3/maps/desat_skirt_1.png') if self.toon.hasLOD(): for lodName in self.toon.getLODNames(): torso = self.toon.getPart('torso', lodName) @@ -123,7 +123,7 @@ class DistributedToonStatuary(DistributedStatuary.DistributedStatuary): def setStoneTexture(self): gray = VBase4(1.6, 1.6, 1.6, 1) self.toon.setColor(gray, 10) - stoneTex = loader.loadTexture('phase_5.5/maps/smoothwall_1.jpg') + stoneTex = loader.loadTexture('phase_5.5/maps/smoothwall_1.png') ts = TextureStage('ts') ts.setPriority(1) self.toon.setTexture(ts, stoneTex) diff --git a/toontown/fishing/DistributedFishingPondAI.py b/toontown/fishing/DistributedFishingPondAI.py index 68754c4..d2e86ab 100644 --- a/toontown/fishing/DistributedFishingPondAI.py +++ b/toontown/fishing/DistributedFishingPondAI.py @@ -3,3 +3,13 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI class DistributedFishingPondAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedFishingPondAI') + + def __init__(self, air): + DistributedObjectAI.__init__(self, air) + self.area = None + + def setArea(self, area): + self.area = area + + def getArea(self): + return self.area diff --git a/toontown/friends/ToontownFriendSecret.py b/toontown/friends/ToontownFriendSecret.py index 491a7ce..f7dc1a8 100644 --- a/toontown/friends/ToontownFriendSecret.py +++ b/toontown/friends/ToontownFriendSecret.py @@ -3,9 +3,13 @@ from direct.gui.DirectGui import * from direct.directnotify import DirectNotifyGlobal from otp.otpbase import OTPLocalizer from toontown.toonbase import TTLocalizer + +# This file overrides key methods in FriendSecret to add Toontown specific text to the OTP buttons + from otp.friends.FriendSecret import AccountSecret from otp.friends.FriendSecret import AvatarSecret from otp.friends.FriendSecret import BothSecrets + from otp.friends import FriendSecret from otp.friends.FriendSecret import globalFriendSecret from otp.friends.FriendSecret import showFriendSecret @@ -18,41 +22,94 @@ def openFriendSecret(secretType): globalFriendSecret.unload() globalFriendSecret = ToontownFriendSecret(secretType) globalFriendSecret.enter() - return - +# there is no way to overload module level methods, so hammer it in FriendSecret.openFriendSecret = openFriendSecret class ToontownFriendSecret(FriendSecret.FriendSecret): - notify = DirectNotifyGlobal.directNotify.newCategory('ToontownFriendSecret') + + notify = DirectNotifyGlobal.directNotify.newCategory("ToontownFriendSecret") def __init__(self, secretType): + #secretType is specefied in toon/ToonAvatarPanel.py-> __handleSecrets(self): FriendSecret.FriendSecret.__init__(self, secretType) self.initialiseoptions(ToontownFriendSecret) def makeFriendTypeButtons(self): + assert self.notify.debugCall() + buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') - self.avatarButton = DirectButton(parent=self, image=(buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), relief=None, text=TTLocalizer.FriendInviterToon, text_scale=0.07, text_pos=(0.0, -0.1), pos=(-0.35, 0.0, -0.05), command=self._FriendSecret__handleAvatar) - avatarText = DirectLabel(parent=self, relief=None, pos=Vec3(0.35, 0, -0.3), text=TTLocalizer.FriendInviterToonFriendInfo, text_fg=(0, 0, 0, 1), text_pos=(0, 0), text_scale=0.055, text_align=TextNode.ACenter) + + # make an avatar friend + self.avatarButton = DirectButton( + parent = self, + image = (buttons.find('**/ChtBx_OKBtn_UP'), + buttons.find('**/ChtBx_OKBtn_DN'), + buttons.find('**/ChtBx_OKBtn_Rllvr')), + relief = None, + text = TTLocalizer.FriendInviterToon, + text_scale = 0.07, + text_pos = (0.0, -0.1), + pos = (-0.35, 0.0, -0.05), + command = self._FriendSecret__handleAvatar + ) + # make a label to show avatar friend desc on rollover + avatarText = DirectLabel( + parent = self, + relief = None, + pos = Vec3(0.35, 0, -0.3), + text = TTLocalizer.FriendInviterToonFriendInfo, + text_fg = (0, 0, 0, 1), + text_pos = (0, 0), + text_scale = 0.055, + text_align = TextNode.ACenter, + ) avatarText.reparentTo(self.avatarButton.stateNodePath[2]) self.avatarButton.hide() - self.accountButton = DirectButton(parent=self, image=(buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')), relief=None, text=TTLocalizer.FriendInviterPlayer, text_scale=0.07, text_pos=(0.0, -0.1), pos=(0.35, 0.0, -0.05), command=self._FriendSecret__handleAccount) - accountText = DirectLabel(parent=self, relief=None, pos=Vec3(-0.35, 0, -0.3), text=TTLocalizer.FriendInviterPlayerFriendInfo, text_fg=(0, 0, 0, 1), text_pos=(0, 0), text_scale=0.055, text_align=TextNode.ACenter) + + # make an account friend + self.accountButton = DirectButton( + parent = self, + image = (buttons.find('**/ChtBx_OKBtn_UP'), + buttons.find('**/ChtBx_OKBtn_DN'), + buttons.find('**/ChtBx_OKBtn_Rllvr')), + relief = None, + text = TTLocalizer.FriendInviterPlayer, + text_scale = 0.07, + text_pos = (0.0, -0.1), + pos = (0.35, 0.0, -0.05), + command = self._FriendSecret__handleAccount + ) + # make a label to show feature desc on rollover + accountText = DirectLabel( + parent = self, + relief = None, + pos = Vec3(-0.35, 0, -0.3), + text = TTLocalizer.FriendInviterPlayerFriendInfo, + text_fg = (0, 0, 0, 1), + text_pos = (0, 0), + text_scale = 0.055, + text_align = TextNode.ACenter, + ) accountText.reparentTo(self.accountButton.stateNodePath[2]) self.accountButton.hide() + buttons.removeNode() - return def __determineSecret(self): + assert self.notify.debugCall() + # If we support both types of secrets... if self.secretType == BothSecrets: + # ask the player what type they want self._FriendSecret__cleanupFirstPage() self.ok1.hide() self.changeOptions.hide() self.nextText['text'] = TTLocalizer.FriendInviterBegin - self.nextText.setPos(0, 0, 0.3) + self.nextText.setPos(0, 0, 0.30) self.nextText.show() self.avatarButton.show() self.accountButton.show() self.cancel.show() else: + # or just get the secret self._FriendSecret__getSecret() diff --git a/toontown/friends/ToontownFriendsManagerAI.py b/toontown/friends/ToontownFriendsManagerAI.py index a068cc7..cca30e2 100644 --- a/toontown/friends/ToontownFriendsManagerAI.py +++ b/toontown/friends/ToontownFriendsManagerAI.py @@ -22,5 +22,14 @@ class ToontownFriendsManagerAI(DistributedObjectGlobalAI): messenger.send("makeFriendsReply", [result, context]) + def requestSecretResponse(self, result, secret, avId): + messenger.send("requestSecretReply", [result, secret, avId]) + def sendRequestSecret(self, requesterId): self.sendUpdate('requestSecret', [requesterId]) + + def sendSubmitSecret(self, avId, secret): + self.sendUpdate('submitSecret', [avId, secret]) + + def submitSecretResponse(self, result, recipient, requesterId): + messenger.send("submitSecretReply", [result, recipient, requesterId]) \ No newline at end of file diff --git a/toontown/friends/ToontownFriendsManagerUD.py b/toontown/friends/ToontownFriendsManagerUD.py index 91830eb..33a4d33 100644 --- a/toontown/friends/ToontownFriendsManagerUD.py +++ b/toontown/friends/ToontownFriendsManagerUD.py @@ -1,28 +1,55 @@ from direct.directnotify import DirectNotifyGlobal from direct.distributed.DistributedObjectGlobalUD import DistributedObjectGlobalUD from direct.distributed.PyDatagram import * - +from direct.distributed.MsgTypes import * from otp.otpbase import OTPGlobals - - +import random +import string +import json +from panda3d.direct import DCPacker class FriendsOperation: + """ + Base class for all friend-related operations. + """ def __init__(self, friendsManager, sender): + """ + Initialize the FriendsOperation. + + :param friendsManager: The friends manager instance. + :param sender: The sender's ID. + """ self.friendsManager = friendsManager self.sender = sender def _handleDone(self): - # TODO - pass + """ + Handle the completion of the operation. + """ + self.friendsManager.operations.remove(self) def _handleError(self, error): - # TODO - pass + """ + Handle an error during the operation. + + :param error: The error message. + """ + self.friendsManager.notify.warning(error) + self.friendsManager.operations.remove(self) class GetFriendsListOperation(FriendsOperation): + """ + Operation to retrieve the friends list of a sender. + """ def __init__(self, friendsManager, sender): + """ + Initialize the GetFriendsListOperation. + + :param friendsManager: The friends manager instance. + :param sender: The sender's ID. + """ FriendsOperation.__init__(self, friendsManager, sender) self.friendsList = None self.tempFriendsList = None @@ -30,6 +57,9 @@ class GetFriendsListOperation(FriendsOperation): self.currentFriendIdx = None def start(self): + """ + Start the operation to retrieve the friends list. + """ self.friendsList = [] self.tempFriendsList = [] self.onlineFriends = [] @@ -38,6 +68,12 @@ class GetFriendsListOperation(FriendsOperation): self.__handleSenderRetrieved) def __handleSenderRetrieved(self, dclass, fields): + """ + Handle the retrieval of the sender's data. + + :param dclass: The data class of the sender. + :param fields: The fields of the sender. + """ if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']: self._handleError('Retrieved sender is not a DistributedToonUD!') return @@ -51,6 +87,12 @@ class GetFriendsListOperation(FriendsOperation): self.__handleFriendRetrieved) def __handleFriendRetrieved(self, dclass, fields): + """ + Handle the retrieval of a friend's data. + + :param dclass: The data class of the friend. + :param fields: The fields of the friend. + """ if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']: self._handleError('Retrieved friend is not a DistributedToonUD!') return @@ -67,11 +109,20 @@ class GetFriendsListOperation(FriendsOperation): self.__handleFriendRetrieved) def __checkFriendsOnline(self): + """ + Check which friends are currently online. + """ self.currentFriendIdx = 0 for friendDetails in self.friendsList: self.friendsManager.air.getActivated(friendDetails[0], self.__gotActivatedResp) def __gotActivatedResp(self, avId, activated): + """ + Handle the response of checking if a friend is activated. + + :param avId: The avatar ID. + :param activated: Whether the friend is activated. + """ self.currentFriendIdx += 1 if activated: self.onlineFriends.append(avId) @@ -80,34 +131,67 @@ class GetFriendsListOperation(FriendsOperation): self._handleDone() def __sendFriendsList(self, success): + """ + Send the friends list to the sender. + + :param success: Whether the operation was successful. + """ self.friendsManager.sendUpdateToAvatarId(self.sender, 'getFriendsListResponse', [success, self.friendsList if success else []]) for friendId in self.onlineFriends: self.friendsManager.sendFriendOnline(self.sender, friendId, 0, 1) def _handleDone(self): + """ + Handle the completion of the operation. + """ self.__sendFriendsList(True) FriendsOperation._handleDone(self) def _handleError(self, error): + """ + Handle an error during the operation. + + :param error: The error message. + """ self.__sendFriendsList(False) FriendsOperation._handleError(self, error) class GetAvatarDetailsOperation(FriendsOperation): + """ + Operation to retrieve the details of an avatar. + """ def __init__(self, friendsManager, sender): + """ + Initialize the GetAvatarDetailsOperation. + + :param friendsManager: The friends manager instance. + :param sender: The sender's ID. + """ FriendsOperation.__init__(self, friendsManager, sender) self.avId = None self.dclass = None self.fields = None def start(self, avId): + """ + Start the operation to retrieve the avatar details. + + :param avId: The avatar ID. + """ self.avId = avId self.fields = {} self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, avId, self.__handleAvatarRetrieved) def __handleAvatarRetrieved(self, dclass, fields): + """ + Handle the retrieval of the avatar's data. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + """ if dclass not in (self.friendsManager.air.dclassesByName['DistributedToonUD'], self.friendsManager.air.dclassesByName['DistributedPetAI']): self._handleError('Retrieved avatar is not a DistributedToonUD or DistributedPetAI!') @@ -119,6 +203,13 @@ class GetAvatarDetailsOperation(FriendsOperation): self._handleDone() def __packAvatarDetails(self, dclass, fields): + """ + Pack the avatar details into a byte array. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + :return: The packed avatar details. + """ # Pack required fields. fieldPacker = DCPacker() for i in range(dclass.getNumInheritedFields()): @@ -140,6 +231,11 @@ class GetAvatarDetailsOperation(FriendsOperation): return fieldPacker.getBytes() def __sendAvatarDetails(self, success): + """ + Send the avatar details to the sender. + + :param success: Whether the operation was successful. + """ datagram = PyDatagram() datagram.addUint32(self.fields['avId']) # avId datagram.addUint8(0 if success else 1) # returnCode @@ -150,17 +246,33 @@ class GetAvatarDetailsOperation(FriendsOperation): self.friendsManager.sendUpdateToAvatarId(self.sender, 'getAvatarDetailsResponse', [datagram.getMessage()]) def _handleDone(self): + """ + Handle the completion of the operation. + """ self.__sendAvatarDetails(True) FriendsOperation._handleDone(self) def _handleError(self, error): + """ + Handle an error during the operation. + + :param error: The error message. + """ self.__sendAvatarDetails(False) FriendsOperation._handleError(self, error) class MakeFriendsOperation(FriendsOperation): + """ + Operation to make two avatars friends. + """ def __init__(self, friendsManager): + """ + Initialize the MakeFriendsOperation. + + :param friendsManager: The friends manager instance. + """ FriendsOperation.__init__(self, friendsManager, None) self.avatarAId = None self.avatarBId = None @@ -172,6 +284,14 @@ class MakeFriendsOperation(FriendsOperation): self.avatarBFriendsList = None def start(self, avatarAId, avatarBId, flags, context): + """ + Start the operation to make two avatars friends. + + :param avatarAId: The first avatar's ID. + :param avatarBId: The second avatar's ID. + :param flags: The friendship flags. + :param context: The context of the operation. + """ self.avatarAId = avatarAId self.avatarBId = avatarBId self.flags = flags @@ -181,14 +301,34 @@ class MakeFriendsOperation(FriendsOperation): self.friendsManager.air.getActivated(self.avatarAId, self.__gotActivatedAvatarA) def __handleActivatedResp(self, avId, activated): + """ + Handle the response of checking if an avatar is activated. + + :param avId: The avatar ID. + :param activated: Whether the avatar is activated. + """ if activated: self.onlineToons.append(avId) def __gotActivatedAvatarA(self, avId, activated): + """ + Handle the response of checking if the first avatar is activated. + + :param avId: The avatar ID. + :param activated: Whether the avatar is activated. + """ self.__handleActivatedResp(avId, activated) self.friendsManager.air.getActivated(self.avatarBId, self.__gotActivatedAvatarB) def __handleMakeFriends(self, dclass, fields, friendId): + """ + Handle the process of making friends. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + :param friendId: The friend's ID. + :return: A tuple indicating success and the updated friends list. + """ if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']: self._handleError('Retrieved avatar is not a DistributedToonUD!') return False, [] @@ -207,6 +347,12 @@ class MakeFriendsOperation(FriendsOperation): return True, friendsList def __handleAvatarARetrieved(self, dclass, fields): + """ + Handle the retrieval of the first avatar's data. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + """ success, avatarAFriendsList = self.__handleMakeFriends(dclass, fields, self.avatarBId) if success: self.avatarAFriendsList = avatarAFriendsList @@ -214,17 +360,35 @@ class MakeFriendsOperation(FriendsOperation): self.__handleAvatarBRetrieved) def __gotActivatedAvatarB(self, avId, activated): + """ + Handle the response of checking if the second avatar is activated. + + :param avId: The avatar ID. + :param activated: Whether the avatar is activated. + """ self.__handleActivatedResp(avId, activated) self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, self.avatarAId, self.__handleAvatarARetrieved) def __handleAvatarBRetrieved(self, dclass, fields): + """ + Handle the retrieval of the second avatar's data. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + """ success, avatarBFriendsList = self.__handleMakeFriends(dclass, fields, self.avatarAId) if success: self.avatarBFriendsList = avatarBFriendsList self._handleDone() def __handleSetFriendsList(self, avId, friendsList): + """ + Handle setting the friends list for an avatar. + + :param avId: The avatar ID. + :param friendsList: The updated friends list. + """ if avId in self.onlineToons: self.friendsManager.sendUpdateToAvatar(avId, 'setFriendsList', [friendsList]) else: @@ -234,6 +398,9 @@ class MakeFriendsOperation(FriendsOperation): {'setFriendsList': [friendsList]}) def _handleDone(self): + """ + Handle the completion of the operation. + """ self.resultCode = 1 if self.avatarAFriendsList is not None and self.avatarBFriendsList is not None: self.__handleSetFriendsList(self.avatarAId, self.avatarAFriendsList) @@ -247,14 +414,28 @@ class MakeFriendsOperation(FriendsOperation): FriendsOperation._handleDone(self) def _handleError(self, error): + """ + Handle an error during the operation. + + :param error: The error message. + """ self.resultCode = 0 self.friendsManager.sendMakeFriendsResponse(self.avatarAId, self.avatarBId, self.resultCode, self.context) FriendsOperation._handleError(self, error) class RemoveFriendOperation(FriendsOperation): + """ + Operation to remove a friend from the sender's friends list. + """ def __init__(self, friendsManager, sender): + """ + Initialize the RemoveFriendOperation. + + :param friendsManager: The friends manager instance. + :param sender: The sender's ID. + """ FriendsOperation.__init__(self, friendsManager, sender) self.friendId = None self.onlineToons = None @@ -262,24 +443,55 @@ class RemoveFriendOperation(FriendsOperation): self.friendFriendsList = None def start(self, friendId): + """ + Start the operation to remove a friend. + + :param friendId: The friend's ID. + """ self.friendId = friendId self.onlineToons = [] self.friendsManager.air.getActivated(self.sender, self.__gotSenderActivated) def __handleActivatedResp(self, avId, activated): + """ + Handle the response of checking if an avatar is activated. + + :param avId: The avatar ID. + :param activated: Whether the avatar is activated. + """ if activated: self.onlineToons.append(avId) def __gotSenderActivated(self, avId, activated): + """ + Handle the response of checking if the sender is activated. + + :param avId: The avatar ID. + :param activated: Whether the avatar is activated. + """ self.__handleActivatedResp(avId, activated) self.friendsManager.air.getActivated(self.friendId, self.__gotFriendActivated) def __gotFriendActivated(self, avId, activated): + """ + Handle the response of checking if the friend is activated. + + :param avId: The avatar ID. + :param activated: Whether the avatar is activated. + """ self.__handleActivatedResp(avId, activated) self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, self.sender, self.__handleSenderRetrieved) def __handleRemoveFriend(self, dclass, fields, friendId): + """ + Handle the process of removing a friend. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + :param friendId: The friend's ID. + :return: A tuple indicating success and the updated friends list. + """ if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']: self._handleError('Retrieved sender is not a DistributedToonUD!') return False, [] @@ -299,6 +511,12 @@ class RemoveFriendOperation(FriendsOperation): return False, [] def __handleSenderRetrieved(self, dclass, fields): + """ + Handle the retrieval of the sender's data. + + :param dclass: The data class of the sender. + :param fields: The fields of the sender. + """ success, senderFriendsList = self.__handleRemoveFriend(dclass, fields, self.friendId) if success: self.senderFriendsList = senderFriendsList @@ -306,12 +524,24 @@ class RemoveFriendOperation(FriendsOperation): self.__handleFriendRetrieved) def __handleFriendRetrieved(self, dclass, fields): + """ + Handle the retrieval of the friend's data. + + :param dclass: The data class of the friend. + :param fields: The fields of the friend. + """ success, friendFriendsList = self.__handleRemoveFriend(dclass, fields, self.sender) if success: self.friendFriendsList = friendFriendsList self._handleDone() def __handleSetFriendsList(self, avId, friendsList): + """ + Handle setting the friends list for an avatar. + + :param avId: The avatar ID. + :param friendsList: The updated friends list. + """ if avId in self.onlineToons: self.friendsManager.sendUpdateToAvatar(avId, 'setFriendsList', [friendsList]) else: @@ -321,6 +551,9 @@ class RemoveFriendOperation(FriendsOperation): {'setFriendsList': [friendsList]}) def _handleDone(self): + """ + Handle the completion of the operation. + """ if self.senderFriendsList is not None and self.friendFriendsList is not None: self.__handleSetFriendsList(self.sender, self.senderFriendsList) self.__handleSetFriendsList(self.friendId, self.friendFriendsList) @@ -336,24 +569,47 @@ class RemoveFriendOperation(FriendsOperation): class ComingOnlineOperation(FriendsOperation): + """ + Operation to handle an avatar coming online. + """ def __init__(self, friendsManager): + """ + Initialize the ComingOnlineOperation. + + :param friendsManager: The friends manager instance. + """ FriendsOperation.__init__(self, friendsManager, None) self.avId = None self.friendsList = None self.currentFriendIdx = None def start(self, avId, friendsList): + """ + Start the operation to handle an avatar coming online. + + :param avId: The avatar ID. + :param friendsList: The friends list of the avatar. + """ self.avId = avId self.friendsList = friendsList self.__checkFriendsOnline() def __checkFriendsOnline(self): + """ + Check which friends are currently online. + """ self.currentFriendIdx = 0 for friendId in self.friendsList: self.friendsManager.air.getActivated(friendId, self.__gotFriendActivated) def __gotFriendActivated(self, avId, activated): + """ + Handle the response of checking if a friend is activated. + + :param avId: The avatar ID. + :param activated: Whether the friend is activated. + """ self.currentFriendIdx += 1 if activated: self.friendsManager.declareObject(avId, self.avId) @@ -365,8 +621,16 @@ class ComingOnlineOperation(FriendsOperation): class GoingOfflineOperation(FriendsOperation): + """ + Operation to handle an avatar going offline. + """ def __init__(self, friendsManager): + """ + Initialize the GoingOfflineOperation. + + :param friendsManager: The friends manager instance. + """ FriendsOperation.__init__(self, friendsManager, None) self.avId = None self.friendsList = None @@ -374,12 +638,23 @@ class GoingOfflineOperation(FriendsOperation): self.currentFriendIdx = None def start(self, avId): + """ + Start the operation to handle an avatar going offline. + + :param avId: The avatar ID. + """ self.avId = avId self.friendsList = [] self.accId = 0 self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, self.avId, self.__handleAvatarRetrieved) def __handleAvatarRetrieved(self, dclass, fields): + """ + Handle the retrieval of the avatar's data. + + :param dclass: The data class of the avatar. + :param fields: The fields of the avatar. + """ if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']: self._handleError('Retrieved avatar is not a DistributedToonUD!') return @@ -389,11 +664,20 @@ class GoingOfflineOperation(FriendsOperation): self.__checkFriendsOnline() def __checkFriendsOnline(self): + """ + Check which friends are currently online. + """ self.currentFriendIdx = 0 for friendId, _ in self.friendsList: self.friendsManager.air.getActivated(friendId, self.__gotFriendActivated) def __gotFriendActivated(self, avId, activated): + """ + Handle the response of checking if a friend is activated. + + :param avId: The avatar ID. + :param activated: Whether the friend is activated. + """ self.currentFriendIdx += 1 if activated: self.friendsManager.undeclareObject(avId, self.avId) @@ -403,19 +687,97 @@ class GoingOfflineOperation(FriendsOperation): if self.currentFriendIdx >= len(self.friendsList): self._handleDone() +class GenerateSecretOperation(FriendsOperation): + """ + Operation to generate a secret. + """ + def __init__(self, friendsManager): + """ + Initialize the GenerateSecretOperation. + + :param friendsManager: The friends manager instance. + :param requesterId: The requester's ID. + """ + FriendsOperation.__init__(self, friendsManager, None) + self.secret = None + self.requesterId = None + + def start(self, requesterId): + """ + Start the operation to generate a secret. + Format of secret: + TT 3 random letters/numbers 3 random letters/numbers + """ + self.requesterId = requesterId + self.friendsManager.loadSecretsDB() + # check if too many secrets + # TODO + self.secret = '' + for i in range(3): + self.secret += random.choice(string.ascii_letters + string.digits) + self.secret += ' ' + for i in range(3): + self.secret += random.choice(string.ascii_letters + string.digits) + + self.friendsManager.secrets[self.secret] = requesterId + self._handleDone() + + def _handleDone(self): + """ + Handle the completion of the operation. + """ + FriendsOperation._handleDone(self) + self.friendsManager.updateSecretsDB() + # send the response to the requester that it was a success, the result and the secret + self.friendsManager.sendRequestSecretResponse(self.requesterId, 1, self.secret) + + + def _handleError(self, error): + """ + Handle an error during the operation. + + :param error: The error message. + """ + FriendsOperation._handleError(self, error) + # send the response to the requester that it was a failure, the result and the secret + self.friendsManager.sendRequestSecretResponse(self.requesterId, 0, '') + class ToontownFriendsManagerUD(DistributedObjectGlobalUD): + """ + The main friends manager class for Toontown. + """ notify = DirectNotifyGlobal.directNotify.newCategory('ToontownFriendsManagerUD') def __init__(self, air): + """ + Initialize the ToontownFriendsManagerUD. + + :param air: The AI repository instance. + """ DistributedObjectGlobalUD.__init__(self, air) + self.secret = None self.operations = [] - self.secrets = [] + self.secrets = {} def sendMakeFriendsResponse(self, avatarAId, avatarBId, result, context): + """ + Send the response for making friends. + + :param avatarAId: The first avatar's ID. + :param avatarBId: The second avatar's ID. + :param result: The result of the operation. + :param context: The context of the operation. + """ self.sendUpdate('makeFriendsResponse', [avatarAId, avatarBId, result, context]) def declareObject(self, doId, objId): + """ + Declare an object to the client. + + :param doId: The distributed object ID. + :param objId: The object ID. + """ datagram = PyDatagram() datagram.addServerHeader(self.GetPuppetConnectionChannel(doId), self.air.ourChannel, CLIENTAGENT_DECLARE_OBJECT) datagram.addUint32(objId) @@ -423,6 +785,13 @@ class ToontownFriendsManagerUD(DistributedObjectGlobalUD): self.air.send(datagram) def undeclareObject(self, doId, objId, isAccount=False): + """ + Undeclare an object to the client. + + :param doId: The distributed object ID. + :param objId: The object ID. + :param isAccount: Whether the object is an account. + """ datagram = PyDatagram() if isAccount: datagram.addServerHeader(self.GetAccountConnectionChannel(doId), self.air.ourChannel, @@ -435,12 +804,33 @@ class ToontownFriendsManagerUD(DistributedObjectGlobalUD): self.air.send(datagram) def sendFriendOnline(self, avId, friendId, commonChatFlags, whitelistChatFlags): + """ + Notify that a friend has come online. + + :param avId: The avatar ID. + :param friendId: The friend's ID. + :param commonChatFlags: The common chat flags. + :param whitelistChatFlags: The whitelist chat flags. + """ self.sendUpdateToAvatarId(avId, 'friendOnline', [friendId, commonChatFlags, whitelistChatFlags]) def sendFriendOffline(self, avId, friendId): + """ + Notify that a friend has gone offline. + + :param avId: The avatar ID. + :param friendId: The friend's ID. + """ self.sendUpdateToAvatarId(avId, 'friendOffline', [friendId]) def sendUpdateToAvatar(self, avId, fieldName, args=[]): + """ + Send an update to an avatar. + + :param avId: The avatar ID. + :param fieldName: The field name to update. + :param args: The arguments for the update. + """ dclass = self.air.dclassesByName['DistributedToonUD'] if not dclass: return @@ -453,6 +843,12 @@ class ToontownFriendsManagerUD(DistributedObjectGlobalUD): self.air.send(datagram) def runSenderOperation(self, operationType, *args): + """ + Run an operation initiated by the sender. + + :param operationType: The type of operation. + :param args: The arguments for the operation. + """ sender = self.air.getAvatarIdFromSender() if not sender: return @@ -462,27 +858,120 @@ class ToontownFriendsManagerUD(DistributedObjectGlobalUD): newOperation.start(*args) def runServerOperation(self, operationType, *args): + """ + Run an operation initiated by the server. + + :param operationType: The type of operation. + :param args: The arguments for the operation. + """ newOperation = operationType(self) self.operations.append(newOperation) newOperation.start(*args) def getFriendsListRequest(self): + """ + Handle a request to get the friends list. + """ self.runSenderOperation(GetFriendsListOperation) def getAvatarDetailsRequest(self, avId): + """ + Handle a request to get avatar details. + + :param avId: The avatar ID. + """ self.runSenderOperation(GetAvatarDetailsOperation, avId) def makeFriends(self, avatarAId, avatarBId, flags, context): + """ + Handle a request to make two avatars friends. + + :param avatarAId: The first avatar's ID. + :param avatarBId: The second avatar's ID. + :param flags: The friendship flags. + :param context: The context of the operation. + """ self.runServerOperation(MakeFriendsOperation, avatarAId, avatarBId, flags, context) def removeFriend(self, friendId): + """ + Handle a request to remove a friend. + + :param friendId: The friend's ID. + """ self.runSenderOperation(RemoveFriendOperation, friendId) + def requestSecret(self, requesterId): + """ + Handle a request to generate a secret. + + """ + self.runServerOperation(GenerateSecretOperation, requesterId) + + def submitSecret(self, avId, secret): + """ + Handle a request to submit a secret. + + :param avId: The avatar ID. + :param secret: The secret. + """ + self.loadSecretsDB() + recipient = self.secrets.get(secret, None) + if recipient: + self.runServerOperation(MakeFriendsOperation, avId, recipient, 0, 0) + self.sendSubmitSecretResponse(avId, 1, recipient) + else: + self.sendSubmitSecretResponse(avId, 0, recipient) + + def sendSubmitSecretResponse(self, requesterId, success, recipient): + """ + Send a response to a secret submission. + + :param requesterId: The requester's ID. + :param success: Whether the operation was successful. + :param secret: The secret. + :param recipient: The recipient's ID. + """ + self.sendUpdate('submitSecretResponse', [success, recipient, requesterId]) + def comingOnline(self, avId, friendsList): + """ + Handle a request for an avatar coming online. + + :param avId: The avatar ID. + :param friendsList: The friends list of the avatar. + """ self.runServerOperation(ComingOnlineOperation, avId, friendsList) def goingOffline(self, avId): + """ + Handle a request for an avatar going offline. + + :param avId: The avatar ID. + """ self.runServerOperation(GoingOfflineOperation, avId) - def requestSecret(self, requesterId): - print('requestSecret') + def sendRequestSecretResponse(self, requesterId, success, secret): + """ + Send a response to a secret request. + + :param requesterId: The requester's ID. + :param success: Whether the operation was successful. + :param secret: The generated secret. + """ + self.sendUpdate('requestSecretResponse', [success, secret, requesterId]) + + + def updateSecretsDB(self): + with open('astron/databases/secrets.json', 'w') as f: + json.dump(self.secrets, f) + self.notify.debug('Updated secrets database') + + def loadSecretsDB(self): + try: + with open('astron/databases/secrets.json', 'r') as f: + self.secrets = json.load(f) + self.notify.debug('Loaded secrets database') + except: + self.notify.warning('Failed to load secrets database') + \ No newline at end of file diff --git a/toontown/golf/GolfHoleBase.py b/toontown/golf/GolfHoleBase.py index 3de8ed8..c2a2106 100644 --- a/toontown/golf/GolfHoleBase.py +++ b/toontown/golf/GolfHoleBase.py @@ -2,6 +2,7 @@ from direct.distributed import DistributedObjectAI from direct.directnotify import DirectNotifyGlobal from toontown.toonbase import ToontownGlobals from panda3d.core import * +from panda3d.ode import OdeTriMeshData, OdeTriMeshGeom, OdeBody, OdeRayGeom from . import DistributedPhysicsWorldAI from direct.fsm.FSM import FSM from toontown.ai.ToonBarrier import * diff --git a/toontown/golf/GolfRewardDialog.py b/toontown/golf/GolfRewardDialog.py index bd90ba8..e02ed2b 100644 --- a/toontown/golf/GolfRewardDialog.py +++ b/toontown/golf/GolfRewardDialog.py @@ -1,5 +1,6 @@ from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * +from direct.gui.DirectGui import * +from toontown.toonbase import TTLocalizer, ToontownGlobals from direct.interval.IntervalGlobal import * from direct.task import Task from direct.directnotify import DirectNotifyGlobal diff --git a/toontown/golf/GolfScoreBoard.py b/toontown/golf/GolfScoreBoard.py index 2664b22..684cb94 100644 --- a/toontown/golf/GolfScoreBoard.py +++ b/toontown/golf/GolfScoreBoard.py @@ -1,6 +1,7 @@ from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * +from toontown.toonbase import TTLocalizer, ToontownGlobals from direct.directnotify import DirectNotifyGlobal +from direct.gui.DirectGui import * from direct.interval.IntervalGlobal import * from direct.task import Task from math import * diff --git a/toontown/golf/PhysicsWorldBase.py b/toontown/golf/PhysicsWorldBase.py index aa45cfa..d83d36c 100644 --- a/toontown/golf/PhysicsWorldBase.py +++ b/toontown/golf/PhysicsWorldBase.py @@ -2,6 +2,7 @@ from direct.distributed import DistributedObject from direct.directnotify import DirectNotifyGlobal from toontown.toonbase import ToontownGlobals from panda3d.core import * +from panda3d.ode import OdeWorld, OdeSimpleSpace, OdeJointGroup, OdePlaneGeom, OdeBody, OdeMass, OdeSphereGeom, OdeBoxGeom, OdeSliderJoint, OdeTriMeshData, OdeTriMeshGeom, OdeHingeJoint from math import * import math from direct.fsm.FSM import FSM diff --git a/toontown/hood/Hood.py b/toontown/hood/Hood.py index 6872c50..3bd164c 100644 --- a/toontown/hood/Hood.py +++ b/toontown/hood/Hood.py @@ -1,24 +1,33 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from toontown.toonbase.ToontownGlobals import * -from toontown.distributed.ToontownMsgTypes import * -from direct.directnotify import DirectNotifyGlobal -from direct.fsm import StateData -from direct.task.Task import Task -from toontown.minigame import Purchase -from direct.gui import OnscreenText -from toontown.building import SuitInterior -from . import QuietZoneState -from . import ZoneUtil -from toontown.toonbase import TTLocalizer -from toontown.toon.Toon import teleportDebug -from direct.interval.IntervalGlobal import * +from panda3d.core import ( + CompassEffect, + ModelPool, + NodePath, + TexturePool, + TransparencyAttrib, + Vec4 +) -class Hood(StateData.StateData): - notify = DirectNotifyGlobal.directNotify.newCategory('Hood') +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.StateData import StateData +from direct.gui.OnscreenText import OnscreenText +from direct.interval.IntervalGlobal import Sequence, Wait, Func +from direct.showbase.MessengerGlobal import messenger +from direct.showbase.PythonUtil import uniqueName +from direct.task.TaskManagerGlobal import taskMgr + +from toontown.hood import ZoneUtil +from toontown.hood.QuietZoneState import QuietZoneState +from toontown.toon.Toon import teleportDebug +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base + + +class Hood(StateData): + notify = directNotify.newCategory('Hood') def __init__(self, parentFSM, doneEvent, dnaStore, hoodId): - StateData.StateData.__init__(self, doneEvent) + StateData.__init__(self, doneEvent) self.loader = 'not initialized' self.parentFSM = parentFSM self.dnaStore = dnaStore @@ -31,21 +40,20 @@ class Hood(StateData.StateData): self.holidayStorageDNADict = {} self.spookySkyFile = None self.halloweenLights = [] - return def enter(self, requestStatus): - hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] hoodText = self.getHoodText(zoneId) - self.titleText = OnscreenText.OnscreenText(hoodText, fg=self.titleColor, font=getSignFont(), pos=(0, -0.5), scale=TTLocalizer.HtitleText, drawOrder=0, mayChange=1) + self.titleText = OnscreenText(hoodText, fg=self.titleColor, font=ToontownGlobals.getSignFont(), pos=(0, -0.5), scale=TTLocalizer.HtitleText, drawOrder=0, mayChange=1) self.fsm.request(requestStatus['loader'], [requestStatus]) def getHoodText(self, zoneId): hoodText = base.cr.hoodMgr.getFullnameFromId(self.id) - if self.id != Tutorial: - streetName = StreetNames.get(ZoneUtil.getCanonicalBranchZone(zoneId)) + if self.id != ToontownGlobals.Tutorial: + streetName = ToontownGlobals.StreetNames.get(ZoneUtil.getCanonicalBranchZone(zoneId)) if streetName: hoodText = hoodText + '\n' + streetName[-1] + return hoodText def spawnTitleText(self, zoneId): @@ -69,32 +77,35 @@ class Hood(StateData.StateData): if self.titleTextSeq: self.titleTextSeq.finish() self.titleTextSeq = None + if self.titleText: self.titleText.cleanup() self.titleText = None + base.localAvatar.stopChat() - return def load(self): if self.storageDNAFile: - loader.loadDNAFile(self.dnaStore, self.storageDNAFile) + base.loader.loadDNAFile(self.dnaStore, self.storageDNAFile) + newsManager = base.cr.newsManager if newsManager: holidayIds = base.cr.newsManager.getDecorationHolidayId() for holiday in holidayIds: for storageFile in self.holidayStorageDNADict.get(holiday, []): - loader.loadDNAFile(self.dnaStore, storageFile) + base.loader.loadDNAFile(self.dnaStore, storageFile) if ToontownGlobals.HALLOWEEN_COSTUMES not in holidayIds and ToontownGlobals.SPOOKY_COSTUMES not in holidayIds or not self.spookySkyFile: - self.sky = loader.loadModel(self.skyFile) + self.sky = base.loader.loadModel(self.skyFile) self.sky.setTag('sky', 'Regular') self.sky.setScale(1.0) self.sky.setFogOff() else: - self.sky = loader.loadModel(self.spookySkyFile) + self.sky = base.loader.loadModel(self.spookySkyFile) self.sky.setTag('sky', 'Halloween') + if not newsManager: - self.sky = loader.loadModel(self.skyFile) + self.sky = base.loader.loadModel(self.skyFile) self.sky.setTag('sky', 'Regular') self.sky.setScale(1.0) self.sky.setFogOff() @@ -105,6 +116,7 @@ class Hood(StateData.StateData): self.loader.exit() self.loader.unload() del self.loader + del self.fsm del self.parentFSM self.dnaStore.resetHood() @@ -134,12 +146,13 @@ class Hood(StateData.StateData): teleportDebug(requestStatus, 'Hood.enterQuietZone: status=%s' % requestStatus) self._quietZoneDoneEvent = uniqueName('quietZoneDone') self.acceptOnce(self._quietZoneDoneEvent, self.handleQuietZoneDone) - self.quietZoneStateData = QuietZoneState.QuietZoneState(self._quietZoneDoneEvent) + self.quietZoneStateData = QuietZoneState(self._quietZoneDoneEvent) self._enterWaitForSetZoneResponseMsg = self.quietZoneStateData.getEnterWaitForSetZoneResponseMsg() self.acceptOnce(self._enterWaitForSetZoneResponseMsg, self.handleWaitForSetZoneResponse) self._quietZoneLeftEvent = self.quietZoneStateData.getQuietZoneLeftEvent() if base.placeBeforeObjects: self.acceptOnce(self._quietZoneLeftEvent, self.handleLeftQuietZone) + self.quietZoneStateData.load() self.quietZoneStateData.enter(requestStatus) @@ -151,7 +164,6 @@ class Hood(StateData.StateData): self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None - return def loadLoader(self, requestStatus): pass @@ -159,19 +171,21 @@ class Hood(StateData.StateData): def handleWaitForSetZoneResponse(self, requestStatus): loaderName = requestStatus['loader'] if loaderName == 'safeZoneLoader': - if not loader.inBulkBlock: - loader.beginBulkLoad('hood', TTLocalizer.HeadingToPlayground, safeZoneCountMap[self.id], 1, TTLocalizer.TIP_GENERAL) + if not base.loader.inBulkBlock: + base.loader.beginBulkLoad('hood', TTLocalizer.HeadingToPlayground, ToontownGlobals.safeZoneCountMap[self.id], 1, TTLocalizer.TIP_GENERAL) + self.loadLoader(requestStatus) - loader.endBulkLoad('hood') + base.loader.endBulkLoad('hood') elif loaderName == 'townLoader': - if not loader.inBulkBlock: + if not base.loader.inBulkBlock: zoneId = requestStatus['zoneId'] - toPhrase = StreetNames[ZoneUtil.getCanonicalBranchZone(zoneId)][0] - streetName = StreetNames[ZoneUtil.getCanonicalBranchZone(zoneId)][-1] - loader.beginBulkLoad('hood', TTLocalizer.HeadingToStreet % {'to': toPhrase, - 'street': streetName}, townCountMap[self.id], 1, TTLocalizer.TIP_STREET) + toPhrase = ToontownGlobals.StreetNames[ZoneUtil.getCanonicalBranchZone(zoneId)][0] + streetName = ToontownGlobals.StreetNames[ZoneUtil.getCanonicalBranchZone(zoneId)][-1] + base.loader.beginBulkLoad('hood', TTLocalizer.HeadingToStreet % {'to': toPhrase, + 'street': streetName}, ToontownGlobals.townCountMap[self.id], 1, TTLocalizer.TIP_STREET) + self.loadLoader(requestStatus) - loader.endBulkLoad('hood') + base.loader.endBulkLoad('hood') elif loaderName == 'minigame': pass elif loaderName == 'cogHQLoader': @@ -197,6 +211,7 @@ class Hood(StateData.StateData): if self.titleTextSeq: self.titleTextSeq.finish() self.titleTextSeq = None + self.hideTitleText() self.ignore(self.loaderDoneEvent) self.loader.exit() @@ -215,7 +230,7 @@ class Hood(StateData.StateData): messenger.send(self.doneEvent) def startSky(self): - self.sky.reparentTo(camera) + self.sky.reparentTo(base.camera) self.sky.setZ(0.0) self.sky.setHpr(0.0, 0.0, 0.0) ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ) @@ -223,17 +238,19 @@ class Hood(StateData.StateData): def stopSky(self): taskMgr.remove('skyTrack') - self.sky.reparentTo(hidden) + self.sky.reparentTo(base.hidden) def startSpookySky(self): if not self.spookySkyFile: return + if hasattr(self, 'sky') and self.sky: self.stopSky() - self.sky = loader.loadModel(self.spookySkyFile) + + self.sky = base.loader.loadModel(self.spookySkyFile) self.sky.setTag('sky', 'Halloween') self.sky.setColor(0.5, 0.5, 0.5, 1) - self.sky.reparentTo(camera) + self.sky.reparentTo(base.camera) self.sky.setTransparency(TransparencyAttrib.MDual, 1) fadeIn = self.sky.colorScaleInterval(1.5, Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0.25), blendType='easeInOut') fadeIn.start() @@ -244,9 +261,10 @@ class Hood(StateData.StateData): def endSpookySky(self): if hasattr(self, 'sky') and self.sky: - self.sky.reparentTo(hidden) + self.sky.reparentTo(base.hidden) + if hasattr(self, 'sky'): - self.sky = loader.loadModel(self.skyFile) + self.sky = base.loader.loadModel(self.skyFile) self.sky.setTag('sky', 'Regular') self.sky.setScale(1.0) self.startSky() diff --git a/toontown/hood/Place.py b/toontown/hood/Place.py index 486bb56..fa346a2 100644 --- a/toontown/hood/Place.py +++ b/toontown/hood/Place.py @@ -1,30 +1,36 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from direct.directnotify import DirectNotifyGlobal -from direct.fsm import StateData -from direct.showbase.PythonUtil import PriorityCallbacks -from toontown.safezone import PublicWalk -from toontown.launcher import DownloadForceAcknowledge -from . import TrialerForceAcknowledge -from . import ZoneUtil -from toontown.friends import FriendsListManager -from toontown.toonbase import ToontownGlobals -from toontown.toon.Toon import teleportDebug -from toontown.estate import HouseGlobals -from toontown.toonbase import TTLocalizer -from otp.otpbase import OTPLocalizer -from otp.avatar import Emote -from otp.avatar.Avatar import teleportNotify -from direct.task import Task -from . import QuietZoneState -from toontown.distributed import ToontownDistrictStats +from panda3d.core import NodePath +from panda3d.otp import NametagGlobals -class Place(StateData.StateData, FriendsListManager.FriendsListManager): - notify = DirectNotifyGlobal.directNotify.newCategory('Place') +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.StateData import StateData +from direct.showbase.MessengerGlobal import messenger +from direct.showbase.PythonUtil import Functor, PriorityCallbacks, SubframeCall, uniqueName +from direct.task.TaskManagerGlobal import taskMgr + +from otp.avatar.Avatar import teleportNotify +from otp.avatar.Emote import globalEmote +from otp.otpbase import OTPLocalizer + +from toontown.distributed import ToontownDistrictStats +from toontown.estate import HouseGlobals +from toontown.friends.FriendsListManager import FriendsListManager +from toontown.hood import ZoneUtil +from toontown.hood.QuietZoneState import QuietZoneState +from toontown.hood.TrialerForceAcknowledge import TrialerForceAcknowledge +from toontown.launcher.DownloadForceAcknowledge import DownloadForceAcknowledge +from toontown.safezone.PublicWalk import PublicWalk +from toontown.toon.Toon import teleportDebug +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base + + +class Place(StateData, FriendsListManager): + notify = directNotify.newCategory('Place') def __init__(self, loader, doneEvent): - StateData.StateData.__init__(self, doneEvent) - FriendsListManager.FriendsListManager.__init__(self) + StateData.__init__(self, doneEvent) + FriendsListManager.__init__(self) self.loader = loader self.dfaDoneEvent = 'dfaDoneEvent' self.trialerFADoneEvent = 'trialerFADoneEvent' @@ -35,26 +41,27 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self._leftQuietZoneSubframeCall = None self._setZoneCompleteLocalCallbacks = PriorityCallbacks() self._setZoneCompleteSubframeCall = None - return def load(self): - StateData.StateData.load(self) - FriendsListManager.FriendsListManager.load(self) + StateData.load(self) + FriendsListManager.load(self) self.walkDoneEvent = 'walkDone' - self.walkStateData = PublicWalk.PublicWalk(self.fsm, self.walkDoneEvent) + self.walkStateData = PublicWalk(self.fsm, self.walkDoneEvent) self.walkStateData.load() self._tempFSM = self.fsm def unload(self): - StateData.StateData.unload(self) - FriendsListManager.FriendsListManager.unload(self) + StateData.unload(self) + FriendsListManager.unload(self) self.notify.info('Unloading Place (%s). Fsm in %s' % (self.zoneId, self._tempFSM.getCurrentState().getName())) if self._leftQuietZoneSubframeCall: self._leftQuietZoneSubframeCall.cleanup() self._leftQuietZoneSubframeCall = None + if self._setZoneCompleteSubframeCall: self._setZoneCompleteSubframeCall.cleanup() self._setZoneCompleteSubframeCall = None + self._leftQuietZoneLocalCallbacks = None self._setZoneCompleteLocalCallbacks = None del self._tempFSM @@ -66,12 +73,12 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): if self.trialerFA: self.trialerFA.exit() del self.trialerFA - return def _getQZState(self): if hasattr(base, 'cr') and hasattr(base.cr, 'playGame'): if hasattr(base.cr.playGame, 'quietZoneStateData') and base.cr.playGame.quietZoneStateData: return base.cr.playGame.quietZoneStateData + return None def addLeftQuietZoneCallback(self, callback, priority = None): @@ -82,22 +89,22 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): token = self._leftQuietZoneLocalCallbacks.add(callback, priority=priority) if not self._leftQuietZoneSubframeCall: self._leftQuietZoneSubframeCall = SubframeCall(self._doLeftQuietZoneCallbacks, taskMgr.getCurrentTask().getPriority() - 1) + return token def removeLeftQuietZoneCallback(self, token): if token is not None: if token in self._leftQuietZoneLocalCallbacks: self._leftQuietZoneLocalCallbacks.remove(token) + qzsd = self._getQZState() if qzsd: qzsd.removeLeftQuietZoneCallback(token) - return def _doLeftQuietZoneCallbacks(self): self._leftQuietZoneLocalCallbacks() self._leftQuietZoneLocalCallbacks.clear() self._leftQuietZoneSubframeCall = None - return def addSetZoneCompleteCallback(self, callback, priority = None): qzsd = self._getQZState() @@ -107,29 +114,30 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): token = self._setZoneCompleteLocalCallbacks.add(callback, priority=priority) if not self._setZoneCompleteSubframeCall: self._setZoneCompleteSubframeCall = SubframeCall(self._doSetZoneCompleteLocalCallbacks, taskMgr.getCurrentTask().getPriority() - 1) + return token def removeSetZoneCompleteCallback(self, token): if token is not None: if any(token == x[1] for x in self._setZoneCompleteLocalCallbacks._callbacks): self._setZoneCompleteLocalCallbacks.remove(token) + qzsd = self._getQZState() if qzsd: qzsd.removeSetZoneCompleteCallback(token) - return def _doSetZoneCompleteLocalCallbacks(self): self._setZoneCompleteSubframeCall = None localCallbacks = self._setZoneCompleteLocalCallbacks self._setZoneCompleteLocalCallbacks() localCallbacks.clear() - return def setState(self, state): if hasattr(self, 'fsm'): curState = self.fsm.getName() if state == 'pet' or curState == 'pet': self.preserveFriendsList() + self.fsm.request(state) def getState(self): @@ -148,10 +156,10 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def handleTeleportQuery(self, fromAvatar, toAvatar): if base.config.GetBool('want-tptrack', False): - if toAvatar == localAvatar: + if toAvatar == base.localAvatar: toAvatar.doTeleportResponse(fromAvatar, toAvatar, toAvatar.doId, 1, toAvatar.defaultShard, base.cr.playGame.getPlaceId(), self.getZoneId(), fromAvatar.doId) else: - self.notify.warning('handleTeleportQuery toAvatar.doId != localAvatar.doId' % (toAvatar.doId, localAvatar.doId)) + self.notify.warning('handleTeleportQuery toAvatar.doId != localAvatar.doId' % (toAvatar.doId, base.localAvatar.doId)) else: fromAvatar.d_teleportResponse(toAvatar.doId, 1, toAvatar.defaultShard, base.cr.playGame.getPlaceId(), self.getZoneId()) @@ -159,6 +167,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): if self.isPeriodTimerEffective(): if base.cr.periodTimerExpired: taskMgr.doMethodLater(5, self.redoPeriodTimer, 'redoPeriodTimer') + self.accept('periodTimerExpired', self.periodTimerExpired) def disablePeriodTimer(self): @@ -167,7 +176,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def redoPeriodTimer(self, task): messenger.send('periodTimerExpired') - return Task.done + return task.done def periodTimerExpired(self): self.fsm.request('final') @@ -209,10 +218,12 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.walkStateData.enter() if teleportIn == 0: self.walkStateData.fsm.request('walking') + self.acceptOnce(self.walkDoneEvent, self.handleWalkDone) if base.cr.productName in ['DisneyOnline-US', 'ES'] and not base.cr.isPaid() and base.localAvatar.tutorialAck: base.localAvatar.chatMgr.obscure(0, 0) base.localAvatar.chatMgr.normalButton.show() + self.accept('teleportQuery', self.handleTeleportQuery) base.localAvatar.setTeleportAvailable(1) base.localAvatar.questPage.acceptOnscreenHooks() @@ -225,6 +236,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.exitFLM() if base.cr.productName in ['DisneyOnline-US', 'ES'] and not base.cr.isPaid() and base.localAvatar.tutorialAck and not base.cr.whiteListChatEnabled: base.localAvatar.chatMgr.obscure(1, 0) + self.disablePeriodTimer() messenger.send('wakeup') self.walkStateData.exit() @@ -233,13 +245,13 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.ignore('teleportQuery') if base.cr.playGame.hood != None: base.cr.playGame.hood.hideTitleText() + base.localAvatar.questPage.hideQuestsOnscreen() base.localAvatar.questPage.ignoreOnscreenHooks() base.localAvatar.invPage.ignoreOnscreenHooks() base.localAvatar.invPage.hideInventoryOnscreen() base.localAvatar.questMap.hide() base.localAvatar.questMap.ignoreOnscreenHooks() - return def handleWalkDone(self, doneStatus): mode = doneStatus['mode'] @@ -308,10 +320,12 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): target = base.cr.doFind('DistributedTarget') if target: target.hideGui() + self.accept('teleportQuery', self.handleTeleportQuery) base.localAvatar.setTeleportAvailable(1) if page: base.localAvatar.book.setPage(page) + base.localAvatar.b_setAnimState('OpenBook', 1, self.enterStickerBookGUI) base.localAvatar.obscureMoveFurnitureButton(1) @@ -328,11 +342,12 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def __handleFallingAsleep(self, task): base.localAvatar.book.exit() base.localAvatar.b_setAnimState('CloseBook', 1, callback=self.__handleFallingAsleepBookClose) - return Task.done + return task.done def __handleFallingAsleepBookClose(self): if hasattr(self, 'fsm'): self.fsm.request('walk') + base.localAvatar.forceGotoSleep() def exitStickerBook(self): @@ -377,10 +392,11 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): base.localAvatar.b_setAnimState('CloseBook', 1, callback=self.startPartyNow, extraArgs=[firstStart, hostId]) def handleBookCloseTeleport(self, hoodId, zoneId): - if localAvatar.hasActiveBoardingGroup(): + if base.localAvatar.hasActiveBoardingGroup(): rejectText = TTLocalizer.BoardingCannotLeaveZone - localAvatar.elevatorNotifier.showMe(rejectText) + base.localAvatar.elevatorNotifier.showMe(rejectText) return + self.requestLeave({'loader': ZoneUtil.getBranchLoaderName(zoneId), 'where': ZoneUtil.getToonWhereName(zoneId), 'how': 'teleportIn', @@ -388,7 +404,6 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): 'zoneId': zoneId, 'shardId': None, 'avId': -1}) - return def __handleBookCloseExit(self): base.localAvatar.b_setAnimState('TeleportOut', 1, self.__handleBookExitTeleport, [0]) @@ -396,14 +411,16 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def __handleBookExitTeleport(self, requestStatus): if base.cr.timeManager: base.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectBookExit) + base.transitions.fadeScreen(1.0) base.cr.gameFSM.request(self.exitTo) def goHomeNow(self, curZoneId): - if localAvatar.hasActiveBoardingGroup(): + if base.localAvatar.hasActiveBoardingGroup(): rejectText = TTLocalizer.BoardingCannotLeaveZone - localAvatar.elevatorNotifier.showMe(rejectText) + base.localAvatar.elevatorNotifier.showMe(rejectText) return + hoodId = ToontownGlobals.MyEstate self.requestLeave({'loader': 'safeZoneLoader', 'where': 'estate', @@ -412,13 +429,13 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): 'zoneId': -1, 'shardId': None, 'avId': -1}) - return def startPartyNow(self, firstStart, hostId): - if localAvatar.hasActiveBoardingGroup(): + if base.localAvatar.hasActiveBoardingGroup(): rejectText = TTLocalizer.BoardingCannotLeaveZone - localAvatar.elevatorNotifier.showMe(rejectText) + base.localAvatar.elevatorNotifier.showMe(rejectText) return + base.localAvatar.creatingNewPartyWithMagicWord = False base.localAvatar.aboutToPlanParty = False hoodId = ToontownGlobals.PartyHood @@ -436,6 +453,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): if shardId == base.localAvatar.defaultShard: shardId = None + base.cr.playGame.getPlace().requestLeave({'loader': 'safeZoneLoader', 'where': 'party', 'how': 'teleportIn', @@ -446,13 +464,13 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): else: if hostId is None: hostId = base.localAvatar.doId + base.cr.partyManager.sendAvatarToParty(hostId) - return - return def handleBookClose(self): if hasattr(self, 'fsm'): self.fsm.request('walk') + if hasattr(self, 'toonSubmerged') and self.toonSubmerged == 1: if hasattr(self, 'walkStateData'): self.walkStateData.fsm.request('swimming', [self.loader.swimSound]) @@ -469,26 +487,27 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def enterDFA(self, requestStatus): teleportDebug(requestStatus, 'enterDFA(%s)' % (requestStatus,)) self.acceptOnce(self.dfaDoneEvent, self.enterDFACallback, [requestStatus]) - self.dfa = DownloadForceAcknowledge.DownloadForceAcknowledge(self.dfaDoneEvent) + self.dfa = DownloadForceAcknowledge(self.dfaDoneEvent) self.dfa.enter(base.cr.hoodMgr.getPhaseFromHood(requestStatus['hoodId'])) def exitDFA(self): self.ignore(self.dfaDoneEvent) def handleEnterTunnel(self, requestStatus, collEntry): - if localAvatar.hasActiveBoardingGroup(): + if base.localAvatar.hasActiveBoardingGroup(): rejectText = TTLocalizer.BoardingCannotLeaveZone - localAvatar.elevatorNotifier.showMe(rejectText) + base.localAvatar.elevatorNotifier.showMe(rejectText) dummyNP = NodePath('dummyNP') - dummyNP.reparentTo(render) + dummyNP.reparentTo(base.render) tunnelOrigin = requestStatus['tunnelOrigin'] - dummyNP.setPos(localAvatar.getPos()) + dummyNP.setPos(base.localAvatar.getPos()) dummyNP.setH(tunnelOrigin.getH()) dummyNP.setPos(dummyNP, 0, 4, 0) - localAvatar.setPos(dummyNP.getPos()) + base.localAvatar.setPos(dummyNP.getPos()) dummyNP.removeNode() del dummyNP return + self.requestLeave(requestStatus) def enterDFACallback(self, requestStatus, doneStatus): @@ -504,6 +523,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): out = {'teleportIn': 'teleportOut', 'tunnelIn': 'tunnelOut', 'doorIn': 'doorOut'} + teleportDebug(requestStatus, 'requesting %s, requestStatus=%s' % (out[requestStatus['how']], requestStatus)) self.fsm.request(out[requestStatus['how']], [requestStatus]) elif doneStatus['mode'] == 'incomplete': @@ -520,7 +540,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def enterTrialerFA(self, requestStatus): teleportDebug(requestStatus, 'enterTrialerFA(%s)' % requestStatus) self.acceptOnce(self.trialerFADoneEvent, self.trialerFACallback, [requestStatus]) - self.trialerFA = TrialerForceAcknowledge.TrialerForceAcknowledge(self.trialerFADoneEvent) + self.trialerFA = TrialerForceAcknowledge(self.trialerFADoneEvent) self.trialerFA.enter(requestStatus['hoodId']) def exitTrialerFA(self): @@ -589,6 +609,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): tunnelName = requestStatus.get('tunnelName') if tunnelName == None: tunnelName = base.cr.hoodMgr.makeLinkTunnelName(self.loader.hood.id, fromZoneId) + self.doneStatus = {'loader': ZoneUtil.getLoaderName(zoneId), 'where': ZoneUtil.getToonWhereName(zoneId), 'how': how, @@ -599,7 +620,6 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.accept('tunnelOutMovieDone', self.__tunnelOutMovieDone) base.localAvatar.tunnelOut(tunnelOrigin) base.localAvatar.stopQuestMap() - return def __tunnelOutMovieDone(self): self.ignore('tunnelOutMovieDone') @@ -621,11 +641,11 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def enterDied(self, requestStatus, callback = None): if callback == None: callback = self.__diedDone + base.localAvatar.laffMeter.start() - camera.wrtReparentTo(render) + base.camera.wrtReparentTo(base.render) base.localAvatar.b_setAnimState('Died', 1, callback, [requestStatus]) base.localAvatar.obscureMoveFurnitureButton(1) - return def __diedDone(self, requestStatus): self.doneStatus = requestStatus @@ -643,6 +663,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): base.cr.estateMgr.getLocalEstateZone(avId) else: base.cr.estateMgr.getLocalEstateZone(base.localAvatar.getDoId()) + if HouseGlobals.WANT_TELEPORT_TIMEOUT: taskMgr.doMethodLater(HouseGlobals.TELEPORT_TIMEOUT, self.goHomeFailed, 'goHomeFailed') @@ -653,6 +674,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.doneStatus['failed'] = 1 self.goHomeFailed(None) return + if ownerId == 0 and zoneId == 0: if self.doneStatus['shardId'] is None or self.doneStatus['shardId'] is base.localAvatar.defaultShard: self.doneStatus['failed'] = 1 @@ -666,14 +688,15 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.doneStatus['how'] = 'teleportIn' messenger.send(self.doneEvent) return + if self.doneStatus['zoneId'] == -1: self.doneStatus['zoneId'] = zoneId elif self.doneStatus['zoneId'] != zoneId: self.doneStatus['where'] = 'house' + self.doneStatus['ownerId'] = ownerId messenger.send(self.doneEvent) messenger.send('localToonLeft') - return def goHomeFailed(self, task): self.notify.debug('goHomeFailed') @@ -682,7 +705,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.doneStatus['hood'] = base.localAvatar.lastHood self.doneStatus['zone'] = base.localAvatar.lastHood self.fsm.request('teleportIn', [self.doneStatus]) - return Task.done + return task.done def notifyUserGoHomeFailed(self): self.notify.debug('notifyUserGoHomeFailed') @@ -692,12 +715,13 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): avatar = base.cr.identifyAvatar(failedToVisitAvId) if avatar: avName = avatar.getName() + if avName: message = TTLocalizer.EstateTeleportFailedNotFriends % avName else: message = TTLocalizer.EstateTeleportFailed + base.localAvatar.setSystemMessage(0, message) - return def enterTeleportIn(self, requestStatus): self._tiToken = self.addSetZoneCompleteCallback(Functor(self._placeTeleportInPostZoneComplete, requestStatus), 100) @@ -723,16 +747,16 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): teleportDebug(requestStatus, 'friend not here, giving up') base.localAvatar.setSystemMessage(avId, OTPLocalizer.WhisperTargetLeftVisit % (friend.getName(),)) friend.d_teleportGiveup(base.localAvatar.doId) + base.transitions.irisIn() self.nextState = requestStatus.get('nextState', 'walk') base.localAvatar.attachCamera() base.localAvatar.startUpdateSmartCamera() base.localAvatar.startPosHprBroadcast() - globalClock.tick() + base.clock.tick() base.localAvatar.b_setAnimState('TeleportIn', 1, callback=self.teleportInDone) base.localAvatar.d_broadcastPositionNow() base.localAvatar.b_setParent(ToontownGlobals.SPRender) - return def teleportInDone(self): if hasattr(self, 'fsm'): @@ -748,7 +772,6 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): base.localAvatar.stopUpdateSmartCamera() base.localAvatar.detachCamera() base.localAvatar.stopPosHprBroadcast() - return def requestTeleport(self, hoodId, zoneId, shardId, avId): if avId > 0: @@ -756,20 +779,25 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): zoneId, shardId, avId),)) - if localAvatar.hasActiveBoardingGroup(): + + if base.localAvatar.hasActiveBoardingGroup(): if avId > 0: teleportNotify.debug('requestTeleport: has active boarding group') + rejectText = TTLocalizer.BoardingCannotLeaveZone - localAvatar.elevatorNotifier.showMe(rejectText) + base.localAvatar.elevatorNotifier.showMe(rejectText) return + loaderId = ZoneUtil.getBranchLoaderName(zoneId) whereId = ZoneUtil.getToonWhereName(zoneId) if hoodId == ToontownGlobals.MyEstate: loaderId = 'safeZoneLoader' whereId = 'estate' + if hoodId == ToontownGlobals.PartyHood: loaderId = 'safeZoneLoader' whereId = 'party' + self.requestLeave({'loader': loaderId, 'where': whereId, 'how': 'teleportIn', @@ -828,6 +856,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): if hasattr(self, 'fsm'): messenger.send('bankAsleep') self.fsm.request('walk') + base.localAvatar.forceGotoSleep() def exitBanking(self): @@ -850,6 +879,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def __handleFallingAsleepPhone(self, arg): if hasattr(self, 'fsm'): self.fsm.request('walk') + messenger.send('phoneAsleep') base.localAvatar.forceGotoSleep() @@ -863,12 +893,13 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def enterStopped(self): base.localAvatar.b_setAnimState('neutral', 1) - Emote.globalEmote.disableBody(base.localAvatar, 'enterStopped') + globalEmote.disableBody(base.localAvatar, 'enterStopped') self.accept('teleportQuery', self.handleTeleportQuery) if base.localAvatar.isDisguised: base.localAvatar.setTeleportAvailable(0) else: base.localAvatar.setTeleportAvailable(1) + base.localAvatar.laffMeter.start() base.localAvatar.obscureMoveFurnitureButton(1) base.localAvatar.startSleepWatch(self.__handleFallingAsleepStopped) @@ -877,11 +908,12 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def __handleFallingAsleepStopped(self, arg): if hasattr(self, 'fsm'): self.fsm.request('walk') + base.localAvatar.forceGotoSleep() messenger.send('stoppedAsleep') def exitStopped(self): - Emote.globalEmote.releaseBody(base.localAvatar, 'exitStopped') + globalEmote.releaseBody(base.localAvatar, 'exitStopped') base.localAvatar.setTeleportAvailable(0) self.ignore('teleportQuery') base.localAvatar.laffMeter.stop() @@ -892,7 +924,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def enterPet(self): base.localAvatar.b_setAnimState('neutral', 1) - Emote.globalEmote.disableBody(base.localAvatar, 'enterPet') + globalEmote.disableBody(base.localAvatar, 'enterPet') self.accept('teleportQuery', self.handleTeleportQuery) base.localAvatar.setTeleportAvailable(1) base.localAvatar.setTeleportAllowed(0) @@ -902,7 +934,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def exitPet(self): base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAllowed(1) - Emote.globalEmote.releaseBody(base.localAvatar, 'exitPet') + globalEmote.releaseBody(base.localAvatar, 'exitPet') self.ignore('teleportQuery') base.localAvatar.laffMeter.stop() self.exitFLM() @@ -910,7 +942,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def enterQuietZone(self, requestStatus): self.quietZoneDoneEvent = uniqueName('quietZoneDone') self.acceptOnce(self.quietZoneDoneEvent, self.handleQuietZoneDone) - self.quietZoneStateData = QuietZoneState.QuietZoneState(self.quietZoneDoneEvent) + self.quietZoneStateData = QuietZoneState(self.quietZoneDoneEvent) self.quietZoneStateData.load() self.quietZoneStateData.enter(requestStatus) @@ -920,7 +952,6 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None - return def handleQuietZoneDone(self): how = base.cr.handlerArgs['how'] diff --git a/toontown/hood/StreetSign.py b/toontown/hood/StreetSign.py index 7b2fc97..6f2a949 100644 --- a/toontown/hood/StreetSign.py +++ b/toontown/hood/StreetSign.py @@ -5,7 +5,7 @@ from direct.distributed import DistributedObject class StreetSign(DistributedObject.DistributedObject): RedownloadTaskName = 'RedownloadStreetSign' - StreetSignFileName = config.GetString('street-sign-filename', 'texture.jpg') + StreetSignFileName = config.GetString('street-sign-filename', 'texture.png') StreetSignBaseDir = config.GetString('street-sign-base-dir', 'sign') StreetSignUrl = base.config.GetString('street-sign-url', 'http://cdn.toontown.disney.go.com/toontown/en/street-signs/img/') notify = DirectNotifyGlobal.directNotify.newCategory('StreetSign') diff --git a/toontown/minigame/DistributedCannonGame.py b/toontown/minigame/DistributedCannonGame.py index 8b75fac..8c46021 100644 --- a/toontown/minigame/DistributedCannonGame.py +++ b/toontown/minigame/DistributedCannonGame.py @@ -1,23 +1,28 @@ -from direct.directnotify import DirectNotifyGlobal -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from .DistributedMinigame import * -from direct.distributed.ClockDelta import * -from direct.interval.IntervalGlobal import * -from direct.fsm import ClassicFSM, State -from direct.fsm import State -from toontown.toonbase import ToontownGlobals -from toontown.toonbase import ToontownTimer +from panda3d.core import Point3, Quat, rad2Deg, Vec3 +from panda3d.otp import Nametag, NametagFloat3d + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.gui.DirectGui import DGG, DirectButton, DirectFrame, DirectLabel +from direct.interval.IntervalGlobal import Parallel, Sequence, SoundInterval, Wait from direct.task.Task import Task -from . import Trajectory -import math -from toontown.toon import ToonHead -from toontown.effects import Splash -from toontown.effects import DustCloud -from . import CannonGameGlobals -from direct.gui.DirectGui import * -from panda3d.core import * +from direct.task.TaskManagerGlobal import taskMgr + +from toontown.effects.DustCloud import DustCloud +from toontown.effects.Splash import Splash +from toontown.minigame import CannonGameGlobals +from toontown.minigame import MinigameGlobals +from toontown.minigame.DistributedMinigame import DistributedMinigame +from toontown.minigame.Trajectory import Trajectory +from toontown.toon.ToonHead import ToonHead +from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base +from toontown.toonbase.ToontownTimer import ToontownTimer + +import math + LAND_TIME = 2 WORLD_SCALE = 2.0 GROUND_SCALE = 1.4 * WORLD_SCALE @@ -40,8 +45,9 @@ TOWER_X_RANGE = int(TOWER_Y_RANGE / 2.0) INITIAL_VELOCITY = 94.0 WHISTLE_SPEED = INITIAL_VELOCITY * 0.55 + class DistributedCannonGame(DistributedMinigame): - notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMinigame') + notify = directNotify.newCategory('DistributedCannonGame') font = ToontownGlobals.getToonFont() LOCAL_CANNON_MOVE_TASK = 'localCannonMoveTask' REWARD_COUNTDOWN_TASK = 'cannonGameRewardCountdown' @@ -58,11 +64,11 @@ class DistributedCannonGame(DistributedMinigame): def __init__(self, cr): DistributedMinigame.__init__(self, cr) - self.gameFSM = ClassicFSM.ClassicFSM('DistributedCannonGame', [State.State('off', self.enterOff, self.exitOff, ['aim']), - State.State('aim', self.enterAim, self.exitAim, ['shoot', 'waitForToonsToLand', 'cleanup']), - State.State('shoot', self.enterShoot, self.exitShoot, ['aim', 'waitForToonsToLand', 'cleanup']), - State.State('waitForToonsToLand', self.enterWaitForToonsToLand, self.exitWaitForToonsToLand, ['cleanup']), - State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') + self.gameFSM = ClassicFSM('DistributedCannonGame', [State('off', self.enterOff, self.exitOff, ['aim']), + State('aim', self.enterAim, self.exitAim, ['shoot', 'waitForToonsToLand', 'cleanup']), + State('shoot', self.enterShoot, self.exitShoot, ['aim', 'waitForToonsToLand', 'cleanup']), + State('waitForToonsToLand', self.enterWaitForToonsToLand, self.exitWaitForToonsToLand, ['cleanup']), + State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.cannonLocationDict = {} self.cannonPositionDict = {} @@ -92,12 +98,12 @@ class DistributedCannonGame(DistributedMinigame): def load(self): self.notify.debug('load') DistributedMinigame.load(self) - self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') - self.ground = loader.loadModel('phase_4/models/minigames/toon_cannon_gameground') - self.tower = loader.loadModel('phase_4/models/minigames/toon_cannon_water_tower') - self.cannon = loader.loadModel('phase_4/models/minigames/toon_cannon') - self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow') - self.hill = loader.loadModel('phase_4/models/minigames/cannon_hill') + self.sky = base.loader.loadModel('phase_3.5/models/props/TT_sky') + self.ground = base.loader.loadModel('phase_4/models/minigames/toon_cannon_gameground') + self.tower = base.loader.loadModel('phase_4/models/minigames/toon_cannon_water_tower') + self.cannon = base.loader.loadModel('phase_4/models/minigames/toon_cannon') + self.dropShadow = base.loader.loadModel('phase_3/models/props/drop_shadow') + self.hill = base.loader.loadModel('phase_4/models/minigames/cannon_hill') self.sky.setScale(WORLD_SCALE) self.ground.setScale(GROUND_SCALE) self.cannon.setScale(CANNON_SCALE) @@ -105,12 +111,12 @@ class DistributedCannonGame(DistributedMinigame): self.ground.setColor(0.85, 0.85, 0.85, 1.0) self.hill.setScale(1, 1, CANNON_Z / 20.0) self.dropShadow.setBin('fixed', 0, 1) - self.splash = Splash.Splash(render) - self.dustCloud = DustCloud.DustCloud(render) - purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') + self.splash = Splash(base.render) + self.dustCloud = DustCloud(base.render) + purchaseModels = base.loader.loadModel('phase_4/models/gui/purchase_gui') self.jarImage = purchaseModels.find('**/Jar') - self.jarImage.reparentTo(hidden) - self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) + self.jarImage.reparentTo(base.hidden) + self.rewardPanel = DirectLabel(parent=base.hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage) self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_cannon_game.ogg') self.sndCannonMove = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_adjust.ogg') @@ -122,7 +128,7 @@ class DistributedCannonGame(DistributedMinigame): self.sndWin = base.loader.loadSfx('phase_4/audio/sfx/MG_win.ogg') self.sndRewardTick = base.loader.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') guiModel = 'phase_4/models/gui/cannon_game_gui' - cannonGui = loader.loadModel(guiModel) + cannonGui = base.loader.loadModel(guiModel) self.aimPad = DirectFrame(image=cannonGui.find('**/CannonFire_PAD'), relief=None, pos=(0.7, 0, -0.553333), scale=0.8) cannonGui.removeNode() self.aimPad.hide() @@ -141,14 +147,13 @@ class DistributedCannonGame(DistributedMinigame): bindButton(self.downButton, self.__downPressed, self.__downReleased) bindButton(self.leftButton, self.__leftPressed, self.__leftReleased) bindButton(self.rightButton, self.__rightPressed, self.__rightReleased) - self.timer = ToontownTimer.ToontownTimer() + self.timer = ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() self.DEBUG_TOWER_RANGE = 0 self.DEBUG_CANNON_FAR_LEFT = 0 self.DEBUG_TOWER_NEAR = 1 self.DEBUG_TOWER_FAR_LEFT = 1 - return def unload(self): self.notify.debug('unload') @@ -199,6 +204,7 @@ class DistributedCannonGame(DistributedMinigame): av.loop('neutral') av.setPlayRate(1.0, 'run') av.nametag.removeNametag(head.tag) + head.delete() del self.toonHeadDict @@ -227,19 +233,19 @@ class DistributedCannonGame(DistributedMinigame): DistributedMinigame.onstage(self) self.__createCannons() for avId in self.avIdList: - self.cannonDict[avId][0].reparentTo(render) + self.cannonDict[avId][0].reparentTo(base.render) self.towerPos = self.getTowerPosition() self.tower.setPos(self.towerPos) - self.tower.reparentTo(render) - self.sky.reparentTo(render) - self.ground.reparentTo(render) + self.tower.reparentTo(base.render) + self.sky.reparentTo(base.render) + self.ground.reparentTo(base.render) self.hill.setPosHpr(0, CANNON_Y + 2.33, 0, 0, 0, 0) - self.hill.reparentTo(render) - self.splash.reparentTo(render) - self.dustCloud.reparentTo(render) + self.hill.reparentTo(base.render) + self.splash.reparentTo(base.render) + self.dustCloud.reparentTo(base.render) self.__createToonModels(self.localAvId) - camera.reparentTo(render) + base.camera.reparentTo(base.render) self.__oldCamFar = base.camLens.getFar() base.camLens.setFar(FAR_PLANE_DIST) self.__startIntro() @@ -248,27 +254,28 @@ class DistributedCannonGame(DistributedMinigame): def offstage(self): self.notify.debug('offstage') - self.sky.reparentTo(hidden) - self.ground.reparentTo(hidden) - self.hill.reparentTo(hidden) - self.tower.reparentTo(hidden) + self.sky.reparentTo(base.hidden) + self.ground.reparentTo(base.hidden) + self.hill.reparentTo(base.hidden) + self.tower.reparentTo(base.hidden) for avId in self.avIdList: - self.cannonDict[avId][0].reparentTo(hidden) + self.cannonDict[avId][0].reparentTo(base.hidden) if avId in self.dropShadowDict: - self.dropShadowDict[avId].reparentTo(hidden) + self.dropShadowDict[avId].reparentTo(base.hidden) + av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() - self.splash.reparentTo(hidden) + self.splash.reparentTo(base.hidden) self.splash.stop() - self.dustCloud.reparentTo(hidden) + self.dustCloud.reparentTo(base.hidden) self.dustCloud.stop() self.__stopIntro() base.camLens.setFar(self.__oldCamFar) - self.timer.reparentTo(hidden) - self.rewardPanel.reparentTo(hidden) + self.timer.reparentTo(base.hidden) + self.rewardPanel.reparentTo(base.hidden) DistributedMinigame.offstage(self) def getTowerPosition(self): @@ -282,6 +289,7 @@ class DistributedCannonGame(DistributedMinigame): y = yMax else: y = self.randomNumGen.randint(yMin, yMax) + xRange = TOWER_X_RANGE if self.DEBUG_TOWER_RANGE: if self.DEBUG_TOWER_FAR_LEFT: @@ -290,6 +298,7 @@ class DistributedCannonGame(DistributedMinigame): x = xRange else: x = self.randomNumGen.randint(0, xRange) + x = x - int(xRange / 2.0) if base.wantMinigameDifficulty: diff = self.getDifficulty() @@ -297,6 +306,7 @@ class DistributedCannonGame(DistributedMinigame): x *= scale yCenter = (yMin + yMax) / 2.0 y = (y - yCenter) * scale + yCenter + x = float(x) * (float(y) / float(yRange)) y = y - int(yRange / 2.0) self.notify.debug('getTowerPosition: ' + str(x) + ', ' + str(y)) @@ -304,7 +314,7 @@ class DistributedCannonGame(DistributedMinigame): def __createCannons(self): for avId in self.avIdList: - cannon = self.cannon.copyTo(hidden) + cannon = self.cannon.copyTo(base.hidden) barrel = cannon.find('**/cannon') self.cannonDict[avId] = [cannon, barrel] @@ -317,6 +327,7 @@ class DistributedCannonGame(DistributedMinigame): self.cannonLocationDict[avId] = Point3(0 * CANNON_X_SPACING - (4 - 1) * CANNON_X_SPACING / 2, CANNON_Y, CANNON_Z) else: self.cannonLocationDict[avId] = Point3(3 * CANNON_X_SPACING - (4 - 1) * CANNON_X_SPACING / 2, CANNON_Y, CANNON_Z) + self.cannonPositionDict[avId] = [0, CannonGameGlobals.CANNON_ANGLE_MIN] self.cannonDict[avId][0].setPos(self.cannonLocationDict[avId]) self.__updateCannonPosition(avId) @@ -324,9 +335,11 @@ class DistributedCannonGame(DistributedMinigame): def setGameReady(self): if not self.hasLocalToon: return + self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return + for avId in self.avIdList: if avId != self.localAvId: self.__createToonModels(avId) @@ -335,13 +348,13 @@ class DistributedCannonGame(DistributedMinigame): toon = self.getAvatar(avId) self.toonScaleDict[avId] = toon.getScale() toon.useLOD(1000) - toonParent = render.attachNewNode('toonOriginChange') + toonParent = base.render.attachNewNode('toonOriginChange') toon.reparentTo(toonParent) toon.setPosHpr(0, 0, -(toon.getHeight() / 2.0), 0, 0, 0) self.toonModelDict[avId] = toonParent - head = ToonHead.ToonHead() + head = ToonHead() head.setupHead(self.getAvatar(avId).style) - head.reparentTo(hidden) + head.reparentTo(base.hidden) self.toonHeadDict[avId] = head toon = self.getAvatar(avId) tag = NametagFloat3d() @@ -354,11 +367,12 @@ class DistributedCannonGame(DistributedMinigame): head.tag = tag self.__loadToonInCannon(avId) self.getAvatar(avId).dropShadow.hide() - self.dropShadowDict[avId] = self.dropShadow.copyTo(hidden) + self.dropShadowDict[avId] = self.dropShadow.copyTo(base.hidden) def setGameStart(self, timestamp): if not self.hasLocalToon: return + self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) self.__stopIntro() @@ -366,13 +380,13 @@ class DistributedCannonGame(DistributedMinigame): if not base.config.GetBool('endless-cannon-game', 0): self.timer.show() self.timer.countdown(CannonGameGlobals.GameTime, self.__gameTimerExpired) - self.rewardPanel.reparentTo(aspect2d) + + self.rewardPanel.reparentTo(base.aspect2d) self.scoreMult = MinigameGlobals.getScoreMult(self.cr.playGame.hood.id) self.__startRewardCountdown() self.airborneToons = 0 self.clockStopTime = None self.gameFSM.request('aim') - return def __gameTimerExpired(self): self.notify.debug('game timer expired') @@ -384,8 +398,10 @@ class DistributedCannonGame(DistributedMinigame): def updateCannonPosition(self, avId, zRot, angle): if not self.hasLocalToon: return + if not self.__playing(): return + if avId != self.localAvId: self.cannonPositionDict[avId] = [zRot, angle] self.__updateCannonPosition(avId) @@ -393,8 +409,10 @@ class DistributedCannonGame(DistributedMinigame): def setCannonWillFire(self, avId, fireTime, zRot, angle): if not self.hasLocalToon: return + if not self.__playing(): return + self.notify.debug('setCannonWillFire: ' + str(avId) + ': zRot=' + str(zRot) + ', angle=' + str(angle) + ', time=' + str(fireTime)) self.cannonPositionDict[avId][0] = zRot self.cannonPositionDict[avId][1] = angle @@ -407,6 +425,7 @@ class DistributedCannonGame(DistributedMinigame): fireTask = Task.sequence(Task.pause(timeToWait), task) else: fireTask = task + fireTask = task taskMgr.add(fireTask, 'fireCannon' + str(avId)) self.airborneToons += 1 @@ -414,10 +433,10 @@ class DistributedCannonGame(DistributedMinigame): def announceToonWillLandInWater(self, avId, landTime): if not self.hasLocalToon: return + self.notify.debug('announceToonWillLandInWater: ' + str(avId) + ': time=' + str(landTime)) if self.clockStopTime == None: self.clockStopTime = landTime - return def enterOff(self): self.notify.debug('enterOff') @@ -444,6 +463,7 @@ class DistributedCannonGame(DistributedMinigame): def __somebodyWon(self, avId): if avId == self.localAvId: base.playSfx(self.sndWin) + self.__killRewardCountdown() self.timer.stop() self.gameFSM.request('waitForToonsToLand') @@ -463,6 +483,7 @@ class DistributedCannonGame(DistributedMinigame): if hasattr(self, 'jarIval'): self.jarIval.finish() del self.jarIval + for avId in self.avIdList: taskMgr.remove('fireCannon' + str(avId)) taskMgr.remove('flyingToon' + str(avId)) @@ -607,27 +628,34 @@ class DistributedCannonGame(DistributedMinigame): rotVel = 0 if self.leftPressed: rotVel += CannonGameGlobals.CANNON_ROTATION_VEL + if self.rightPressed: rotVel -= CannonGameGlobals.CANNON_ROTATION_VEL - pos[0] += rotVel * globalClock.getDt() + + pos[0] += rotVel * base.clock.getDt() if pos[0] < CannonGameGlobals.CANNON_ROTATION_MIN: pos[0] = CannonGameGlobals.CANNON_ROTATION_MIN elif pos[0] > CannonGameGlobals.CANNON_ROTATION_MAX: pos[0] = CannonGameGlobals.CANNON_ROTATION_MAX + angVel = 0 if self.upPressed: angVel += CannonGameGlobals.CANNON_ANGLE_VEL + if self.downPressed: angVel -= CannonGameGlobals.CANNON_ANGLE_VEL - pos[1] += angVel * globalClock.getDt() + + pos[1] += angVel * base.clock.getDt() if pos[1] < CannonGameGlobals.CANNON_ANGLE_MIN: pos[1] = CannonGameGlobals.CANNON_ANGLE_MIN elif pos[1] > CannonGameGlobals.CANNON_ANGLE_MAX: pos[1] = CannonGameGlobals.CANNON_ANGLE_MAX + if oldRot != pos[0] or oldAng != pos[1]: if self.cannonMoving == 0: self.cannonMoving = 1 base.playSfx(self.sndCannonMove, looping=1) + self.__updateCannonPosition(self.localAvId) if task.time - task.lastPositionBroadcastTime > CANNON_MOVE_UPDATE_FREQ: task.lastPositionBroadcastTime = task.time @@ -636,7 +664,8 @@ class DistributedCannonGame(DistributedMinigame): self.cannonMoving = 0 self.sndCannonMove.stop() self.__broadcastLocalCannonPosition() - return Task.cont + + return task.cont def __broadcastLocalCannonPosition(self): self.sendUpdate('setCannonPosition', [self.cannonPositionDict[self.localAvId][0], self.cannonPositionDict[self.localAvId][1]]) @@ -649,8 +678,8 @@ class DistributedCannonGame(DistributedMinigame): return Point3(self.cannonLocationDict[self.localAvId][0], CANNON_Y - 25.0, CANNON_Z + 7) def __putCameraBehindCannon(self): - camera.setPos(self.__getCameraPositionBehindCannon()) - camera.setHpr(0, 0, 0) + base.camera.setPos(self.__getCameraPositionBehindCannon()) + base.camera.setHpr(0, 0, 0) def __loadToonInCannon(self, avId): self.toonModelDict[avId].detachNode() @@ -660,7 +689,7 @@ class DistributedCannonGame(DistributedMinigame): head.reparentTo(self.cannonDict[avId][1]) head.setPosHpr(0, 6, 0, 0, -45, 0) sc = self.toonScaleDict[avId] - head.setScale(render, sc[0], sc[1], sc[2]) + head.setScale(base.render, sc[0], sc[1], sc[2]) def __toRadians(self, angle): return angle * 2.0 * math.pi / 360.0 @@ -670,10 +699,10 @@ class DistributedCannonGame(DistributedMinigame): def __calcFlightResults(self, avId, launchTime): head = self.toonHeadDict[avId] - startPos = head.getPos(render) - startHpr = head.getHpr(render) - hpr = self.cannonDict[avId][1].getHpr(render) - towerPos = self.tower.getPos(render) + startPos = head.getPos(base.render) + startHpr = head.getHpr(base.render) + hpr = self.cannonDict[avId][1].getHpr(base.render) + towerPos = self.tower.getPos(base.render) rotation = self.__toRadians(hpr[0]) angle = self.__toRadians(hpr[1]) horizVel = INITIAL_VELOCITY * math.cos(angle) @@ -681,7 +710,7 @@ class DistributedCannonGame(DistributedMinigame): yVel = horizVel * math.cos(rotation) zVel = INITIAL_VELOCITY * math.sin(angle) startVel = Vec3(xVel, yVel, zVel) - trajectory = Trajectory.Trajectory(launchTime, startPos, startVel) + trajectory = Trajectory(launchTime, startPos, startVel) towerList = [towerPos + Point3(0, 0, BUCKET_HEIGHT), TOWER_RADIUS, TOWER_HEIGHT - BUCKET_HEIGHT] self.notify.debug('calcFlightResults(%s): rotation(%s), angle(%s), horizVel(%s), xVel(%s), yVel(%s), zVel(%s), startVel(%s), trajectory(%s), towerList(%s)' % (avId, rotation, @@ -701,7 +730,6 @@ class DistributedCannonGame(DistributedMinigame): avId = task.avId self.notify.debug('FIRING CANNON FOR AVATAR ' + str(avId)) startPos, startHpr, startVel, trajectory, timeOfImpact, hitWhat = self.__calcFlightResults(avId, launchTime) - self.notify.debug('start position: ' + str(startPos)) self.notify.debug('start velocity: ' + str(startVel)) self.notify.debug('time of launch: ' + str(launchTime)) @@ -713,12 +741,13 @@ class DistributedCannonGame(DistributedMinigame): self.notify.debug('toon will hit the tower') else: self.notify.debug('toon will hit the ground') + head = self.toonHeadDict[avId] head.stopBlink() head.stopLookAroundNow() - head.reparentTo(hidden) + head.reparentTo(base.hidden) av = self.toonModelDict[avId] - av.reparentTo(render) + av.reparentTo(base.render) av.setPos(startPos) av.setHpr(startHpr) avatar = self.getAvatar(avId) @@ -737,7 +766,7 @@ class DistributedCannonGame(DistributedMinigame): info['hRot'] = self.cannonPositionDict[avId][0] info['haveWhistled'] = 0 info['maxCamPullback'] = CAMERA_PULLBACK_MIN - info['timeEnterTowerXY'], info['timeExitTowerXY'] = trajectory.calcEnterAndLeaveCylinderXY(self.tower.getPos(render), TOWER_RADIUS) + info['timeEnterTowerXY'], info['timeExitTowerXY'] = trajectory.calcEnterAndLeaveCylinderXY(self.tower.getPos(base.render), TOWER_RADIUS) shootTask.info = info flyTask.info = info seqDoneTask.info = info @@ -746,7 +775,8 @@ class DistributedCannonGame(DistributedMinigame): if avId == self.localAvId: if info['hitWhat'] == self.HIT_WATER: self.sendUpdate('setToonWillLandInWater', [info['timeOfImpact']]) - return Task.done + + return task.done def __calcToonImpact(self, trajectory, waterTower): self.notify.debug('trajectory: %s' % trajectory) @@ -757,10 +787,12 @@ class DistributedCannonGame(DistributedMinigame): self.notify.debug('t_waterImpact: %s' % t_waterImpact) if t_waterImpact > 0: return (t_waterImpact, self.HIT_WATER) + t_towerImpact = trajectory.checkCollisionWithCylinderSides(waterTower[0], waterTower[1], waterTower[2]) self.notify.debug('t_towerImpact: %s' % t_towerImpact) if t_towerImpact > 0: return (t_towerImpact, self.HIT_TOWER) + t_groundImpact = trajectory.checkCollisionWithGround() self.notify.debug('t_groundImpact: %s' % t_groundImpact) if t_groundImpact >= trajectory.getStartTime(): @@ -771,8 +803,8 @@ class DistributedCannonGame(DistributedMinigame): def __shootTask(self, task): base.playSfx(self.sndCannonFire) - self.dropShadowDict[task.info['avId']].reparentTo(render) - return Task.done + self.dropShadowDict[task.info['avId']].reparentTo(base.render) + return task.done def __flyTask(self, task): curTime = task.time + task.info['launchTime'] @@ -780,10 +812,11 @@ class DistributedCannonGame(DistributedMinigame): pos = task.info['trajectory'].getPos(t) task.info['toon'].setPos(pos) shadowPos = Point3(pos) - if t >= task.info['timeEnterTowerXY'] and t <= task.info['timeExitTowerXY'] and pos[2] >= self.tower.getPos(render)[2] + TOWER_HEIGHT: - shadowPos.setZ(self.tower.getPos(render)[2] + TOWER_HEIGHT + SHADOW_Z_OFFSET) + if t >= task.info['timeEnterTowerXY'] and t <= task.info['timeExitTowerXY'] and pos[2] >= self.tower.getPos(base.render)[2] + TOWER_HEIGHT: + shadowPos.setZ(self.tower.getPos(base.render)[2] + TOWER_HEIGHT + SHADOW_Z_OFFSET) else: shadowPos.setZ(SHADOW_Z_OFFSET) + self.dropShadowDict[task.info['avId']].setPos(shadowPos) vel = task.info['trajectory'].getVel(t) run = math.sqrt(vel[0] * vel[0] + vel[1] * vel[1]) @@ -791,7 +824,7 @@ class DistributedCannonGame(DistributedMinigame): theta = self.__toDegrees(math.atan(rise / run)) task.info['toon'].setHpr(task.info['hRot'], -90 + theta, 0) if task.info['avId'] == self.localAvId: - lookAt = self.tower.getPos(render) + lookAt = self.tower.getPos(base.render) lookAt.setZ(lookAt.getZ() - TOWER_HEIGHT / 2.0) towerPos = Point3(self.towerPos) towerPos.setZ(TOWER_HEIGHT) @@ -804,26 +837,31 @@ class DistributedCannonGame(DistributedMinigame): perp.normalize() if ttVec.dot(perp) > 0.0: perp = Vec3(-perp[0], -perp[1], -perp[2]) + a = 1.0 - toonTowerDist / TOON_TOWER_THRESHOLD a_2 = a * a multiplier = -2.0 * a_2 * a + 3 * a_2 lookAt = lookAt + perp * (multiplier * MAX_LOOKAT_OFFSET) + foo = Vec3(pos - lookAt) foo.normalize() task.info['maxCamPullback'] = max(task.info['maxCamPullback'], CAMERA_PULLBACK_MIN + multiplier * (CAMERA_PULLBACK_MAX - CAMERA_PULLBACK_MIN)) foo = foo * task.info['maxCamPullback'] camPos = pos + Point3(foo) - camera.setPos(camPos) - camera.lookAt(pos) + base.camera.setPos(camPos) + base.camera.lookAt(pos) + if task.info['haveWhistled'] == 0: if -vel[2] > WHISTLE_SPEED: if t < task.info['timeOfImpact'] - 0.5: task.info['haveWhistled'] = 1 base.playSfx(self.sndWhizz) + if t == task.info['timeOfImpact']: if task.info['haveWhistled']: self.sndWhizz.stop() - self.dropShadowDict[task.info['avId']].reparentTo(hidden) + + self.dropShadowDict[task.info['avId']].reparentTo(base.hidden) avatar = self.getAvatar(task.info['avId']) if task.info['hitWhat'] == self.HIT_WATER: avatar.loop('neutral') @@ -853,15 +891,17 @@ class DistributedCannonGame(DistributedMinigame): avatar.pose('slip-forward', 25) base.playSfx(self.sndHitTower) elif task.info['hitWhat'] == self.HIT_GROUND: - task.info['toon'].setP(render, -150.0) + task.info['toon'].setP(base.render, -150.0) self.dustCloud.setPos(task.info['toon'], 0, 0, -2.5) self.dustCloud.setScale(0.35) self.dustCloud.play() base.playSfx(self.sndHitGround) avatar.setPlayRate(2.0, 'run') avatar.loop('run') - return Task.done - return Task.cont + + return task.done + + return task.cont def __flySequenceDoneTask(self, task): self.airborneToons -= 1 @@ -872,7 +912,8 @@ class DistributedCannonGame(DistributedMinigame): self.__loadToonInCannon(task.info['avId']) if task.info['avId'] == self.localAvId: self.gameFSM.request('aim') - return Task.done + + return task.done def __startRewardCountdown(self): taskMgr.remove(self.REWARD_COUNTDOWN_TASK) @@ -883,24 +924,29 @@ class DistributedCannonGame(DistributedMinigame): def __updateRewardCountdown(self, task): if not hasattr(self, 'rewardPanel'): - return Task.cont + return task.cont + curTime = self.getCurrentGameTime() if self.clockStopTime is not None: if self.clockStopTime < curTime: self.__killRewardCountdown() curTime = self.clockStopTime + score = int(self.scoreMult * CannonGameGlobals.calcScore(curTime) + 0.5) if not hasattr(task, 'curScore'): task.curScore = score + self.rewardPanel['text'] = str(score) if task.curScore != score: if hasattr(self, 'jarIval'): self.jarIval.finish() + s = self.rewardPanel.getScale() self.jarIval = Parallel(Sequence(self.rewardPanel.scaleInterval(0.15, s * 3.0 / 4.0, blendType='easeOut'), self.rewardPanel.scaleInterval(0.15, s, blendType='easeIn')), SoundInterval(self.sndRewardTick), name='cannonGameRewardJarThrob') self.jarIval.start() + task.curScore = score - return Task.cont + return task.cont def __startIntro(self): self.T_WATER = 1 @@ -926,18 +972,19 @@ class DistributedCannonGame(DistributedMinigame): if self.introCameraSeq: self.introCameraSeq.finish() self.introCameraSeq = None - camera.wrtReparentTo(render) + + base.camera.wrtReparentTo(base.render) def __spawnCameraLookAtLerp(self, targetPos, targetLookAt, duration): - oldPos = camera.getPos() - oldHpr = camera.getHpr() - camera.setPos(targetPos) - camera.lookAt(targetLookAt) + oldPos = base.camera.getPos() + oldHpr = base.camera.getHpr() + base.camera.setPos(targetPos) + base.camera.lookAt(targetLookAt) targetQuat = Quat() - targetQuat.setHpr(camera.getHpr()) - camera.setPos(oldPos) - camera.setHpr(oldHpr) - self.introCameraSeq = camera.posQuatInterval(duration, Point3(targetPos), targetQuat, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP) + targetQuat.setHpr(base.camera.getHpr()) + base.camera.setPos(oldPos) + base.camera.setHpr(oldHpr) + self.introCameraSeq = base.camera.posQuatInterval(duration, Point3(targetPos), targetQuat, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP) self.introCameraSeq.start() def __taskLookInWater(self, task): @@ -949,40 +996,40 @@ class DistributedCannonGame(DistributedMinigame): vecAwayFromCannons.normalize() camLoc = Point3(vecAwayFromCannons * 20) + Point3(0, 0, 20) camLoc = camLoc + task.data['towerWaterCenter'] - camera.setPos(camLoc) - camera.lookAt(task.data['towerWaterCenter']) + base.camera.setPos(camLoc) + base.camera.lookAt(task.data['towerWaterCenter']) task.data['vecAwayFromCannons'] = vecAwayFromCannons - return Task.done + return task.done def __taskPullBackFromWater(self, task): camLoc = Point3(task.data['vecAwayFromCannons'] * 40) + Point3(0, 0, 20) camLoc = camLoc + task.data['towerWaterCenter'] lookAt = task.data['cannonCenter'] self.__spawnCameraLookAtLerp(camLoc, lookAt, self.T_WATER2LONGVIEW) - return Task.done + return task.done def __flyUpToToon(self, task): - headPos = self.toonHeadDict[self.localAvId].getPos(render) + headPos = self.toonHeadDict[self.localAvId].getPos(base.render) camLoc = headPos + Point3(0, 5, 0) lookAt = Point3(headPos) self.__spawnCameraLookAtLerp(camLoc, lookAt, self.T_LONGVIEW2TOONHEAD) - return Task.done + return task.done def __flyToBackOfCannon(self, task): - lerpNode = hidden.attachNewNode('CannonGameCameraLerpNode') - lerpNode.reparentTo(render) + lerpNode = base.hidden.attachNewNode('CannonGameCameraLerpNode') + lerpNode.reparentTo(base.render) lerpNode.setPos(self.cannonLocationDict[self.localAvId] + Point3(0, 1, 0)) - relCamPos = camera.getPos(lerpNode) - relCamHpr = camera.getHpr(lerpNode) + relCamPos = base.camera.getPos(lerpNode) + relCamHpr = base.camera.getHpr(lerpNode) startRotation = lerpNode.getHpr() endRotation = Point3(-180, 0, 0) lerpNode.setHpr(endRotation) - camera.setPos(self.__getCameraPositionBehindCannon()) - endPos = camera.getPos(lerpNode) + base.camera.setPos(self.__getCameraPositionBehindCannon()) + endPos = base.camera.getPos(lerpNode) lerpNode.setHpr(startRotation) - camera.reparentTo(lerpNode) - camera.setPos(relCamPos) - camera.setHpr(relCamHpr) - self.introCameraSeq = Parallel(lerpNode.hprInterval(self.T_TOONHEAD2CANNONBACK, endRotation, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP), camera.posInterval(self.T_TOONHEAD2CANNONBACK, endPos, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP)) + base.camera.reparentTo(lerpNode) + base.camera.setPos(relCamPos) + base.camera.setHpr(relCamHpr) + self.introCameraSeq = Parallel(lerpNode.hprInterval(self.T_TOONHEAD2CANNONBACK, endRotation, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP), base.camera.posInterval(self.T_TOONHEAD2CANNONBACK, endPos, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP)) self.introCameraSeq.start() - return Task.done + return task.done diff --git a/toontown/minigame/DistributedPairingGame.py b/toontown/minigame/DistributedPairingGame.py index 0c70f9c..9fa4964 100644 --- a/toontown/minigame/DistributedPairingGame.py +++ b/toontown/minigame/DistributedPairingGame.py @@ -11,7 +11,7 @@ from toontown.minigame import PlayingCardDeck from toontown.minigame import PairingGameGlobals from .OrthoWalk import OrthoWalk from .OrthoDrive import OrthoDrive -from direct.interval.IntervalGlobal import Sequence, Parallel, Func, LerpColorScaleInterval, LerpScaleInterval, LerpFunctionInterval, Wait, SoundInterval +from direct.interval.IntervalGlobal import Sequence, Parallel, Func, LerpColorScaleInterval, LerpScaleInterval, LerpFunctionInterval, Wait, SoundInterval, WaitInterval from toontown.toonbase.ToontownGlobals import GlobalDialogColor class DistributedPairingGame(DistributedMinigame): diff --git a/toontown/minigame/DistributedPatternGame.py b/toontown/minigame/DistributedPatternGame.py index 286ea7e..7e7420c 100644 --- a/toontown/minigame/DistributedPatternGame.py +++ b/toontown/minigame/DistributedPatternGame.py @@ -1,22 +1,36 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from direct.interval.IntervalGlobal import * -from .DistributedMinigame import * -from direct.gui.DirectGui import * -from panda3d.core import * -from direct.fsm import ClassicFSM, State -from direct.fsm import State -from toontown.toonbase import ToontownTimer -from . import PatternGameGlobals -from toontown.toon import ToonHead -from toontown.char import CharDNA -from toontown.char import Char -from . import ArrowKeys -import random +from panda3d.core import Point3, VBase4, Vec3 +from panda3d.otp import CFSpeech, NametagGlobals + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.gui.DirectGui import DirectLabel +from direct.interval.IntervalGlobal import ( + ActorInterval, + Func, + LerpColorInterval, + LerpHprInterval, + LerpPosInterval, + Parallel, + Sequence, + Wait +) + +from toontown.char.Char import Char +from toontown.char.CharDNA import CharDNA +from toontown.minigame import PatternGameGlobals +from toontown.minigame.ArrowKeys import ArrowKeys +from toontown.minigame.DistributedMinigame import DistributedMinigame from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base +from toontown.toonbase.ToontownTimer import ToontownTimer + +from random import choice + class DistributedPatternGame(DistributedMinigame): + notify = directNotify.newCategory('DistributedPatternGame') phase4snd = 'phase_4/audio/sfx/' ButtonSoundNames = (phase4snd + 'm_match_trumpet.ogg', phase4snd + 'm_match_guitar.ogg', @@ -46,14 +60,14 @@ class DistributedPatternGame(DistributedMinigame): def __init__(self, cr): DistributedMinigame.__init__(self, cr) - self.gameFSM = ClassicFSM.ClassicFSM('DistributedPatternGame', [State.State('off', self.enterOff, self.exitOff, ['waitForServerPattern']), - State.State('waitForServerPattern', self.enterWaitForServerPattern, self.exitWaitForServerPattern, ['showServerPattern', 'cleanup']), - State.State('showServerPattern', self.enterShowServerPattern, self.exitShowServerPattern, ['getUserInput', 'playBackPatterns', 'cleanup']), - State.State('getUserInput', self.enterGetUserInput, self.exitGetUserInput, ['waitForPlayerPatterns', 'playBackPatterns', 'cleanup']), - State.State('waitForPlayerPatterns', self.enterWaitForPlayerPatterns, self.exitWaitForPlayerPatterns, ['playBackPatterns', 'cleanup', 'checkGameOver']), - State.State('playBackPatterns', self.enterPlayBackPatterns, self.exitPlayBackPatterns, ['checkGameOver', 'cleanup']), - State.State('checkGameOver', self.enterCheckGameOver, self.exitCheckGameOver, ['waitForServerPattern', 'cleanup']), - State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') + self.gameFSM = ClassicFSM('DistributedPatternGame', [State('off', self.enterOff, self.exitOff, ['waitForServerPattern']), + State('waitForServerPattern', self.enterWaitForServerPattern, self.exitWaitForServerPattern, ['showServerPattern', 'cleanup']), + State('showServerPattern', self.enterShowServerPattern, self.exitShowServerPattern, ['getUserInput', 'playBackPatterns', 'cleanup']), + State('getUserInput', self.enterGetUserInput, self.exitGetUserInput, ['waitForPlayerPatterns', 'playBackPatterns', 'cleanup']), + State('waitForPlayerPatterns', self.enterWaitForPlayerPatterns, self.exitWaitForPlayerPatterns, ['playBackPatterns', 'cleanup', 'checkGameOver']), + State('playBackPatterns', self.enterPlayBackPatterns, self.exitPlayBackPatterns, ['checkGameOver', 'cleanup']), + State('checkGameOver', self.enterCheckGameOver, self.exitCheckGameOver, ['waitForServerPattern', 'cleanup']), + State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.arrowColor = VBase4(1, 0, 0, 1) self.xColor = VBase4(1, 0, 0, 1) @@ -63,7 +77,6 @@ class DistributedPatternGame(DistributedMinigame): self.opaq = VBase4(1, 0, 0, 1) self.normalTextColor = VBase4(0.537, 0.84, 0.33, 1.0) self.__otherToonIndex = {} - return def getTitle(self): return TTLocalizer.PatternGameTitle @@ -78,10 +91,10 @@ class DistributedPatternGame(DistributedMinigame): def load(self): self.notify.debug('load') DistributedMinigame.load(self) - self.timer = ToontownTimer.ToontownTimer() + self.timer = ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() - self.room = loader.loadModel('phase_4/models/minigames/matching_room') + self.room = base.loader.loadModel('phase_4/models/minigames/matching_room') self.buttonSounds = [] for soundName in self.ButtonSoundNames: self.buttonSounds.append(base.loader.loadSfx(soundName)) @@ -95,18 +108,18 @@ class DistributedPatternGame(DistributedMinigame): self.roundText = DirectLabel(text=self.strRound % 1, text_fg=self.normalTextColor, frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0.014, 0, -.84), scale=0.12) self.roundText.hide() self.waitingText.hide() - matchingGameGui = loader.loadModel('phase_3.5/models/gui/matching_game_gui') + matchingGameGui = base.loader.loadModel('phase_3.5/models/gui/matching_game_gui') minnieArrow = matchingGameGui.find('**/minnieArrow') minnieX = matchingGameGui.find('**/minnieX') minnieCircle = matchingGameGui.find('**/minnieCircle') self.arrows = [None] * 5 for x in range(0, 5): - self.arrows[x] = minnieArrow.copyTo(hidden) + self.arrows[x] = minnieArrow.copyTo(base.hidden) self.arrows[x].hide() self.xs = [None] * 5 for x in range(0, 5): - self.xs[x] = minnieX.copyTo(hidden) + self.xs[x] = minnieX.copyTo(base.hidden) self.xs[x].hide() self.statusBalls = [] @@ -116,20 +129,20 @@ class DistributedPatternGame(DistributedMinigame): for x in range(0, 4): for y in range(0, self.totalMoves): - self.statusBalls[x][y] = minnieCircle.copyTo(hidden) + self.statusBalls[x][y] = minnieCircle.copyTo(base.hidden) self.statusBalls[x][y].hide() minnieArrow.removeNode() minnieX.removeNode() minnieCircle.removeNode() matchingGameGui.removeNode() - self.minnie = Char.Char() + self.minnie = Char() m = self.minnie - dna = CharDNA.CharDNA() + dna = CharDNA() dna.newChar('mn') m.setDNA(dna) m.setName(TTLocalizer.Minnie) - m.reparentTo(hidden) + m.reparentTo(base.hidden) self.backRowHome = Point3(3, 11, 0) self.backRowXSpacing = 1.8 self.frontRowHome = Point3(0, 18, 0) @@ -140,12 +153,10 @@ class DistributedPatternGame(DistributedMinigame): self.animPlayRates = [] animPlayRate = 1.4 animPlayRateMult = 1.06 - for i in range(PatternGameGlobals.NUM_ROUNDS): + for _ in range(PatternGameGlobals.NUM_ROUNDS): self.animPlayRates.append(animPlayRate) animPlayRate *= animPlayRateMult - return - def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) @@ -201,12 +212,12 @@ class DistributedPatternGame(DistributedMinigame): DistributedMinigame.onstage(self) self.arrowDict = {} self.lt = base.localAvatar - camera.reparentTo(render) - camera.setPosHpr(0.0, -14.59, 10.56, 0.0, -16.39, 0.0) + base.camera.reparentTo(base.render) + base.camera.setPosHpr(0.0, -14.59, 10.56, 0.0, -16.39, 0.0) base.camLens.setFov(24.66) NametagGlobals.setGlobalNametagScale(0.6) - self.arrowKeys = ArrowKeys.ArrowKeys() - self.room.reparentTo(render) + self.arrowKeys = ArrowKeys() + self.room.reparentTo(base.render) self.room.setPosHpr(0.0, 18.39, -ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0) self.room.setScale(1) for anim in self.minnieAnimNames: @@ -226,7 +237,7 @@ class DistributedPatternGame(DistributedMinigame): self.toonAnimSpeedMult[anim] = float(self.__numPingPongFrames(numFrames)) / float(self.stdNumDanceStepPingPongFrames) lt = self.lt - lt.reparentTo(render) + lt.reparentTo(base.render) lt.useLOD(1000) lt.setPos(-3.5, 11, 0.0) lt.setScale(1) @@ -246,11 +257,12 @@ class DistributedPatternGame(DistributedMinigame): else: self.arrowDict['lt'][k].setScale(4, 4, 4) self.arrowDict['lt'][k].setColor(self.xColor) + self.arrowDict['lt'][k].setPos(0, 0, 1) self.formatStatusBalls(self.arrowDict['lt'][2], jj) m = self.minnie - m.reparentTo(render) + m.reparentTo(base.render) m.setPos(-1.6, 20, 0) m.setScale(1) self.makeToonLookatCamera(m) @@ -280,13 +292,13 @@ class DistributedPatternGame(DistributedMinigame): NametagGlobals.setGlobalNametagScale(1.0) self.arrowKeys.destroy() del self.arrowKeys - self.room.reparentTo(hidden) + self.room.reparentTo(base.hidden) self.roundText.hide() self.minnie.nametag.unmanage(base.marginManager) self.minnie.stopEarTask() self.minnie.stop() self.minnie.stopBlink() - self.minnie.reparentTo(hidden) + self.minnie.reparentTo(base.hidden) self.lt.setScale(1) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) @@ -303,9 +315,11 @@ class DistributedPatternGame(DistributedMinigame): def setGameReady(self): if not self.hasLocalToon: return + self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return + for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: @@ -321,10 +335,11 @@ class DistributedPatternGame(DistributedMinigame): else: self.arrowDict[avId][k].setScale(4, 4, 4) self.arrowDict[avId][k].setColor(self.xColor) + self.arrowDict[avId][k].setPos(0, 0, 1) self.formatStatusBalls(self.arrowDict[avId][2], jj) - toon.reparentTo(render) + toon.reparentTo(base.render) toon.useLOD(1000) toon.setPos(self.getBackRowPos(avId)) toon.setScale(0.9) @@ -338,16 +353,17 @@ class DistributedPatternGame(DistributedMinigame): self.waitingText['text'] = self.strPleaseWait else: self.waitingText['text'] = self.strWaitingOtherPlayers + self.animTracks = {} for avId in self.avIdList: self.animTracks[avId] = None self.__initGameVars() - return def setGameStart(self, timestamp): if not self.hasLocalToon: return + self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) self.gameFSM.request('waitForServerPattern') @@ -360,7 +376,7 @@ class DistributedPatternGame(DistributedMinigame): return numFrames * 2 - 1 def makeToonLookatCamera(self, toon): - toon.headsUp(camera) + toon.headsUp(base.camera) def setText(self, t, newtext): t['text'] = newtext @@ -376,6 +392,7 @@ class DistributedPatternGame(DistributedMinigame): if startPos: toon.setPos(startPos) track.append(Func(toon.setPos, startPos)) + for endPos in posList: toon.headsUp(Point3(endPos)) track.append(Func(toon.setHpr, Point3(toon.getH(), 0, 0))) @@ -387,14 +404,16 @@ class DistributedPatternGame(DistributedMinigame): if lookAtCam: saveHpr = toon.getHpr() - toon.headsUp(camera) + toon.headsUp(base.camera) endHeading = toon.getHpr()[0] toon.setHpr(saveHpr) + curHeading = toon.getH() if endHeading - curHeading > 180.0: endHeading -= 360 elif endHeading - curHeading < -180.0: endHeading += 360 + endHpr = Point3(endHeading, 0, 0) duration = abs(endHeading - curHeading) / 180.0 * 0.3 track.extend([Func(toon.loop, 'walk'), LerpHprInterval(toon, duration, endHpr), Func(toon.loop, 'neutral')]) @@ -456,6 +475,7 @@ class DistributedPatternGame(DistributedMinigame): ri.append(ActorInterval(actor=self.lt, animName='victory', duration=5.5)) else: ri.append(Func(self.lt.loop, 'neutral')) + for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: @@ -503,18 +523,21 @@ class DistributedPatternGame(DistributedMinigame): track = Sequence(Func(self.changeArrow, toonID, index), Wait(wait)) else: track = Sequence(Func(self.changeArrow, toonID, index), Wait(wait), LerpColorInterval(self.arrowDict[toonID][0], d, self.trans, self.opaq)) + return track def getDanceSequenceAnimTrack(self, toon, pattern): getDanceStepTrack = self.__getToonDanceStepAnimTrack if toon == self.minnie: getDanceStepTrack = self.__getMinnieDanceStepAnimTrack + tracks = Sequence() for direction in pattern: tracks.append(getDanceStepTrack(toon, direction)) if len(pattern): tracks.append(Func(toon.loop, 'neutral')) + return tracks def getDanceSequenceButtonSoundTrack(self, pattern): @@ -558,6 +581,7 @@ class DistributedPatternGame(DistributedMinigame): def setPattern(self, pattern): if not self.hasLocalToon: return + self.notify.debug('setPattern: ' + str(pattern)) self.__serverPattern = pattern self.gameFSM.request('showServerPattern') @@ -591,6 +615,7 @@ class DistributedPatternGame(DistributedMinigame): def exitShowServerPattern(self): if self.showTrack.isPlaying(): self.showTrack.pause() + del self.showTrack def enterGetUserInput(self): @@ -599,7 +624,7 @@ class DistributedPatternGame(DistributedMinigame): self.proceedTrack = None def startTimer(self = self): - self.currentStartTime = globalClock.getFrameTime() + self.currentStartTime = base.clock.getFrameTime() self.timer.show() self.timer.countdown(PatternGameGlobals.InputTime, self.__handleInputTimeout) @@ -629,7 +654,6 @@ class DistributedPatternGame(DistributedMinigame): self.setupTrack = Sequence(Func(self.__setMinnieChat, self.strGo, 0), Func(self.setText, self.roundText, TTLocalizer.PatternGameGo), Func(self.roundText.setScale, 0.3), Func(enableKeys), Func(startTimer), Wait(0.8), Func(self.__clearMinnieChat), Func(self.setText, self.roundText, ' '), Func(self.roundText.setScale, 0.12), Func(self.setTextFG, self.roundText, self.normalTextColor)) self.setupTrack.start() - return def __handleInputTimeout(self): self.__doneGettingInput(self.__localPattern) @@ -643,15 +667,18 @@ class DistributedPatternGame(DistributedMinigame): def remoteButtonPressed(self, avId, index, wrong): if not self.hasLocalToon: return + if self.gameFSM.getCurrentState().getName() not in ['getUserInput', 'waitForPlayerPatterns']: return + if avId != self.localAvId: if self.animTracks[avId]: self.animTracks[avId].finish() + av = self.getAvatar(avId) if wrong: acts = ['slip-forward', 'slip-backward'] - ag = random.choice(acts) + ag = choice(acts) self.arrowDict[avId][0].hide() self.animTracks[avId] = Sequence(Func(self.showX, avId), Func(self.colorStatusBall, avId, self.__otherToonIndex[avId], 0), ActorInterval(actor=av, animName=ag, duration=2.35), Func(av.loop, 'neutral'), Func(self.hideX, avId)) else: @@ -659,6 +686,7 @@ class DistributedPatternGame(DistributedMinigame): arrowTrack = self.getDanceArrowAnimTrack(avId, [index], 1) potTrack = self.getDanceSequenceAnimTrack(av, [index]) self.animTracks[avId] = Parallel(potTrack, arrowTrack) + self.__otherToonIndex[avId] += 1 self.animTracks[avId].start() @@ -668,13 +696,15 @@ class DistributedPatternGame(DistributedMinigame): def __buttonPressed(self, index): if len(self.__localPattern) >= len(self.__serverPattern): return + if self.animTracks[self.localAvId]: self.animTracks[self.localAvId].finish() + badd = 0 if index != self.__serverPattern[len(self.__localPattern)]: badd = 1 acts = ['slip-forward', 'slip-backward'] - ag = random.choice(acts) + ag = choice(acts) self.animTracks[self.localAvId] = Sequence(Func(self.showX, 'lt'), Func(self.colorStatusBall, 'lt', len(self.__localPattern), 0), ActorInterval(actor=self.lt, animName=ag, duration=2.35), Func(self.lt.loop, 'neutral'), Func(self.hideX, 'lt')) self.arrowDict['lt'][0].hide() base.playSfx(self.fallSound) @@ -684,6 +714,7 @@ class DistributedPatternGame(DistributedMinigame): arrowTrack = self.getDanceArrowAnimTrack('lt', [index], 1) potTrack = self.getDanceSequenceAnimTrack(self.lt, [index]) self.animTracks[self.localAvId] = Parallel(potTrack, arrowTrack) + self.sendUpdate('reportButtonPress', [index, badd]) self.animTracks[self.localAvId].start() self.__localPattern.append(index) @@ -692,7 +723,7 @@ class DistributedPatternGame(DistributedMinigame): def __doneGettingInput(self, pattern): self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS) - self.currentTotalTime = globalClock.getFrameTime() - self.currentStartTime + self.currentTotalTime = base.clock.getFrameTime() - self.currentStartTime self.proceedTrack = Sequence(Wait(self.getDanceStepDuration()), Func(self.sendUpdate, 'reportPlayerPattern', [pattern, self.currentTotalTime]), Func(self.gameFSM.request, 'waitForPlayerPatterns')) self.proceedTrack.start() @@ -703,8 +734,10 @@ class DistributedPatternGame(DistributedMinigame): self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS) if self.setupTrack and self.setupTrack.isPlaying(): self.setupTrack.pause() + if self.proceedTrack and self.proceedTrack.isPlaying(): self.proceedTrack.pause() + del self.setupTrack del self.proceedTrack self.__clearMinnieChat() @@ -715,6 +748,7 @@ class DistributedPatternGame(DistributedMinigame): def setPlayerPatterns(self, pattern1, pattern2, pattern3, pattern4, fastestAvId): if not self.hasLocalToon: return + self.fastestAvId = fastestAvId self.notify.debug('setPlayerPatterns:' + ' pattern1:' + str(pattern1) + ' pattern2:' + str(pattern2) + ' pattern3:' + str(pattern3) + ' pattern4:' + str(pattern4)) self.playerPatterns = {} @@ -738,6 +772,7 @@ class DistributedPatternGame(DistributedMinigame): self.roundText['text'] = TTLocalizer.PatternGameFastest else: self.roundText['text'] = TTLocalizer.PatternGameFaster + jumpTrack = Sequence(ActorInterval(actor=self.lt, animName='jump', duration=1.7), Func(self.lt.loop, 'neutral')) elif self.fastestAvId == 0: if self.round == PatternGameGlobals.NUM_ROUNDS: @@ -745,6 +780,7 @@ class DistributedPatternGame(DistributedMinigame): else: self.roundText.setScale(0.1) self.roundText['text'] = TTLocalizer.PatternGameYouCanDoIt + jumpTrack = Sequence(Wait(0.5), Wait(0.5)) elif self.fastestAvId == 1: self.roundText.setScale(0.1) @@ -758,7 +794,9 @@ class DistributedPatternGame(DistributedMinigame): rewardStr = TTLocalizer.PatternGameOtherFastest else: rewardStr = TTLocalizer.PatternGameOtherFaster + self.roundText['text'] = av.getName() + rewardStr + success = self.playerPatterns[self.localAvId] == self.__serverPattern self.hideStatusBalls('lt') for avId in self.remoteAvIdList: @@ -771,6 +809,7 @@ class DistributedPatternGame(DistributedMinigame): self.perfectGame = 0 sound = self.incorrectSound text = self.strWrong + soundTrack = Sequence(Func(base.playSfx, sound), Wait(1.6)) textTrack = Sequence(Wait(0.2), Func(self.__setMinnieChat, text, 0), Wait(1.3), Func(self.__clearMinnieChat)) self.playBackPatternsTrack = Sequence(Parallel(soundTrack, textTrack, jumpTrack), Func(self.gameFSM.request, 'checkGameOver')) @@ -779,6 +818,7 @@ class DistributedPatternGame(DistributedMinigame): def exitPlayBackPatterns(self): if self.playBackPatternsTrack.isPlaying(): self.playBackPatternsTrack.pause() + del self.playBackPatternsTrack def enterCheckGameOver(self): @@ -794,17 +834,19 @@ class DistributedPatternGame(DistributedMinigame): text = self.strPerfect sound = self.perfectSound delay = 2.2 + if self.celebrate: text = TTLocalizer.PatternGameImprov self.__winTrack = Sequence(Func(self.__setMinnieChat, text, 1), Func(base.playSfx, self.perfectSound), Sequence(self.returnCelebrationIntervals(1)), Sequence(self.returnCelebrationIntervals(0)), Func(self.__clearMinnieChat), Func(self.gameOver)) else: self.__winTrack = Sequence(Func(self.__setMinnieChat, text, 1), Func(base.playSfx, sound), Wait(delay), Func(self.__clearMinnieChat), Func(self.gameOver)) + self.__winTrack.start() - return def exitCheckGameOver(self): if self.__winTrack and self.__winTrack.isPlaying(): self.__winTrack.pause() + del self.__winTrack def enterCleanup(self): diff --git a/toontown/minigame/DistributedPhotoGame.py b/toontown/minigame/DistributedPhotoGame.py index 5321eec..bcf6096 100644 --- a/toontown/minigame/DistributedPhotoGame.py +++ b/toontown/minigame/DistributedPhotoGame.py @@ -28,6 +28,8 @@ from toontown.makeatoon import NameGenerator from otp.otpbase import OTPGlobals from toontown.battle import BattleParticles from toontown.minigame import PhotoGameBase +from panda3d.otp import * + WORLD_SCALE = 2.0 FAR_PLANE_DIST = 600 * WORLD_SCALE STAGE_Z_OFFSET = 7.0 @@ -243,6 +245,11 @@ class DistributedPhotoGame(DistributedMinigame, PhotoGameBase.PhotoGameBase): self.removeChildGameFSM(self.gameFSM) del self.gameFSM self.ignoreAll() + + for rayEntry in self.rayArray: + rayEntry[3].remove_node() + del self.rayArray + return def onstage(self): diff --git a/toontown/minigame/DistributedTargetGame.py b/toontown/minigame/DistributedTargetGame.py index 8a2ee37..335f3f8 100644 --- a/toontown/minigame/DistributedTargetGame.py +++ b/toontown/minigame/DistributedTargetGame.py @@ -137,10 +137,10 @@ class DistributedTargetGame(DistributedMinigame): UPDATE_RUBBER_BAND_PRIORITY = 2 COLLISION_DETECTION_PRIORITY = 5 UPDATE_SHADOWS_PRIORITY = 47 - UMBRELLA_TEXTURE_LIST = ['phase_4/maps/mg_slingshot_umbrella_blue.jpg', - 'phase_4/maps/mg_slingshot_umbrella_purple.jpg', - 'phase_4/maps/mg_slingshot_umbrella_red.jpg', - 'phase_4/maps/mg_slingshot_umbrella_yellow.jpg'] + UMBRELLA_TEXTURE_LIST = ['phase_4/maps/mg_slingshot_umbrella_blue.png', + 'phase_4/maps/mg_slingshot_umbrella_purple.png', + 'phase_4/maps/mg_slingshot_umbrella_red.png', + 'phase_4/maps/mg_slingshot_umbrella_yellow.png'] RT_UNKNOWN = 0 RT_SUCCESS = 1 RT_GROUPSUCCESS = 2 diff --git a/toontown/minigame/DistributedTugOfWarGame.py b/toontown/minigame/DistributedTugOfWarGame.py index 7530efe..2dcae83 100644 --- a/toontown/minigame/DistributedTugOfWarGame.py +++ b/toontown/minigame/DistributedTugOfWarGame.py @@ -1,30 +1,42 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from direct.interval.IntervalGlobal import * -from .DistributedMinigame import * -from direct.gui.DirectGui import * -from panda3d.core import * -from direct.fsm import ClassicFSM, State -from direct.fsm import State -from toontown.toonbase import ToontownTimer -from toontown.toon import ToonHead -from toontown.suit import SuitDNA -from toontown.suit import Suit -from toontown.char import Char -from . import ArrowKeys -import random +from panda3d.core import RopeNode, VBase3 +from panda3d.otp import NametagGlobals + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.gui.DirectGui import DGG, DirectLabel +from direct.interval.IntervalGlobal import ( + ActorInterval, + Func, + LerpHprInterval, + LerpPosInterval, + LerpPosHprInterval, + Parallel, + Sequence, + Wait +) + +from direct.showutil.Rope import Rope +from direct.task.TaskManagerGlobal import taskMgr + +from toontown.effects.Ripples import Ripples +from toontown.effects.Splash import Splash +from toontown.minigame import TugOfWarGameGlobals +from toontown.minigame.ArrowKeys import ArrowKeys +from toontown.minigame.DistributedMinigame import DistributedMinigame +from toontown.minigame.MinigamePowerMeter import MinigamePowerMeter +from toontown.suit.Suit import Suit +from toontown.suit.SuitDNA import SuitDNA from toontown.toonbase import ToontownGlobals -import string from toontown.toonbase import TTLocalizer -from . import TugOfWarGameGlobals -from direct.showutil import Rope -from toontown.effects import Splash -from toontown.effects import Ripples -from toontown.toonbase import TTLocalizer -from . import MinigamePowerMeter -from direct.task.Task import Task +from toontown.toonbase.ToonBaseGlobal import base +from toontown.toonbase.ToontownTimer import ToontownTimer + +import math + class DistributedTugOfWarGame(DistributedMinigame): + notify = directNotify.newCategory('DistributedTugOfWarGame') bgm = 'phase_4/audio/bgm/MG_tug_o_war.ogg' toonAnimNames = ['neutral', 'tug-o-war', @@ -46,11 +58,11 @@ class DistributedTugOfWarGame(DistributedMinigame): def __init__(self, cr): DistributedMinigame.__init__(self, cr) - self.gameFSM = ClassicFSM.ClassicFSM('DistributedTugOfWarGame', [State.State('off', self.enterOff, self.exitOff, ['waitForGoSignal']), - State.State('waitForGoSignal', self.enterWaitForGoSignal, self.exitWaitForGoSignal, ['tug', 'cleanup']), - State.State('tug', self.enterTug, self.exitTug, ['gameDone', 'cleanup']), - State.State('gameDone', self.enterGameDone, self.exitGameDone, ['cleanup']), - State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') + self.gameFSM = ClassicFSM('DistributedTugOfWarGame', [State('off', self.enterOff, self.exitOff, ['waitForGoSignal']), + State('waitForGoSignal', self.enterWaitForGoSignal, self.exitWaitForGoSignal, ['tug', 'cleanup']), + State('tug', self.enterTug, self.exitTug, ['gameDone', 'cleanup']), + State('gameDone', self.enterGameDone, self.exitGameDone, ['cleanup']), + State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.gameType = TugOfWarGameGlobals.TOON_VS_TOON self.suit = None @@ -92,13 +104,11 @@ class DistributedTugOfWarGame(DistributedMinigame): for k in range(4): self.drinkPositions.append(VBase3(-.2 + 0.2 * k, 16 + 2 * k, 0.0)) - self.rng = RandomNumGen.RandomNumGen(1000) self.introTrack = None self.showTrack = None self.setupTrack = None self.animTracks = {} self.randomNumGen = None - return def getTitle(self): return TTLocalizer.TugOfWarGameTitle @@ -112,40 +122,39 @@ class DistributedTugOfWarGame(DistributedMinigame): def load(self): self.notify.debug('load') DistributedMinigame.load(self) - self.timer = ToontownTimer.ToontownTimer() + self.timer = ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() - self.room = loader.loadModel('phase_4/models/minigames/tug_of_war_dock') - self.room.reparentTo(hidden) - ropeModel = loader.loadModel('phase_4/models/minigames/tug_of_war_rope') + self.room = base.loader.loadModel('phase_4/models/minigames/tug_of_war_dock') + self.room.reparentTo(base.hidden) + ropeModel = base.loader.loadModel('phase_4/models/minigames/tug_of_war_rope') self.ropeTexture = ropeModel.findTexture('*') ropeModel.removeNode() - self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') - self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow') + self.sky = base.loader.loadModel('phase_3.5/models/props/TT_sky') + self.dropShadow = base.loader.loadModel('phase_3/models/props/drop_shadow') self.correctSound = base.loader.loadSfx('phase_4/audio/sfx/MG_pos_buzzer.ogg') self.sndHitWater = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_splash.ogg') self.whistleSound = base.loader.loadSfx('phase_4/audio/sfx/AA_sound_whistle.ogg') self.music = base.loader.loadMusic(self.bgm) self.roundText = DirectLabel(text=' ', text_fg=(0, 1, 0, 1), frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0.014, 0, -.84), scale=0.2) - self.powerMeter = MinigamePowerMeter.MinigamePowerMeter(17) - self.powerMeter.reparentTo(aspect2d) + self.powerMeter = MinigamePowerMeter(17) + self.powerMeter.reparentTo(base.aspect2d) self.powerMeter.setPos(0, 0, 0.4) self.powerMeter.setPower(8) self.powerMeter.setTarget(8) self.arrows = [None] * 2 for x in range(len(self.arrows)): - self.arrows[x] = loader.loadModel('phase_3/models/props/arrow') + self.arrows[x] = base.loader.loadModel('phase_3/models/props/arrow') self.arrows[x].reparentTo(self.powerMeter) self.arrows[x].hide() self.arrows[x].setScale(0.2 - 0.4 * x, 0.2, 0.2) self.arrows[x].setPos(0.12 - 0.24 * x, 0, -.26) self.disableArrow(self.arrows[x]) - self.splash = Splash.Splash(render) - self.suitSplash = Splash.Splash(render) - self.ripples = Ripples.Ripples(render) - self.suitRipples = Ripples.Ripples(render) - return + self.splash = Splash(base.render) + self.suitSplash = Splash(base.render) + self.ripples = Ripples(base.render) + self.suitRipples = Ripples(base.render) def toggleMouseMode(self, param): self.mouseMode = not self.mouseMode @@ -155,6 +164,7 @@ class DistributedTugOfWarGame(DistributedMinigame): self.hilightArrow(self.arrows[1]) else: self.hilightArrow(self.arrows[0]) + self.__spawnMouseSpeedTask() else: self.__releaseHandler(0) @@ -183,6 +193,7 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.powerMeter: self.powerMeter.destroy() del self.powerMeter + for x in self.arrows: if x: x.removeNode() @@ -197,10 +208,12 @@ class DistributedTugOfWarGame(DistributedMinigame): self.ripples.stop() self.ripples.detachNode() del self.ripples + if self.suitRipples != None: self.suitRipples.stop() self.suitRipples.detachNode() del self.suitRipples + for x in self.avList: del x @@ -208,6 +221,7 @@ class DistributedTugOfWarGame(DistributedMinigame): for x in self.tugRopes: if x != None: x.detachNode() + del x del self.tugRopes @@ -235,6 +249,7 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.suit: self.suit.delete() del self.suit + del self.sides del self.buttons del self.pullingDict @@ -245,26 +260,24 @@ class DistributedTugOfWarGame(DistributedMinigame): del self.drinkPositions del self.offsetDict del self.keyTTL - del self.rng - return def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) self.lt = base.localAvatar NametagGlobals.setGlobalNametagScale(1) - self.arrowKeys = ArrowKeys.ArrowKeys() - self.room.reparentTo(render) + self.arrowKeys = ArrowKeys() + self.room.reparentTo(base.render) self.room.setPosHpr(0.0, 18.39, -ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0) self.room.setScale(0.4) self.sky.setZ(-5) - self.sky.reparentTo(render) + self.sky.reparentTo(base.render) self.dropShadow.setColor(0, 0, 0, 0.5) - camera.reparentTo(render) - camera.setPosHpr(-11.4427, 9.03559, 2.80094, -49.104, -0.89, 0) + base.camera.reparentTo(base.render) + base.camera.setPosHpr(-11.4427, 9.03559, 2.80094, -49.104, -0.89, 0) self.dropShadow.setBin('fixed', 0, 1) - self.splash.reparentTo(render) - self.suitSplash.reparentTo(render) + self.splash.reparentTo(base.render) + self.suitSplash.reparentTo(base.render) base.playMusic(self.music, looping=1, volume=1) for x in range(len(self.arrows)): self.arrows[x].show() @@ -280,20 +293,24 @@ class DistributedTugOfWarGame(DistributedMinigame): self.introTrack.finish() del self.introTrack self.introTrack = None + for track in list(self.animTracks.values()): if track: track.finish() del track + self.animTracks = {} if self.showTrack: self.showTrack.finish() del self.showTrack self.showTrack = None + if self.setupTrack: self.setupTrack.finish() del self.setupTrack self.setupTrack = None + base.camLens.setFov(ToontownGlobals.DefaultCameraFov) base.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) NametagGlobals.setGlobalNametagScale(1.0) @@ -303,13 +320,14 @@ class DistributedTugOfWarGame(DistributedMinigame): self.arrowKeys.destroy() del self.arrowKeys self.arrowKeys = None - self.room.reparentTo(hidden) - self.sky.reparentTo(hidden) - self.splash.reparentTo(hidden) + + self.room.reparentTo(base.hidden) + self.sky.reparentTo(base.hidden) + self.splash.reparentTo(base.hidden) self.splash.stop() - self.suitSplash.reparentTo(hidden) + self.suitSplash.reparentTo(base.hidden) self.suitSplash.stop() - self.ripples.reparentTo(hidden) + self.ripples.reparentTo(base.hidden) self.ripples.stop() self.hideControls() self.roundText.hide() @@ -322,42 +340,36 @@ class DistributedTugOfWarGame(DistributedMinigame): for x in self.tugRopes: if x != None: - x.reparentTo(hidden) + x.reparentTo(base.hidden) if self.suit: - self.suit.reparentTo(hidden) + self.suit.reparentTo(base.hidden) + for avId in self.avIdList: if avId in self.dropShadowDict: - self.dropShadowDict[avId].reparentTo(hidden) + self.dropShadowDict[avId].reparentTo(base.hidden) if self.suitId in self.dropShadowDict: - self.dropShadowDict[self.suitId].reparentTo(hidden) - return + self.dropShadowDict[self.suitId].reparentTo(base.hidden) def initCamera(self): - birdseyePosHpr = [1.95461, - 18.4891, - 38.4646, - 1.18185, - -87.5308, - 0] introPosHpr = [None] * 2 introPosHpr[0] = [VBase3(-11.4427, 9.03559, 2.80094), VBase3(-49.104, -0.732374, 0)] introPosHpr[1] = [VBase3(16.9291, 13.9302, 2.64282), VBase3(66.9685, -6.195, 0)] gameCamHpr = VBase3(-1.13, 1.042, 0) gameCamPos = VBase3(0, 1.0838, 2.745) - camera.reparentTo(render) - camera.setPosHpr(introPosHpr[self.sides[self.localAvId]][0], introPosHpr[self.sides[self.localAvId]][1]) + base.camera.reparentTo(base.render) + base.camera.setPosHpr(introPosHpr[self.sides[self.localAvId]][0], introPosHpr[self.sides[self.localAvId]][1]) lerpDur = 8 - self.introTrack = LerpPosHprInterval(camera, lerpDur, pos=gameCamPos, hpr=gameCamHpr, blendType='easeInOut', name=self.uniqueName('introLerpCameraPos')) + self.introTrack = LerpPosHprInterval(base.camera, lerpDur, pos=gameCamPos, hpr=gameCamHpr, blendType='easeInOut', name=self.uniqueName('introLerpCameraPos')) self.introTrack.start() base.camLens.setFov(60 + 2 * self.numPlayers) base.camLens.setFar(450.0) - return def sendGameType(self, index, suit): if not self.hasLocalToon: return + self.gameType = index self.suitLevel = suit if suit == 1: @@ -372,9 +384,11 @@ class DistributedTugOfWarGame(DistributedMinigame): def setGameReady(self): if not self.hasLocalToon: return + self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return + self.initToons() self.createSuits() self.calculatePositions() @@ -389,7 +403,6 @@ class DistributedTugOfWarGame(DistributedMinigame): self.showTrack = None self.setupTrack = None self.__initGameVars() - return def hideControls(self): for x in range(len(self.arrows)): @@ -397,40 +410,39 @@ class DistributedTugOfWarGame(DistributedMinigame): for rope in self.tugRopes: if rope != None: - rope.reparentTo(hidden) + rope.reparentTo(base.hidden) for tex in self.ropeTex: if tex != None: for texi in tex: if texi: - texi.reparentTo(hidden) + texi.reparentTo(base.hidden) if self.powerMeter != None: self.powerMeter.unbind(DGG.B1PRESS) self.powerMeter.unbind(DGG.B1RELEASE) self.powerMeter.hide() - return def setUpRopes(self, notTaut): if self.numPlayers == 1: suitRightHand = self.suit.getRightHand() toonRightHand = self.rightHandDict[self.avIdList[0]] if notTaut: - self.tugRopes[0].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, + self.tugRopes[0].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) else: - midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0 self.tugRopes[0].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) - self.tugRopes[0].reparentTo(render) + + self.tugRopes[0].reparentTo(base.render) elif self.numPlayers == 2: if self.gameType == TugOfWarGameGlobals.TOON_VS_COG: self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0, @@ -442,25 +454,25 @@ class DistributedTugOfWarGame(DistributedMinigame): suitRightHand = self.suit.getRightHand() toonRightHand = self.rightHandDict[self.avIdList[1]] if notTaut: - self.tugRopes[1].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, + self.tugRopes[1].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) else: - midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0 self.tugRopes[1].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) - self.tugRopes[0].reparentTo(render) - self.tugRopes[1].reparentTo(render) + + self.tugRopes[0].reparentTo(base.render) + self.tugRopes[1].reparentTo(base.render) else: if notTaut: - self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (render, (0, 18, -1)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0, + self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (base.render, (0, 18, -1)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0, 0, 0, 1, @@ -473,7 +485,8 @@ class DistributedTugOfWarGame(DistributedMinigame): 1, 1, 1]) - self.tugRopes[0].reparentTo(render) + + self.tugRopes[0].reparentTo(base.render) elif self.numPlayers == 3: if self.gameType == TugOfWarGameGlobals.TOON_VS_COG: self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0, @@ -491,26 +504,26 @@ class DistributedTugOfWarGame(DistributedMinigame): suitRightHand = self.suit.getRightHand() toonRightHand = self.rightHandDict[self.avIdList[2]] if notTaut: - self.tugRopes[2].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, + self.tugRopes[2].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) else: - midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0 self.tugRopes[2].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) - self.tugRopes[0].reparentTo(render) - self.tugRopes[1].reparentTo(render) - self.tugRopes[2].reparentTo(render) + + self.tugRopes[0].reparentTo(base.render) + self.tugRopes[1].reparentTo(base.render) + self.tugRopes[2].reparentTo(base.render) else: if notTaut: - self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0, + self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (base.render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0, 0, 0, 1, @@ -523,14 +536,15 @@ class DistributedTugOfWarGame(DistributedMinigame): 1, 1, 1]) + self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0, 0, 0, 1, 1, 1]) - self.tugRopes[0].reparentTo(render) - self.tugRopes[1].reparentTo(render) + self.tugRopes[0].reparentTo(base.render) + self.tugRopes[1].reparentTo(base.render) elif self.numPlayers == 4: if self.gameType == TugOfWarGameGlobals.TOON_VS_COG: self.tugRopes[2].setup(3, ((self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[3]], (0, 0, 0))), [0, @@ -554,24 +568,24 @@ class DistributedTugOfWarGame(DistributedMinigame): suitRightHand = self.suit.getRightHand() toonRightHand = self.rightHandDict[self.avIdList[3]] if notTaut: - self.tugRopes[3].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, + self.tugRopes[3].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) else: - midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0 self.tugRopes[3].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0, 0, 0, 1, 1, 1]) - self.tugRopes[0].reparentTo(render) - self.tugRopes[1].reparentTo(render) - self.tugRopes[2].reparentTo(render) - self.tugRopes[3].reparentTo(render) + + self.tugRopes[0].reparentTo(base.render) + self.tugRopes[1].reparentTo(base.render) + self.tugRopes[2].reparentTo(base.render) + self.tugRopes[3].reparentTo(base.render) else: self.tugRopes[2].setup(3, ((self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[3]], (0, 0, 0))), [0, 0, @@ -586,7 +600,7 @@ class DistributedTugOfWarGame(DistributedMinigame): 1, 1]) if notTaut: - self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0, + self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (base.render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0, 0, 0, 1, @@ -599,15 +613,16 @@ class DistributedTugOfWarGame(DistributedMinigame): 1, 1, 1]) - self.tugRopes[0].reparentTo(render) - self.tugRopes[1].reparentTo(render) - self.tugRopes[2].reparentTo(render) + + self.tugRopes[0].reparentTo(base.render) + self.tugRopes[1].reparentTo(base.render) + self.tugRopes[2].reparentTo(base.render) def initToons(self): for avId in self.avIdList: toon = self.getAvatar(avId) if toon: - toon.reparentTo(render) + toon.reparentTo(base.render) toon.useLOD(1000) toon.startBlink() toon.startLookAround() @@ -618,7 +633,7 @@ class DistributedTugOfWarGame(DistributedMinigame): self.rightHandDict[avId] = toon.getRightHands()[0] toon.loop('neutral') toon.dropShadow.hide() - self.dropShadowDict[avId] = self.dropShadow.copyTo(hidden) + self.dropShadowDict[avId] = self.dropShadow.copyTo(base.hidden) self.dropShadowDict[avId].reparentTo(toon) self.dropShadowDict[avId].setScale(0.35) @@ -696,6 +711,7 @@ class DistributedTugOfWarGame(DistributedMinigame): self.hprDict[self.avIdList[1]] = hprPositions[0] self.hprDict[self.avIdList[2]] = hprPositions[1] self.hprDict[self.avIdList[3]] = hprPositions[1] + for x in self.avIdList: self.offsetDict[x] = 0 if self.posDict[x][0] < 0: @@ -741,9 +757,11 @@ class DistributedTugOfWarGame(DistributedMinigame): def setGameStart(self, timestamp): if not self.hasLocalToon: return + self.notify.debug('setGameStart') if not self.__playing(): return + DistributedMinigame.setGameStart(self, timestamp) self.gameFSM.request('waitForGoSignal') @@ -751,7 +769,7 @@ class DistributedTugOfWarGame(DistributedMinigame): pass def makeToonLookatCamera(self, toon): - toon.headsUp(camera) + toon.headsUp(base.camera) def setText(self, t, newtext): t['text'] = newtext @@ -788,6 +806,7 @@ class DistributedTugOfWarGame(DistributedMinigame): self.notify.debug('exitTug') if self.suit: self.suit.loop('neutral') + self.timer.stop() self.timer.hide() taskMgr.remove(self.taskName('tug-timeout')) @@ -828,7 +847,8 @@ class DistributedTugOfWarGame(DistributedMinigame): def __updateKeyPressRateTask(self, task): if self.gameFSM.getCurrentState().getName() != 'tug': - return Task.done + return task.done + for i in range(len(self.keyTTL)): self.keyTTL[i] -= 0.1 @@ -844,18 +864,20 @@ class DistributedTugOfWarGame(DistributedMinigame): self.rateMatchAward += 0.3 else: self.rateMatchAward = 0 + self.__spawnUpdateKeyPressRateTask() - return Task.done + return task.done def __updateTimerTask(self, task): if self.gameFSM.getCurrentState().getName() != 'tug': - return Task.done + return task.done + self.currentForce = self.computeForce(self.keyRate) self.sendUpdate('reportCurrentKeyRate', [self.keyRate, self.currentForce]) self.setSpeedGauge() self.setAnimState(self.localAvId, self.keyRate) self.__spawnUpdateTimerTask() - return Task.done + return task.done def __spawnUpdateTimerTask(self): taskMgr.remove(self.taskName(self.UPDATE_TIMER_TASK)) @@ -881,10 +903,12 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.nextRateIndex < len(self.targetRateList): if self.nextRateIndex == len(self.targetRateList) - 1: self.allOutMode = 1 + self.idealRate = self.targetRateList[self.nextRateIndex][1] self.idealForce = self.advantage * (4 + 0.4 * self.idealRate) taskMgr.doMethodLater(self.targetRateList[self.nextRateIndex][0], self.__updateIdealRateTask, self.taskName('targetRateTimer')) - return Task.done + + return task.done def __killUpdateIdealRateTask(self): taskMgr.remove(self.taskName('targetRateTimer')) @@ -892,14 +916,14 @@ class DistributedTugOfWarGame(DistributedMinigame): def sendGoSignal(self, index): if not self.hasLocalToon: return + self.notify.debug('sendGoSignal') self.buttons = index self.setupTrack = None self.showTrack = None def startTimer(self = self): - self.currentStartTime = int(globalClock.getFrameTime() * 1000) - time = 10 + self.currentStartTime = int(base.clock.getFrameTime() * 1000) self.timer.show() self.timer.setTime(TugOfWarGameGlobals.GAME_DURATION) self.timer.countdown(TugOfWarGameGlobals.GAME_DURATION, self.__gameTimerExpired) @@ -926,13 +950,14 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.introTrack != None: self.introTrack.finish() self.introTrack = None + self.setupTrack = Sequence(Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameReady), Wait(1.5), Func(base.playSfx, self.whistleSound), Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameGo), Func(self.roundText.setScale, 0.3), Wait(1.5), Func(startTimer), Func(enableKeys), Func(self.gameFSM.request, 'tug'), Func(self.setText, self.roundText, ' '), Func(self.roundText.setScale, 0.2)) self.setupTrack.start() - return def sendStopSignal(self, winners, losers, tieers): if not self.hasLocalToon: return + self.notify.debug('sendStopSignal') self.gameFSM.request('gameDone') self.hideControls() @@ -941,6 +966,7 @@ class DistributedTugOfWarGame(DistributedMinigame): suitSlipTime = 0 if self.gameFSM.getCurrentState().getName() == 'cleanup' or not self.randomNumGen: return + if self.suit: if self.suitId in winners: newPos = VBase3(2.65, 18, 0.1) @@ -959,6 +985,7 @@ class DistributedTugOfWarGame(DistributedMinigame): destHpr = startHpr + VBase3(0, 0, -30) oopsTrack = Sequence(Parallel(Func(self.suit.play, 'flail', None, 26, 38), LerpHprInterval(self.suit, 0.5, destHpr, startHpr=startHpr)), Parallel(Func(self.suit.play, 'slip-forward'), LerpPosInterval(self.suit, duration=1, pos=waterPos), Sequence(Wait(0.55), Func(base.playSfx, self.sndHitWater), Func(self.suitSplash.play), Func(self.ripples.play)))) reactSeq.append(Sequence(Func(self.suit.loop, 'victory'), Wait(2.6), LerpPosInterval(self.suit, duration=2, pos=newPos), oopsTrack, Func(self.suit.loop, 'neutral'))) + for avId in self.avIdList: toon = self.getAvatar(avId) toon.loop('neutral') @@ -978,6 +1005,7 @@ class DistributedTugOfWarGame(DistributedMinigame): else: exitSeq.append(Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameTie)) exitSeq.append(Wait(2.5)) + exitSeq.append(Func(self.gameOver)) self.showTrack = Parallel(reactSeq, exitSeq) for x in list(self.animTracks.values()): @@ -988,27 +1016,31 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.arrowKeys: self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS) self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS) - return def remoteKeyRateUpdate(self, avId, keyRate): if not self.hasLocalToon: return + if avId != self.localAvId: self.setAnimState(avId, keyRate) def sendSuitPosition(self, suitOffset): if not self.hasLocalToon: return + if self.gameFSM.getCurrentState().getName() != 'tug': return + self.suitOffset = suitOffset self.moveSuits() def sendCurrentPosition(self, avIdList, offsetList): if not self.hasLocalToon: return + if self.gameFSM.getCurrentState().getName() != 'tug': return + for i in range(len(avIdList)): self.offsetDict[avIdList[i]] = offsetList[i] @@ -1017,20 +1049,20 @@ class DistributedTugOfWarGame(DistributedMinigame): def createSuits(self): if self.gameType == TugOfWarGameGlobals.TOON_VS_COG: - self.suit = Suit.Suit() + self.suit = Suit() self.origSuitPosHpr = [VBase3(6.0, 18, 0.1), VBase3(120, 0, 0)] self.suitOffset = 0 - d = SuitDNA.SuitDNA() + d = SuitDNA() d.newSuit(self.suitType) self.suit.setDNA(d) - self.suit.reparentTo(render) + self.suit.reparentTo(base.render) self.suit.setPos(self.origSuitPosHpr[0]) self.suit.setHpr(self.origSuitPosHpr[1]) for anim in self.suitAnimNames: self.suit.pose(anim, 0) self.suit.pose('tug-o-war', 0) - self.dropShadowDict[self.suitId] = self.dropShadow.copyTo(hidden) + self.dropShadowDict[self.suitId] = self.dropShadow.copyTo(base.hidden) self.dropShadowDict[self.suitId].reparentTo(self.suit) self.dropShadowDict[self.suitId].setScale(0.45) @@ -1040,11 +1072,13 @@ class DistributedTugOfWarGame(DistributedMinigame): toon = self.getAvatar(self.avList[0][0]) if self.avList[0][0] == self.localAvId: self.advantage = 2.0 + toon.applyCheesyEffect(ToontownGlobals.CEBigHead) elif len(self.avList[1]) == 1: toon = self.getAvatar(self.avList[1][0]) if self.avList[1][0] == self.localAvId: self.advantage = 2.0 + toon.applyCheesyEffect(ToontownGlobals.CEBigHead) def setSpeedGauge(self): @@ -1052,12 +1086,14 @@ class DistributedTugOfWarGame(DistributedMinigame): self.powerMeter.setTarget(self.idealRate) if not self.allOutMode: self.powerMeter.updateTooSlowTooFast() + if not self.allOutMode: index = float(self.currentForce) / self.idealForce bonus = 0.0 if index > 1: bonus = max(1, index - 1) index = 1 + color = (0, 0.75 * index + 0.25 * bonus, 0.75 * (1 - index), @@ -1069,10 +1105,12 @@ class DistributedTugOfWarGame(DistributedMinigame): def setAnimState(self, avId, keyRate): if self.gameFSM.getCurrentState().getName() != 'tug': return + toon = self.getAvatar(avId) if keyRate > 0 and self.pullingDict[avId] == 0: toon.loop('tug-o-war') self.pullingDict[avId] = 1 + if keyRate <= 0 and self.pullingDict[avId] == 1: toon.pose('tug-o-war', 3) toon.startLookAround() @@ -1081,6 +1119,7 @@ class DistributedTugOfWarGame(DistributedMinigame): def moveSuits(self): if self.gameType != TugOfWarGameGlobals.TOON_VS_COG: return + origPos = self.origSuitPosHpr[0] curPos = self.suit.getPos() newPos = VBase3(origPos[0] + self.suitOffset, curPos[1], curPos[2]) @@ -1088,10 +1127,10 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.animTracks[self.suitId].isPlaying(): self.animTracks[self.suitId].finish() self.checkIfFallen() + if self.suitId not in self.fallenList: self.animTracks[self.suitId] = Sequence(LerpPosInterval(self.suit, duration=TugOfWarGameGlobals.SEND_UPDATE, pos=newPos), Func(self.checkIfFallen)) self.animTracks[self.suitId].start() - return def moveToons(self): for avId in self.avIdList: @@ -1105,12 +1144,11 @@ class DistributedTugOfWarGame(DistributedMinigame): if self.animTracks[avId].isPlaying(): self.animTracks[avId].finish() self.checkIfFallen(avId) + if avId not in self.fallenList: self.animTracks[avId] = Sequence(LerpPosInterval(toon, duration=TugOfWarGameGlobals.SEND_UPDATE, pos=newPos), Func(self.checkIfFallen, avId)) self.animTracks[avId].start() - return - def checkIfFallen(self, avId = None): if avId == None: if self.suitId not in self.fallenList: @@ -1132,7 +1170,6 @@ class DistributedTugOfWarGame(DistributedMinigame): self.throwInWater(avId) self.sendUpdate('reportEndOfContest', [losingSide]) - return def throwInWater(self, avId = None): if avId == None: @@ -1140,7 +1177,7 @@ class DistributedTugOfWarGame(DistributedMinigame): waterPos = self.drinkPositions.pop() newPos = VBase3(waterPos[0], waterPos[1], waterPos[2] - self.suit.getHeight() / 1.5) self.suit.loop('neutral') - self.dropShadowDict[self.suitId].reparentTo(hidden) + self.dropShadowDict[self.suitId].reparentTo(base.hidden) loser = self.suit animId = self.suitId else: @@ -1149,19 +1186,20 @@ class DistributedTugOfWarGame(DistributedMinigame): waterPos = self.drinkPositions.pop() newPos = VBase3(waterPos[0], waterPos[1], waterPos[2] - toon.getHeight()) toon.loop('neutral') - self.dropShadowDict[avId].reparentTo(hidden) + self.dropShadowDict[avId].reparentTo(base.hidden) loser = toon animId = avId + if self.animTracks[animId] != None: if self.animTracks[animId].isPlaying(): self.animTracks[animId].finish() + self.splash.setPos(newPos[0], newPos[1], -1.8) self.splash.setScale(2.5, 2.5, 1) self.ripples.setPos(newPos[0], newPos[1], -1.7) self.ripples.setScale(1, 1, 1) self.animTracks[animId] = Sequence(Parallel(ActorInterval(actor=loser, animName='slip-forward', duration=2.0), LerpPosInterval(loser, duration=2.0, pos=newPos), Sequence(Wait(1.0), Parallel(Func(base.playSfx, self.sndHitWater), Func(self.splash.play), Func(self.ripples.play)))), Func(loser.loop, 'neutral')) self.animTracks[animId].start() - return def computeForce(self, keyRate): F = 0 @@ -1170,6 +1208,7 @@ class DistributedTugOfWarGame(DistributedMinigame): else: stdDev = 0.25 * self.idealRate F = self.advantage * (self.rateMatchAward + 4 + 0.4 * self.idealRate) * math.pow(math.e, -math.pow(keyRate - self.idealRate, 2) / (2.0 * math.pow(stdDev, 2))) + return F def initRopes(self): @@ -1177,8 +1216,9 @@ class DistributedTugOfWarGame(DistributedMinigame): numRopes = self.numPlayers else: numRopes = self.numPlayers - 1 + for x in range(0, numRopes): - rope = Rope.Rope(self.uniqueName('TugRope' + str(x))) + rope = Rope(self.uniqueName('TugRope' + str(x))) if rope.showRope: rope.ropeNode.setRenderMode(RopeNode.RMBillboard) rope.ropeNode.setThickness(0.2) @@ -1187,6 +1227,7 @@ class DistributedTugOfWarGame(DistributedMinigame): rope.ropeNode.setUvDirection(1) rope.setTransparency(1) rope.setColor(0.89, 0.89, 0.6, 1) + self.tugRopes.append(rope) self.setUpRopes(1) @@ -1203,18 +1244,18 @@ class DistributedTugOfWarGame(DistributedMinigame): for j in range(len(self.ropePts[i])): self.ropeTex[i][j].setPos(self.ropePts[i][j]) - return Task.cont + return task.cont def __killUpdateRopeTask(self): taskMgr.remove(self.taskName(self.UPDATE_ROPE_TASK)) def tugTimeoutTask(self, task): self.gameOver() - return Task.done + return task.done def waitForGoTimeoutTask(self, task): self.gameOver() - return Task.done + return task.done def __spawnMouseSpeedTask(self): taskMgr.remove(self.taskName('mouseSpeed')) @@ -1227,7 +1268,6 @@ class DistributedTugOfWarGame(DistributedMinigame): dx = 0.1 if self.mouseMode: mx = base.mouseWatcherNode.getMouseX() - my = base.mouseWatcherNode.getMouseY() if self.mouseSide == 0: if mx > dx: self.mouseSide = 1 @@ -1242,4 +1282,5 @@ class DistributedTugOfWarGame(DistributedMinigame): self.__pressHandler(1) elif mx < dx: self.__releaseHandler(0) - return Task.cont + + return task.cont diff --git a/toontown/minigame/OrthoDrive.py b/toontown/minigame/OrthoDrive.py index 0b3a904..e341905 100644 --- a/toontown/minigame/OrthoDrive.py +++ b/toontown/minigame/OrthoDrive.py @@ -1,11 +1,18 @@ -from direct.interval.IntervalGlobal import * -from direct.task.Task import Task +from panda3d.core import Point3, Vec3 + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.interval.IntervalGlobal import LerpHprInterval +from direct.showbase.PythonUtil import fitSrcAngle2Dest +from direct.task.TaskManagerGlobal import taskMgr + from otp.otpbase import OTPGlobals -from toontown.toonbase.ToonBaseGlobal import * -from . import ArrowKeys + +from toontown.minigame.ArrowKeys import ArrowKeys +from toontown.toonbase.ToonBaseGlobal import base + class OrthoDrive: - notify = DirectNotifyGlobal.directNotify.newCategory('OrthoDrive') + notify = directNotify.newCategory('OrthoDrive') TASK_NAME = 'OrthoDriveTask' SET_ATREST_HEADING_TASK = 'setAtRestHeadingTask' @@ -17,7 +24,7 @@ class OrthoDrive: self.priority = priority self.setHeading = setHeading self.upHeading = upHeading - self.arrowKeys = ArrowKeys.ArrowKeys() + self.arrowKeys = ArrowKeys() self.lt = base.localAvatar self.instantTurn = instantTurn @@ -31,18 +38,17 @@ class OrthoDrive: self.__placeToonHOG(self.lt.getPos()) taskMgr.add(self.__update, OrthoDrive.TASK_NAME, priority=self.priority) self.lastAction = None - return def __placeToonHOG(self, pos, h = None): if h == None: h = self.lt.getH() + self.lt.setPos(pos) self.lt.setH(h) self.lastPos = pos self.atRestHeading = h self.lastXVel = 0 self.lastYVel = 0 - return def stop(self): self.notify.debug('stop') @@ -52,7 +58,9 @@ class OrthoDrive: if hasattr(self, 'turnLocalToonIval'): if self.turnLocalToonIval.isPlaying(): self.turnLocalToonIval.pause() + del self.turnLocalToonIval + base.localAvatar.setSpeed(0, 0) def __update(self, task): @@ -61,12 +69,16 @@ class OrthoDrive: yVel = 0 if self.arrowKeys.upPressed(): yVel += 1 + if self.arrowKeys.downPressed(): yVel -= 1 + if self.arrowKeys.leftPressed(): xVel -= 1 + if self.arrowKeys.rightPressed(): xVel += 1 + vel.setX(xVel) vel.setY(yVel) vel.normalize() @@ -82,10 +94,12 @@ class OrthoDrive: self.lt.runSound() else: self.lt.stopSound() + if self.setHeading: self.__handleHeading(xVel, yVel) + toonPos = self.lt.getPos() - dt = globalClock.getDt() + dt = base.clock.getDt() posOffset = vel * dt posOffset += toonPos - self.lastPos toonPos = self.lastPos @@ -94,13 +108,15 @@ class OrthoDrive: if posOffsetLen > self.maxFrameMove: posOffset *= self.maxFrameMove posOffset /= posOffsetLen + if self.customCollisionCallback: toonPos = self.customCollisionCallback(toonPos, toonPos + posOffset) else: toonPos = toonPos + posOffset + self.lt.setPos(toonPos) self.lastPos = toonPos - return Task.cont + return task.cont def __handleHeading(self, xVel, yVel): def getHeading(xVel, yVel): @@ -126,11 +142,13 @@ class OrthoDrive: if ((self.lastXVel and self.lastYVel) and not (xVel and yVel)): def setAtRestHeading(task, self = self, angle = curHeading): self.atRestHeading = angle - return Task.done + return task.done taskMgr.doMethodLater(0.05, setAtRestHeading, OrthoDrive.SET_ATREST_HEADING_TASK) else: self.atRestHeading = curHeading + orientToon(curHeading) + self.lastXVel = xVel self.lastYVel = yVel diff --git a/toontown/minigame/Purchase.py b/toontown/minigame/Purchase.py index 1c7b987..d7147a9 100644 --- a/toontown/minigame/Purchase.py +++ b/toontown/minigame/Purchase.py @@ -51,15 +51,15 @@ class Purchase(PurchaseBase): self.bg = loader.loadModel('phase_%s/models/modules/toon_interior' % interiorPhase) self.bg.setPos(0.0, 5.0, -1.0) self.wt = self.bg.find('**/random_tc1_TI_wallpaper') - wallTex = loader.loadTexture('phase_%s/maps/wall_paper_a5.jpg' % interiorPhase) + wallTex = loader.loadTexture('phase_%s/maps/wall_paper_a5.png' % interiorPhase) self.wt.setTexture(wallTex, 100) self.wt.setColorScale(0.8, 0.67, 0.549, 1.0) self.bt = self.bg.find('**/random_tc1_TI_wallpaper_border') - wallTex = loader.loadTexture('phase_%s/maps/wall_paper_a5.jpg' % interiorPhase) + wallTex = loader.loadTexture('phase_%s/maps/wall_paper_a5.png' % interiorPhase) self.bt.setTexture(wallTex, 100) self.bt.setColorScale(0.8, 0.67, 0.549, 1.0) self.wb = self.bg.find('**/random_tc1_TI_wainscotting') - wainTex = loader.loadTexture('phase_%s/maps/wall_paper_b4.jpg' % interiorPhase) + wainTex = loader.loadTexture('phase_%s/maps/wall_paper_b4.png' % interiorPhase) self.wb.setTexture(wainTex, 100) self.wb.setColorScale(0.473, 0.675, 0.488, 1.0) self.playAgain = DirectButton(parent=self.frame, relief=None, scale=1.04, pos=(0.72, 0, -0.24), image=(purchaseModels.find('**/PurchScrn_BTN_UP'), diff --git a/toontown/minigame/SwingVine.py b/toontown/minigame/SwingVine.py index efa7b14..e9bfaad 100644 --- a/toontown/minigame/SwingVine.py +++ b/toontown/minigame/SwingVine.py @@ -112,7 +112,7 @@ class SwingVine(NodePath): self.link1 = self.links[-2][0] self.rope = self.makeSpline() self.rope.reparentTo(self.root) - myTexture = loader.loadTexture('phase_4/maps/swinging_vine.jpg') + myTexture = loader.loadTexture('phase_4/maps/swinging_vine.png') gameAssets = loader.loadModel('phase_4/models/minigames/vine_game') vine = gameAssets.find('**/vine1') self.cableTex = vine.findTexture('*') diff --git a/toontown/minigame/ToonBlitzAssetMgr.py b/toontown/minigame/ToonBlitzAssetMgr.py index ea4cfd0..aecf8c0 100644 --- a/toontown/minigame/ToonBlitzAssetMgr.py +++ b/toontown/minigame/ToonBlitzAssetMgr.py @@ -1,12 +1,15 @@ -from panda3d.core import * +from panda3d.core import CardMaker, CollisionNode, CollisionPlane, NodePath, Plane, Point3, Vec3 + +from direct.directnotify.DirectNotifyGlobal import directNotify from direct.showbase.DirectObject import DirectObject -from toontown.toonbase.ToonBaseGlobal import * -from direct.directnotify import DirectNotifyGlobal -from toontown.minigame import ToonBlitzGlobals, TwoDBlock -from panda3d.core import CardMaker + +from toontown.minigame import ToonBlitzGlobals +from toontown.toonbase import ToontownGlobals +from toontown.toonbase.ToonBaseGlobal import base + class ToonBlitzAssetMgr(DirectObject): - notify = DirectNotifyGlobal.directNotify.newCategory('DistributedToonBlitzAssets') + notify = directNotify.newCategory('DistributedToonBlitzAssets') def __init__(self, game): self.__defineConstants() @@ -18,47 +21,47 @@ class ToonBlitzAssetMgr(DirectObject): def load(self): self.world = NodePath('ToonBlitzWorld') - self.background = loader.loadModel('phase_4/models/minigames/toonblitz_game') + self.background = base.loader.loadModel('phase_4/models/minigames/toonblitz_game') self.background.reparentTo(self.world) - self.startingWall = loader.loadModel('phase_4/models/minigames/toonblitz_game_wall') - self.startingPipe = loader.loadModel('phase_4/models/minigames/toonblitz_game_start') - self.exitElevator = loader.loadModel('phase_4/models/minigames/toonblitz_game_elevator') - self.arrow = loader.loadModel('phase_4/models/minigames/toonblitz_game_arrow') - self.sprayProp = loader.loadModel('phase_4/models/minigames/prop_waterspray') + self.startingWall = base.loader.loadModel('phase_4/models/minigames/toonblitz_game_wall') + self.startingPipe = base.loader.loadModel('phase_4/models/minigames/toonblitz_game_start') + self.exitElevator = base.loader.loadModel('phase_4/models/minigames/toonblitz_game_elevator') + self.arrow = base.loader.loadModel('phase_4/models/minigames/toonblitz_game_arrow') + self.sprayProp = base.loader.loadModel('phase_4/models/minigames/prop_waterspray') self.treasureModelList = [] - salesIcon = loader.loadModel('phase_4/models/minigames/salesIcon') + salesIcon = base.loader.loadModel('phase_4/models/minigames/salesIcon') self.treasureModelList.append(salesIcon) - moneyIcon = loader.loadModel('phase_4/models/minigames/moneyIcon') + moneyIcon = base.loader.loadModel('phase_4/models/minigames/moneyIcon') self.treasureModelList.append(moneyIcon) - legalIcon = loader.loadModel('phase_4/models/minigames/legalIcon') + legalIcon = base.loader.loadModel('phase_4/models/minigames/legalIcon') self.treasureModelList.append(legalIcon) - corpIcon = loader.loadModel('phase_4/models/minigames/corpIcon') + corpIcon = base.loader.loadModel('phase_4/models/minigames/corpIcon') self.treasureModelList.append(corpIcon) - self.particleGlow = loader.loadModel('phase_4/models/minigames/particleGlow') + self.particleGlow = base.loader.loadModel('phase_4/models/minigames/particleGlow') self.blockTypes = [] for i in range(4): - blockType = loader.loadModel('phase_4/models/minigames/toonblitz_game_block0' + str(i)) + blockType = base.loader.loadModel('phase_4/models/minigames/toonblitz_game_block0' + str(i)) self.blockTypes.append(blockType) - self.stomper = loader.loadModel('phase_4/models/minigames/toonblitz_game_stomper') + self.stomper = base.loader.loadModel('phase_4/models/minigames/toonblitz_game_stomper') plane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, -50))) dropPlane = CollisionNode('dropPlane') dropPlane.addSolid(plane) dropPlane.setCollideMask(ToontownGlobals.FloorBitmask) self.world.attachNewNode(dropPlane) self.gameMusic = base.loader.loadMusic('phase_4/audio/bgm/MG_TwoDGame.ogg') - self.treasureGrabSound = loader.loadSfx('phase_4/audio/sfx/SZ_DD_treasure.ogg') + self.treasureGrabSound = base.loader.loadSfx('phase_4/audio/sfx/SZ_DD_treasure.ogg') self.sndOof = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg') self.soundJump = base.loader.loadSfx('phase_4/audio/sfx/MG_sfx_vine_game_jump.ogg') self.fallSound = base.loader.loadSfx('phase_4/audio/sfx/MG_sfx_vine_game_fall.ogg') self.watergunSound = base.loader.loadSfx('phase_4/audio/sfx/AA_squirt_seltzer_miss.ogg') self.splashSound = base.loader.loadSfx('phase_4/audio/sfx/Seltzer_squirt_2dgame_hit.ogg') - self.threeSparkles = loader.loadSfx('phase_4/audio/sfx/threeSparkles.ogg') - self.sparkleSound = loader.loadSfx('phase_4/audio/sfx/sparkly.ogg') - self.headCollideSound = loader.loadSfx('phase_3.5/audio/sfx/AV_collision.ogg') + self.threeSparkles = base.loader.loadSfx('phase_4/audio/sfx/threeSparkles.ogg') + self.sparkleSound = base.loader.loadSfx('phase_4/audio/sfx/sparkly.ogg') + self.headCollideSound = base.loader.loadSfx('phase_3.5/audio/sfx/AV_collision.ogg') self.faceStartPos = Vec3(-0.8, 0, -0.87) self.faceEndPos = Vec3(0.8, 0, -0.87) - self.aspect2dRoot = aspect2d.attachNewNode('TwoDGuiAspect2dRoot') + self.aspect2dRoot = base.aspect2d.attachNewNode('TwoDGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.cardMaker = CardMaker('card') self.cardMaker.reset() @@ -114,10 +117,9 @@ class ToonBlitzAssetMgr(DirectObject): del self.sparkleSound del self.headCollideSound self.game = None - return def onstage(self): - self.world.reparentTo(render) + self.world.reparentTo(base.render) base.playMusic(self.gameMusic, looping=1, volume=0.9) def offstage(self): diff --git a/toontown/minigame/TwoDBattleMgr.py b/toontown/minigame/TwoDBattleMgr.py index 7937237..db135a3 100644 --- a/toontown/minigame/TwoDBattleMgr.py +++ b/toontown/minigame/TwoDBattleMgr.py @@ -1,14 +1,29 @@ -from panda3d.core import * +from panda3d.core import CollisionHandlerEvent, CollisionNode, CollisionSphere, Point3, Point4, VBase3, Vec3 + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.interval.IntervalGlobal import ( + ActorInterval, + Func, + LerpPosInterval, + LerpScaleInterval, + Parallel, + Sequence, + Wait +) + from direct.showbase.DirectObject import DirectObject -from toontown.toonbase.ToonBaseGlobal import * -from direct.directnotify import DirectNotifyGlobal -from direct.interval.IntervalGlobal import * -from toontown.battle.BattleProps import * +from direct.showbase.MessengerGlobal import messenger + from toontown.battle import MovieUtil -import math +from toontown.battle.BattleProps import globalPropPool +from toontown.toonbase import ToontownGlobals +from toontown.toonbase.ToonBaseGlobal import base + +from math import sin + class TwoDBattleMgr(DirectObject): - notify = DirectNotifyGlobal.directNotify.newCategory('TwoDBattleMgr') + notify = directNotify.newCategory('TwoDBattleMgr') def __init__(self, game, toon): self.game = game @@ -26,7 +41,6 @@ class TwoDBattleMgr(DirectObject): self.setupPistol() if self.toon == base.localAvatar: self.createShootCollision() - return def destroy(self): if self.toon == base.localAvatar: @@ -34,18 +48,20 @@ class TwoDBattleMgr(DirectObject): self.waterBulletIval.finish() del self.waterBulletIval self.waterBulletIval = None + self.ignore('enter' + self.collSphereName) base.localAvatar.controlManager.currentControls.cTrav.removeCollider(self.waterBullet) self.waterBullet.removeNode() del self.waterBullet + self.hand_jointpath0.removeNode() MovieUtil.removeProp(self.pistol) if self.shootTrack != None: self.shootTrack.finish() self.shootTrack = None + self.game = None self.toon = None - return def start(self): pass @@ -67,6 +83,7 @@ class TwoDBattleMgr(DirectObject): if self.toon == base.localAvatar: self.shootTrack.append(Func(self.game.assetMgr.playWatergunSound)) self.shootTrack.append(self.getWaterBulletIval()) + self.shootTrack.start() return elif self.shootTrack.isStopped(): @@ -74,6 +91,7 @@ class TwoDBattleMgr(DirectObject): if self.toon == base.localAvatar: self.shootTrack.append(Func(self.game.assetMgr.playWatergunSound)) self.shootTrack.append(self.getWaterBulletIval()) + self.shootTrack.start() def createShootCollision(self): @@ -90,6 +108,7 @@ class TwoDBattleMgr(DirectObject): self.waterBullet.hide() if self.showCollSpheres: self.waterBullet.show() + bulletEvent = CollisionHandlerEvent() bulletEvent.addInPattern('enter%fn') bulletEvent.addOutPattern('exit%fn') @@ -108,22 +127,23 @@ class TwoDBattleMgr(DirectObject): else: toon.loop('neutral') - torso = self.toon.getPart('torso', '1000') toonTrack = Sequence(ActorInterval(self.toon, 'water-gun', startFrame=48, endFrame=58, partName='torso'), ActorInterval(self.toon, 'water-gun', startFrame=107, endFrame=126, playRate=2, partName='torso'), Func(returnToLastAnim, self.toon)) return toonTrack def calcSprayStartPos(self): if self.toon: self.toon.update(0) + joint = self.pistol.find('**/joint_nozzle') - p = joint.getPos(render) + p = joint.getPos(base.render) self.origin = p def calcSprayEndPos(self): if self.toon: - xDirection = -math.sin(self.toon.getH()) + xDirection = -sin(self.toon.getH()) else: - xDirection = -math.sin(-90) + xDirection = -sin(-90) + endPos = Point3(self.origin.getX() + self.SHOOT_DISTANCE * xDirection, self.origin.getY(), self.origin.getZ()) self.target = endPos @@ -131,7 +151,7 @@ class TwoDBattleMgr(DirectObject): dSprayScale = 0.15 dSprayHold = 0.035 color = self.WATER_SPRAY_COLOR - parent = render + parent = base.render horizScale = 1.0 vertScale = 1.0 @@ -161,12 +181,13 @@ class TwoDBattleMgr(DirectObject): sprayScale.removeNode() sprayProp = self.sprayProp - sprayScale = hidden.attachNewNode('spray-parent') - sprayRot = hidden.attachNewNode('spray-rotate') + sprayScale = base.hidden.attachNewNode('spray-parent') + sprayRot = base.hidden.attachNewNode('spray-rotate') spray = sprayRot spray.setColor(color) if color[3] < 1.0: spray.setTransparency(1) + track = Sequence(Wait(0.1), Func(self.calcSprayStartPos), Func(self.calcSprayEndPos), Func(showSpray, sprayScale, sprayRot, sprayProp, parent), LerpScaleInterval(sprayScale, dSprayScale, calcTargetScale, startScale=MovieUtil.PNT3_NEARZERO), Wait(dSprayHold), Func(prepareToShrinkSpray, spray, sprayProp), LerpScaleInterval(sprayScale, dSprayScale, MovieUtil.PNT3_NEARZERO), Func(hideSpray, spray, sprayScale, sprayRot, sprayProp, globalPropPool)) return track @@ -180,8 +201,8 @@ class TwoDBattleMgr(DirectObject): if self.waterBulletIval: self.waterBulletIval.finish() del self.waterBulletIval + self.waterBulletIval = None - return def getWaterBulletIval(self): if not self.waterBulletIval.isPlaying(): diff --git a/toontown/minigame/TwoDDrive.py b/toontown/minigame/TwoDDrive.py index 0fc34f1..1111f66 100644 --- a/toontown/minigame/TwoDDrive.py +++ b/toontown/minigame/TwoDDrive.py @@ -1,11 +1,19 @@ -from toontown.toonbase.ToonBaseGlobal import * +from panda3d.core import Point3, Vec3 + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.interval.IntervalGlobal import LerpHprInterval +from direct.showbase.MessengerGlobal import messenger +from direct.showbase.PythonUtil import fitSrcAngle2Dest +from direct.task.TaskManagerGlobal import taskMgr + from otp.otpbase import OTPGlobals -from direct.interval.IntervalGlobal import * -from . import ArrowKeys -from direct.task.Task import Task + +from toontown.minigame.ArrowKeys import ArrowKeys +from toontown.toonbase.ToonBaseGlobal import base + class TwoDDrive: - notify = DirectNotifyGlobal.directNotify.newCategory('TwoDDrive') + notify = directNotify.newCategory('TwoDDrive') TASK_NAME = 'TwoDDriveTask' SET_ATREST_HEADING_TASK = 'setAtRestHeadingTask' @@ -17,7 +25,7 @@ class TwoDDrive: self.priority = priority self.setHeading = setHeading self.upHeading = upHeading - self.arrowKeys = ArrowKeys.ArrowKeys() + self.arrowKeys = ArrowKeys() self.wasUpReleased = True self.lt = base.localAvatar base.localAvatar.useTwoDControls() @@ -25,7 +33,6 @@ class TwoDDrive: self.ONE_JUMP_PER_UP_PRESSED = True self.lastAction = None self.isMovingX = False - return def destroy(self): self.game = None @@ -35,7 +42,6 @@ class TwoDDrive: del self.arrowKeys del self.customCollisionCallback self.lastAction = None - return def start(self): self.notify.debug('start') @@ -47,6 +53,7 @@ class TwoDDrive: def __placeToonHOG(self, pos, h = None): if h == None: h = self.lt.getH() + self.lt.setPos(pos) self.lt.setH(h) self.lastPos = pos @@ -54,7 +61,6 @@ class TwoDDrive: self.oldAtRestHeading = h self.lastXVel = 0 self.lastYVel = 0 - return def stop(self): self.notify.debug('stop') @@ -64,7 +70,9 @@ class TwoDDrive: if hasattr(self, 'turnLocalToonIval'): if self.turnLocalToonIval.isPlaying(): self.turnLocalToonIval.pause() + del self.turnLocalToonIval + base.localAvatar.setSpeed(0, 0) base.localAvatar.stopSound() @@ -78,16 +86,19 @@ class TwoDDrive: elif self.arrowKeys.upPressed() and self.wasUpReleased: self.wasUpReleased = False if not self.game.isHeadInFloor: - if localAvatar.controlManager.currentControls == localAvatar.controlManager.get('twoD'): + if base.localAvatar.controlManager.currentControls == base.localAvatar.controlManager.get('twoD'): base.localAvatar.controlManager.currentControls.jumpPressed() elif self.arrowKeys.upPressed(): if not self.game.isHeadInFloor: - if localAvatar.controlManager.currentControls == localAvatar.controlManager.get('twoD'): + if base.localAvatar.controlManager.currentControls == base.localAvatar.controlManager.get('twoD'): base.localAvatar.controlManager.currentControls.jumpPressed() + if self.arrowKeys.leftPressed(): xVel -= 1 + if self.arrowKeys.rightPressed(): xVel += 1 + vel.setX(xVel) vel.setY(yVel) vel.normalize() @@ -99,6 +110,7 @@ class TwoDDrive: elif self.isMovingX: self.isMovingX = False messenger.send('avatarStoppedX') + speed = vel.length() action = self.lt.setSpeed(speed, 0) if action != self.lastAction: @@ -107,18 +119,21 @@ class TwoDDrive: base.localAvatar.runSound() else: base.localAvatar.stopSound() + if self.setHeading: self.__handleHeading(xVel, yVel) + toonPos = self.lt.getPos() - dt = globalClock.getDt() + dt = base.clock.getDt() posOffset = vel * dt if self.customCollisionCallback: toonPos = self.customCollisionCallback(toonPos, toonPos + posOffset) else: toonPos += posOffset + self.lt.setPos(toonPos) self.lastPos = toonPos - return Task.cont + return task.cont def __handleHeading(self, xVel, yVel): def getHeading(xVel, yVel): @@ -144,11 +159,13 @@ class TwoDDrive: if ((self.lastXVel and self.lastYVel) and not (xVel and yVel)): def setAtRestHeading(task, self = self, angle = curHeading): self.atRestHeading = angle - return Task.done + return task.done taskMgr.doMethodLater(0.05, setAtRestHeading, TwoDDrive.SET_ATREST_HEADING_TASK) else: self.atRestHeading = curHeading + orientToon(curHeading) + self.lastXVel = xVel self.lastYVel = yVel diff --git a/toontown/parties/DistributedPartyJukebox40Activity.py b/toontown/parties/DistributedPartyJukebox40Activity.py index 6358bed..8454aa2 100644 --- a/toontown/parties/DistributedPartyJukebox40Activity.py +++ b/toontown/parties/DistributedPartyJukebox40Activity.py @@ -9,7 +9,7 @@ class DistributedPartyJukebox40Activity(DistributedPartyJukeboxActivityBase): def load(self): DistributedPartyJukeboxActivityBase.load(self) - newTexture = loader.loadTexture('phase_13/maps/tt_t_ara_pty_jukeboxBlue.jpg', 'phase_13/maps/tt_t_ara_pty_jukeboxBlue_a.rgb') + newTexture = loader.loadTexture('phase_13/maps/tt_t_ara_pty_jukeboxBlue.png') case = self.jukebox.find('**/jukeboxGlass') if not case.isEmpty(): case.setTexture(newTexture, 1) diff --git a/toontown/parties/DistributedPartyValentineJukebox40Activity.py b/toontown/parties/DistributedPartyValentineJukebox40Activity.py index 7fc3f28..101db6b 100644 --- a/toontown/parties/DistributedPartyValentineJukebox40Activity.py +++ b/toontown/parties/DistributedPartyValentineJukebox40Activity.py @@ -9,7 +9,7 @@ class DistributedPartyValentineJukebox40Activity(DistributedPartyJukeboxActivity def load(self): DistributedPartyJukeboxActivityBase.load(self) - newTexture = loader.loadTexture('phase_13/maps/tt_t_ara_pty_jukeboxValentineB.jpg', 'phase_13/maps/tt_t_ara_pty_jukeboxValentineB_a.rgb') + newTexture = loader.loadTexture('phase_13/maps/tt_t_ara_pty_jukeboxValentineB.png') case = self.jukebox.find('**/jukeboxGlass') if not case.isEmpty(): case.setTexture(newTexture, 1) diff --git a/toontown/parties/DistributedPartyValentineJukeboxActivity.py b/toontown/parties/DistributedPartyValentineJukeboxActivity.py index f67cb5a..0b8f11d 100644 --- a/toontown/parties/DistributedPartyValentineJukeboxActivity.py +++ b/toontown/parties/DistributedPartyValentineJukeboxActivity.py @@ -9,7 +9,7 @@ class DistributedPartyValentineJukeboxActivity(DistributedPartyJukeboxActivityBa def load(self): DistributedPartyJukeboxActivityBase.load(self) - newTexture = loader.loadTexture('phase_13/maps/tt_t_ara_pty_jukeboxValentineA.jpg', 'phase_13/maps/tt_t_ara_pty_jukeboxValentineA_a.rgb') + newTexture = loader.loadTexture('phase_13/maps/tt_t_ara_pty_jukeboxValentineA.png') case = self.jukebox.find('**/jukeboxGlass') if not case.isEmpty(): case.setTexture(newTexture, 1) diff --git a/toontown/parties/DistributedPartyValentineTrampolineActivity.py b/toontown/parties/DistributedPartyValentineTrampolineActivity.py index a362d3c..bb665c2 100644 --- a/toontown/parties/DistributedPartyValentineTrampolineActivity.py +++ b/toontown/parties/DistributedPartyValentineTrampolineActivity.py @@ -3,4 +3,4 @@ from toontown.parties.DistributedPartyTrampolineActivity import DistributedParty class DistributedPartyValentineTrampolineActivity(DistributedPartyTrampolineActivity): def __init__(self, cr, doJellyBeans = True, doTricks = False, texture = None): - DistributedPartyTrampolineActivity.__init__(self, cr, doJellyBeans, doTricks, 'phase_13/maps/tt_t_ara_pty_trampolineValentine.jpg') + DistributedPartyTrampolineActivity.__init__(self, cr, doJellyBeans, doTricks, 'phase_13/maps/tt_t_ara_pty_trampolineValentine.png') diff --git a/toontown/parties/DistributedPartyVictoryTrampolineActivity.py b/toontown/parties/DistributedPartyVictoryTrampolineActivity.py index 99d156b..3659fc1 100644 --- a/toontown/parties/DistributedPartyVictoryTrampolineActivity.py +++ b/toontown/parties/DistributedPartyVictoryTrampolineActivity.py @@ -3,4 +3,4 @@ from toontown.parties.DistributedPartyTrampolineActivity import DistributedParty class DistributedPartyVictoryTrampolineActivity(DistributedPartyTrampolineActivity): def __init__(self, cr, doJellyBeans = True, doTricks = False, texture = None): - DistributedPartyTrampolineActivity.__init__(self, cr, doJellyBeans, doTricks, 'phase_13/maps/tt_t_ara_pty_trampolineVictory.jpg') + DistributedPartyTrampolineActivity.__init__(self, cr, doJellyBeans, doTricks, 'phase_13/maps/tt_t_ara_pty_trampolineVictory.png') diff --git a/toontown/parties/DistributedPartyWinterTrampolineActivity.py b/toontown/parties/DistributedPartyWinterTrampolineActivity.py index a0dcbfd..3db46be 100644 --- a/toontown/parties/DistributedPartyWinterTrampolineActivity.py +++ b/toontown/parties/DistributedPartyWinterTrampolineActivity.py @@ -3,4 +3,4 @@ from toontown.parties.DistributedPartyTrampolineActivity import DistributedParty class DistributedPartyWinterTrampolineActivity(DistributedPartyTrampolineActivity): def __init__(self, cr, doJellyBeans = True, doTricks = False, texture = None): - DistributedPartyTrampolineActivity.__init__(self, cr, doJellyBeans, doTricks, 'phase_13/maps/tt_t_ara_pty_trampolineWinter.jpg') + DistributedPartyTrampolineActivity.__init__(self, cr, doJellyBeans, doTricks, 'phase_13/maps/tt_t_ara_pty_trampolineWinter.png') diff --git a/toontown/parties/PartyCogActivity.py b/toontown/parties/PartyCogActivity.py index d8c9b9b..7bf5659 100644 --- a/toontown/parties/PartyCogActivity.py +++ b/toontown/parties/PartyCogActivity.py @@ -97,8 +97,7 @@ class PartyCogActivity(DirectObject): signLocator = self.arena.find('**/eventSign_locator') self.activity.sign.setPos(signLocator.getPos(self.root)) if self.texture: - textureAlpha = self.texture[:-4] + '_a.rgb' - reskinTexture = loader.loadTexture(self.texture, textureAlpha) + reskinTexture = loader.loadTexture(self.texture) self.arena.find('**/center_grp').setTexture(reskinTexture, 100) self.arena.find('**/leftSide_grp').setTexture(reskinTexture, 100) self.arena.find('**/rightSide_grp').setTexture(reskinTexture, 100) diff --git a/toontown/pets/Pet.py b/toontown/pets/Pet.py index 241f5f0..b23e1a6 100644 --- a/toontown/pets/Pet.py +++ b/toontown/pets/Pet.py @@ -247,11 +247,11 @@ class Pet(Avatar.Avatar): self.rightHighlight.hide() self.leftHighlight.hide() if self.style[8]: - self.eyesOpenTexture = loader.loadTexture('phase_4/maps/BeanEyeBoys2.jpg', 'phase_4/maps/BeanEyeBoys2_a.rgb') - self.eyesClosedTexture = loader.loadTexture('phase_4/maps/BeanEyeBoysBlink.jpg', 'phase_4/maps/BeanEyeBoysBlink_a.rgb') + self.eyesOpenTexture = loader.loadTexture('phase_4/maps/BeanEyeBoys2.png') + self.eyesClosedTexture = loader.loadTexture('phase_4/maps/BeanEyeBoysBlink.png') else: - self.eyesOpenTexture = loader.loadTexture('phase_4/maps/BeanEyeGirlsNew.jpg', 'phase_4/maps/BeanEyeGirlsNew_a.rgb') - self.eyesClosedTexture = loader.loadTexture('phase_4/maps/BeanEyeGirlsBlinkNew.jpg', 'phase_4/maps/BeanEyeGirlsBlinkNew_a.rgb') + self.eyesOpenTexture = loader.loadTexture('phase_4/maps/BeanEyeGirlsNew.png') + self.eyesClosedTexture = loader.loadTexture('phase_4/maps/BeanEyeGirlsBlinkNew.png') self.eyesOpenTexture.setMinfilter(Texture.FTLinear) self.eyesOpenTexture.setMagfilter(Texture.FTLinear) self.eyesClosedTexture.setMinfilter(Texture.FTLinear) diff --git a/toontown/pets/PetDNA.py b/toontown/pets/PetDNA.py index a0b4b09..03b0b40 100644 --- a/toontown/pets/PetDNA.py +++ b/toontown/pets/PetDNA.py @@ -21,13 +21,13 @@ EarParts = ['horns', EarTextures = {'horns': None, 'antennae': None, 'dogEars': None, - 'catEars': 'phase_4/maps/BeanCatEar6.jpg', - 'rabbitEars': 'phase_4/maps/BeanBunnyEar6.jpg'} + 'catEars': 'phase_4/maps/BeanCatEar6.png', + 'rabbitEars': 'phase_4/maps/BeanBunnyEar6.png'} ExoticEarTextures = {'horns': None, 'antennae': None, 'dogEars': None, - 'catEars': 'phase_4/maps/BeanCatEar3Yellow.jpg', - 'rabbitEars': 'phase_4/maps/BeanBunnyEar6.jpg'} + 'catEars': 'phase_4/maps/BeanCatEar3Yellow.png', + 'rabbitEars': 'phase_4/maps/BeanBunnyEar6.png'} NoseParts = ['clownNose', 'dogNose', 'ovalNose', @@ -36,12 +36,12 @@ TailParts = ['catTail', 'longTail', 'birdTail', 'bunnyTail'] -TailTextures = {'catTail': 'phase_4/maps/beanCatTail6.jpg', - 'longTail': 'phase_4/maps/BeanLongTail6.jpg', +TailTextures = {'catTail': 'phase_4/maps/beanCatTail6.png', + 'longTail': 'phase_4/maps/BeanLongTail6.png', 'birdTail': None, 'bunnyTail': None} -GiraffeTail = 'phase_4/maps/BeanLongTailGiraffe.jpg' -LeopardTail = 'phase_4/maps/BeanLongTailLepord.jpg' +GiraffeTail = 'phase_4/maps/BeanLongTailGiraffe.png' +LeopardTail = 'phase_4/maps/BeanLongTailLepord.png' GenericBodies = ['dots', 'threeStripe', 'tigerStripe', @@ -85,17 +85,17 @@ PetRarities = {'body': {ToontownGlobals.ToontownCentral: {'threeStripe': 50, 'turtle': 25, 'giraffe': 20, 'leopard': 10}}} -BodyTextures = {'dots': 'phase_4/maps/BeanbodyDots6.jpg', - 'threeStripe': 'phase_4/maps/Beanbody3stripes6.jpg', - 'tigerStripe': 'phase_4/maps/BeanbodyZebraStripes6.jpg', - 'turtle': 'phase_4/maps/BeanbodyTurtle.jpg', - 'giraffe': 'phase_4/maps/BeanbodyGiraffe1.jpg', - 'leopard': 'phase_4/maps/BeanbodyLepord2.jpg', - 'tummy': 'phase_4/maps/BeanbodyTummy6.jpg'} -FeetTextures = {'normal': 'phase_4/maps/BeanFoot6.jpg', - 'turtle': 'phase_4/maps/BeanFootTurttle.jpg', - 'giraffe': 'phase_4/maps/BeanFootYellow3.jpg', - 'leopard': 'phase_4/maps/BeanFootYellow3.jpg'} +BodyTextures = {'dots': 'phase_4/maps/BeanbodyDots6.png', + 'threeStripe': 'phase_4/maps/Beanbody3stripes6.png', + 'tigerStripe': 'phase_4/maps/BeanbodyZebraStripes6.png', + 'turtle': 'phase_4/maps/BeanbodyTurtle.png', + 'giraffe': 'phase_4/maps/BeanbodyGiraffe1.png', + 'leopard': 'phase_4/maps/BeanbodyLepord2.png', + 'tummy': 'phase_4/maps/BeanbodyTummy6.png'} +FeetTextures = {'normal': 'phase_4/maps/BeanFoot6.png', + 'turtle': 'phase_4/maps/BeanFootTurttle.png', + 'giraffe': 'phase_4/maps/BeanFootYellow3.png', + 'leopard': 'phase_4/maps/BeanFootYellow3.png'} AllPetColors = (VBase4(1.0, 1.0, 1.0, 1.0), VBase4(0.96875, 0.691406, 0.699219, 1.0), VBase4(0.933594, 0.265625, 0.28125, 1.0), diff --git a/toontown/racing/DistributedLeaderBoard.py b/toontown/racing/DistributedLeaderBoard.py index ee8b1af..ccf3fe3 100644 --- a/toontown/racing/DistributedLeaderBoard.py +++ b/toontown/racing/DistributedLeaderBoard.py @@ -1,39 +1,39 @@ -from direct.distributed import DistributedObject -from direct.directnotify import DirectNotifyGlobal -from otp.otpbase import OTPTimer +from panda3d.core import NodePath, TextNode + +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.distributed.DistributedObject import DistributedObject + +from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer -from toontown.racing import KartShopGlobals -from toontown.toonbase.ToonBaseGlobal import * -from panda3d.core import * -from toontown.toonbase.ToontownGlobals import * -import random +from toontown.toonbase.ToonBaseGlobal import base + import pickle -class DistributedLeaderBoard(DistributedObject.DistributedObject): - notify = DirectNotifyGlobal.directNotify.newCategory('DisributedLeaderBoard') + +class DistributedLeaderBoard(DistributedObject): + notify = directNotify.newCategory('DisributedLeaderBoard') def __init__(self, cr): self.notify.debug('__init__: initialization of local leaderboard') - DistributedObject.DistributedObject.__init__(self, cr) + DistributedObject.__init__(self, cr) self.corner = 0 self.length = 0 self.width = 0 self.updateCount = 0 self.board = None self.surface = None - return def generateInit(self): - DistributedObject.DistributedObject.generateInit(self) + DistributedObject.generateInit(self) self.board = NodePath(self.uniqueName('LeaderBoard')) def generate(self): - DistributedObject.DistributedObject.generate(self) + DistributedObject.generate(self) self.buildListParts() def announceGenerate(self): - DistributedObject.DistributedObject.announceGenerate(self) - self.board.reparentTo(render) + DistributedObject.announceGenerate(self) + self.board.reparentTo(base.render) self.accept('decorator-holiday-%d-ending' % ToontownGlobals.CRASHED_LEADERBOARD, self.showLists) self.accept('decorator-holiday-%d-starting' % ToontownGlobals.CRASHED_LEADERBOARD, self.hideLists) newsManager = base.cr.newsManager @@ -72,7 +72,7 @@ class DistributedLeaderBoard(DistributedObject.DistributedObject): z = zListTop self.nameTextNodes = [] self.timeTextNodes = [] - for i in range(10): + for _ in range(10): row, nameText, timeText, placeText = self.buildLeaderRow() self.nameTextNodes.append(nameText) placeText.setText(str(len(self.nameTextNodes)) + '.') @@ -81,6 +81,7 @@ class DistributedLeaderBoard(DistributedObject.DistributedObject): if len(self.nameTextNodes) == 6: z = zListTop x = 0.35 + row.setX(x) row.setZ(z) row.setY(1.6) @@ -105,7 +106,7 @@ class DistributedLeaderBoard(DistributedObject.DistributedObject): self.timeTextNodes[i].setText('%02d:%02d:%02d' % (min, sec, hundredths * 100)) def buildTitleRow(self): - row = hidden.attachNewNode('TitleRow') + row = base.hidden.attachNewNode('TitleRow') nameText = TextNode('titleRow') nameText.setFont(ToontownGlobals.getSignFont()) nameText.setAlign(TextNode.ACenter) @@ -117,7 +118,7 @@ class DistributedLeaderBoard(DistributedObject.DistributedObject): return (row, nameText) def buildTrackRow(self): - row = hidden.attachNewNode('trackRow') + row = base.hidden.attachNewNode('trackRow') nameText = TextNode('trackRow') nameText.setFont(ToontownGlobals.getSignFont()) nameText.setAlign(TextNode.ACenter) @@ -129,7 +130,7 @@ class DistributedLeaderBoard(DistributedObject.DistributedObject): return (row, nameText) def buildLeaderRow(self): - row = hidden.attachNewNode('leaderRow') + row = base.hidden.attachNewNode('leaderRow') nameText = TextNode('nameText') nameText.setFont(ToontownGlobals.getToonFont()) nameText.setAlign(TextNode.ALeft) @@ -166,4 +167,4 @@ class DistributedLeaderBoard(DistributedObject.DistributedObject): self.notify.debug('delete: deleting local leaderboard') self.ignoreAll() self.board.removeNode() - DistributedObject.DistributedObject.delete(self) + DistributedObject.delete(self) diff --git a/toontown/racing/DistributedRace.py b/toontown/racing/DistributedRace.py index c065083..d96cf0d 100644 --- a/toontown/racing/DistributedRace.py +++ b/toontown/racing/DistributedRace.py @@ -41,7 +41,7 @@ class DistributedRace(DistributedObject.DistributedObject): def __init__(self, cr): self.qbox = loader.loadModel('phase_6/models/karting/qbox') - self.boostArrowTexture = loader.loadTexture('phase_6/maps/boost_arrow.jpg', 'phase_6/maps/boost_arrow_a.rgb') + self.boostArrowTexture = loader.loadTexture('phase_6/maps/boost_arrow.png') self.boostArrowTexture.setMinfilter(Texture.FTLinear) DistributedObject.DistributedObject.__init__(self, cr) self.kartMap = {} diff --git a/toontown/racing/Kart.py b/toontown/racing/Kart.py index fd19504..acea62b 100644 --- a/toontown/racing/Kart.py +++ b/toontown/racing/Kart.py @@ -1,7 +1,7 @@ from direct.directnotify import DirectNotifyGlobal from panda3d.core import * +from panda3d.physics import * from direct.gui.DirectGui import * -from panda3d.core import * from direct.interval.IntervalGlobal import * from otp.avatar import ShadowCaster from toontown.racing.KartDNA import * @@ -315,7 +315,7 @@ class Kart(NodePath, ShadowCaster.ShadowCaster): rimTexPath = getAccessory(getDefaultRim()) else: rimTexPath = getAccessory(self.kartDNA[KartDNA.rimsType]) - rimTex = loader.loadTexture('%s.jpg' % rimTexPath, '%s_a.rgb' % rimTexPath) + rimTex = loader.loadTexture('%s.png' % rimTexPath) for kart in self.geom: leftFrontWheelRim = self.geom[kart].find('**/leftFrontWheelRim') rightFrontWheelRim = self.geom[kart].find('**/rightFrontWheelRim') @@ -397,8 +397,8 @@ class Kart(NodePath, ShadowCaster.ShadowCaster): if self.kartDNA[KartDNA.decalType] != InvalidEntry: decalId = getAccessory(self.kartDNA[KartDNA.decalType]) kartDecal = getDecalId(self.kartDNA[KartDNA.bodyType]) - hoodDecalTex = loader.loadTexture('phase_6/maps/%s_HoodDecal_%s.jpg' % (kartDecal, decalId), 'phase_6/maps/%s_HoodDecal_%s_a.rgb' % (kartDecal, decalId)) - sideDecalTex = loader.loadTexture('phase_6/maps/%s_SideDecal_%s.jpg' % (kartDecal, decalId), 'phase_6/maps/%s_SideDecal_%s_a.rgb' % (kartDecal, decalId)) + hoodDecalTex = loader.loadTexture('phase_6/maps/%s_HoodDecal_%s.png' % (kartDecal, decalId)) + sideDecalTex = loader.loadTexture('phase_6/maps/%s_SideDecal_%s.png' % (kartDecal, decalId)) hoodDecalTex.setMinfilter(Texture.FTLinearMipmapLinear) sideDecalTex.setMinfilter(Texture.FTLinearMipmapLinear) for kart in self.geom: diff --git a/toontown/racing/KartShopGui.py b/toontown/racing/KartShopGui.py index 547c903..c9c31d2 100644 --- a/toontown/racing/KartShopGui.py +++ b/toontown/racing/KartShopGui.py @@ -688,15 +688,15 @@ class KartShopGuiMgr(DirectObject.DirectObject, object): KartDNA.fwwType, KartDNA.bwwType]: texNodePath = getTexCardNode(accID) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath, 'phase_6/maps/%s_a.rgb' % texNodePath) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath) elif accType == KartDNA.rimsType: if accID == InvalidEntry: texNodePath = getTexCardNode(getDefaultRim()) else: texNodePath = getTexCardNode(accID) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath, 'phase_6/maps/%s_a.rgb' % texNodePath) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath) elif accType in [KartDNA.bodyColor, KartDNA.accColor]: - tex = loader.loadTexture('phase_6/maps/Kartmenu_paintbucket.jpg', 'phase_6/maps/Kartmenu_paintbucket_a.rgb') + tex = loader.loadTexture('phase_6/maps/Kartmenu_paintbucket.png') if accID == InvalidEntry: self.kartView.component('geom0').setColorScale(getDefaultColor()) else: @@ -704,9 +704,9 @@ class KartShopGuiMgr(DirectObject.DirectObject, object): elif accType == KartDNA.decalType: kartDecal = getDecalId(base.localAvatar.getKartBodyType()) texNodePath = getTexCardNode(accID) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath % kartDecal, 'phase_6/maps/%s_a.rgb' % texNodePath % kartDecal) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath % kartDecal) else: - tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.jpg', 'phase_6/maps/NoAccessoryIcon3_a.rgb') + tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.png') tex.setMinfilter(Texture.FTLinearMipmapLinear) self.kartView.component('geom0').setTexture(tex, 1) self.initialize = True @@ -748,15 +748,15 @@ class KartShopGuiMgr(DirectObject.DirectObject, object): KartDNA.fwwType, KartDNA.bwwType]: texNodePath = getTexCardNode(accID) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath, 'phase_6/maps/%s_a.rgb' % texNodePath) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath) elif accType == KartDNA.rimsType: if accID == InvalidEntry: texNodePath = getTexCardNode(getDefaultRim()) else: texNodePath = getTexCardNode(accID) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath, 'phase_6/maps/%s_a.rgb' % texNodePath) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath) elif accType in [KartDNA.bodyColor, KartDNA.accColor]: - tex = loader.loadTexture('phase_6/maps/Kartmenu_paintbucket.jpg', 'phase_6/maps/Kartmenu_paintbucket_a.rgb') + tex = loader.loadTexture('phase_6/maps/Kartmenu_paintbucket.png') if accID == InvalidEntry: self.kartView.component('geom0').setColorScale(getDefaultColor()) else: @@ -764,9 +764,9 @@ class KartShopGuiMgr(DirectObject.DirectObject, object): elif accType == KartDNA.decalType: kartDecal = getDecalId(base.localAvatar.getKartBodyType()) texNodePath = getTexCardNode(accID) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath % kartDecal, 'phase_6/maps/%s_a.rgb' % texNodePath % kartDecal) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath % kartDecal) else: - tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.jpg', 'phase_6/maps/NoAccessoryIcon3_a.rgb') + tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.png') tex.setMinfilter(Texture.FTLinearMipmapLinear) self.kartView.component('geom0').setTexture(tex, 1) self.initialize = True diff --git a/toontown/safezone/Playground.py b/toontown/safezone/Playground.py index 2a7a18e..5484176 100644 --- a/toontown/safezone/Playground.py +++ b/toontown/safezone/Playground.py @@ -1,41 +1,45 @@ -from direct.interval.IntervalGlobal import * -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -from direct.directnotify import DirectNotifyGlobal -from toontown.hood import Place -from direct.showbase import DirectObject -from direct.fsm import StateData -from direct.fsm import ClassicFSM, State -from direct.fsm import State -from direct.task import Task -from toontown.toon import DeathForceAcknowledge -from toontown.toon import HealthForceAcknowledge -from toontown.tutorial import TutorialForceAcknowledge -from toontown.toon import NPCForceAcknowledge -from toontown.trolley import Trolley -from toontown.toontowngui import TTDialog -from toontown.toonbase import ToontownGlobals -from toontown.toon.Toon import teleportDebug -from toontown.toonbase import TTLocalizer -from direct.gui import DirectLabel -from otp.distributed.TelemetryLimiter import RotationLimitToH, TLGatherAllAvs -from toontown.quest import Quests +from panda3d.core import LineSegs, NodePath, TextNode, Vec4 +from panda3d.otp import NametagGlobals -class Playground(Place.Place): - notify = DirectNotifyGlobal.directNotify.newCategory('Playground') +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.fsm.ClassicFSM import ClassicFSM +from direct.fsm.State import State +from direct.gui.DirectLabel import DirectLabel +from direct.interval.IntervalGlobal import Func, LerpColorScaleInterval, Sequence +from direct.showbase.MessengerGlobal import messenger + +from otp.distributed.TelemetryLimiter import RotationLimitToH, TLGatherAllAvs + +from toontown.classicchars import CCharPaths +from toontown.hood.Place import Place +from toontown.quest import Quests +from toontown.toon.DeathForceAcknowledge import DeathForceAcknowledge +from toontown.toon.HealthForceAcknowledge import HealthForceAcknowledge +from toontown.toon.NPCForceAcknowledge import NPCForceAcknowledge +from toontown.toon.Toon import teleportDebug +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase.ToonBaseGlobal import base +from toontown.toontowngui import TTDialog +from toontown.trolley.Trolley import Trolley +from toontown.tutorial.TutorialForceAcknowledge import TutorialForceAcknowledge + + +class Playground(Place): + notify = directNotify.newCategory('Playground') def __init__(self, loader, parentFSM, doneEvent): - Place.Place.__init__(self, loader, doneEvent) + Place.__init__(self, loader, doneEvent) self.tfaDoneEvent = 'tfaDoneEvent' - self.fsm = ClassicFSM.ClassicFSM('Playground', [ - State.State('start', + self.fsm = ClassicFSM('Playground', [ + State('start', self.enterStart, self.exitStart, [ 'walk', 'deathAck', 'doorIn', 'tunnelIn']), - State.State('walk', + State('walk', self.enterWalk, self.exitWalk, [ 'drive', @@ -52,7 +56,7 @@ class Playground(Place.Place): 'purchase', 'stopped', 'fishing']), - State.State('stickerBook', + State('stickerBook', self.enterStickerBook, self.exitStickerBook, [ 'walk', @@ -66,124 +70,124 @@ class Playground(Place.Place): 'stopped', 'fishing', 'trialerFA']), - State.State('sit', + State('sit', self.enterSit, self.exitSit, [ 'walk', 'DFA', 'trialerFA']), - State.State('drive', + State('drive', self.enterDrive, self.exitDrive, [ 'walk', 'DFA', 'trialerFA']), - State.State('trolley', + State('trolley', self.enterTrolley, self.exitTrolley, [ 'walk']), - State.State('doorIn', + State('doorIn', self.enterDoorIn, self.exitDoorIn, [ 'walk']), - State.State('doorOut', + State('doorOut', self.enterDoorOut, self.exitDoorOut, [ 'walk']), - State.State('TFA', + State('TFA', self.enterTFA, self.exitTFA, [ 'TFAReject', 'DFA']), - State.State('TFAReject', + State('TFAReject', self.enterTFAReject, self.exitTFAReject, [ 'walk']), - State.State('trialerFA', + State('trialerFA', self.enterTrialerFA, self.exitTrialerFA, [ 'trialerFAReject', 'DFA']), - State.State('trialerFAReject', + State('trialerFAReject', self.enterTrialerFAReject, self.exitTrialerFAReject, [ 'walk']), - State.State('DFA', + State('DFA', self.enterDFA, self.exitDFA, [ 'DFAReject', 'NPCFA', 'HFA']), - State.State('DFAReject', + State('DFAReject', self.enterDFAReject, self.exitDFAReject, [ 'walk']), - State.State('NPCFA', + State('NPCFA', self.enterNPCFA, self.exitNPCFA, [ 'NPCFAReject', 'HFA']), - State.State('NPCFAReject', + State('NPCFAReject', self.enterNPCFAReject, self.exitNPCFAReject, [ 'walk']), - State.State('HFA', + State('HFA', self.enterHFA, self.exitHFA, [ 'HFAReject', 'teleportOut', 'tunnelOut']), - State.State('HFAReject', + State('HFAReject', self.enterHFAReject, self.exitHFAReject, [ 'walk']), - State.State('deathAck', + State('deathAck', self.enterDeathAck, self.exitDeathAck, [ 'teleportIn']), - State.State('teleportIn', + State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, [ 'walk', 'popup']), - State.State('popup', + State('popup', self.enterPopup, self.exitPopup, [ 'walk']), - State.State('teleportOut', + State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, [ 'deathAck', 'teleportIn']), - State.State('died', + State('died', self.enterDied, self.exitDied, [ 'final']), - State.State('tunnelIn', + State('tunnelIn', self.enterTunnelIn, self.exitTunnelIn, [ 'walk']), - State.State('tunnelOut', + State('tunnelOut', self.enterTunnelOut, self.exitTunnelOut, [ 'final']), - State.State('quest', + State('quest', self.enterQuest, self.exitQuest, [ 'walk']), - State.State('purchase', + State('purchase', self.enterPurchase, self.exitPurchase, [ 'walk']), - State.State('stopped', + State('stopped', self.enterStopped, self.exitStopped, [ 'walk']), - State.State('fishing', + State('fishing', self.enterFishing, self.exitFishing, [ 'walk']), - State.State('final', + State('final', self.enterFinal, self.exitFinal, [ 'start'])], @@ -195,7 +199,6 @@ class Playground(Place.Place): self.npcfaDoneEvent = 'npcfaDoneEvent' self.dialog = None self.deathAckBox = None - return def enter(self, requestStatus): self.fsm.enterInitialState() @@ -203,7 +206,7 @@ class Playground(Place.Place): self.accept('doorDoneEvent', self.handleDoorDoneEvent) self.accept('DistributedDoor_doorTrigger', self.handleDoorTrigger) base.playMusic(self.loader.music, looping=1, volume=0.8) - self.loader.geom.reparentTo(render) + self.loader.geom.reparentTo(base.render) for i in self.loader.nodeList: self.loader.enterAnimatedProps(i) @@ -231,12 +234,14 @@ class Playground(Place.Place): self.loader.hood.startSky() lightsOn = LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() + NametagGlobals.setMasterArrowsOn(1) self.zoneId = requestStatus['zoneId'] self.tunnelOriginList = base.cr.hoodMgr.addLinkTunnelHooks(self, self.loader.nodeList, self.zoneId) how = requestStatus['how'] if how == 'teleportIn': how = 'deathAck' + self.fsm.request(how, [requestStatus]) def exit(self): @@ -248,13 +253,12 @@ class Playground(Place.Place): node.removeNode() del self.tunnelOriginList - self.loader.geom.reparentTo(hidden) + self.loader.geom.reparentTo(base.hidden) def __lightDecorationOff__(): for light in self.loader.hood.halloweenLights: - light.reparentTo(hidden) + light.reparentTo(base.hidden) - newsManager = base.cr.newsManager NametagGlobals.setMasterArrowsOn(0) for i in self.loader.nodeList: self.loader.exitAnimatedProps(i) @@ -263,7 +267,7 @@ class Playground(Place.Place): self.loader.music.stop() def load(self): - Place.Place.load(self) + Place.load(self) self.parentFSM.getStateNamed('playground').addChild(self.fsm) def unload(self): @@ -273,13 +277,14 @@ class Playground(Place.Place): if self.dialog: self.dialog.cleanup() self.dialog = None + if self.deathAckBox: self.deathAckBox.cleanup() self.deathAckBox = None + TTDialog.cleanupDialog('globalDialog') self.ignoreAll() - Place.Place.unload(self) - return + Place.unload(self) def showTreasurePoints(self, points): self.hideDebugPointText() @@ -303,7 +308,6 @@ class Playground(Place.Place): self.hideDebugPointText() lines = LineSegs() lines.setColor(1, 0, 0, 1) - from toontown.classicchars import CCharPaths for name, pointDef in list(paths.items()): self.showDebugPointText(name, pointDef[0]) for connectTo in pointDef[1]: @@ -333,6 +337,7 @@ class Playground(Place.Place): self.debugTextNode.setTextColor(1, 0, 0, 1) self.debugTextNode.setAlign(TextNode.ACenter) self.debugTextNode.setFont(ToontownGlobals.getSignFont()) + self.debugTextNode.setText(text) np = self.debugText.attachNewNode(self.debugTextNode.generate()) np.setPos(point[0], point[1], point[2]) @@ -344,7 +349,7 @@ class Playground(Place.Place): base.localAvatar.b_setAnimState('off', 1) base.localAvatar.cantLeaveGame = 1 self.accept(self.trolleyDoneEvent, self.handleTrolleyDone) - self.trolley = Trolley.Trolley(self, self.fsm, self.trolleyDoneEvent) + self.trolley = Trolley(self, self.fsm, self.trolleyDoneEvent) self.trolley.load() self.trolley.enter() @@ -376,7 +381,6 @@ class Playground(Place.Place): messenger.send(self.doneEvent) else: self.notify.error('Unknown mode: ' + mode + ' in handleTrolleyDone') - return def debugStartMinigame(self, zoneId, minigameId): self.doneStatus = {'loader': 'minigame', @@ -386,7 +390,6 @@ class Playground(Place.Place): 'shardId': None, 'minigameId': minigameId} messenger.send(self.doneEvent) - return def enterTFACallback(self, requestStatus, doneStatus): self.tfa.exit() @@ -412,7 +415,7 @@ class Playground(Place.Place): def enterHFA(self, requestStatus): self.acceptOnce(self.hfaDoneEvent, self.enterHFACallback, [requestStatus]) - self.hfa = HealthForceAcknowledge.HealthForceAcknowledge(self.hfaDoneEvent) + self.hfa = HealthForceAcknowledge(self.hfaDoneEvent) self.hfa.enter(1) def exitHFA(self): @@ -428,6 +431,7 @@ class Playground(Place.Place): outHow = {'teleportIn': 'teleportOut', 'tunnelIn': 'tunnelOut', 'doorIn': 'doorOut'} + self.fsm.request(outHow[requestStatus['how']], [requestStatus]) elif doneStatus['mode'] == 'incomplete': self.fsm.request('HFAReject') @@ -442,7 +446,7 @@ class Playground(Place.Place): def enterNPCFA(self, requestStatus): self.acceptOnce(self.npcfaDoneEvent, self.enterNPCFACallback, [requestStatus]) - self.npcfa = NPCForceAcknowledge.NPCForceAcknowledge(self.npcfaDoneEvent) + self.npcfa = NPCForceAcknowledge(self.npcfaDoneEvent) self.npcfa.enter() def exitNPCFA(self): @@ -469,20 +473,18 @@ class Playground(Place.Place): self.ignore('deathAck') self.deathAckBox.cleanup() self.deathAckBox = None - Place.Place.enterWalk(self, teleportIn) - return + + Place.enterWalk(self, teleportIn) def enterDeathAck(self, requestStatus): self.deathAckBox = None self.fsm.request('teleportIn', [requestStatus]) - return def exitDeathAck(self): if self.deathAckBox: self.ignore('deathAck') self.deathAckBox.cleanup() self.deathAckBox = None - return def enterTeleportIn(self, requestStatus): imgScale = 0.25 @@ -492,10 +494,10 @@ class Playground(Place.Place): requestStatus['nextState'] = 'popup' x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId(self.loader.hood.id) self.accept('deathAck', self.__handleDeathAck, extraArgs=[requestStatus]) - self.deathAckBox = DeathForceAcknowledge.DeathForceAcknowledge(doneEvent='deathAck') + self.deathAckBox = DeathForceAcknowledge(doneEvent='deathAck') elif base.localAvatar.hp > 0 and (Quests.avatarHasTrolleyQuest(base.localAvatar) or Quests.avatarHasFirstCogQuest(base.localAvatar) or Quests.avatarHasFriendQuest(base.localAvatar) or Quests.avatarHasPhoneQuest(base.localAvatar) and Quests.avatarHasCompletedPhoneQuest(base.localAvatar)) and self.loader.hood.id == ToontownGlobals.ToontownCentral: requestStatus['nextState'] = 'popup' - imageModel = loader.loadModel('phase_4/models/gui/tfa_images') + imageModel = base.loader.loadModel('phase_4/models/gui/tfa_images') if base.localAvatar.quests[0][0] == Quests.TROLLEY_QUEST_ID: if not Quests.avatarHasCompletedTrolleyQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint(base.cr.hoodMgr.ToontownCentralInitialDropPoints) @@ -526,7 +528,7 @@ class Playground(Place.Place): if not Quests.avatarHasCompletedFriendQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint(base.cr.hoodMgr.ToontownCentralInitialDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage7 - gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui') + gui = base.loader.loadModel('phase_3.5/models/gui/friendslist_gui') imgNodePath = gui.find('**/FriendsBox_Closed') imgPos = (0, 0, 0.04) imgScale = 1.0 @@ -544,38 +546,40 @@ class Playground(Place.Place): imgNodePath = imageModel.find('**/hq-dialog-image') imgPos = (0, 0, 0.05) imgScale = 0.5 + self.dialog = TTDialog.TTDialog(text=msg, command=self.__cleanupDialog, style=TTDialog.Acknowledge) - imgLabel = DirectLabel.DirectLabel(parent=self.dialog, relief=None, pos=imgPos, scale=TTLocalizer.PimgLabel, image=imgNodePath, image_scale=imgScale) + imgLabel = DirectLabel(parent=self.dialog, relief=None, pos=imgPos, scale=TTLocalizer.PimgLabel, image=imgNodePath, image_scale=imgScale) imageModel.removeNode() else: requestStatus['nextState'] = 'walk' x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId(self.loader.hood.id) + base.localAvatar.detachNode() - base.localAvatar.setPosHpr(render, x, y, z, h, p, r) - Place.Place.enterTeleportIn(self, requestStatus) - return + base.localAvatar.setPosHpr(base.render, x, y, z, h, p, r) + Place.enterTeleportIn(self, requestStatus) def __cleanupDialog(self, value): if self.dialog: self.dialog.cleanup() self.dialog = None + if hasattr(self, 'fsm'): self.fsm.request('walk', [1]) - return def __handleDeathAck(self, requestStatus): if self.deathAckBox: self.ignore('deathAck') self.deathAckBox.cleanup() self.deathAckBox = None + self.fsm.request('walk', [1]) - return def enterPopup(self, teleportIn = 0): if base.localAvatar.hp < 1: base.localAvatar.b_setAnimState('Sad', 1) else: base.localAvatar.b_setAnimState('neutral', 1.0) + self.accept('teleportQuery', self.handleTeleportQuery) base.localAvatar.setTeleportAvailable(1) base.localAvatar.startSleepWatch(self.__handleFallingAsleepPopup) @@ -589,18 +593,19 @@ class Playground(Place.Place): if hasattr(self, 'fsm'): self.fsm.request('walk') base.localAvatar.forceGotoSleep() - return Task.done + + return task.done def enterTeleportOut(self, requestStatus): - Place.Place.enterTeleportOut(self, requestStatus, self.__teleportOutDone) + Place.enterTeleportOut(self, requestStatus, self.__teleportOutDone) def __teleportOutDone(self, requestStatus): teleportDebug(requestStatus, 'Playground.__teleportOutDone(%s)' % (requestStatus,)) if hasattr(self, 'activityFsm'): self.activityFsm.requestFinalState() + hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] - avId = requestStatus['avId'] shardId = requestStatus['shardId'] if hoodId == self.loader.hood.hoodId and zoneId == self.loader.hood.hoodId and shardId == None: teleportDebug(requestStatus, 'same playground') @@ -612,19 +617,19 @@ class Playground(Place.Place): teleportDebug(requestStatus, 'different hood/zone') self.doneStatus = requestStatus messenger.send(self.doneEvent) - return def exitTeleportOut(self): - Place.Place.exitTeleportOut(self) + Place.exitTeleportOut(self) def createPlayground(self, dnaFile): - loader.loadDNAFile(self.loader.dnaStore, self.safeZoneStorageDNAFile) - node = loader.loadDNAFile(self.loader.dnaStore, dnaFile) + base.loader.loadDNAFile(self.loader.dnaStore, self.safeZoneStorageDNAFile) + node = base.loader.loadDNAFile(self.loader.dnaStore, dnaFile) if node.getNumParents() == 1: self.geom = NodePath(node.getParent(0)) - self.geom.reparentTo(hidden) + self.geom.reparentTo(base.hidden) else: - self.geom = hidden.attachNewNode(node) + self.geom = base.hidden.attachNewNode(node) + self.makeDictionaries(self.loader.dnaStore) self.tunnelOriginList = base.cr.hoodMgr.addLinkTunnelHooks(self, self.nodeList, self.zoneId) self.geom.flattenMedium() @@ -636,10 +641,10 @@ class Playground(Place.Place): self.nodeList = [] for i in range(dnaStore.getNumDNAVisGroups()): groupFullName = dnaStore.getDNAVisGroupName(i) - groupName = base.cr.hoodMgr.extractGroupName(groupFullName) groupNode = self.geom.find('**/' + groupFullName) if groupNode.isEmpty(): self.notify.error('Could not find visgroup') + self.nodeList.append(groupNode) self.removeLandmarkBlockNodes() @@ -655,7 +660,7 @@ class Playground(Place.Place): def enterTFA(self, requestStatus): self.acceptOnce(self.tfaDoneEvent, self.enterTFACallback, [requestStatus]) - self.tfa = TutorialForceAcknowledge.TutorialForceAcknowledge(self.tfaDoneEvent) + self.tfa = TutorialForceAcknowledge(self.tfaDoneEvent) self.tfa.enter() def exitTFA(self): diff --git a/toontown/shtiker/InGameNewsFrame.py b/toontown/shtiker/InGameNewsFrame.py index 44166d9..154d1af 100644 --- a/toontown/shtiker/InGameNewsFrame.py +++ b/toontown/shtiker/InGameNewsFrame.py @@ -34,6 +34,6 @@ class InGameNewsFrame(HtmlView.HtmlView): filename = filename.replace('.', '-') pngfilename = filename + '.png' self.writeTex(pngfilename) - jpgfilename = filename + '.jpg' + jpgfilename = filename + '.png' self.writeTex(jpgfilename) return jpgfilename diff --git a/toontown/shtiker/IssueFrame.py b/toontown/shtiker/IssueFrame.py index 58b2f82..cd2c25e 100644 --- a/toontown/shtiker/IssueFrame.py +++ b/toontown/shtiker/IssueFrame.py @@ -23,7 +23,7 @@ class IssueFrame(DirectFrame): -0.751666665077, 0.751666665077) notify = DirectNotifyGlobal.directNotify.newCategory('IssueFrame') - ContentPattern = 'tt_i_art_%s_%s%d.jpg' + ContentPattern = 'tt_i_art_%s_%s%d.png' SectionIdents = ['hom', 'new', 'evt', diff --git a/toontown/shtiker/KartPage.py b/toontown/shtiker/KartPage.py index 2180a78..dc79e5c 100644 --- a/toontown/shtiker/KartPage.py +++ b/toontown/shtiker/KartPage.py @@ -366,7 +366,7 @@ class ItemSelector(DirectFrame): self.locator2 = self.attachNewNode('locator2') self.locator1.setPos(0, 0, 0.035) self.locator2.setPos(0.0, 0.0, 0.0) - tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.jpg', 'phase_6/maps/NoAccessoryIcon3_a.rgb') + tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.png') self.uiImagePlane.component('geom0').setTexture(tex, self.texCount) self.texCount += 1 self.uiTextBox = DirectFrame(parent=self, relief=None, scale=1.0, text='', text_font=ToontownGlobals.getInterfaceFont(), text_fg=(0.5, 0, 0, 1), text_shadow=(0, 0, 0, 1), text_scale=0.0715, text_pos=(0.0, -0.23, 0.0)) @@ -526,15 +526,15 @@ class ItemSelector(DirectFrame): KartDNA.fwwType, KartDNA.bwwType]: texNodePath = getTexCardNode(self.currItem) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath, 'phase_6/maps/%s_a.rgb' % texNodePath) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath) elif self.currAccessoryType == KartDNA.rimsType: if self.currItem == InvalidEntry: texNodePath = getTexCardNode(getDefaultRim()) else: texNodePath = getTexCardNode(self.currItem) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath, 'phase_6/maps/%s_a.rgb' % texNodePath) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath) elif self.currAccessoryType in [KartDNA.bodyColor, KartDNA.accColor]: - tex = loader.loadTexture('phase_6/maps/Kartmenu_paintbucket.jpg', 'phase_6/maps/Kartmenu_paintbucket_a.rgb') + tex = loader.loadTexture('phase_6/maps/Kartmenu_paintbucket.png') if self.currItem == InvalidEntry: self.uiImagePlane.component('geom0').setColorScale(getDefaultColor()) else: @@ -543,9 +543,9 @@ class ItemSelector(DirectFrame): kart = self._parent._parent.getKartViewer().getKart() kartDecal = getDecalId(kart.kartDNA[KartDNA.bodyType]) texNodePath = getTexCardNode(self.currItem) - tex = loader.loadTexture('phase_6/maps/%s.jpg' % texNodePath % kartDecal, 'phase_6/maps/%s_a.rgb' % texNodePath % kartDecal) + tex = loader.loadTexture('phase_6/maps/%s.png' % texNodePath % kartDecal) else: - tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.jpg', 'phase_6/maps/NoAccessoryIcon3_a.rgb') + tex = loader.loadTexture('phase_6/maps/NoAccessoryIcon3.png') colorTypeList = [KartDNA.bodyColor, KartDNA.accColor] if self.currItem == InvalidEntry: if self.currAccessoryType == KartDNA.rimsType: @@ -561,7 +561,7 @@ class ItemSelector(DirectFrame): def __handleHideItem(self): self.uiImagePlane.component('geom0').setColorScale(1.0, 1.0, 1.0, 1.0) - self.uiImagePlane.component('geom0').setTexture(loader.loadTexture('phase_6/maps/NoAccessoryIcon3.jpg', 'phase_6/maps/NoAccessoryIcon3_a.rgb'), self.texCount) + self.uiImagePlane.component('geom0').setTexture(loader.loadTexture('phase_6/maps/NoAccessoryIcon3.png'), self.texCount) self.texCount += 1 def __handleItemDeleteConfirm(self): diff --git a/toontown/shtiker/PhotoAlbumPage.py b/toontown/shtiker/PhotoAlbumPage.py index 5352179..2e93625 100644 --- a/toontown/shtiker/PhotoAlbumPage.py +++ b/toontown/shtiker/PhotoAlbumPage.py @@ -182,7 +182,7 @@ class PhotoAlbumPage(ShtikerPage.ShtikerPage): files = os.listdir('.') photos = [] for fileName in files: - if fileName[0:10] == 'screenshot' and fileName[-4:] == '.jpg': + if fileName[0:10] == 'screenshot' and fileName[-4:] == '.png': photos.append(fileName) return photos diff --git a/toontown/spellbook/MagicWordIndex.py b/toontown/spellbook/MagicWordIndex.py index d01e34e..543e02b 100644 --- a/toontown/spellbook/MagicWordIndex.py +++ b/toontown/spellbook/MagicWordIndex.py @@ -176,7 +176,6 @@ class MagicWord(DirectObject): def handleWord(self, invoker, avId, toon, *args): raise NotImplementedError - class SetHP(MagicWord): aliases = ["hp", "setlaff", "laff"] desc = "Sets the target's current laff." @@ -200,7 +199,6 @@ class SetHP(MagicWord): toon.b_setHp(hp) return "{}'s laff has been set to {}.".format(toon.getName(), hp) - class SetMaxHP(MagicWord): aliases = ["maxhp", "setmaxlaff", "maxlaff"] desc = "Sets the target's max laff." @@ -219,7 +217,6 @@ class SetMaxHP(MagicWord): toon.toonUp(maxhp) return "{}'s max laff has been set to {}.".format(toon.getName(), maxhp) - class ToggleOobe(MagicWord): aliases = ["oobe"] desc = "Toggles the out of body experience mode, which lets you move the camera freely." @@ -232,7 +229,6 @@ class ToggleOobe(MagicWord): base.oobe() return "Oobe mode has been toggled." - class ToggleRun(MagicWord): aliases = ["run"] desc = "Toggles run mode, which gives you a faster running speed." @@ -286,7 +282,40 @@ class MaxToon(MagicWord): toon.b_setCogLevels([ToontownGlobals.MaxCogSuitLevel] * 4) return f"Successfully maxed {toon.getName()}!" + +class Inventory(MagicWord): + # by default restock the inventory + aliases = ['gags', 'inv'] + desc = 'This allows you to modify your inventory in various ways.' + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [("command", str, False, ''), ("track", str, False, ""), ("level", int, False, 0), ("amount", int, False, 0)] + def handleWord(self, invoker, avId, toon, *args): + command = args[0] + # the list of words that can be used to restock the inventory + restockInvWords = ['restock', 'max', 'all', '', 'fill'] + # the list of words that can be used to empty the inventory + emptyInvWords = ['empty', 'zero', 'null', 'clear', 'none', 'reset'] + if command in restockInvWords: + toon.inventory.maxOutInv() + toon.d_setInventory(toon.inventory.makeNetString()) + return ("Maxing out inventory for " + toon.getName() + ".") + if command in emptyInvWords: + toon.inventory.zeroInv() + toon.d_setInventory(toon.inventory.makeNetString()) + return ("Zeroing inventory for " + toon.getName() + ".") +class SetPinkSlips(MagicWord): + # this command gives the target toon the specified amount of pink slips + # default is 255 + aliases = ["pinkslips", "fires", 'setfires'] + desc = "Gives the target toon the specified amount of pink slips." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [("amount", int, False, 255)] + + def handleWord(self, invoker, avId, toon, *args): + toon.b_setPinkSlips(args[0]) + return f"Gave {toon.getName()} {args[0]} pink slips!" + class AbortMinigame(MagicWord): aliases = ["exitgame", "exitminigame", "quitgame", "quitminigame", "skipgame", "skipminigame"] desc = "Aborts an ongoing minigame." @@ -295,7 +324,52 @@ class AbortMinigame(MagicWord): def handleWord(self, invoker, avId, toon, *args): messenger.send("minigameAbort") - return "Requested minigame abort." + return "Requested minigame abort." + +class SkipMiniGolfHole(MagicWord): + aliases = ["skipgolfhole", "skipgolf", "skiphole"] + desc = "Skips the current golf hole." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [] + + def handleWord(self, invoker, avId, toon, *args): + from toontown.golf.DistributedGolfCourseAI import DistributedGolfCourseAI + course = None + for do in simbase.air.doId2do.values(): # For all doids, check whether it's a golf course, then check if our target is part of it. + if isinstance(do, DistributedGolfCourseAI): + if invoker.doId in do.avIdList: + course = do + break + if not course: + return "You aren't in a golf course!" + + if course.isPlayingLastHole(): # If the Toon is on the final hole, calling holeOver() will softlock, so instead we move onto the reward screen. + course.demand('WaitReward') + else: + course.holeOver() + + return "Skipped the current hole." + +class AbortGolfCourse(MagicWord): + aliases = ["abortminigolf", "abortgolf", "abortcourse", "leavegolf", "leavecourse"] + desc = "Aborts the current golf course." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [] + + def handleWord(self, invoker, avId, toon, *args): + from toontown.golf.DistributedGolfCourseAI import DistributedGolfCourseAI + course = None + for do in simbase.air.doId2do.values(): # For all doids, check whether it's a golf course, then check if our target is part of it. + if isinstance(do, DistributedGolfCourseAI): + if invoker.doId in do.avIdList: + course = do + break + if not course: + return "You aren't in a golf course!" + + course.setCourseAbort() + + return "Aborted golf course." class Minigame(MagicWord): aliases = ["mg"] @@ -350,8 +424,10 @@ class Minigame(MagicWord): mgId = ToontownGlobals.MinigameNames.get(minigame) if any((isTeleport, isRequest)): - if isTeleport and (ZoneUtil.isDynamicZone(toon.zoneId) or not toon.zoneId == mgSzId): - return "Target needs to be in a playground to teleport to a minigame." + if isTeleport: + if ZoneUtil.isDynamicZone(toon.zoneId) or not toon.zoneId == mgSzId: + return "Target needs to be in a playground to teleport to a minigame." + mgSzId = ToontownGlobals.ToontownCentral if ZoneUtil.isWelcomeValley(mgSzId) else mgSzId MinigameCreatorAI.RequestMinigame[avId] = (mgId, mgKeep, mgDiff, mgSzId) if isTeleport: try: @@ -479,7 +555,7 @@ class BossBattle(MagicWord): if not start: respText += " in Frolic state" - return respText + ", teleporting...", ["cogHQLoader", "cogHQBossBattle", "movie" if start else "teleportIn", boss.getHoodId(), boss.zoneId, 0] + return respText + ", teleporting...", toon.doId, ["cogHQLoader", "cogHQBossBattle", "movie" if start else "teleportIn", boss.getHoodId(), boss.zoneId, 0] elif command == "list": # List all the ongoing boss battles. @@ -521,7 +597,7 @@ class BossBattle(MagicWord): return "Index out of range!" boss = AllBossCogs[index] - return "Teleporting to boss battle...", ["cogHQLoader", "cogHQBossBattle", "", boss.getHoodId(), boss.zoneId, 0] + return "Teleporting to boss battle...", toon.doId, ["cogHQLoader", "cogHQBossBattle", "", boss.getHoodId(), boss.zoneId, 0] # The following commands needs the invoker to be in a boss battle. @@ -560,13 +636,129 @@ class BossBattle(MagicWord): # The create command is already described when the invoker is not in a battle. These are the commands # they can use INSIDE the battle. - return respText + f"Unknown command: \"{command}\". Valid commands: \"start\", \"stop\", \"skip\", \"final\", \"kill\"." + return f"Unknown command: \"{command}\". Valid commands: \"start\", \"stop\", \"skip\", \"final\", \"kill\"." def __destroyBoss(self, boss): bossZone = boss.zoneId boss.requestDelete() self.air.deallocateZone(bossZone) +class GlobalTeleport(MagicWord): + aliases = ["globaltp", "tpaccess"] + desc = "Enables teleport access to all zones." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + + def handleWord(self, invoker, avId, toon, *args): + from toontown.toonbase import ToontownGlobals + toon.b_setHoodsVisited(ToontownGlobals.HoodsForTeleportAll) + toon.b_setTeleportAccess(ToontownGlobals.HoodsForTeleportAll) + return f"Enabled teleport access to all zones for {toon.getName()}." + +class Teleport(MagicWord): + aliases = ["tp", "goto"] + desc = "Teleport to a specified zone." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [("zoneName", str, False, '')] + + def handleWord(self, invoker, avId, toon, *args): + from toontown.hood import ZoneUtil + from toontown.toonbase import ToontownGlobals + zoneName = args[0] + + # Can add stuff like streets to this too if you wanted, but if you do you'll want it to be a valid zone on that street. eg: 2100 is invalid, but any value 2101 to 2156 is fine. + # so if you wanted to add a silly street key, theroetically you could do something like this: 'sillystreet': ToontownGlobals.SillyStreet +1, + zoneName2Id = {'ttc': ToontownGlobals.ToontownCentral, + 'dd': ToontownGlobals.DonaldsDock, + 'dg': ToontownGlobals.DaisyGardens, + 'mml': ToontownGlobals.MinniesMelodyland, + 'tb': ToontownGlobals.TheBrrrgh, + 'ddl': ToontownGlobals.DonaldsDreamland, + 'gs': ToontownGlobals.GoofySpeedway, + 'oz': ToontownGlobals.OutdoorZone, + 'aa': ToontownGlobals.OutdoorZone, + 'gz': ToontownGlobals.GolfZone, + 'sbhq': ToontownGlobals.SellbotHQ, + 'factory': ToontownGlobals.SellbotFactoryExt, + 'cbhq': ToontownGlobals.CashbotHQ, + 'lbhq': ToontownGlobals.LawbotHQ, + 'bbhq': ToontownGlobals.BossbotHQ} + + try: + zone = zoneName2Id[zoneName] + except KeyError: + return "Unknown zone name!" + + return f"Requested to teleport {toon.getName()} to zone {zone}.", toon.doId, [ZoneUtil.getBranchLoaderName(zone), ZoneUtil.getToonWhereName(zone), "", ZoneUtil.getHoodId(zone), zone, 0] + +class ToggleSleep(MagicWord): + aliases = ["sleep", "nosleep", "neversleep", "togglesleeping", "insomnia"] + desc = "Toggles sleeping for the target." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + + def handleWord(self, invoker, avId, toon, *args): + toon.d_toggleSleep() + return f"Toggled sleeping for {toon.getName()}." + +class ToggleImmortal(MagicWord): + aliases = ["immortal", "invincible", "invulnerable"] + desc = "Toggle immortal mode. This makes the Toon immune to damage." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + + def handleWord(self, invoker, avId, toon, *args): + toon.setImmortalMode(not toon.immortalMode) + return f"Toggled immortal mode for {toon.getName()}" + +class ToggleGhost(MagicWord): + aliases = ["ghost", "invisible", "spy"] + desc = "Toggle ghost mode." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + + def handleWord(self, invoker, avId, toon, *args): + # 1 is for the attic, 2 enables you to see yourself other ghost toons. 0 is off. + toon.b_setGhostMode(2 if not toon.ghostMode else 0) # As it's primarily for moderation purposes, we set it to 2 here, or 0 if it's already on. + return f"Toggled ghost mode for {toon.getName()}" + +class SetGM(MagicWord): + aliases = ["icon", "seticon", "gm", "gmicon", "setgmicon"] + desc = "Sets the GM icon on the target." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [("iconRequest", int, False, 0),] + + def handleWord(self, invoker, avId, toon, *args): + from toontown.toonbase import TTLocalizer + + iconRequest = args[0] + if iconRequest > len(TTLocalizer.GM_NAMES) or iconRequest < 0: + return "Invalid GM icon ID!" + + toon.b_setGM(0) # Reset it first, otherwise the Toon keeps the old icon, but the name still changes. + toon.b_setGM(iconRequest) + return f"GM icon set to {iconRequest} for {toon.getName()}" + +class SetMaxCarry(MagicWord): + aliases = ["gagpouch", "pouch", "gagcapacity"] + desc = "Set a Toon's gag pouch size." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + arguments = [("pouchSize", int, True)] + + def handleWord(self, invoker, avId, toon, *args): + pouchSize = args[0] + + if pouchSize > 255 or pouchSize < 0: + return "Specified pouch size must be between 1 and 255." + + toon.b_setMaxCarry(pouchSize) + return f"Set gag pouch size to {pouchSize} for {toon.getName()}" + +class ToggleInstantKill(MagicWord): + aliases = ["instantkill", "instakill"] + desc = "Toggle the ability to instantly kill a Cog with any gag." + execLocation = MagicWordConfig.EXEC_LOC_SERVER + + def handleWord(self, invoker, avId, toon, *args): + toon.setInstantKillMode(not toon.instantKillMode) + return f"Toggled instant-kill mode for {toon.getName()}" + class Fireworks(MagicWord): aliases = ["firework"] desc = "Starts a firework show." diff --git a/toontown/spellbook/ToontownMagicWordManager.py b/toontown/spellbook/ToontownMagicWordManager.py index 9a53d36..d8a6c2f 100644 --- a/toontown/spellbook/ToontownMagicWordManager.py +++ b/toontown/spellbook/ToontownMagicWordManager.py @@ -275,11 +275,14 @@ class ToontownMagicWordManager(DistributedObject.DistributedObject): hoodId = place.loader.hood.id if avId == 0: avId = -1 - place.fsm.forceTransition('teleportOut', - [{"loader": loaderId, - "where": whereId, - "how": how, - "hoodId": hoodId, - "zoneId": zoneId, - "shardId": None, - "avId": avId}]) + try: + place.fsm.forceTransition('teleportOut', + [{"loader": loaderId, + "where": whereId, + "how": how, + "hoodId": hoodId, + "zoneId": zoneId, + "shardId": None, + "avId": avId}]) + except Exception: # Most likely cause is the place the avatar is in has no teleportOut state, for example, boss lobbies. + place.fsm.request('DFAReject') # We have to do this, or the avatar will be stuck. diff --git a/toontown/suit/DistributedCashbotBoss.py b/toontown/suit/DistributedCashbotBoss.py index b8186b6..b4cdfce 100644 --- a/toontown/suit/DistributedCashbotBoss.py +++ b/toontown/suit/DistributedCashbotBoss.py @@ -19,6 +19,7 @@ from toontown.distributed import DelayDelete from toontown.chat import ResistanceChat from toontown.coghq import CogDisguiseGlobals from panda3d.core import * +from panda3d.direct import ShowInterval from panda3d.physics import * from panda3d.otp import * import random diff --git a/toontown/suit/Suit.py b/toontown/suit/Suit.py index ee6bce0..8681baf 100644 --- a/toontown/suit/Suit.py +++ b/toontown/suit/Suit.py @@ -442,7 +442,7 @@ class Suit(Avatar.Avatar): self.scale = 6.75 / cSize self.handColor = VBase4(0.85, 0.55, 0.55, 1.0) self.generateBody() - self.headTexture = 'corporate-raider.jpg' + self.headTexture = 'corporate-raider.png' self.generateHead('flunky') self.setHeight(8.23) elif dna.name == 'tbc': @@ -455,21 +455,21 @@ class Suit(Avatar.Avatar): self.scale = 4.0 / cSize self.handColor = SuitDNA.legalPolyColor self.generateBody() - self.headTexture = 'bottom-feeder.jpg' + self.headTexture = 'bottom-feeder.png' self.generateHead('tightwad') self.setHeight(4.81) elif dna.name == 'b': self.scale = 4.375 / bSize self.handColor = VBase4(0.95, 0.95, 1.0, 1.0) self.generateBody() - self.headTexture = 'blood-sucker.jpg' + self.headTexture = 'blood-sucker.png' self.generateHead('movershaker') self.setHeight(6.17) elif dna.name == 'dt': self.scale = 4.25 / aSize self.handColor = SuitDNA.legalPolyColor self.generateBody() - self.headTexture = 'double-talker.jpg' + self.headTexture = 'double-talker.png' self.generateHead('twoface') self.setHeight(5.63) elif dna.name == 'ac': @@ -488,7 +488,7 @@ class Suit(Avatar.Avatar): self.scale = 5.65 / bSize self.handColor = VBase4(0.5, 0.8, 0.75, 1.0) self.generateBody() - self.headTexture = 'spin-doctor.jpg' + self.headTexture = 'spin-doctor.png' self.generateHead('telemarketer') self.setHeight(7.9) elif dna.name == 'le': @@ -549,7 +549,7 @@ class Suit(Avatar.Avatar): self.scale = 7.0 / aSize self.handColor = SuitDNA.moneyPolyColor self.generateBody() - self.headTexture = 'robber-baron.jpg' + self.headTexture = 'robber-baron.png' self.generateHead('yesman') self.setHeight(8.95) elif dna.name == 'cc': @@ -569,7 +569,7 @@ class Suit(Avatar.Avatar): self.scale = 4.35 / aSize self.handColor = SuitDNA.salesPolyColor self.generateBody() - self.headTexture = 'name-dropper.jpg' + self.headTexture = 'name-dropper.png' self.generateHead('numbercruncher') self.setHeight(5.98) elif dna.name == 'gh': @@ -594,7 +594,7 @@ class Suit(Avatar.Avatar): self.scale = 5.75 / aSize self.handColor = SuitDNA.salesPolyColor self.generateBody() - self.headTexture = 'mingler.jpg' + self.headTexture = 'mingler.png' self.generateHead('twoface') self.setHeight(7.61) elif dna.name == 'mh': @@ -677,13 +677,13 @@ class Suit(Avatar.Avatar): phase = 3.5 def __doItTheOldWay__(): - torsoTex = loader.loadTexture('phase_%s/maps/%s_blazer.jpg' % (phase, dept)) + torsoTex = loader.loadTexture('phase_%s/maps/%s_blazer.png' % (phase, dept)) torsoTex.setMinfilter(Texture.FTLinearMipmapLinear) torsoTex.setMagfilter(Texture.FTLinear) - legTex = loader.loadTexture('phase_%s/maps/%s_leg.jpg' % (phase, dept)) + legTex = loader.loadTexture('phase_%s/maps/%s_leg.png' % (phase, dept)) legTex.setMinfilter(Texture.FTLinearMipmapLinear) legTex.setMagfilter(Texture.FTLinear) - armTex = loader.loadTexture('phase_%s/maps/%s_sleeve.jpg' % (phase, dept)) + armTex = loader.loadTexture('phase_%s/maps/%s_sleeve.png' % (phase, dept)) armTex.setMinfilter(Texture.FTLinearMipmapLinear) armTex.setMagfilter(Texture.FTLinear) modelRoot.find('**/torso').setTexture(torsoTex, 1) @@ -707,8 +707,8 @@ class Suit(Avatar.Avatar): if self.find('**/body').isEmpty(): __doItTheOldWay__() else: - filepath = 'phase_3.5/maps/tt_t_ene_' + texType + '.jpg' - if cogExists('/maps/tt_t_ene_' + texType + '.jpg'): + filepath = 'phase_3.5/maps/tt_t_ene_' + texType + '.png' + if cogExists('/maps/tt_t_ene_' + texType + '.png'): bodyTex = loader.loadTexture(filepath) self.find('**/body').setTexture(bodyTex, 1) self.leftHand = self.find('**/def_joint_left_hold') @@ -722,13 +722,13 @@ class Suit(Avatar.Avatar): if not modelRoot: modelRoot = self self.isWaiter = 1 - torsoTex = loader.loadTexture('phase_3.5/maps/waiter_m_blazer.jpg') + torsoTex = loader.loadTexture('phase_3.5/maps/waiter_m_blazer.png') torsoTex.setMinfilter(Texture.FTLinearMipmapLinear) torsoTex.setMagfilter(Texture.FTLinear) - legTex = loader.loadTexture('phase_3.5/maps/waiter_m_leg.jpg') + legTex = loader.loadTexture('phase_3.5/maps/waiter_m_leg.png') legTex.setMinfilter(Texture.FTLinearMipmapLinear) legTex.setMagfilter(Texture.FTLinear) - armTex = loader.loadTexture('phase_3.5/maps/waiter_m_sleeve.jpg') + armTex = loader.loadTexture('phase_3.5/maps/waiter_m_sleeve.png') armTex.setMinfilter(Texture.FTLinearMipmapLinear) armTex.setMagfilter(Texture.FTLinear) modelRoot.find('**/torso').setTexture(torsoTex, 1) @@ -739,10 +739,10 @@ class Suit(Avatar.Avatar): if not modelRoot: modelRoot = self.getGeomNode() if suitType == 's': - torsoTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_blazer.jpg') - legTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_leg.jpg') - armTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_sleeve.jpg') - handTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_hand.jpg') + torsoTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_blazer.png') + legTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_leg.png') + armTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_sleeve.png') + handTex = loader.loadTexture('phase_3.5/maps/tt_t_ene_sellbotRental_hand.png') else: self.notify.warning('No rental suit for cog type %s' % suitType) return @@ -786,13 +786,13 @@ class Suit(Avatar.Avatar): self.notify.warning('skelecog has no tie model!!!') return if dept == 'c': - tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_boss.jpg') + tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_boss.png') elif dept == 's': - tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_sales.jpg') + tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_sales.png') elif dept == 'l': - tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_legal.jpg') + tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_legal.png') elif dept == 'm': - tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_money.jpg') + tieTex = loader.loadTexture('phase_5/maps/cog_robot_tie_money.png') tieTex.setMinfilter(Texture.FTLinearMipmapLinear) tieTex.setMagfilter(Texture.FTLinear) tie.setTexture(tieTex, 1) diff --git a/toontown/toon/DistributedToon.py b/toontown/toon/DistributedToon.py index 0602211..3a52f75 100644 --- a/toontown/toon/DistributedToon.py +++ b/toontown/toon/DistributedToon.py @@ -2528,7 +2528,7 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute self._handleGMName() def _handleGMName(self): - name = self.name + name = self._name self.setDisplayName(name) if self._isGM: self.setNametagStyle(5) @@ -2589,3 +2589,6 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute def getTransitioning(self): return self.transitioning + + def toggleSleep(self): + base.localAvatar.noSleep = not base.localAvatar.noSleep \ No newline at end of file diff --git a/toontown/toon/DistributedToonAI.py b/toontown/toon/DistributedToonAI.py index cf78958..b5489fe 100644 --- a/toontown/toon/DistributedToonAI.py +++ b/toontown/toon/DistributedToonAI.py @@ -155,6 +155,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo self.savedCheesyExpireTime = 0 self.ghostMode = 0 self.immortalMode = 0 + self.instantKillMode = 0 self.numPies = 0 self.pieType = 0 self._isGM = False @@ -2375,6 +2376,9 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo def setImmortalMode(self, flag): self.immortalMode = flag + def setInstantKillMode(self, flag): + self.instantKillMode = flag + def b_setSpeedChatStyleIndex(self, index): self.setSpeedChatStyleIndex(index) self.d_setSpeedChatStyleIndex(index) @@ -4129,6 +4133,9 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo zoneId]) self.air.send(dg) + def d_toggleSleep(self): + self.sendUpdate('toggleSleep', []) + @staticmethod def staticGetLogicalZoneChangeAllEvent(): return 'DOLogicalChangeZone-all' diff --git a/toontown/toon/Toon.py b/toontown/toon/Toon.py index caec571..75b616b 100644 --- a/toontown/toon/Toon.py +++ b/toontown/toon/Toon.py @@ -860,6 +860,9 @@ class Toon(Avatar.Avatar, ToonHead): self.resetHeight() self.setupToonNodes() self.generateBackpack() + hands = self.getRightHands() + for bookActor, hand in zip(self.__bookActors, hands): + bookActor.reparentTo(hand) def generateToonHead(self, copy = 1): headHeight = ToonHead.generateToonHead(self, copy, self.style, ('1000', '500', '250')) @@ -1165,7 +1168,7 @@ class Toon(Avatar.Avatar, ToonHead): for geom in geoms: texName = ToonDNA.ShoesTextures[shoes[1]] if self.style.legs == 'l' and shoes[0] == 3: - texName = texName[:-4] + 'LL.jpg' + texName = texName[:-4] + 'LL.png' tex = loader.loadTexture(texName, okMissing=True) if tex is None: self.sendLogSuspiciousEvent('failed to load texture %s' % texName) @@ -1995,7 +1998,7 @@ class Toon(Avatar.Avatar, ToonHead): def exitSitStart(self): self.playingAnim = 'neutral' if self.track != None: - self.track.finish() + self.track.pause() DelayDelete.cleanupDelayDeletes(self.track) self.track = None Emote.globalEmote.releaseBody(self) diff --git a/toontown/toon/ToonDNA.py b/toontown/toon/ToonDNA.py index 2961625..ab2f52e 100644 --- a/toontown/toon/ToonDNA.py +++ b/toontown/toon/ToonDNA.py @@ -175,157 +175,157 @@ toonTorsoTypes = ['ss', 'm', 'l'] toonLegTypes = ['s', 'm', 'l'] -Shirts = ['phase_3/maps/desat_shirt_1.jpg', - 'phase_3/maps/desat_shirt_2.jpg', - 'phase_3/maps/desat_shirt_3.jpg', - 'phase_3/maps/desat_shirt_4.jpg', - 'phase_3/maps/desat_shirt_5.jpg', - 'phase_3/maps/desat_shirt_6.jpg', - 'phase_3/maps/desat_shirt_7.jpg', - 'phase_3/maps/desat_shirt_8.jpg', - 'phase_3/maps/desat_shirt_9.jpg', - 'phase_3/maps/desat_shirt_10.jpg', - 'phase_3/maps/desat_shirt_11.jpg', - 'phase_3/maps/desat_shirt_12.jpg', - 'phase_3/maps/desat_shirt_13.jpg', - 'phase_3/maps/desat_shirt_14.jpg', - 'phase_3/maps/desat_shirt_15.jpg', - 'phase_3/maps/desat_shirt_16.jpg', - 'phase_3/maps/desat_shirt_17.jpg', - 'phase_3/maps/desat_shirt_18.jpg', - 'phase_3/maps/desat_shirt_19.jpg', - 'phase_3/maps/desat_shirt_20.jpg', - 'phase_3/maps/desat_shirt_21.jpg', - 'phase_3/maps/desat_shirt_22.jpg', - 'phase_3/maps/desat_shirt_23.jpg', - 'phase_4/maps/female_shirt1b.jpg', - 'phase_4/maps/female_shirt2.jpg', - 'phase_4/maps/female_shirt3.jpg', - 'phase_4/maps/male_shirt1.jpg', - 'phase_4/maps/male_shirt2_palm.jpg', - 'phase_4/maps/male_shirt3c.jpg', - 'phase_4/maps/shirt_ghost.jpg', - 'phase_4/maps/shirt_pumkin.jpg', - 'phase_4/maps/holiday_shirt1.jpg', - 'phase_4/maps/holiday_shirt2b.jpg', - 'phase_4/maps/holidayShirt3b.jpg', - 'phase_4/maps/holidayShirt4.jpg', - 'phase_4/maps/female_shirt1b.jpg', - 'phase_4/maps/female_shirt5New.jpg', - 'phase_4/maps/shirtMale4B.jpg', - 'phase_4/maps/shirt6New.jpg', - 'phase_4/maps/shirtMaleNew7.jpg', - 'phase_4/maps/femaleShirtNew6.jpg', - 'phase_4/maps/Vday1Shirt5.jpg', - 'phase_4/maps/Vday1Shirt6SHD.jpg', - 'phase_4/maps/Vday1Shirt4.jpg', - 'phase_4/maps/Vday_shirt2c.jpg', - 'phase_4/maps/shirtTieDyeNew.jpg', - 'phase_4/maps/male_shirt1.jpg', - 'phase_4/maps/StPats_shirt1.jpg', - 'phase_4/maps/StPats_shirt2.jpg', - 'phase_4/maps/ContestfishingVestShirt2.jpg', - 'phase_4/maps/ContestFishtankShirt1.jpg', - 'phase_4/maps/ContestPawShirt1.jpg', - 'phase_4/maps/CowboyShirt1.jpg', - 'phase_4/maps/CowboyShirt2.jpg', - 'phase_4/maps/CowboyShirt3.jpg', - 'phase_4/maps/CowboyShirt4.jpg', - 'phase_4/maps/CowboyShirt5.jpg', - 'phase_4/maps/CowboyShirt6.jpg', - 'phase_4/maps/4thJulyShirt1.jpg', - 'phase_4/maps/4thJulyShirt2.jpg', - 'phase_4/maps/shirt_Cat7_01.jpg', - 'phase_4/maps/shirt_Cat7_02.jpg', - 'phase_4/maps/contest_backpack3.jpg', - 'phase_4/maps/contest_leder.jpg', - 'phase_4/maps/contest_mellon2.jpg', - 'phase_4/maps/contest_race2.jpg', - 'phase_4/maps/PJBlueBanana2.jpg', - 'phase_4/maps/PJRedHorn2.jpg', - 'phase_4/maps/PJGlasses2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_valentine1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_valentine2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_desat4.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_fishing1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_fishing2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_gardening1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_gardening2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_party1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_party2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_racing1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_racing2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_summer1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_summer2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_golf1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_golf2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_marathon1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_toonTask1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_toonTask2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_trolley1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_trolley2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_winter1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween3.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween4.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_valentine3.jpg', - 'phase_4/maps/tt_t_chr_shirt_scientistC.jpg', - 'phase_4/maps/tt_t_chr_shirt_scientistA.jpg', - 'phase_4/maps/tt_t_chr_shirt_scientistB.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_mailbox.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_trashcan.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_loonyLabs.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_hydrant.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_whistle.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_cogbuster.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated01.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_victoryParty01.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_victoryParty02.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_sellbotIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_sellbotVPIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_sellbotCrusher.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_jellyBeans.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_doodle.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween5.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloweenTurtle.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_greentoon1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_getConnectedMoverShaker.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_racingGrandPrix.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_lawbotIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_lawbotVPIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_lawbotCrusher.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_bee.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_pirate.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_supertoon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_vampire.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_dinosaur.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_fishing04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_golf03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated02.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_racing03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding3.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_trolley03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_fishing05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_golf04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween06.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_winter03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_halloween07.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_winter02.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_fishing06.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_fishing07.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_golf05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_racing04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_racing05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_trolley04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_trolley05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding4.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirt_anniversary.jpg'] +Shirts = ['phase_3/maps/desat_shirt_1.png', + 'phase_3/maps/desat_shirt_2.png', + 'phase_3/maps/desat_shirt_3.png', + 'phase_3/maps/desat_shirt_4.png', + 'phase_3/maps/desat_shirt_5.png', + 'phase_3/maps/desat_shirt_6.png', + 'phase_3/maps/desat_shirt_7.png', + 'phase_3/maps/desat_shirt_8.png', + 'phase_3/maps/desat_shirt_9.png', + 'phase_3/maps/desat_shirt_10.png', + 'phase_3/maps/desat_shirt_11.png', + 'phase_3/maps/desat_shirt_12.png', + 'phase_3/maps/desat_shirt_13.png', + 'phase_3/maps/desat_shirt_14.png', + 'phase_3/maps/desat_shirt_15.png', + 'phase_3/maps/desat_shirt_16.png', + 'phase_3/maps/desat_shirt_17.png', + 'phase_3/maps/desat_shirt_18.png', + 'phase_3/maps/desat_shirt_19.png', + 'phase_3/maps/desat_shirt_20.png', + 'phase_3/maps/desat_shirt_21.png', + 'phase_3/maps/desat_shirt_22.png', + 'phase_3/maps/desat_shirt_23.png', + 'phase_4/maps/female_shirt1b.png', + 'phase_4/maps/female_shirt2.png', + 'phase_4/maps/female_shirt3.png', + 'phase_4/maps/male_shirt1.png', + 'phase_4/maps/male_shirt2_palm.png', + 'phase_4/maps/male_shirt3c.png', + 'phase_4/maps/shirt_ghost.png', + 'phase_4/maps/shirt_pumkin.png', + 'phase_4/maps/holiday_shirt1.png', + 'phase_4/maps/holiday_shirt2b.png', + 'phase_4/maps/holidayShirt3b.png', + 'phase_4/maps/holidayShirt4.png', + 'phase_4/maps/female_shirt1b.png', + 'phase_4/maps/female_shirt5New.png', + 'phase_4/maps/shirtMale4B.png', + 'phase_4/maps/shirt6New.png', + 'phase_4/maps/shirtMaleNew7.png', + 'phase_4/maps/femaleShirtNew6.png', + 'phase_4/maps/Vday1Shirt5.png', + 'phase_4/maps/Vday1Shirt6SHD.png', + 'phase_4/maps/Vday1Shirt4.png', + 'phase_4/maps/Vday_shirt2c.png', + 'phase_4/maps/shirtTieDyeNew.png', + 'phase_4/maps/male_shirt1.png', + 'phase_4/maps/StPats_shirt1.png', + 'phase_4/maps/StPats_shirt2.png', + 'phase_4/maps/ContestfishingVestShirt2.png', + 'phase_4/maps/ContestFishtankShirt1.png', + 'phase_4/maps/ContestPawShirt1.png', + 'phase_4/maps/CowboyShirt1.png', + 'phase_4/maps/CowboyShirt2.png', + 'phase_4/maps/CowboyShirt3.png', + 'phase_4/maps/CowboyShirt4.png', + 'phase_4/maps/CowboyShirt5.png', + 'phase_4/maps/CowboyShirt6.png', + 'phase_4/maps/4thJulyShirt1.png', + 'phase_4/maps/4thJulyShirt2.png', + 'phase_4/maps/shirt_Cat7_01.png', + 'phase_4/maps/shirt_Cat7_02.png', + 'phase_4/maps/contest_backpack3.png', + 'phase_4/maps/contest_leder.png', + 'phase_4/maps/contest_mellon2.png', + 'phase_4/maps/contest_race2.png', + 'phase_4/maps/PJBlueBanana2.png', + 'phase_4/maps/PJRedHorn2.png', + 'phase_4/maps/PJGlasses2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_valentine1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_valentine2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_desat4.png', + 'phase_4/maps/tt_t_chr_avt_shirt_fishing1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_fishing2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_gardening1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_gardening2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_party1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_party2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_racing1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_racing2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_summer1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_summer2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_golf1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_golf2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_marathon1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_toonTask1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_toonTask2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_trolley1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_trolley2.png', + 'phase_4/maps/tt_t_chr_avt_shirt_winter1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween3.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween4.png', + 'phase_4/maps/tt_t_chr_avt_shirt_valentine3.png', + 'phase_4/maps/tt_t_chr_shirt_scientistC.png', + 'phase_4/maps/tt_t_chr_shirt_scientistA.png', + 'phase_4/maps/tt_t_chr_shirt_scientistB.png', + 'phase_4/maps/tt_t_chr_avt_shirt_mailbox.png', + 'phase_4/maps/tt_t_chr_avt_shirt_trashcan.png', + 'phase_4/maps/tt_t_chr_avt_shirt_loonyLabs.png', + 'phase_4/maps/tt_t_chr_avt_shirt_hydrant.png', + 'phase_4/maps/tt_t_chr_avt_shirt_whistle.png', + 'phase_4/maps/tt_t_chr_avt_shirt_cogbuster.png', + 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated01.png', + 'phase_4/maps/tt_t_chr_avt_shirt_victoryParty01.png', + 'phase_4/maps/tt_t_chr_avt_shirt_victoryParty02.png', + 'phase_4/maps/tt_t_chr_avt_shirt_sellbotIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirt_sellbotVPIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirt_sellbotCrusher.png', + 'phase_4/maps/tt_t_chr_avt_shirt_jellyBeans.png', + 'phase_4/maps/tt_t_chr_avt_shirt_doodle.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween5.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloweenTurtle.png', + 'phase_4/maps/tt_t_chr_avt_shirt_greentoon1.png', + 'phase_4/maps/tt_t_chr_avt_shirt_getConnectedMoverShaker.png', + 'phase_4/maps/tt_t_chr_avt_shirt_racingGrandPrix.png', + 'phase_4/maps/tt_t_chr_avt_shirt_lawbotIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirt_lawbotVPIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirt_lawbotCrusher.png', + 'phase_4/maps/tt_t_chr_avt_shirt_bee.png', + 'phase_4/maps/tt_t_chr_avt_shirt_pirate.png', + 'phase_4/maps/tt_t_chr_avt_shirt_supertoon.png', + 'phase_4/maps/tt_t_chr_avt_shirt_vampire.png', + 'phase_4/maps/tt_t_chr_avt_shirt_dinosaur.png', + 'phase_4/maps/tt_t_chr_avt_shirt_fishing04.png', + 'phase_4/maps/tt_t_chr_avt_shirt_golf03.png', + 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated02.png', + 'phase_4/maps/tt_t_chr_avt_shirt_racing03.png', + 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding3.png', + 'phase_4/maps/tt_t_chr_avt_shirt_trolley03.png', + 'phase_4/maps/tt_t_chr_avt_shirt_fishing05.png', + 'phase_4/maps/tt_t_chr_avt_shirt_golf04.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween06.png', + 'phase_4/maps/tt_t_chr_avt_shirt_winter03.png', + 'phase_4/maps/tt_t_chr_avt_shirt_halloween07.png', + 'phase_4/maps/tt_t_chr_avt_shirt_winter02.png', + 'phase_4/maps/tt_t_chr_avt_shirt_fishing06.png', + 'phase_4/maps/tt_t_chr_avt_shirt_fishing07.png', + 'phase_4/maps/tt_t_chr_avt_shirt_golf05.png', + 'phase_4/maps/tt_t_chr_avt_shirt_racing04.png', + 'phase_4/maps/tt_t_chr_avt_shirt_racing05.png', + 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated03.png', + 'phase_4/maps/tt_t_chr_avt_shirt_mostCogsDefeated04.png', + 'phase_4/maps/tt_t_chr_avt_shirt_trolley04.png', + 'phase_4/maps/tt_t_chr_avt_shirt_trolley05.png', + 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding4.png', + 'phase_4/maps/tt_t_chr_avt_shirt_saveBuilding05.png', + 'phase_4/maps/tt_t_chr_avt_shirt_anniversary.png'] BoyShirts = [(0, 0), (1, 1), (2, 2), @@ -373,267 +373,267 @@ def isValidGirlShirt(index): return 0 -Sleeves = ['phase_3/maps/desat_sleeve_1.jpg', - 'phase_3/maps/desat_sleeve_2.jpg', - 'phase_3/maps/desat_sleeve_3.jpg', - 'phase_3/maps/desat_sleeve_4.jpg', - 'phase_3/maps/desat_sleeve_5.jpg', - 'phase_3/maps/desat_sleeve_6.jpg', - 'phase_3/maps/desat_sleeve_7.jpg', - 'phase_3/maps/desat_sleeve_8.jpg', - 'phase_3/maps/desat_sleeve_9.jpg', - 'phase_3/maps/desat_sleeve_10.jpg', - 'phase_3/maps/desat_sleeve_15.jpg', - 'phase_3/maps/desat_sleeve_16.jpg', - 'phase_3/maps/desat_sleeve_19.jpg', - 'phase_3/maps/desat_sleeve_20.jpg', - 'phase_4/maps/female_sleeve1b.jpg', - 'phase_4/maps/female_sleeve2.jpg', - 'phase_4/maps/female_sleeve3.jpg', - 'phase_4/maps/male_sleeve1.jpg', - 'phase_4/maps/male_sleeve2_palm.jpg', - 'phase_4/maps/male_sleeve3c.jpg', - 'phase_4/maps/shirt_Sleeve_ghost.jpg', - 'phase_4/maps/shirt_Sleeve_pumkin.jpg', - 'phase_4/maps/holidaySleeve1.jpg', - 'phase_4/maps/holidaySleeve3.jpg', - 'phase_4/maps/female_sleeve1b.jpg', - 'phase_4/maps/female_sleeve5New.jpg', - 'phase_4/maps/male_sleeve4New.jpg', - 'phase_4/maps/sleeve6New.jpg', - 'phase_4/maps/SleeveMaleNew7.jpg', - 'phase_4/maps/female_sleeveNew6.jpg', - 'phase_4/maps/Vday5Sleeve.jpg', - 'phase_4/maps/Vda6Sleeve.jpg', - 'phase_4/maps/Vday_shirt4sleeve.jpg', - 'phase_4/maps/Vday2cSleeve.jpg', - 'phase_4/maps/sleeveTieDye.jpg', - 'phase_4/maps/male_sleeve1.jpg', - 'phase_4/maps/StPats_sleeve.jpg', - 'phase_4/maps/StPats_sleeve2.jpg', - 'phase_4/maps/ContestfishingVestSleeve1.jpg', - 'phase_4/maps/ContestFishtankSleeve1.jpg', - 'phase_4/maps/ContestPawSleeve1.jpg', - 'phase_4/maps/CowboySleeve1.jpg', - 'phase_4/maps/CowboySleeve2.jpg', - 'phase_4/maps/CowboySleeve3.jpg', - 'phase_4/maps/CowboySleeve4.jpg', - 'phase_4/maps/CowboySleeve5.jpg', - 'phase_4/maps/CowboySleeve6.jpg', - 'phase_4/maps/4thJulySleeve1.jpg', - 'phase_4/maps/4thJulySleeve2.jpg', - 'phase_4/maps/shirt_sleeveCat7_01.jpg', - 'phase_4/maps/shirt_sleeveCat7_02.jpg', - 'phase_4/maps/contest_backpack_sleeve.jpg', - 'phase_4/maps/Contest_leder_sleeve.jpg', - 'phase_4/maps/contest_mellon_sleeve2.jpg', - 'phase_4/maps/contest_race_sleeve.jpg', - 'phase_4/maps/PJSleeveBlue.jpg', - 'phase_4/maps/PJSleeveRed.jpg', - 'phase_4/maps/PJSleevePurple.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_valentine1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_valentine2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_desat4.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_gardening1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_gardening2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_party1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_party2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_summer1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_summer2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_marathon1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_toonTask1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_toonTask2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley2.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_winter1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween3.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween4.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_valentine3.jpg', - 'phase_4/maps/tt_t_chr_shirtSleeve_scientist.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mailbox.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trashcan.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_loonyLabs.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_hydrant.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_whistle.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_cogbuster.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated01.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_victoryParty01.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_victoryParty02.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_sellbotIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_sellbotVPIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_sellbotCrusher.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_jellyBeans.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_doodle.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween5.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloweenTurtle.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_greentoon1.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_getConnectedMoverShaker.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racingGrandPrix.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_lawbotIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_lawbotVPIcon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_lawbotCrusher.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_bee.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_pirate.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_supertoon.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_vampire.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_dinosaur.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated02.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding3.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween06.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_winter03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween07.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_winter02.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing06.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing07.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated03.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley04.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding4.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding05.jpg', - 'phase_4/maps/tt_t_chr_avt_shirtSleeve_anniversary.jpg'] -BoyShorts = ['phase_3/maps/desat_shorts_1.jpg', - 'phase_3/maps/desat_shorts_2.jpg', - 'phase_3/maps/desat_shorts_4.jpg', - 'phase_3/maps/desat_shorts_6.jpg', - 'phase_3/maps/desat_shorts_7.jpg', - 'phase_3/maps/desat_shorts_8.jpg', - 'phase_3/maps/desat_shorts_9.jpg', - 'phase_3/maps/desat_shorts_10.jpg', - 'phase_4/maps/VdayShorts2.jpg', - 'phase_4/maps/shorts4.jpg', - 'phase_4/maps/shorts1.jpg', - 'phase_4/maps/shorts5.jpg', - 'phase_4/maps/CowboyShorts1.jpg', - 'phase_4/maps/CowboyShorts2.jpg', - 'phase_4/maps/4thJulyShorts1.jpg', - 'phase_4/maps/shortsCat7_01.jpg', - 'phase_4/maps/Blue_shorts_1.jpg', - 'phase_4/maps/Red_shorts_1.jpg', - 'phase_4/maps/Purple_shorts_1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_winter1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_winter2.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_winter3.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_winter4.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_valentine1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_valentine2.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_fishing1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_gardening1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_party1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_racing1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_summer1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_golf1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_halloween1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_halloween2.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_saveBuilding1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_trolley1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_halloween4.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_halloween3.jpg', - 'phase_4/maps/tt_t_chr_shorts_scientistA.jpg', - 'phase_4/maps/tt_t_chr_shorts_scientistB.jpg', - 'phase_4/maps/tt_t_chr_shorts_scientistC.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_cogbuster.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_sellbotCrusher.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_halloween5.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_halloweenTurtle.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_greentoon1.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_racingGrandPrix.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_lawbotCrusher.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_bee.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_pirate.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_supertoon.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_vampire.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_dinosaur.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_golf03.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_racing03.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_golf04.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_golf05.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_racing04.jpg', - 'phase_4/maps/tt_t_chr_avt_shorts_racing05.jpg'] +Sleeves = ['phase_3/maps/desat_sleeve_1.png', + 'phase_3/maps/desat_sleeve_2.png', + 'phase_3/maps/desat_sleeve_3.png', + 'phase_3/maps/desat_sleeve_4.png', + 'phase_3/maps/desat_sleeve_5.png', + 'phase_3/maps/desat_sleeve_6.png', + 'phase_3/maps/desat_sleeve_7.png', + 'phase_3/maps/desat_sleeve_8.png', + 'phase_3/maps/desat_sleeve_9.png', + 'phase_3/maps/desat_sleeve_10.png', + 'phase_3/maps/desat_sleeve_15.png', + 'phase_3/maps/desat_sleeve_16.png', + 'phase_3/maps/desat_sleeve_19.png', + 'phase_3/maps/desat_sleeve_20.png', + 'phase_4/maps/female_sleeve1b.png', + 'phase_4/maps/female_sleeve2.png', + 'phase_4/maps/female_sleeve3.png', + 'phase_4/maps/male_sleeve1.png', + 'phase_4/maps/male_sleeve2_palm.png', + 'phase_4/maps/male_sleeve3c.png', + 'phase_4/maps/shirt_Sleeve_ghost.png', + 'phase_4/maps/shirt_Sleeve_pumkin.png', + 'phase_4/maps/holidaySleeve1.png', + 'phase_4/maps/holidaySleeve3.png', + 'phase_4/maps/female_sleeve1b.png', + 'phase_4/maps/female_sleeve5New.png', + 'phase_4/maps/male_sleeve4New.png', + 'phase_4/maps/sleeve6New.png', + 'phase_4/maps/SleeveMaleNew7.png', + 'phase_4/maps/female_sleeveNew6.png', + 'phase_4/maps/Vday5Sleeve.png', + 'phase_4/maps/Vda6Sleeve.png', + 'phase_4/maps/Vday_shirt4sleeve.png', + 'phase_4/maps/Vday2cSleeve.png', + 'phase_4/maps/sleeveTieDye.png', + 'phase_4/maps/male_sleeve1.png', + 'phase_4/maps/StPats_sleeve.png', + 'phase_4/maps/StPats_sleeve2.png', + 'phase_4/maps/ContestfishingVestSleeve1.png', + 'phase_4/maps/ContestFishtankSleeve1.png', + 'phase_4/maps/ContestPawSleeve1.png', + 'phase_4/maps/CowboySleeve1.png', + 'phase_4/maps/CowboySleeve2.png', + 'phase_4/maps/CowboySleeve3.png', + 'phase_4/maps/CowboySleeve4.png', + 'phase_4/maps/CowboySleeve5.png', + 'phase_4/maps/CowboySleeve6.png', + 'phase_4/maps/4thJulySleeve1.png', + 'phase_4/maps/4thJulySleeve2.png', + 'phase_4/maps/shirt_sleeveCat7_01.png', + 'phase_4/maps/shirt_sleeveCat7_02.png', + 'phase_4/maps/contest_backpack_sleeve.png', + 'phase_4/maps/Contest_leder_sleeve.png', + 'phase_4/maps/contest_mellon_sleeve2.png', + 'phase_4/maps/contest_race_sleeve.png', + 'phase_4/maps/PJSleeveBlue.png', + 'phase_4/maps/PJSleeveRed.png', + 'phase_4/maps/PJSleevePurple.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_valentine1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_valentine2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_desat4.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_gardening1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_gardening2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_party1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_party2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_summer1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_summer2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_marathon1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_toonTask1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_toonTask2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley2.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_winter1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween3.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween4.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_valentine3.png', + 'phase_4/maps/tt_t_chr_shirtSleeve_scientist.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mailbox.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trashcan.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_loonyLabs.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_hydrant.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_whistle.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_cogbuster.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated01.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_victoryParty01.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_victoryParty02.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_sellbotIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_sellbotVPIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_sellbotCrusher.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_jellyBeans.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_doodle.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween5.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloweenTurtle.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_greentoon1.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_getConnectedMoverShaker.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racingGrandPrix.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_lawbotIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_lawbotVPIcon.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_lawbotCrusher.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_bee.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_pirate.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_supertoon.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_vampire.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_dinosaur.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing04.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf03.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated02.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing03.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding3.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley03.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing05.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf04.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween06.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_winter03.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_halloween07.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_winter02.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing06.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_fishing07.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_golf05.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing04.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_racing05.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated03.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_mostCogsDefeated04.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley04.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_trolley05.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding4.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_saveBuilding05.png', + 'phase_4/maps/tt_t_chr_avt_shirtSleeve_anniversary.png'] +BoyShorts = ['phase_3/maps/desat_shorts_1.png', + 'phase_3/maps/desat_shorts_2.png', + 'phase_3/maps/desat_shorts_4.png', + 'phase_3/maps/desat_shorts_6.png', + 'phase_3/maps/desat_shorts_7.png', + 'phase_3/maps/desat_shorts_8.png', + 'phase_3/maps/desat_shorts_9.png', + 'phase_3/maps/desat_shorts_10.png', + 'phase_4/maps/VdayShorts2.png', + 'phase_4/maps/shorts4.png', + 'phase_4/maps/shorts1.png', + 'phase_4/maps/shorts5.png', + 'phase_4/maps/CowboyShorts1.png', + 'phase_4/maps/CowboyShorts2.png', + 'phase_4/maps/4thJulyShorts1.png', + 'phase_4/maps/shortsCat7_01.png', + 'phase_4/maps/Blue_shorts_1.png', + 'phase_4/maps/Red_shorts_1.png', + 'phase_4/maps/Purple_shorts_1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_winter1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_winter2.png', + 'phase_4/maps/tt_t_chr_avt_shorts_winter3.png', + 'phase_4/maps/tt_t_chr_avt_shorts_winter4.png', + 'phase_4/maps/tt_t_chr_avt_shorts_valentine1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_valentine2.png', + 'phase_4/maps/tt_t_chr_avt_shorts_fishing1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_gardening1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_party1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_racing1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_summer1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_golf1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_halloween1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_halloween2.png', + 'phase_4/maps/tt_t_chr_avt_shorts_saveBuilding1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_trolley1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_halloween4.png', + 'phase_4/maps/tt_t_chr_avt_shorts_halloween3.png', + 'phase_4/maps/tt_t_chr_shorts_scientistA.png', + 'phase_4/maps/tt_t_chr_shorts_scientistB.png', + 'phase_4/maps/tt_t_chr_shorts_scientistC.png', + 'phase_4/maps/tt_t_chr_avt_shorts_cogbuster.png', + 'phase_4/maps/tt_t_chr_avt_shorts_sellbotCrusher.png', + 'phase_4/maps/tt_t_chr_avt_shorts_halloween5.png', + 'phase_4/maps/tt_t_chr_avt_shorts_halloweenTurtle.png', + 'phase_4/maps/tt_t_chr_avt_shorts_greentoon1.png', + 'phase_4/maps/tt_t_chr_avt_shorts_racingGrandPrix.png', + 'phase_4/maps/tt_t_chr_avt_shorts_lawbotCrusher.png', + 'phase_4/maps/tt_t_chr_avt_shorts_bee.png', + 'phase_4/maps/tt_t_chr_avt_shorts_pirate.png', + 'phase_4/maps/tt_t_chr_avt_shorts_supertoon.png', + 'phase_4/maps/tt_t_chr_avt_shorts_vampire.png', + 'phase_4/maps/tt_t_chr_avt_shorts_dinosaur.png', + 'phase_4/maps/tt_t_chr_avt_shorts_golf03.png', + 'phase_4/maps/tt_t_chr_avt_shorts_racing03.png', + 'phase_4/maps/tt_t_chr_avt_shorts_golf04.png', + 'phase_4/maps/tt_t_chr_avt_shorts_golf05.png', + 'phase_4/maps/tt_t_chr_avt_shorts_racing04.png', + 'phase_4/maps/tt_t_chr_avt_shorts_racing05.png'] SHORTS = 0 SKIRT = 1 -GirlBottoms = [('phase_3/maps/desat_skirt_1.jpg', SKIRT), - ('phase_3/maps/desat_skirt_2.jpg', SKIRT), - ('phase_3/maps/desat_skirt_3.jpg', SKIRT), - ('phase_3/maps/desat_skirt_4.jpg', SKIRT), - ('phase_3/maps/desat_skirt_5.jpg', SKIRT), - ('phase_3/maps/desat_shorts_1.jpg', SHORTS), - ('phase_3/maps/desat_shorts_5.jpg', SHORTS), - ('phase_3/maps/desat_skirt_6.jpg', SKIRT), - ('phase_3/maps/desat_skirt_7.jpg', SKIRT), - ('phase_3/maps/desat_shorts_10.jpg', SHORTS), - ('phase_4/maps/female_skirt1.jpg', SKIRT), - ('phase_4/maps/female_skirt2.jpg', SKIRT), - ('phase_4/maps/female_skirt3.jpg', SKIRT), - ('phase_4/maps/VdaySkirt1.jpg', SKIRT), - ('phase_4/maps/skirtNew5.jpg', SKIRT), - ('phase_4/maps/shorts5.jpg', SHORTS), - ('phase_4/maps/CowboySkirt1.jpg', SKIRT), - ('phase_4/maps/CowboySkirt2.jpg', SKIRT), - ('phase_4/maps/4thJulySkirt1.jpg', SKIRT), - ('phase_4/maps/skirtCat7_01.jpg', SKIRT), - ('phase_4/maps/Blue_shorts_1.jpg', SHORTS), - ('phase_4/maps/Red_shorts_1.jpg', SHORTS), - ('phase_4/maps/Purple_shorts_1.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_skirt_winter1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_winter2.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_winter3.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_winter4.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_valentine1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_valentine2.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_fishing1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_gardening1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_party1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_racing1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_summer1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_golf1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_halloween1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_halloween2.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_saveBuilding1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_trolley1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_halloween3.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_halloween4.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_shorts_scientistA.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_shorts_scientistB.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_shorts_scientistC.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_cogbuster.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_sellbotCrusher.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_halloween5.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_halloweenTurtle.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_skirt_greentoon1.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_racingGrandPrix.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_shorts_lawbotCrusher.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_bee.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_pirate.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_skirt_pirate.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_shorts_supertoon.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_vampire.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_shorts_dinosaur.jpg', SHORTS), - ('phase_4/maps/tt_t_chr_avt_skirt_golf02.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_racing03.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_golf03.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_golf04.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_racing04.jpg', SKIRT), - ('phase_4/maps/tt_t_chr_avt_skirt_racing05.jpg', SKIRT)] +GirlBottoms = [('phase_3/maps/desat_skirt_1.png', SKIRT), + ('phase_3/maps/desat_skirt_2.png', SKIRT), + ('phase_3/maps/desat_skirt_3.png', SKIRT), + ('phase_3/maps/desat_skirt_4.png', SKIRT), + ('phase_3/maps/desat_skirt_5.png', SKIRT), + ('phase_3/maps/desat_shorts_1.png', SHORTS), + ('phase_3/maps/desat_shorts_5.png', SHORTS), + ('phase_3/maps/desat_skirt_6.png', SKIRT), + ('phase_3/maps/desat_skirt_7.png', SKIRT), + ('phase_3/maps/desat_shorts_10.png', SHORTS), + ('phase_4/maps/female_skirt1.png', SKIRT), + ('phase_4/maps/female_skirt2.png', SKIRT), + ('phase_4/maps/female_skirt3.png', SKIRT), + ('phase_4/maps/VdaySkirt1.png', SKIRT), + ('phase_4/maps/skirtNew5.png', SKIRT), + ('phase_4/maps/shorts5.png', SHORTS), + ('phase_4/maps/CowboySkirt1.png', SKIRT), + ('phase_4/maps/CowboySkirt2.png', SKIRT), + ('phase_4/maps/4thJulySkirt1.png', SKIRT), + ('phase_4/maps/skirtCat7_01.png', SKIRT), + ('phase_4/maps/Blue_shorts_1.png', SHORTS), + ('phase_4/maps/Red_shorts_1.png', SHORTS), + ('phase_4/maps/Purple_shorts_1.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_skirt_winter1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_winter2.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_winter3.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_winter4.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_valentine1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_valentine2.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_fishing1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_gardening1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_party1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_racing1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_summer1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_golf1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_halloween1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_halloween2.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_saveBuilding1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_trolley1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_halloween3.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_halloween4.png', SKIRT), + ('phase_4/maps/tt_t_chr_shorts_scientistA.png', SHORTS), + ('phase_4/maps/tt_t_chr_shorts_scientistB.png', SHORTS), + ('phase_4/maps/tt_t_chr_shorts_scientistC.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_cogbuster.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_sellbotCrusher.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_halloween5.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_halloweenTurtle.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_skirt_greentoon1.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_racingGrandPrix.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_shorts_lawbotCrusher.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_bee.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_pirate.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_skirt_pirate.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_shorts_supertoon.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_vampire.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_shorts_dinosaur.png', SHORTS), + ('phase_4/maps/tt_t_chr_avt_skirt_golf02.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_racing03.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_golf03.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_golf04.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_racing04.png', SKIRT), + ('phase_4/maps/tt_t_chr_avt_skirt_racing05.png', SKIRT)] ClothesColors = [VBase4(0.933594, 0.265625, 0.28125, 1.0), VBase4(0.863281, 0.40625, 0.417969, 1.0), VBase4(0.710938, 0.234375, 0.4375, 1.0), @@ -2037,25 +2037,25 @@ HatModels = [None, 'phase_4/models/accessories/tt_m_chr_avt_acc_hat_band', 'phase_4/models/accessories/tt_m_chr_avt_acc_hat_birdNest'] HatTextures = [None, - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonRed.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonPurple.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_heartYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_topHatBlue.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_safariBrown.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_safariGreen.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballBlue.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballOrange.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonChecker.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonLtRed.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonRainbow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballRed.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballTeal.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonPinkDots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballPurple.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonCheckerGreen.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_hat_partyToon.jpg'] + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonRed.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonPurple.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_heartYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_topHatBlue.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_safariBrown.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_safariGreen.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballBlue.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballOrange.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonChecker.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonLtRed.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonRainbow.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballRed.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballTeal.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonPinkDots.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_baseballPurple.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_ribbonCheckerGreen.png', + 'phase_4/maps/tt_t_chr_avt_acc_hat_partyToon.png'] GlassesModels = [None, 'phase_4/models/accessories/tt_m_chr_avt_acc_msk_roundGlasses', 'phase_4/models/accessories/tt_m_chr_avt_acc_msk_miniblinds', @@ -2079,10 +2079,10 @@ GlassesModels = [None, 'phase_4/models/accessories/tt_m_chr_avt_acc_msk_eyepatch', 'phase_4/models/accessories/tt_m_chr_avt_acc_msk_alienGlasses'] GlassesTextures = [None, - 'phase_4/maps/tt_t_chr_avt_acc_msk_masqueradeTypeMask2.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_msk_masqueradeTypeMask4.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_msk_masqueradeTypeMask5.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_msk_eyepatchGems.jpg'] + 'phase_4/maps/tt_t_chr_avt_acc_msk_masqueradeTypeMask2.png', + 'phase_4/maps/tt_t_chr_avt_acc_msk_masqueradeTypeMask4.png', + 'phase_4/maps/tt_t_chr_avt_acc_msk_masqueradeTypeMask5.png', + 'phase_4/maps/tt_t_chr_avt_acc_msk_eyepatchGems.png'] BackpackModels = [None, 'phase_4/models/accessories/tt_m_chr_avt_acc_pac_backpack', 'phase_4/models/accessories/tt_m_chr_avt_acc_pac_batWings', @@ -2109,65 +2109,65 @@ BackpackModels = [None, 'phase_4/models/accessories/tt_m_chr_avt_acc_pac_gags', 'phase_4/models/accessories/tt_m_chr_avt_acc_pac_flunky'] BackpackTextures = [None, - 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackOrange.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackPurple.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackPolkaDotRed.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackPolkaDotYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_pac_angelWingsMultiColor.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_pac_butterflyWingsStyle2.jpg'] + 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackOrange.png', + 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackPurple.png', + 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackPolkaDotRed.png', + 'phase_4/maps/tt_t_chr_avt_acc_pac_backpackPolkaDotYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_pac_angelWingsMultiColor.png', + 'phase_4/maps/tt_t_chr_avt_acc_pac_butterflyWingsStyle2.png'] ShoesModels = ['feet', 'shoes', 'boots_short', 'boots_long'] -ShoesTextures = ['phase_3/maps/tt_t_chr_avt_acc_sho_athleticGreen.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_athleticRed.jpg', - 'phase_3/maps/tt_t_chr_avt_acc_sho_docMartinBootsGreen.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleGreen.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_wingtips.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoes.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_deckShoes.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_athleticYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleBlack.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleWhite.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStylePink.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_cowboyBoots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsPurple.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_hiTopSneakers.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoesBrown.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoesRed.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_superToonRedBoots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesGreen.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesPink.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleRed.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsAqua.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsBrown.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsBlueSquares.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsGreenHearts.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsGreyDots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsOrangeStars.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsPinkStars.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_loafers.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoesPurple.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_motorcycleBoots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_oxfords.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsPink.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_santaBoots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_winterBootsBeige.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_winterBootsPink.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_workBoots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsPink.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_hiTopSneakersPink.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsRedDots.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesPurple.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesViolet.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsBlue.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsYellow.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_athleticBlack.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_pirate.jpg', - 'phase_4/maps/tt_t_chr_avt_acc_sho_dinosaur.jpg'] +ShoesTextures = ['phase_3/maps/tt_t_chr_avt_acc_sho_athleticGreen.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_athleticRed.png', + 'phase_3/maps/tt_t_chr_avt_acc_sho_docMartinBootsGreen.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleGreen.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_wingtips.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoes.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_deckShoes.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_athleticYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleBlack.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleWhite.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStylePink.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_cowboyBoots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsPurple.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_hiTopSneakers.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoesBrown.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoesRed.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_superToonRedBoots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesGreen.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesPink.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleRed.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsAqua.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsBrown.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsBlueSquares.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsGreenHearts.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsGreyDots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsOrangeStars.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_fashionBootsPinkStars.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_loafers.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_maryJaneShoesPurple.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_motorcycleBoots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_oxfords.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsPink.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_santaBoots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_winterBootsBeige.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_winterBootsPink.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_workBoots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_docMartinBootsPink.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_hiTopSneakersPink.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsRedDots.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesPurple.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesViolet.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_tennisShoesYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsBlue.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_rainBootsYellow.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_athleticBlack.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_pirate.png', + 'phase_4/maps/tt_t_chr_avt_acc_sho_dinosaur.png'] HatStyles = {'none': [0, 0, 0], 'hbb1': [1, 0, 0], 'hsf1': [2, 0, 0], diff --git a/toontown/toon/ToonHead.py b/toontown/toon/ToonHead.py index cabe008..8ac6f87 100644 --- a/toontown/toon/ToonHead.py +++ b/toontown/toon/ToonHead.py @@ -49,31 +49,31 @@ DogMuzzleDict = {'dls': '/models/char/dogMM_Shorts-headMuzzles-', class ToonHead(Actor.Actor): notify = DirectNotifyGlobal.directNotify.newCategory('ToonHead') - EyesOpen = loader.loadTexture('phase_3/maps/eyes.jpg', 'phase_3/maps/eyes_a.rgb') + EyesOpen = loader.loadTexture('phase_3/maps/eyes.png') EyesOpen.setMinfilter(Texture.FTLinear) EyesOpen.setMagfilter(Texture.FTLinear) - EyesClosed = loader.loadTexture('phase_3/maps/eyesClosed.jpg', 'phase_3/maps/eyesClosed_a.rgb') + EyesClosed = loader.loadTexture('phase_3/maps/eyesClosed.png') EyesClosed.setMinfilter(Texture.FTLinear) EyesClosed.setMagfilter(Texture.FTLinear) - EyesSadOpen = loader.loadTexture('phase_3/maps/eyesSad.jpg', 'phase_3/maps/eyesSad_a.rgb') + EyesSadOpen = loader.loadTexture('phase_3/maps/eyesSad.png') EyesSadOpen.setMinfilter(Texture.FTLinear) EyesSadOpen.setMagfilter(Texture.FTLinear) - EyesSadClosed = loader.loadTexture('phase_3/maps/eyesSadClosed.jpg', 'phase_3/maps/eyesSadClosed_a.rgb') + EyesSadClosed = loader.loadTexture('phase_3/maps/eyesSadClosed.png') EyesSadClosed.setMinfilter(Texture.FTLinear) EyesSadClosed.setMagfilter(Texture.FTLinear) - EyesAngryOpen = loader.loadTexture('phase_3/maps/eyesAngry.jpg', 'phase_3/maps/eyesAngry_a.rgb') + EyesAngryOpen = loader.loadTexture('phase_3/maps/eyesAngry.png') EyesAngryOpen.setMinfilter(Texture.FTLinear) EyesAngryOpen.setMagfilter(Texture.FTLinear) - EyesAngryClosed = loader.loadTexture('phase_3/maps/eyesAngryClosed.jpg', 'phase_3/maps/eyesAngryClosed_a.rgb') + EyesAngryClosed = loader.loadTexture('phase_3/maps/eyesAngryClosed.png') EyesAngryClosed.setMinfilter(Texture.FTLinear) EyesAngryClosed.setMagfilter(Texture.FTLinear) - EyesSurprised = loader.loadTexture('phase_3/maps/eyesSurprised.jpg', 'phase_3/maps/eyesSurprised_a.rgb') + EyesSurprised = loader.loadTexture('phase_3/maps/eyesSurprised.png') EyesSurprised.setMinfilter(Texture.FTLinear) EyesSurprised.setMagfilter(Texture.FTLinear) - Muzzle = loader.loadTexture('phase_3/maps/muzzleShrtGeneric.jpg') + Muzzle = loader.loadTexture('phase_3/maps/muzzleShrtGeneric.png') Muzzle.setMinfilter(Texture.FTLinear) Muzzle.setMagfilter(Texture.FTLinear) - MuzzleSurprised = loader.loadTexture('phase_3/maps/muzzleShortSurprised.jpg') + MuzzleSurprised = loader.loadTexture('phase_3/maps/muzzleShortSurprised.png') MuzzleSurprised.setMinfilter(Texture.FTLinear) MuzzleSurprised.setMagfilter(Texture.FTLinear) LeftA = Point3(0.06, 0.0, 0.14) diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 925284f..2416935 100644 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -10,22 +10,24 @@ InterfaceFont = 'phase_3/models/fonts/ImpressBT.ttf' ToonFont = 'phase_3/models/fonts/ImpressBT.ttf' SuitFont = 'phase_3/models/fonts/vtRemingtonPortable.ttf' SignFont = 'phase_3/models/fonts/MickeyFont' -MinnieFont = 'phase_3/models/fonts/MinnieFont' -FancyFont = 'phase_3/models/fonts/Comedy' -NametagFonts = ('phase_3/models/fonts/AnimGothic', - 'phase_3/models/fonts/Aftershock', - 'phase_3/models/fonts/JiggeryPokery', - 'phase_3/models/fonts/Ironwork', - 'phase_3/models/fonts/HastyPudding', - 'phase_3/models/fonts/Comedy', - 'phase_3/models/fonts/Humanist', - 'phase_3/models/fonts/Portago', - 'phase_3/models/fonts/Musicals', - 'phase_3/models/fonts/Scurlock', - 'phase_3/models/fonts/Danger', - 'phase_3/models/fonts/Alie', - 'phase_3/models/fonts/OysterBar', - 'phase_3/models/fonts/RedDogSaloon') +MinnieFont = 'phase_3/models/fonts/MinnieFont.ttf' +FancyFont = 'phase_3/models/fonts/Comedy.ttf' +NametagFonts = ( + 'phase_3/models/fonts/AnimGothic.ttf', + 'phase_3/models/fonts/Aftershock.ttf', + 'phase_3/models/fonts/JiggeryPokery.ttf', + 'phase_3/models/fonts/Ironwork.ttf', + 'phase_3/models/fonts/HastyPudding.ttf', + 'phase_3/models/fonts/Comedy.ttf', + 'phase_3/models/fonts/Humanist.ttf', + 'phase_3/models/fonts/Portago.ttf', + 'phase_3/models/fonts/Musicals.ttf', + 'phase_3/models/fonts/Scurlock.ttf', + 'phase_3/models/fonts/Danger.ttf', + 'phase_3/models/fonts/Alie.ttf', + 'phase_3/models/fonts/OysterBar.ttf', + 'phase_3/models/fonts/RedDogSaloon.ttf' +) NametagFontNames = ('Member', 'Shivering', 'Wonky', diff --git a/toontown/toonbase/ToonBaseGlobal.py b/toontown/toonbase/ToonBaseGlobal.py index d10c337..7ddaba1 100644 --- a/toontown/toonbase/ToonBaseGlobal.py +++ b/toontown/toonbase/ToonBaseGlobal.py @@ -1 +1,5 @@ -from .ToonBase import * +__all__ = ['base'] + +from .ToonBase import ToonBase + +base = ToonBase() diff --git a/toontown/toonbase/ToontownStart.py b/toontown/toonbase/ToontownStart.py index 6ecda03..de6d608 100644 --- a/toontown/toonbase/ToontownStart.py +++ b/toontown/toonbase/ToontownStart.py @@ -6,7 +6,20 @@ class game: builtins.game = game() -from panda3d.core import * +from panda3d.core import ( + ConfigVariableBool, + ConfigVariableDouble, + ConfigVariableString, + Filename, + HTTPClient, + Loader, + loadPrcFile, + TextNode, + Thread, + VBase3, + Vec4 +) + import time import sys try: @@ -31,6 +44,7 @@ if launcher.isDummy(): http = HTTPClient() else: http = launcher.http + tempLoader = Loader() backgroundNode = tempLoader.loadSync(Filename('phase_3/models/gui/loading-background')) from direct.gui import DirectGuiGlobals @@ -38,11 +52,11 @@ print('ToontownStart: setting default font') from . import ToontownGlobals DirectGuiGlobals.setDefaultFontFunc(ToontownGlobals.getInterfaceFont) launcher.setPandaErrorCode(7) -from . import ToonBase -ToonBase.ToonBase() +from .ToonBaseGlobal import base if base.win == None: print('Unable to open window; aborting.') sys.exit() + launcher.setPandaErrorCode(0) launcher.setPandaWindowOpen() ConfigVariableDouble('decompressor-step-time').setValue(0.01) @@ -65,31 +79,32 @@ if base.musicManagerIsValid: music.setLoop(1) music.setVolume(0.9) music.play() + print('ToontownStart: Loading default gui sounds') DirectGuiGlobals.setDefaultRolloverSound(base.loader.loadSfx('phase_3/audio/sfx/GUI_rollover.ogg')) DirectGuiGlobals.setDefaultClickSound(base.loader.loadSfx('phase_3/audio/sfx/GUI_create_toon_fwd.ogg')) else: music = None -from direct.gui.DirectGui import * + +from direct.gui.DirectGui import OnscreenText serverVersion = ConfigVariableString('server-version', 'no_version_set').value print('ToontownStart: serverVersion: ', serverVersion) version = OnscreenText(serverVersion, pos=(-1.3, -0.975), scale=0.06, fg=Vec4(0, 0, 1, 0.6), align=TextNode.ALeft) loader.beginBulkLoad('init', TTLocalizer.LoaderLabel, 138, 0, TTLocalizer.TIP_NONE) -from .ToonBaseGlobal import * -from direct.showbase.MessengerGlobal import * -from toontown.distributed import ToontownClientRepository -cr = ToontownClientRepository.ToontownClientRepository(serverVersion, launcher) +from toontown.distributed.ToontownClientRepository import ToontownClientRepository +cr = ToontownClientRepository(serverVersion, launcher) cr.music = music del music base.initNametagGlobals() base.cr = cr loader.endBulkLoad('init') -from otp.distributed.OtpDoGlobals import * +from otp.distributed.OtpDoGlobals import OTP_DO_ID_FRIEND_MANAGER cr.generateGlobalObject(OTP_DO_ID_FRIEND_MANAGER, 'FriendManager') if not launcher.isDummy(): base.startShow(cr, launcher.getGameServer()) else: base.startShow(cr) + backgroundNodePath.reparentTo(hidden) backgroundNodePath.removeNode() del backgroundNodePath @@ -97,7 +112,6 @@ del backgroundNode del tempLoader version.cleanup() del version -base.loader = base.loader builtins.loader = base.loader autoRun = ConfigVariableBool('toontown-auto-run', 1) if autoRun and launcher.isDummy() and (not Thread.isTrueThreads() or __name__ == '__main__'): diff --git a/toontown/town/Street.py b/toontown/town/Street.py index 14788b1..5f0238a 100644 --- a/toontown/town/Street.py +++ b/toontown/town/Street.py @@ -381,13 +381,11 @@ class Street(BattlePlace.BattlePlace): streetSign = base.cr.streetSign signTexturePath = streetSign.StreetSignBaseDir + '/' + streetSign.StreetSignFileName loaderTexturePath = Filename(str(signTexturePath)) - alphaPath = 'phase_4/maps/tt_t_ara_gen_tunnelAheadSign_a.rgb' inDreamland = False if place.zoneId and ZoneUtil.getCanonicalHoodId(place.zoneId) == ToontownGlobals.DonaldsDreamland: inDreamland = True - alphaPath = 'phase_4/maps/tt_t_ara_gen_tunnelAheadSign_a.rgb' if Filename(signTexturePath).exists(): - signTexture = loader.loadTexture(loaderTexturePath, alphaPath) + signTexture = loader.loadTexture(loaderTexturePath) for sign in signs: if Filename(signTexturePath).exists(): sign.setTexture(signTexture, 1) diff --git a/toontown/uberdog/DistributedPartyManagerAI.py b/toontown/uberdog/DistributedPartyManagerAI.py index 2de29d9..75866e7 100644 --- a/toontown/uberdog/DistributedPartyManagerAI.py +++ b/toontown/uberdog/DistributedPartyManagerAI.py @@ -3,3 +3,6 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI class DistributedPartyManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPartyManagerAI') + + def canBuyParties(self): + return False # TODO