diff --git a/astron/dclass/united.dc b/astron/dclass/united.dc index 0d66844a..6741f6d1 100644 --- a/astron/dclass/united.dc +++ b/astron/dclass/united.dc @@ -1957,16 +1957,17 @@ dclass DistributedNPCKartClerk : DistributedNPCToonBase { transactionDone() airecv clsend; }; +dclass DistributedNPCLaffRestock : DistributedNPCToonBase { + setMovie(uint8, uint32, uint32, uint32[], int16) broadcast ram; + restock(uint32, uint8) airecv clsend; + transactionDone() airecv clsend; +}; + dclass DistributedNPCGlove : DistributedNPCToonBase { doTransformation(uint32 avId, uint32) broadcast; requestTransformation(uint32) airecv clsend; }; -dclass DistributedNPCLaffRestock : DistributedNPCToonBase { - restock() airecv clsend; - restockResult(int8, int16); -}; - dclass DistributedKnockKnockDoor : DistributedAnimatedProp { }; diff --git a/guieditor/EditorStart.py b/guieditor/EditorStart.py index a7ca0301..cf914e88 100644 --- a/guieditor/EditorStart.py +++ b/guieditor/EditorStart.py @@ -13,7 +13,7 @@ from direct.gui.DirectGui import * """ -def inject(): +def inject(_): code = textbox.GetValue() exec(code, globals()) @@ -30,4 +30,4 @@ textbox.AppendText(defaultText) threading.Thread(target=app.MainLoop).start() __builtin__.base = ShowBase() -base.run() \ No newline at end of file +base.run() diff --git a/otp/distributed/DCClassImports.py b/otp/distributed/DCClassImports.py index de933193..b8998e9d 100644 --- a/otp/distributed/DCClassImports.py +++ b/otp/distributed/DCClassImports.py @@ -2,7 +2,7 @@ from pandac.PandaModules import * -hashVal = 3008682321L +hashVal = 630664315 from toontown.coghq import DistributedCashbotBossSafe, DistributedCashbotBossCrane, DistributedBattleFactory, DistributedCashbotBossTreasure, DistributedCogHQDoor, DistributedSellbotHQDoor, DistributedFactoryElevatorExt, DistributedMintElevatorExt, DistributedLawOfficeElevatorExt, DistributedLawOfficeElevatorInt, LobbyManager, DistributedMegaCorp, DistributedFactory, DistributedLawOffice, DistributedLawOfficeFloor, DistributedLift, DistributedDoorEntity, DistributedSwitch, DistributedButton, DistributedTrigger, DistributedCrushableEntity, DistributedCrusherEntity, DistributedStomper, DistributedStomperPair, DistributedLaserField, DistributedGolfGreenGame, DistributedSecurityCamera, DistributedMover, DistributedElevatorMarker, DistributedBarrelBase, DistributedGagBarrel, DistributedBeanBarrel, DistributedHealBarrel, DistributedGrid, ActiveCell, DirectionalCell, CrusherCell, DistributedCrate, DistributedSinkingPlatform, BattleBlocker, DistributedMint, DistributedMintRoom, DistributedMintBattle, DistributedStage, DistributedStageRoom, DistributedStageBattle, DistributedLawbotBossGavel, DistributedLawbotCannon, DistributedLawbotChair, DistributedCogKart, DistributedCountryClub, DistributedCountryClubRoom, DistributedMoleField, DistributedCountryClubBattle, DistributedMaze, DistributedFoodBelt, DistributedBanquetTable, DistributedGolfSpot diff --git a/toontown/coghq/CogHQExterior.py b/toontown/coghq/CogHQExterior.py index 3f772417..6dfdb59a 100644 --- a/toontown/coghq/CogHQExterior.py +++ b/toontown/coghq/CogHQExterior.py @@ -18,6 +18,7 @@ class CogHQExterior(BattlePlace.BattlePlace): 'teleportIn', 'doorIn']), State.State('walk', self.enterWalk, self.exitWalk, ['stickerBook', + 'purchase', 'teleportOut', 'tunnelOut', 'doorOut', @@ -38,6 +39,7 @@ class CogHQExterior(BattlePlace.BattlePlace): 'doorOut', 'squished', 'died']), + State.State('purchase', self.enterPurchase, self.exitPurchase, ['walk']), State.State('WaitForBattle', self.enterWaitForBattle, self.exitWaitForBattle, ['battle', 'walk']), State.State('battle', self.enterBattle, self.exitBattle, ['walk', 'teleportOut', 'died']), State.State('squished', self.enterSquished, self.exitSquished, ['walk', 'died', 'teleportOut']), @@ -86,6 +88,19 @@ class CogHQExterior(BattlePlace.BattlePlace): self.ignoreAll() BattlePlace.BattlePlace.exit(self) + def enterPurchase(self): + base.localAvatar.b_setAnimState('neutral', 1) + self.accept('teleportQuery', self.handleTeleportQuery) + base.localAvatar.setTeleportAvailable(1) + base.localAvatar.laffMeter.start() + base.localAvatar.obscureMoveFurnitureButton(1) + + def exitPurchase(self): + base.localAvatar.setTeleportAvailable(0) + self.ignore('teleportQuery') + base.localAvatar.laffMeter.stop() + base.localAvatar.obscureMoveFurnitureButton(-1) + def enterTunnelOut(self, requestStatus): fromZoneId = self.zoneId - self.zoneId % 100 tunnelName = base.cr.hoodMgr.makeLinkTunnelName(self.loader.hood.id, fromZoneId) diff --git a/toontown/coghq/CogHQLoader.py b/toontown/coghq/CogHQLoader.py index 917b082d..499d625e 100644 --- a/toontown/coghq/CogHQLoader.py +++ b/toontown/coghq/CogHQLoader.py @@ -19,13 +19,33 @@ class CogHQLoader(StateData.StateData): self.parentFSMState = parentFSMState self.placeDoneEvent = 'cogHQLoaderPlaceDone' self.townBattleDoneEvent = 'town-battle-done' - self.fsm = ClassicFSM.ClassicFSM('CogHQLoader', [State.State('start', None, None, ['quietZone', 'cogHQExterior', 'cogHQBossBattle']), - State.State('cogHQExterior', self.enterCogHQExterior, self.exitCogHQExterior, ['quietZone', 'cogHQLobby']), - State.State('cogHQLobby', self.enterCogHQLobby, self.exitCogHQLobby, ['quietZone', 'cogHQExterior', 'cogHQBossBattle']), - State.State('cogHQBossBattle', self.enterCogHQBossBattle, self.exitCogHQBossBattle, ['quietZone']), - State.State('quietZone', self.enterQuietZone, self.exitQuietZone, ['cogHQExterior', 'cogHQLobby', 'cogHQBossBattle']), - State.State('final', None, None, ['start'])], 'start', 'final') - return + self.fsm = ClassicFSM.ClassicFSM( + 'CogHQLoader', [State.State('start', + None, + None, + ['quietZone', 'cogHQExterior', 'cogHQBossBattle']), + State.State('cogHQExterior', + self.enterCogHQExterior, + self.exitCogHQExterior, + ['quietZone', 'cogHQLobby']), + State.State('cogHQLobby', + self.enterCogHQLobby, + self.exitCogHQLobby, + ['quietZone', 'cogHQExterior', 'cogHQBossBattle']), + State.State('cogHQBossBattle', + self.enterCogHQBossBattle, + self.exitCogHQBossBattle, + ['quietZone']), + State.State('quietZone', + self.enterQuietZone, + self.exitQuietZone, + ['cogHQExterior', 'cogHQLobby', 'cogHQBossBattle']), + State.State('final', + None, + None, + ['start'])], + 'start', + 'final') def load(self, zoneId): self.parentFSMState.addChild(self.fsm) diff --git a/toontown/hood/CogHood.py b/toontown/hood/CogHood.py index 11a30993..e9a9a9b5 100644 --- a/toontown/hood/CogHood.py +++ b/toontown/hood/CogHood.py @@ -14,10 +14,27 @@ class CogHood(Hood): def __init__(self, parentFSM, doneEvent, dnaStore, hoodId): Hood.__init__(self, parentFSM, doneEvent, dnaStore, hoodId) - self.fsm = ClassicFSM.ClassicFSM('Hood', [State.State('start', self.enterStart, self.exitStart, ['cogHQLoader']), - State.State('cogHQLoader', self.enterCogHQLoader, self.exitCogHQLoader, ['quietZone']), - State.State('quietZone', self.enterQuietZone, self.exitQuietZone, ['cogHQLoader']), - State.State('final', self.enterFinal, self.exitFinal, [])], 'start', 'final') + self.fsm = ClassicFSM.ClassicFSM( + 'Hood', + [State.State('start', + self.enterStart, + self.exitStart, + ['cogHQLoader']), + State.State('cogHQLoader', + self.enterCogHQLoader, + self.exitCogHQLoader, + ['quietZone']), + State.State('quietZone', + self.enterQuietZone, + self.exitQuietZone, + ['cogHQLoader']), + State.State('final', + self.enterFinal, + self.exitFinal, + []) + ], + 'start', + 'final') self.fsm.enterInitialState() # Until Hood is cleaned up, we will need to define some variables: diff --git a/toontown/toon/DistributedNPCLaffRestock.py b/toontown/toon/DistributedNPCLaffRestock.py index 7e40e400..7784e077 100644 --- a/toontown/toon/DistributedNPCLaffRestock.py +++ b/toontown/toon/DistributedNPCLaffRestock.py @@ -1,24 +1,28 @@ +from pandac.PandaModules import * +from direct.distributed import ClockDelta from toontown.chat.ChatGlobals import CFSpeech, CFTimeout from toontown.toonbase import TTLocalizer, ToontownGlobals from toontown.toontowngui import TTDialog from toontown.toon import NPCToons from DistributedNPCToonBase import DistributedNPCToonBase import LaffRestockGlobals +from LaffShopGui import * class DistributedNPCLaffRestock(DistributedNPCToonBase): def __init__(self, cr): DistributedNPCToonBase.__init__(self, cr) + self.isLocalToon = 0 + self.av = None + self.laffGui = None def disable(self): self.ignoreAll() - self.destroyDialog() + if self.laffGui: + self.laffGui.destroy() + self.laffGui = None + self.av = None DistributedNPCToonBase.disable(self) - - def destroyDialog(self): - if hasattr(self, 'dialog'): - self.dialog.cleanup() - del self.dialog def initToonState(self): self.setAnimState('neutral', 0.9, None, None) @@ -28,44 +32,80 @@ class DistributedNPCLaffRestock(DistributedNPCToonBase): self.setH(pos[1]) def getCollSphereRadius(self): - return 1.0 + return 1.25 def handleCollisionSphereEnter(self, collEntry): - laff = base.localAvatar.getMaxHp() - base.localAvatar.getHp() + base.cr.playGame.getPlace().fsm.request('purchase') + self.sendUpdate('avatarEnter', []) - if laff <= 0: - self.setChatAbsolute(TTLocalizer.RestockFullLaffMessage, CFSpeech|CFTimeout) + def __handleUnexpectedExit(self): + self.notify.warning('unexpected exit') + self.av = None + + def resetLaffClerk(self): + self.ignoreAll() + if self.laffGui: + self.laffGui.destroy() + self.laffGui = None + self.show() + self.startLookAround() + self.detectAvatars() + if self.isLocalToon: + self.showNametag2d() + self.freeAvatar() + return Task.done + + def setMovie(self, mode, npcId, avId, extraArgs, timestamp): + timeStamp = ClockDelta.globalClockDelta.localElapsedTime(timestamp) + self.remain = NPCToons.CLERK_COUNTDOWN_TIME - timeStamp + self.npcId = npcId + self.isLocalToon = avId == base.localAvatar.doId + if mode == NPCToons.SELL_MOVIE_CLEAR: return + if mode == NPCToons.SELL_MOVIE_TIMEOUT: + if self.isLocalToon: + if self.laffGui: + self.laffGui.destroy() + self.laffGui = None + self.setChatAbsolute(TTLocalizer.STOREOWNER_TOOKTOOLONG, CFSpeech | CFTimeout) + self.resetLaffClerk() + elif mode == NPCToons.SELL_MOVIE_START: + self.av = base.cr.doId2do.get(avId) + if self.av is None: + self.notify.warning('Avatar %d not found in doId' % avId) + return + else: + self.accept(self.av.uniqueName('disable'), self.__handleUnexpectedExit) + self.setupAvatars(self.av) + if self.isLocalToon: + self.hideNametag2d() + laff = self.av.getMaxHp() - self.av.getHp() + cost = laff * ToontownGlobals.CostPerLaffRestock + self.popupLaffGUI(laff, cost) + elif mode == NPCToons.SELL_MOVIE_COMPLETE: + self.setChatAbsolute(TTLocalizer.RestockLaffMessage, CFSpeech | CFTimeout) + self.resetLaffClerk() + elif mode == LaffRestockGlobals.FullLaff: + self.setChatAbsolute(TTLocalizer.RestockFullLaffMessage, CFSpeech | CFTimeout) + self.resetLaffClerk() + elif mode == LaffRestockGlobals.NoMoney: + self.setChatAbsolute(TTLocalizer.RestockNoMoneyMessage, CFSpeech | CFTimeout) + self.resetLaffClerk() - cost = laff * ToontownGlobals.CostPerLaffRestock + def __handleRestock(self, cost): + self.sendUpdate('restock', [self.av.doId, cost]) - if cost > base.localAvatar.getTotalMoney(): - self.setChatAbsolute(TTLocalizer.RestockNoMoneyMessage % cost, CFSpeech|CFTimeout) - return + def __handleGuiDone(self, bTimedOut=False): + self.ignoreAll() + if self.laffGui: + self.laffGui.destroy() + self.laffGui = None + if not bTimedOut: + self.sendUpdate('transactionDone') - base.cr.playGame.getPlace().setState('stopped') - base.setCellsActive(base.bottomCells, 0) - - self.dialog = TTDialog.TTDialog(style=TTDialog.YesNo, text=TTLocalizer.RestockAskMessage % (laff, cost), command=self.confirmRestock) - self.dialog.show() - - def confirmRestock(self, value): - base.cr.playGame.getPlace().setState('walk') - base.setCellsActive(base.bottomCells, 1) - - if value > 0: - self.sendUpdate('restock') - else: - self.setChatAbsolute(TTLocalizer.RestockLaffCancelMessage, CFSpeech|CFTimeout) - - self.destroyDialog() - - def restockResult(self, state, cost): - if state == LaffRestockGlobals.NO_LAFF: - message = TTLocalizer.RestockFullLaffMessage - elif state == LaffRestockGlobals.NO_MONEY: - message = TTLocalizer.RestockNoMoneyMessage % cost - else: - message = TTLocalizer.RestockLaffMessage - - self.setChatAbsolute(message, CFSpeech|CFTimeout) + def popupLaffGUI(self, laff, cost): + self.setChatAbsolute('', CFSpeech) + self.accept('restockLaff', self.__handleRestock) + self.acceptOnce('guiDone', self.__handleGuiDone) + self.laffGui = LaffShopGui(text=TTLocalizer.RestockAskMessage % (laff, cost), + extraArgs=[cost]) diff --git a/toontown/toon/DistributedNPCLaffRestockAI.py b/toontown/toon/DistributedNPCLaffRestockAI.py index c7ffd37b..70a1d815 100644 --- a/toontown/toon/DistributedNPCLaffRestockAI.py +++ b/toontown/toon/DistributedNPCLaffRestockAI.py @@ -1,27 +1,94 @@ +from direct.distributed import ClockDelta from toontown.toonbase import ToontownGlobals -import LaffRestockGlobals, DistributedNPCToonBaseAI +from DistributedNPCToonBaseAI import DistributedNPCToonBaseAI +from pandac.PandaModules import * +from toontown.toonbase import TTLocalizer +from direct.task import Task +import LaffRestockGlobals +from toontown.toon import NPCToons -class DistributedNPCLaffRestockAI(DistributedNPCToonBaseAI.DistributedNPCToonBaseAI): +class DistributedNPCLaffRestockAI(DistributedNPCToonBaseAI): - def restock(self): + def __init__(self, air, npcId): + DistributedNPCToonBaseAI.__init__(self, air, npcId) + self.givesQuests = 0 + self.busy = 0 + + def delete(self): + taskMgr.remove(self.uniqueName('clearMovie')) + self.ignoreAll() + DistributedNPCToonBaseAI.delete(self) + + def d_setMovie(self, avId, flag, extraArgs=[]): + self.sendUpdate('setMovie', [flag, + self.npcId, + avId, + extraArgs, + ClockDelta.globalClockDelta.getRealNetworkTime()]) + + def avatarEnter(self): avId = self.air.getAvatarIdFromSender() - av = self.air.doId2do.get(avId) - - if not av: + if avId not in self.air.doId2do: + self.notify.warning('Avatar: %s not found' % avId) return - + if self.isBusy(): + self.freeAvatar(avId) + return + av = self.air.doId2do[avId] + self.busy = avId + self.acceptOnce(self.air.getAvatarExitEvent(avId), self.__handleUnexpectedExit, extraArgs=[avId]) laff = av.getMaxHp() - av.getHp() - - if laff <= 0: - self.sendUpdateToAvatarId(avId, 'restockResult', [LaffRestockGlobals.NO_LAFF, 0]) - return - cost = laff * ToontownGlobals.CostPerLaffRestock + if laff <= 0: + self.d_setMovie(avId, LaffRestockGlobals.FullLaff) + self.sendClearMovie(None) + elif cost > av.getTotalMoney(): + self.d_setMovie(avId, LaffRestockGlobals.NoMoney) + self.sendClearMovie(None) + else: + self.d_setMovie(avId, NPCToons.SELL_MOVIE_START) + taskMgr.doMethodLater(LaffRestockGlobals.LAFFCLERK_TIMER, self.sendTimeoutMovie, self.uniqueName('clearMovie')) + DistributedNPCToonBaseAI.avatarEnter(self) - if cost > av.getTotalMoney(): - self.sendUpdateToAvatarId(avId, 'restockResult', [LaffRestockGlobals.NO_MONEY, cost]) + def transactionDone(self): + avId = self.air.getAvatarIdFromSender() + if self.busy != avId: + self.air.writeServerEvent('suspicious', avId, 'DistributedNPCLaffRestockAI.transactionDone busy with %s' % self.busy) + self.notify.warning('somebody called transactionDone that I was not busy with! avId: %s' % avId) return + av = simbase.air.doId2do.get(avId) + if av: + self.d_setMovie(avId, NPCToons.SELL_MOVIE_COMPLETE, []) + self.sendClearMovie(None) + return - av.takeMoney(cost) - av.b_setHp(av.getMaxHp()) - self.sendUpdateToAvatarId(avId, 'restockResult', [LaffRestockGlobals.SUCCESS, 0]) + def __handleUnexpectedExit(self, avId): + self.notify.warning('avatar:' + str(avId) + ' has exited unexpectedly') + self.notify.warning('not busy with avId: %s, busy: %s ' % (avId, self.busy)) + taskMgr.remove(self.uniqueName('clearMovie')) + self.sendClearMovie(None) + return + + def sendTimeoutMovie(self, task): + self.d_setMovie(self.busy, NPCToons.SELL_MOVIE_TIMEOUT) + self.sendClearMovie(None) + return Task.done + + def sendClearMovie(self, task): + self.ignore(self.air.getAvatarExitEvent(self.busy)) + taskMgr.remove(self.uniqueName('clearMovie')) + self.busy = 0 + self.d_setMovie(0, NPCToons.SELL_MOVIE_CLEAR) + return Task.done + + def restock(self, avId, cost): + sendAvId = self.air.getAvatarIdFromSender() + if self.busy != avId: + self.air.writeServerEvent('suspicious', avId, 'DistributedNPCLaffRestockAI.restock busy with %s' % self.busy) + self.notify.warning('somebody called restock that I was not busy with! avId: %s' % avId) + return + av = simbase.air.doId2do.get(avId) + if av: + movieType = NPCToons.SELL_MOVIE_COMPLETE + av.takeMoney(cost) + av.b_setHp(av.getMaxHp()) diff --git a/toontown/toon/DistributedNPCToon.py b/toontown/toon/DistributedNPCToon.py index cf8454a7..0247669f 100644 --- a/toontown/toon/DistributedNPCToon.py +++ b/toontown/toon/DistributedNPCToon.py @@ -15,6 +15,7 @@ ChoiceTimeout = 20 class DistributedNPCToon(DistributedNPCToonBase): + def __init__(self, cr): DistributedNPCToonBase.__init__(self, cr) @@ -221,4 +222,4 @@ class DistributedNPCToon(DistributedNPCToonBase): if self.trackChoiceGui: self.trackChoiceGui.destroy() self.trackChoiceGui = None - self.sendUpdate('chooseTrack', [trackId]) \ No newline at end of file + self.sendUpdate('chooseTrack', [trackId]) diff --git a/toontown/toon/DistributedNPCToonBase.py b/toontown/toon/DistributedNPCToonBase.py index e0b2df98..b71f2e05 100644 --- a/toontown/toon/DistributedNPCToonBase.py +++ b/toontown/toon/DistributedNPCToonBase.py @@ -17,6 +17,7 @@ from toontown.toonbase import ToontownGlobals class DistributedNPCToonBase(DistributedToon.DistributedToon): + def __init__(self, cr): try: self.DistributedNPCToon_initialized diff --git a/toontown/toon/LaffRestockGlobals.py b/toontown/toon/LaffRestockGlobals.py index 2f6d6c81..91f9a70a 100644 --- a/toontown/toon/LaffRestockGlobals.py +++ b/toontown/toon/LaffRestockGlobals.py @@ -1,3 +1,4 @@ -NO_LAFF = 0 -NO_MONEY = 1 -SUCCESS = 2 +LAFFCLERK_TIMER = 30 +FullLaff = 12 +NoMoney = 14 +Success = 1 diff --git a/toontown/toon/LaffShopGui.py b/toontown/toon/LaffShopGui.py new file mode 100644 index 00000000..7e32e8fd --- /dev/null +++ b/toontown/toon/LaffShopGui.py @@ -0,0 +1,55 @@ +from pandac.PandaModules import * +from direct.directnotify import DirectNotifyGlobal +from direct.gui.DirectGui import * +from direct.showbase import DirectObject +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase import ToontownTimer +from toontown.toontowngui import TTDialog +import LaffRestockGlobals + +class LaffShopGui(object, DirectObject.DirectObject): + notify = DirectNotifyGlobal.directNotify.newCategory('LaffShopGui') + + def __init__(self, **kw): + self.dialog = None + self.timer = None + self.timer = ToontownTimer.ToontownTimer() + self.timer.reparentTo(aspect2d) + self.timer.posInTopRightCorner() + self.timer.accept('RESET_LAFFSHOP_TIMER', self.__resetTimer) + self.timer.countdown(LaffRestockGlobals.LAFFCLERK_TIMER, self.__timerExpired) + self.__doDialog(**kw) + + def destroy(self): + self.ignoreAll() + if self.timer: + self.timer.destroy() + self.timer = None + if self.dialog: + self.dialog.destroy() + self.dialog = None + + def __resetTimer(self): + if self.timer: + self.timer.stop() + self.timer.countdown(LaffRestockGlobals.LAFFCLERK_TIMER, self.__timerExpired) + + def __timerExpired(self): + messenger.send('guiDone', [True]) + + def __destroyDialog(self, resp, cost): + if self.timer: + self.ignoreAll() + if self.dialog: + self.dialog.destroy() + self.dialog = None + if resp == LaffRestockGlobals.Success: + messenger.send('restockLaff', [cost]) + messenger.send('guiDone', [False]) + + def __doDialog(self, **kw): + self.dialog = TTDialog.TTDialog(style=TTDialog.YesNo, + command=self.__destroyDialog, + **kw) + self.dialog.show() diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 08b35c19..0389003b 100644 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -8443,8 +8443,7 @@ DonaldChatter = ["I'm glad you're here today!", 'I love to play tag. Do you?'] NPCFriendUnavailable = 'Unavailable' FireTalkMessage = "You're fired!" -RestockFullLaffMessage = "Sorry, but you're already happy!" -RestockNoMoneyMessage = "Sorry, but you need %s jellybeans to restock your laff!" +RestockFullLaffMessage = "You're already happy!" +RestockNoMoneyMessage = "You need more jellybeans to restock your laff!" +RestockLaffMessage = "Have fun!" RestockAskMessage = "Would you like to restock %s laff for %s jellybeans?" -RestockLaffMessage = "Enjoy your happiness!" -RestockLaffCancelMessage = "Alright. Come back here if you change your mind."