True Friends

This commit is contained in:
John 2015-07-31 14:45:00 +03:00
parent 8a0467cf7e
commit 90b98ad3ef
16 changed files with 436 additions and 78 deletions

5
.gitignore vendored
View file

@ -19,3 +19,8 @@
# Local config
dependencies/config/local.prc
# PyMongo
bson
gridfs
pymongo

View file

@ -175,6 +175,9 @@ dclass FriendManager : DistributedObject {
friendResponse(int8, int32);
inviteeFriendQuery(int32, string, blob, int32);
inviteeCancelFriendQuery(int32);
requestTFCode() airecv clsend;
redeemTFCode(string) airecv clsend;
tfResponse(uint8, string);
};
from toontown.building import DistributedAnimatedProp/AI
@ -742,8 +745,9 @@ dclass DistributedToon : DistributedPlayer {
setBuffs(uint32[] = []) required ownrecv db;
setRedeemedCodes(string [] = []) required ownrecv db;
setEmblems(uint32[] = [0, 0]) required ownrecv db;
setTrueFriends(uint32[] = []) required clsend ownrecv db;
setTrueFriends(uint32[] = []) required ownrecv db;
setNextKnockHeal(uint32) ram airecv;
setTFRequest(uint32[] = [0, 0]) ram airecv;
setEPP(uint8[] = []) required ownrecv db;
setStats(uint32[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) required ownrecv db;
requestNametagStyle(uint8) airecv ownsend;

View file

@ -91,3 +91,14 @@ class FriendManager(DistributedObject.DistributedObject):
self.notify.debug('Client: inviteeCancelFriendQuery(%d)' % context)
messenger.send('cancelFriendInvitation', [context])
self.up_inviteeAcknowledgeCancel(context)
def requestTFCode(self, callback):
self.tfCallback = callback
self.sendUpdate('requestTFCode')
def redeemTFCode(self, code, callback):
self.tfCallback = callback
self.sendUpdate('redeemTFCode', [code])
def tfResponse(self, response, code):
self.tfCallback(response, code)

View file

@ -1,5 +1,56 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from otp.otpbase import OTPGlobals
from toontown.toonbase import ToontownGlobals
import datetime, uuid, time
class AddTrueFriend:
def __init__(self, manager, av, targetId, code):
self.air = manager.air
self.manager = manager
self.av = av
self.targetId = targetId
self.code = code
def start(self):
self.air.dbInterface.queryObject(self.air.dbId, self.targetId, self.__gotAvatar)
def __gotAvatar(self, dclass, fields):
dclasses = self.air.dclassesByName['DistributedToonAI']
if dclass != dclasses:
return
friendsList = fields['setFriendsList'][0]
trueFriendsList = fields['setTrueFriends'][0]
name = fields['setName'][0]
avId = self.av.doId
if avId in trueFriendsList:
self.manager.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_ALREADY_FRIENDS_NAME, name])
return
elif avId not in friendsList:
if len(friendsList) >= OTPGlobals.MaxFriends:
self.manager.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_FRIENDS_LIST_FULL_HIM, name])
return
friendsList.append(avId)
if self.targetId not in self.av.getFriendsList():
self.av.extendFriendsList(self.targetId)
if hasattr(self.manager, 'data'):
del self.manager.data[self.code]
else:
self.air.dbGlobalCursor.tfCodes.remove({'_id': self.code})
self.av.addTrueFriend(self.targetId)
trueFriendsList.append(avId)
self.air.send(dclasses.aiFormatUpdate('setFriendsList', self.targetId, self.targetId, self.air.ourChannel, [friendsList]))
self.air.send(dclasses.aiFormatUpdate('setTrueFriends', self.targetId, self.targetId, self.air.ourChannel, [trueFriendsList]))
self.manager.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_SUCCESS, name])
del self.manager.tfFsms[avId]
class FriendManagerAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("FriendManagerAI")
@ -9,6 +60,15 @@ class FriendManagerAI(DistributedObjectAI):
self.air = air
self.currentContext = 0
self.requests = {}
self.tfFsms = {}
self.connectToDatabase()
def connectToDatabase(self):
if not self.air.dbConn:
self.notify.warning('Not using mongodb, true friends will be non-persistent')
self.data = {}
else:
self.air.dbGlobalCursor.tfCodes.ensure_index('date', expireAfterSeconds=ToontownGlobals.TF_EXPIRE_SECS)
def friendQuery(self, requested):
avId = self.air.getAvatarIdFromSender()
@ -118,3 +178,67 @@ class FriendManagerAI(DistributedObjectAI):
return
del self.requests[context]
def requestTFCode(self):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if not av:
return
tfRequest = av.getTFRequest()
if tfRequest[1] >= ToontownGlobals.MAX_TF_TRIES and tfRequest[0] >= time.time():
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_COOLDOWN, ''])
return
code = str(uuid.uuid4())
if hasattr(self, 'data'):
self.data[code] = avId
else:
self.air.dbGlobalCursor.tfCodes.insert({'_id': code, 'date': datetime.datetime.utcnow(), 'avId': avId})
av.b_setTFRequest((time.time() + ToontownGlobals.TF_COOLDOWN_SECS, tfRequest[1] + 1))
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_SUCCESS, code])
def redeemTFCode(self, code):
avId = self.air.getAvatarIdFromSender()
if avId in self.tfFsms:
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_TOO_FAST, ''])
return
av = self.air.doId2do.get(avId)
if not av:
return
if hasattr(self, 'data'):
if code not in self.data:
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_UNKNOWN_SECRET, ''])
return
targetId = self.data[code]
else:
fields = self.air.dbGlobalCursor.tfCodes.find_one({'_id': code})
if not fields:
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_UNKNOWN_SECRET, ''])
return
targetId = fields['avId']
if avId == targetId:
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_SELF_SECRET, ''])
return
elif av.isTrueFriends(targetId):
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_ALREADY_FRIENDS, ''])
return
elif targetId not in av.getFriendsList() and len(av.getFriendsList()) >= OTPGlobals.MaxFriends:
self.sendUpdateToAvatarId(avId, 'tfResponse', [ToontownGlobals.TF_FRIENDS_LIST_FULL_YOU, ''])
return
tfOperation = AddTrueFriend(self, av, targetId, code)
tfOperation.start()
self.tfFsms[avId] = tfOperation

View file

@ -234,6 +234,7 @@ FriendInviterConfirmRemove = 'Remove'
FriendInviterYes = lYes
FriendInviterNo = lNo
FriendInviterClickToon = 'Click on the toon you would like to make friends with.'
FriendInviterTooMany = 'You have too many friends on your list to add another one now. You will have to remove some friends if you want to make friends with %s.'
FriendInviterToonTooMany = 'You have too many toon friends on your list to add another one now. You will have to remove some toon friends if you want to make friends with %s.'
FriendInviterNotYet = 'Would you like to make friends with %s?'
FriendInviterCheckAvailability = 'Seeing if %s is available.'

View file

@ -30,6 +30,7 @@ from toontown.toonbase.ToontownGlobals import *
from toontown.distributed import DelayDelete
from toontown.friends import FriendHandle
from toontown.friends import FriendsListPanel
from toontown.friends import ToontownFriendSecret
from toontown.login import AvatarChooser
from toontown.makeatoon import MakeAToon
from toontown.pets import DistributedPet, PetDetail, PetHandle
@ -408,6 +409,7 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository):
if self.objectManager != None:
self.objectManager.destroy()
self.objectManager = None
ToontownFriendSecret.unloadFriendSecret()
FriendsListPanel.unloadFriendsList()
messenger.send('cancelFriendInvitation')
base.removeGlitchMessage()
@ -663,7 +665,6 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository):
def removeFriend(self, avatarId):
self.ttsFriendsManager.d_removeFriend(avatarId)
base.localAvatar.removeTrueFriends(avatarId)
def clearFriendState(self):
self.friendsMap = {}

View file

@ -5,6 +5,7 @@ import FriendInvitee
import FriendNotifier
from direct.directnotify import DirectNotifyGlobal
from toontown.toon import ToonTeleportPanel
from toontown.friends import ToontownFriendSecret
from toontown.pets import PetAvatarPanel
from toontown.toon import ToonAvatarPanel
from toontown.suit import SuitAvatarPanel
@ -73,6 +74,7 @@ class FriendsListManager:
self.ignore('friendAvatar')
self.ignore('avatarDetails')
FriendsListPanel.hideFriendsList()
ToontownFriendSecret.hideFriendSecret()
if base.cr.friendManager:
base.cr.friendManager.setAvailable(0)
self.ignore('friendInvitation')

View file

@ -2,6 +2,7 @@ from panda3d.core import *
from direct.gui.DirectGui import *
from direct.fsm import StateData
from toontown.toon import ToonAvatarPanel
from toontown.friends import ToontownFriendSecret
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from otp.nametag.NametagGroup import *
@ -94,7 +95,6 @@ class FriendsListPanel(DirectFrame, StateData.StateData):
self.textDownColor = Vec4(0.5, 0.9, 1, 1)
self.textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
self.panelType = FLPOnline
return
def load(self):
if self.isLoaded == 1:
@ -128,9 +128,12 @@ class FriendsListPanel(DirectFrame, StateData.StateData):
gui.find('**/Horiz_Arrow_Rllvr'),
gui.find('**/Horiz_Arrow_UP')), image3_color=Vec4(0.6, 0.6, 0.6, 0.6), pos=(0.17, 0, -0.38), command=self.__right)
self.newFriend = DirectButton(parent=self, relief=None, pos=(-0.14, 0.0, 0.14), image=(auxGui.find('**/Frnds_Btn_UP'), auxGui.find('**/Frnds_Btn_DN'), auxGui.find('**/Frnds_Btn_RLVR')), text=('', TTLocalizer.FriendsListPanelNewFriend, TTLocalizer.FriendsListPanelNewFriend), text_scale=TTLocalizer.FLPnewFriend, text_fg=(0, 0, 0, 1), text_bg=(1, 1, 1, 1), text_pos=(0.1, -0.085), textMayChange=0, command=self.__newFriend)
self.trueFriends = DirectButton(parent=self, relief=None, pos=TTLocalizer.FLPtruefriendsPos, image=(auxGui.find('**/ChtBx_ChtBtn_UP'), auxGui.find('**/ChtBx_ChtBtn_DN'), auxGui.find('**/ChtBx_ChtBtn_RLVR')), text=('',
TTLocalizer.FriendsListPanelTrueFriends,
TTLocalizer.FriendsListPanelTrueFriends,
''), text_scale=TTLocalizer.FLPtruefriends, text_fg=(0, 0, 0, 1), text_bg=(1, 1, 1, 1), text_pos=(-0.04, -0.085), textMayChange=0, command=self.__trueFriends)
gui.removeNode()
auxGui.removeNode()
return
def unload(self):
if self.isLoaded == 0:
@ -144,7 +147,6 @@ class FriendsListPanel(DirectFrame, StateData.StateData):
del self.right
del self.friends
DirectFrame.destroy(self)
return None
def makeFriendButton(self, avId, color):
handle = base.cr.identifyFriend(avId)
@ -212,10 +214,13 @@ class FriendsListPanel(DirectFrame, StateData.StateData):
self.__updateTitle()
self.__updateArrows()
def __trueFriends(self):
messenger.send('wakeup')
ToontownFriendSecret.showFriendSecret()
def __newFriend(self):
messenger.send('wakeup')
messenger.send('friendAvatar', [None, None, None])
return
def __choseFriend(self, friendId):
messenger.send('wakeup')

View file

@ -95,10 +95,11 @@ class RemoveFriendOperation(OperationFSM):
self.demand('Error', 'Distributed Class was not a Toon.')
return
self.demand('Retrieved', fields['setFriendsList'][0])
self.demand('Retrieved', fields['setFriendsList'][0], fields['setTrueFriends'][0])
def enterRetrieved(self, friendsList):
def enterRetrieved(self, friendsList, trueFriendsList):
friendsList.remove(self.target)
trueFriendsList.remove(self.target)
if self.sender in self.mgr.onlineToons:
dg = self.air.dclassesByName['DistributedToonUD'].aiFormatUpdate(
'setFriendsList', self.sender, self.sender,
@ -114,7 +115,7 @@ class RemoveFriendOperation(OperationFSM):
self.air.dbInterface.updateObject(self.air.dbId, self.sender,
self.air.dclassesByName['DistributedToonUD'],
{'setFriendsList' : [friendsList]})
{'setFriendsList' : [friendsList], 'setTrueFriends' : [trueFriendsList]})
self.demand('Off')
# -- Clear List --

View file

@ -0,0 +1,197 @@
from pandac.PandaModules import *
from direct.gui.DirectGui import *
from direct.directnotify import DirectNotifyGlobal
from toontown.toonbase import TTLocalizer, ToontownGlobals
from otp.otpbase import OTPGlobals
globalFriendSecret = None
def showFriendSecret():
global globalFriendSecret
if not settings['trueFriends']:
chatMgr = base.localAvatar.chatMgr
chatMgr.fsm.request('noTrueFriends')
else:
if globalFriendSecret != None:
globalFriendSecret.unload()
globalFriendSecret = ToontownFriendSecret()
globalFriendSecret.enter()
def hideFriendSecret():
if globalFriendSecret != None:
globalFriendSecret.exit()
def unloadFriendSecret():
global globalFriendSecret
if globalFriendSecret != None:
globalFriendSecret.unload()
globalFriendSecret = None
return
class ToontownFriendSecret(DirectFrame):
notify = DirectNotifyGlobal.directNotify.newCategory('ToontownFriendSecret')
def __init__(self):
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))
self.initialiseoptions(ToontownFriendSecret)
self.isLoaded = 0
self.isEntered = 0
def unload(self):
if self.isLoaded == 0:
return None
self.isLoaded = 0
self.exit()
del self.introText
del self.getSecret
del self.enterSecretText
del self.enterSecret
del self.ok1
del self.ok2
del self.cancel
del self.secretText
DirectFrame.destroy(self)
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=TTLocalizer.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=TTLocalizer.FSgetSecret, text=TTLocalizer.FriendSecretGetSecret, text_scale=TTLocalizer.FSgetSecretButton, text_pos=(0, -0.02), command=self.__getSecret)
self.getSecret.hide()
self.enterSecretText = DirectLabel(parent=self, relief=None, pos=TTLocalizer.FSenterSecretTextPos, scale=0.05, text=TTLocalizer.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.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=TTLocalizer.FSok1, text=TTLocalizer.FriendSecretEnter, text_scale=0.06, text_pos=(0, -0.02), pos=(0, 0, -0.5), command=self.__ok1)
self.ok1.hide()
self.ok2 = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=TTLocalizer.FSok2, text=TTLocalizer.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=TTLocalizer.FriendSecretCancel, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=TTLocalizer.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=TTLocalizer.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.08, text='', text_fg=(0, 0, 0, 1), text_wordwrap=30)
self.secretText.hide()
guiButton.removeNode()
def enter(self):
if self.isEntered == 1:
return
self.isEntered = 1
if self.isLoaded == 0:
self.load()
self.show()
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')
self.enterSecret['focus'] = 1
def exit(self):
if self.isEntered == 0:
return
self.isEntered = 0
self.__cleanupFirstPage()
self.hide()
def __getSecret(self):
self.__cleanupFirstPage()
self.nextText['text'] = TTLocalizer.FriendSecretGettingSecret
self.nextText.setPos(0, 0, 0.3)
self.nextText.show()
self.ok1.hide()
self.cancel.show()
base.cr.friendManager.requestTFCode(self.gotSecret)
def gotSecret(self, response, code):
if response == ToontownGlobals.TF_COOLDOWN:
self.rejectGetSecret(TTLocalizer.FriendSecretTooMany)
elif response == ToontownGlobals.TF_SUCCESS:
self.successGetSecret(code)
def rejectGetSecret(self, reason):
self.nextText['text'] = reason
self.nextText.show()
self.secretText.show()
self.cancel.hide()
self.ok1.hide()
self.ok2.show()
def successGetSecret(self, code):
self.nextText['text'] = TTLocalizer.FriendSecretGotSecret % code
self.nextText.setPos(*TTLocalizer.FSgotSecretPos)
self.secretText['text'] = secret
self.nextText.show()
self.secretText.show()
self.cancel.hide()
self.ok1.hide()
self.ok2.show()
def __enterSecret(self, secret):
self.enterSecret.set('')
secret = secret.strip()
if not secret:
self.exit()
return
self.__cleanupFirstPage()
self.nextText['text'] = TTLocalizer.FriendSecretTryingSecret
base.cr.friendManager.redeemTFCode(secret, self.gotResponse)
self.nextText.setPos(0, 0, 0.3)
self.nextText.show()
self.cancel.hide()
self.ok1.hide()
self.ok2.show()
def gotResponse(self, response, name):
if response == ToontownGlobals.TF_UNKNOWN_SECRET:
self.nextText['text'] = TTLocalizer.FriendSecretEnteredSecretUnknown
elif response == ToontownGlobals.TF_SELF_SECRET:
self.nextText['text'] = TTLocalizer.FriendSecretEnteredSecretSelf
elif response == ToontownGlobals.TF_TOO_FAST:
self.nextText['text'] = TTLocalizer.FriendSecretTooFast
elif response == ToontownGlobals.TF_FRIENDS_LIST_FULL_YOU:
self.nextText['text'] = TTLocalizer.FriendSecretEnteredSecretFullYou
elif response == ToontownGlobals.TF_FRIENDS_LIST_FULL_HIM:
self.nextText['text'] = TTLocalizer.FriendSecretEnteredSecretFullHim % name
elif response == ToontownGlobals.TF_ALREADY_FRIENDS:
self.nextText['text'] = TTLocalizer.FriendSecretAlreadyFriends
elif response == ToontownGlobals.TF_ALREADY_FRIENDS_NAME:
self.nextText['text'] = TTLocalizer.FriendSecretAlreadyFriendsName % name
elif response == ToontownGlobals.TF_SUCCESS:
self.nextText['text'] = TTLocalizer.FriendSecretNowFriends % name
self.nextText.show()
self.cancel.hide()
self.ok1.hide()
self.ok2.show()
def __ok1(self):
secret = self.enterSecret.get()
self.__enterSecret(secret)
def __ok2(self):
self.exit()
def __cancel(self):
self.exit()
def __cleanupFirstPage(self):
self.introText.hide()
self.getSecret.hide()
self.enterSecretText.hide()
self.enterSecret.hide()
base.localAvatar.chatMgr.fsm.request('mainMenu')

View file

@ -2384,30 +2384,13 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
if not self.isReported(doId):
self.reported.append(doId)
def b_setTrueFriends(self, trueFriends):
self.setTrueFriends(trueFriends)
self.d_setTrueFriends(trueFriends)
def setTrueFriends(self, trueFriends):
Toon.reconsiderAllToonsUnderstandable()
self.trueFriends = trueFriends
def d_setTrueFriends(self, trueFriends):
self.sendUpdate('setTrueFriends', [trueFriends])
def isTrueFriends(self, doId):
return doId in self.trueFriends
def addTrueFriends(self, doId):
if not self.isTrueFriends(doId):
self.trueFriends.append(doId)
self.b_setTrueFriends(self.trueFriends)
def removeTrueFriends(self, doId):
if self.isTrueFriends(doId):
self.trueFriends.remove(doId)
self.b_setTrueFriends(self.trueFriends)
def applyBuffs(self):
for id, timestamp in enumerate(self.buffs):
if id == ToontownGlobals.BMovementSpeed:

View file

@ -161,6 +161,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
self.trueFriends = []
self.fishBingoTutorialDone = False
self.nextKnockHeal = 0
self.tfRequest = (0, 0)
self.epp = []
def generate(self):
@ -4091,7 +4092,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
self.b_setRedeemedCodes(self.redeemedCodes)
def setTrueFriends(self, trueFriends):
self.trueFriends = trueFriends[:OTPGlobals.MaxFriends]
self.trueFriends = trueFriends
def d_setTrueFriends(self, trueFriends):
self.sendUpdate('setTrueFriends', [trueFriends])
@ -4100,6 +4101,16 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
self.setTrueFriends(trueFriends)
self.d_setTrueFriends(trueFriends)
def isTrueFriends(self, avId):
return avId in self.trueFriends
def addTrueFriend(self, avId):
if avId in self.trueFriends:
return
self.trueFriends.append(avId)
self.b_setTrueFriends(self.trueFriends)
def getTrueFriends(self, trueFriends):
return self.trueFriends
@ -4116,6 +4127,19 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
def getNextKnockHeal(self):
return self.nextKnockHeal
def setTFRequest(self, tfRequest):
self.tfRequest = tfRequest
def d_setTFRequest(self, tfRequest):
self.sendUpdate('setTFRequest', [tfRequest])
def b_setTFRequest(self, tfRequest):
self.setTFRequest(tfRequest)
self.d_setTFRequest(tfRequest)
def getTFRequest(self):
return self.tfRequest
def setEPP(self, epp):
self.epp = epp

View file

@ -8,6 +8,7 @@ from direct.distributed import DistributedObject
from direct.directnotify import DirectNotifyGlobal
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.friends import ToontownFriendSecret
import ToonAvatarDetailPanel
import AvatarPanelBase
from toontown.toontowngui import TTDialog
@ -353,6 +354,10 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase):
def __handleWhisper(self):
base.localAvatar.chatMgr.whisperTo(self.avName, self.avId)
def __handleTrueFriends(self):
base.localAvatar.chatMgr.noWhisper()
ToontownFriendSecret.showFriendSecret()
def __handleFriend(self):
base.localAvatar.chatMgr.noWhisper()
messenger.send('friendAvatar', [self.avId, self.avName, self.avDisableName])
@ -550,46 +555,3 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase):
groupInviteGui.removeNode()
groupAvatarBgGui.removeNode()
helpGui.removeNode()
return
def __handleTrueFriends(self):
if not settings['trueFriends']:
base.localAvatar.chatMgr.fsm.request('noTrueFriends')
return
self.cleanupDialog()
base.cr.playGame.getPlace().fsm.request('stopped')
if base.localAvatar.isTrueFriends(self.avatar.doId):
self.dialog = TTDialog.TTDialog(style=TTDialog.YesNo, text=TTLocalizer.TrueFriendsRemoveNotice % self.avatar.getName(), text_wordwrap=20, command=self.confirmTrueFriendsRemove)
self.dialog.show()
elif not base.cr.isFriend(self.avatar.doId):
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.TrueFriendsNotFriends % self.avatar.getName(), text_wordwrap=20, command=self.cleanupDialogAndWalk)
self.dialog.show()
else:
self.dialog = TTDialog.TTDialog(style=TTDialog.YesNo, text=TTLocalizer.TrueFriendsAddNotice % self.avatar.getName(), text_wordwrap=20, command=self.confirmTrueFriendsAdd)
self.dialog.show()
def confirmTrueFriendsAdd(self, state):
self.cleanupDialog()
if state > 0:
base.localAvatar.addTrueFriends(self.avatar.doId)
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.TrueFriendsAdded.replace('%s', self.avatar.getName()), text_wordwrap=20, command=self.cleanupDialogAndWalk)
self.dialog.show()
else:
base.cr.playGame.getPlace().fsm.request('walk')
def confirmTrueFriendsRemove(self, state):
self.cleanupDialog()
if state > 0:
base.localAvatar.removeTrueFriends(self.avatar.doId)
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.TrueFriendsRemoved % self.avatar.getName(), text_wordwrap=20, command=self.cleanupDialogAndWalk)
self.dialog.show()
else:
base.cr.playGame.getPlace().fsm.request('walk')
def cleanupDialogAndWalk(self, state=None):
self.cleanupDialog()
base.cr.playGame.getPlace().fsm.request('walk')

View file

@ -3247,6 +3247,7 @@ FriendsListPanelNewFriend = 'New Friend'
FriendsListPanelOnlineFriends = 'ONLINE TOON\nFRIENDS'
FriendsListPanelAllFriends = 'ALL TOON\nFRIENDS'
FriendsListPanelPets = 'NEARBY\nPETS'
FriendsListPanelTrueFriends = 'True Friends'
FriendInviterClickToon = 'Click on the toon you would like to make friends with.\n\n(You have %s friends)'
FriendInviterThatToon = 'That toon'
FriendInviterToonTooMany = 'You have too many toon friends to add another one now. You will have to remove some toon friends if you want to make friends with %s.'
@ -8491,11 +8492,6 @@ CogPanelSkeleton = 'Skeleton'
CogPanelVirtual = 'Virtual'
CogPanelRevives = 'v%s.0'
CogPanelWaiter = 'Waiter'
TrueFriendsRemoveNotice = 'Are you sure you want to remove %s as your True Friend?\n\nYou will no longer be able to chat without limits.'
TrueFriendsNotFriends = 'You cannot be True Friends with %s until you are regular friends first.'
TrueFriendsAddNotice = 'If you are playing Toontown with someone you trust, you can become True Friends.\n\nYou can chat using the keyboard with your True Friends.\n\nOther Toons won\'t understand what you\'re saying.\n\n\x01WLRed\x01However, this chat is completely unfiltered.\x02\n\nAre you sure you want to be True Friends with %s?'
TrueFriendsAdded = 'You are now True Friends with %s!\n\nYou can now understand everything %s says.\n\nHowever, chances are %s hasn\'t added you as a True Friend yet.\n\nIf this is the case, he cannot understand you yet. Please ask %s to add you as a True Friend aswell!'
TrueFriendsRemoved = 'You are no longer True Friends with %s.'
def convertSecondsToDate(seconds):
m, s = divmod(seconds, 60)
@ -8654,6 +8650,25 @@ StatResetDone = 'Your stats have been reset.'
ChairAskToUse = 'Would you like to sit on this chair?'
FriendSecretIntro = "If you are playing Toontown Stride with someone you know in the real world, you can become True Friends. You can chat using the keyboard with your True Friends. Other Toons won't understand what you're saying.\n\nYou do this by getting a True Friend Code. Tell the True Friend Code to your friend, but not to anyone else. When your friend types in your True Friend Code on his or her screen, you'll be True Friends in Toontown!"
FriendSecretGetSecret = 'Get a True Friend Code'
FriendSecretEnterSecret = 'If you have a True Friend Code from someone you know, type it here.'
FriendSecretOK = lOK
FriendSecretEnter = 'Enter True Friend Code'
FriendSecretCancel = lCancel
FriendSecretGettingSecret = 'Getting True Friend Code. . .'
FriendSecretGotSecret = "Here is your new True Friend Code. Be sure to write it down!\n\nYou may give this True Friend Code to one person only. Once someone types in your True Friend Code, it will not work for anyone else. If you want to give a True Friend Code to more than one person, get another True Friend Code.\n\nThe True Friend Code will only work for the next three days. Your friend will have to type it in before it goes away, or it won't work.\n\nYour True Friend Code is: %s"
FriendSecretTooMany = "Sorry, you can't have any more True Friend Codes today. You've already had more than your fair share!\n\nTry again tomorrow."
FriendSecretTryingSecret = 'Trying True Friend Code. . .'
FriendSecretEnteredSecretUnknown = "That's not anyone's True Friend Code. Are you sure you spelled it correctly?\n\nIf you did type it correctly, it may have expired. Ask your friend to get a new True Friend Code for you (or get a new one yourself and give it to your friend)."
FriendSecretEnteredSecretFullYou = "You can't be True Friends because you have too many friends on your friends list."
FriendSecretEnteredSecretFullHim = "You can't be True Friends because %s has too many friends on his friends list."
FriendSecretAlreadyFriends = 'You are already True Friends!'
FriendSecretAlreadyFriendsName = 'You are already True Friends with %s!'
FriendSecretEnteredSecretSelf = 'You just typed in your own True Friend Code!'
FriendSecretTooFast = 'You are redeeming codes too fast! Please wait a few seconds.'
FriendSecretNowFriends = 'You are now True Friends with %s!'
Blacklist = [
"$1ut",
"$h1t",

View file

@ -56,6 +56,8 @@ FPnewEntry = 0.08
FPnewRecord = 0.08
GPgenus = 0.045
FLPnewFriend = 0.045
FLPtruefriends = 0.045
FLPtruefriendsPos = (0.152, 0.0, 0.14)
FLPtitle = 0.04
FIbStop = 0.05
FIdirectFrame = 0.06
@ -283,6 +285,14 @@ TPhaveFun = 0.1
TPjoinUs = 0.1
TBSOSPSPenter = 0.1
TexitButton = 0.8
FSenterSecretTextPos = (0, 0, -0.25)
FSgotSecretPos = (0, 0, 0.47)
FSgetSecretButton = 0.06
FSnextText = 1.0
FSgetSecret = (1.55, 1, 1)
FSok1 = (1.55, 1, 1)
FSok2 = (0.6, 1, 1)
FScancel = (0.6, 1, 1)
#Some languages need to change the word order
SellbotFactoryPosPart1 = (0, -0.25)
SellbotFactoryScalePart1 = 0.075

View file

@ -1672,3 +1672,16 @@ CHAIR_STOP = 1
CHAIR_NONE = 0
CHAIR_EXIT = 1
CHAIR_UNEXPECTED_EXIT = 2
MAX_TF_TRIES = 5
TF_COOLDOWN_SECS = 60 * 60 * 24
TF_EXPIRE_SECS = 3 * 60 * 60 * 24
TF_COOLDOWN = 0
TF_UNKNOWN_SECRET = 1
TF_SELF_SECRET = 2
TF_TOO_FAST = 3
TF_FRIENDS_LIST_FULL_YOU = 4
TF_FRIENDS_LIST_FULL_HIM = 5
TF_ALREADY_FRIENDS = 6
TF_ALREADY_FRIENDS_NAME = 7
TF_SUCCESS = 8