2015-03-03 16:10:12 -06:00
|
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
|
|
from direct.gui import DirectGuiGlobals as DGG
|
|
|
|
from direct.showbase.PythonUtil import Functor
|
|
|
|
from direct.task.Task import Task
|
|
|
|
|
|
|
|
import MinigameGlobals
|
|
|
|
from PurchaseBase import *
|
|
|
|
from toontown.distributed import DelayDelete
|
2015-06-24 14:08:15 -05:00
|
|
|
from otp.nametag.NametagFloat2d import *
|
|
|
|
from otp.nametag import NametagGlobals
|
2015-03-03 16:10:12 -06:00
|
|
|
from toontown.toon import ToonHead
|
|
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
from toontown.toonbase import ToontownTimer
|
|
|
|
|
|
|
|
|
|
|
|
COUNT_UP_RATE = 0.15
|
|
|
|
COUNT_UP_DURATION = 0.5
|
|
|
|
DELAY_BEFORE_COUNT_UP = 1.0
|
|
|
|
DELAY_AFTER_COUNT_UP = 1.0
|
|
|
|
COUNT_DOWN_RATE = 0.075
|
|
|
|
COUNT_DOWN_DURATION = 0.5
|
|
|
|
DELAY_AFTER_COUNT_DOWN = 0.0
|
|
|
|
DELAY_AFTER_CELEBRATE = 2.6
|
|
|
|
COUNT_SFX_MIN_DELAY = 0.034
|
|
|
|
COUNT_SFX_START_T = 0.079
|
|
|
|
OVERMAX_SFX_MIN_DELAY = 0.067
|
|
|
|
OVERMAX_SFX_START_T = 0.021
|
|
|
|
|
|
|
|
class Purchase(PurchaseBase):
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('Purchase')
|
|
|
|
|
2015-05-05 13:43:30 -05:00
|
|
|
def __init__(self, toon, pointsArray, playerMoney, ids, states, remain, doneEvent):
|
2015-03-03 16:10:12 -06:00
|
|
|
PurchaseBase.__init__(self, toon, doneEvent)
|
|
|
|
self.ids = ids
|
|
|
|
self.pointsArray = pointsArray
|
|
|
|
self.playerMoney = playerMoney
|
|
|
|
self.states = states
|
|
|
|
self.remain = remain
|
|
|
|
self.tutorialMode = 0
|
|
|
|
self.fsm.addState(State.State('reward', self.enterReward, self.exitReward, ['purchase']))
|
|
|
|
doneState = self.fsm.getStateNamed('done')
|
|
|
|
doneState.addTransition('reward')
|
|
|
|
self.unexpectedEventNames = []
|
|
|
|
self.unexpectedExits = []
|
|
|
|
self.setupUnexpectedExitHooks()
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui')
|
|
|
|
PurchaseBase.load(self, purchaseModels)
|
|
|
|
interiorPhase = 3.5
|
|
|
|
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)
|
|
|
|
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)
|
|
|
|
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)
|
|
|
|
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'),
|
|
|
|
purchaseModels.find('**/PurchScrn_BTN_DN'),
|
|
|
|
purchaseModels.find('**/PurchScrn_BTN_RLVR'),
|
|
|
|
purchaseModels.find('**/PurchScrn_BTN_UP')), text=TTLocalizer.GagShopPlayAgain, text_fg=(0, 0.1, 0.7, 1), text_scale=0.05, text_pos=(0, 0.015, 0), image3_color=Vec4(0.6, 0.6, 0.6, 1), text3_fg=Vec4(0, 0, 0.4, 1), command=self.__handlePlayAgain)
|
|
|
|
self.backToPlayground = DirectButton(parent=self.frame, relief=None, scale=1.04, pos=(0.72, 0, -0.045), image=(purchaseModels.find('**/PurchScrn_BTN_UP'),
|
|
|
|
purchaseModels.find('**/PurchScrn_BTN_DN'),
|
|
|
|
purchaseModels.find('**/PurchScrn_BTN_RLVR'),
|
|
|
|
purchaseModels.find('**/PurchScrn_BTN_UP')), text=TTLocalizer.GagShopBackToPlayground, text_fg=(0, 0.1, 0.7, 1), text_scale=0.05, text_pos=(0, 0.015, 0), image3_color=Vec4(0.6, 0.6, 0.6, 1), text3_fg=Vec4(0, 0, 0.4, 1), command=self.__handleBackToPlayground)
|
|
|
|
self.timer = ToontownTimer.ToontownTimer()
|
|
|
|
self.timer.hide()
|
|
|
|
self.timer.posInTopRightCorner()
|
|
|
|
numAvs = 0
|
|
|
|
count = 0
|
|
|
|
localToonIndex = 0
|
|
|
|
for index in xrange(len(self.ids)):
|
|
|
|
avId = self.ids[index]
|
|
|
|
if avId == base.localAvatar.doId:
|
|
|
|
localToonIndex = index
|
|
|
|
if self.states[index] != PURCHASE_NO_CLIENT_STATE and self.states[index] != PURCHASE_DISCONNECTED_STATE:
|
|
|
|
numAvs = numAvs + 1
|
|
|
|
|
|
|
|
layoutList = (None,
|
|
|
|
(0,),
|
|
|
|
(0, 2),
|
|
|
|
(0, 1, 3),
|
|
|
|
(0, 1, 2, 3))
|
|
|
|
layout = layoutList[numAvs]
|
|
|
|
headFramePosList = (Vec3(0.105, 0, -0.384),
|
|
|
|
Vec3(0.105, 0, -0.776),
|
|
|
|
Vec3(0.85, 0, -0.555),
|
|
|
|
Vec3(-0.654, 0, -0.555))
|
|
|
|
AVID_INDEX = 0
|
|
|
|
LAYOUT_INDEX = 1
|
|
|
|
TOON_INDEX = 2
|
|
|
|
self.avInfoArray = [(base.localAvatar.doId, headFramePosList[0], localToonIndex)]
|
|
|
|
pos = 1
|
|
|
|
for index in xrange(len(self.ids)):
|
|
|
|
avId = self.ids[index]
|
|
|
|
if self.states[index] != PURCHASE_NO_CLIENT_STATE and self.states[index] != PURCHASE_DISCONNECTED_STATE:
|
|
|
|
if avId != base.localAvatar.doId:
|
|
|
|
if avId in base.cr.doId2do:
|
|
|
|
self.avInfoArray.append((avId, headFramePosList[layout[pos]], index))
|
|
|
|
pos = pos + 1
|
|
|
|
|
|
|
|
self.headFrames = []
|
|
|
|
for avInfo in self.avInfoArray:
|
|
|
|
av = base.cr.doId2do.get(avInfo[AVID_INDEX])
|
|
|
|
if av:
|
|
|
|
headFrame = PurchaseHeadFrame(av, purchaseModels)
|
|
|
|
headFrame.setAvatarState(self.states[avInfo[TOON_INDEX]])
|
|
|
|
headFrame.setPos(avInfo[LAYOUT_INDEX])
|
|
|
|
self.headFrames.append((avInfo[AVID_INDEX], headFrame))
|
|
|
|
|
|
|
|
purchaseModels.removeNode()
|
|
|
|
self.foreground = loader.loadModel('phase_3.5/models/modules/TT_A1')
|
|
|
|
self.foreground.setPos(12.5, -20, -5.5)
|
|
|
|
self.foreground.setHpr(180, 0, 0)
|
|
|
|
self.backgroundL = self.foreground.copyTo(hidden)
|
|
|
|
self.backgroundL.setPos(-14.5, -25, -5)
|
|
|
|
self.backgroundL.setHpr(180, 0, 0)
|
|
|
|
self.backgroundR = self.backgroundL.copyTo(hidden)
|
|
|
|
self.backgroundR.setPos(30, -25, -5)
|
|
|
|
self.backgroundR.setHpr(180, 0, 0)
|
|
|
|
streets = loader.loadModel('phase_3.5/models/modules/street_modules')
|
|
|
|
sidewalk = streets.find('**/street_sidewalk_40x40')
|
|
|
|
self.sidewalk = sidewalk.copyTo(hidden)
|
|
|
|
self.sidewalkR = sidewalk.copyTo(hidden)
|
|
|
|
self.sidewalkL = sidewalk.copyTo(hidden)
|
|
|
|
self.sidewalk.setPos(-20, -25, -5.5)
|
|
|
|
self.sidewalk.setColor(0.9, 0.6, 0.4)
|
|
|
|
self.sidewalkL.setPos(-40, -25, -5.5)
|
|
|
|
self.sidewalkL.setColor(0.9, 0.6, 0.4)
|
|
|
|
self.sidewalkR.setPos(0, -25, -5.5)
|
|
|
|
self.sidewalkR.setColor(0.9, 0.6, 0.4)
|
|
|
|
streets.removeNode()
|
|
|
|
doors = loader.loadModel('phase_4/models/modules/doors')
|
|
|
|
door = doors.find('**/door_single_square_ur_door')
|
|
|
|
self.door = door.copyTo(hidden)
|
|
|
|
self.door.setH(180)
|
|
|
|
self.door.setPos(0, -16.75, -5.5)
|
|
|
|
self.door.setScale(1.5, 1.5, 2.0)
|
|
|
|
self.door.setColor(1.0, 0.8, 0, 1)
|
|
|
|
doors.removeNode()
|
|
|
|
self.rewardDoubledJellybeanLabel = DirectLabel(text=TTLocalizer.PartyRewardDoubledJellybean, text_fg=(1.0, 0.125, 0.125, 1.0), text_shadow=(0, 0, 0, 1), relief=None, pos=(0.0, 0, -0.67), scale=0.08)
|
|
|
|
self.rewardDoubledJellybeanLabel.hide()
|
|
|
|
self.countSound = base.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg')
|
|
|
|
self.overMaxSound = base.loadSfx('phase_3.5/audio/sfx/AV_collision.ogg')
|
|
|
|
self.celebrateSound = base.loadSfx('phase_4/audio/sfx/MG_win.ogg')
|
|
|
|
return
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
PurchaseBase.unload(self)
|
|
|
|
self.cleanupUnexpectedExitHooks()
|
|
|
|
self.bg.removeNode()
|
|
|
|
del self.bg
|
|
|
|
self.notify.debug('destroying head frames')
|
|
|
|
for headFrame in self.headFrames:
|
|
|
|
if not headFrame[1].isEmpty():
|
|
|
|
headFrame[1].reparentTo(hidden)
|
|
|
|
headFrame[1].destroy()
|
|
|
|
|
|
|
|
del self.headFrames
|
|
|
|
self.playAgain.destroy()
|
|
|
|
del self.playAgain
|
|
|
|
self.backToPlayground.destroy()
|
|
|
|
del self.backToPlayground
|
|
|
|
self.timer.stop()
|
|
|
|
self.timer.destroy()
|
|
|
|
del self.timer
|
|
|
|
for counter in self.counters:
|
|
|
|
counter.destroy()
|
|
|
|
del counter
|
|
|
|
|
|
|
|
del self.counters
|
|
|
|
for total in self.totalCounters:
|
|
|
|
total.destroy()
|
|
|
|
del total
|
|
|
|
|
|
|
|
del self.totalCounters
|
|
|
|
loader.unloadModel('phase_3.5/models/modules/TT_A1')
|
|
|
|
loader.unloadModel('phase_3.5/models/modules/street_modules')
|
|
|
|
loader.unloadModel('phase_4/models/modules/doors')
|
|
|
|
taskMgr.remove('countUpTask')
|
|
|
|
taskMgr.remove('countDownTask')
|
|
|
|
taskMgr.remove('celebrate')
|
|
|
|
taskMgr.remove('purchase-trans')
|
|
|
|
taskMgr.remove('delayAdd')
|
|
|
|
taskMgr.remove('delaySubtract')
|
|
|
|
self.foreground.removeNode()
|
|
|
|
del self.foreground
|
|
|
|
self.backgroundL.removeNode()
|
|
|
|
del self.backgroundL
|
|
|
|
self.backgroundR.removeNode()
|
|
|
|
del self.backgroundR
|
|
|
|
self.sidewalk.removeNode()
|
|
|
|
self.sidewalkL.removeNode()
|
|
|
|
self.sidewalkR.removeNode()
|
|
|
|
del self.sidewalk
|
|
|
|
del self.sidewalkL
|
|
|
|
del self.sidewalkR
|
|
|
|
self.door.removeNode()
|
|
|
|
del self.door
|
|
|
|
self.collisionFloor.removeNode()
|
|
|
|
del self.collisionFloor
|
|
|
|
del self.countSound
|
|
|
|
del self.celebrateSound
|
|
|
|
self.rewardDoubledJellybeanLabel.removeNode()
|
|
|
|
del self.rewardDoubledJellybeanLabel
|
|
|
|
|
|
|
|
def showStatusText(self, text):
|
|
|
|
self.statusLabel['text'] = text
|
|
|
|
taskMgr.remove('resetStatusText')
|
|
|
|
taskMgr.doMethodLater(2.0, self.resetStatusText, 'resetStatusText')
|
|
|
|
|
|
|
|
def resetStatusText(self, task):
|
|
|
|
self.statusLabel['text'] = ''
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
def __handlePlayAgain(self):
|
|
|
|
for headFrame in self.headFrames:
|
|
|
|
headFrame[1].wrtReparentTo(aspect2d)
|
|
|
|
|
|
|
|
self.toon.inventory.reparentTo(hidden)
|
|
|
|
self.toon.inventory.hide()
|
|
|
|
taskMgr.remove('resetStatusText')
|
|
|
|
taskMgr.remove('showBrokeMsgTask')
|
2015-04-23 12:55:47 -05:00
|
|
|
self.statusLabel['text'] = TTLocalizer.WaitingForOtherToons
|
2015-03-03 16:10:12 -06:00
|
|
|
messenger.send('purchasePlayAgain')
|
|
|
|
|
|
|
|
def handleDone(self, playAgain):
|
|
|
|
base.localAvatar.b_setParent(ToontownGlobals.SPHidden)
|
|
|
|
if playAgain:
|
|
|
|
self.doneStatus = {'loader': 'minigame',
|
|
|
|
'where': 'minigame'}
|
|
|
|
else:
|
|
|
|
self.doneStatus = {'loader': 'safeZoneLoader',
|
|
|
|
'where': 'playground'}
|
|
|
|
messenger.send(self.doneEvent)
|
|
|
|
|
|
|
|
def __handleBackToPlayground(self):
|
|
|
|
self.toon.inventory.reparentTo(hidden)
|
|
|
|
self.toon.inventory.hide()
|
|
|
|
messenger.send('purchaseBackToToontown')
|
|
|
|
|
|
|
|
def __timerExpired(self):
|
|
|
|
messenger.send('purchaseTimeout')
|
|
|
|
|
|
|
|
def findHeadFrame(self, id):
|
|
|
|
for headFrame in self.headFrames:
|
|
|
|
if headFrame[0] == id:
|
|
|
|
return headFrame[1]
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
def __handleStateChange(self, playerStates):
|
|
|
|
self.states = playerStates
|
|
|
|
for avInfo in self.avInfoArray:
|
|
|
|
index = avInfo[2]
|
|
|
|
headFrame = self.findHeadFrame(avInfo[0])
|
|
|
|
state = self.states[index]
|
|
|
|
headFrame.setAvatarState(state)
|
|
|
|
|
|
|
|
def enter(self):
|
|
|
|
base.playMusic(self.music, looping=1, volume=0.8)
|
|
|
|
self.fsm.request('reward')
|
|
|
|
|
|
|
|
def enterReward(self):
|
|
|
|
numToons = 0
|
|
|
|
toonLayouts = ((2,),
|
|
|
|
(1, 3),
|
|
|
|
(0, 2, 4),
|
|
|
|
(0, 1, 3, 4))
|
|
|
|
toonPositions = (5.0,
|
|
|
|
1.75,
|
|
|
|
-0.25,
|
|
|
|
-1.75,
|
|
|
|
-5.0)
|
|
|
|
self.toons = []
|
|
|
|
self.toonsKeep = []
|
|
|
|
self.counters = []
|
|
|
|
self.totalCounters = []
|
|
|
|
camera.reparentTo(render)
|
|
|
|
camera.setPos(0, 16.0, 2.0)
|
|
|
|
camera.lookAt(0, 0, 0.75)
|
|
|
|
base.transitions.irisIn(0.4)
|
|
|
|
base.camLens.setMinFov(60/(4./3.))
|
|
|
|
base.setBackgroundColor(Vec4(0, 0.6, 1, 1))
|
|
|
|
self.title.reparentTo(aspect2d)
|
|
|
|
self.foreground.reparentTo(render)
|
|
|
|
self.backgroundL.reparentTo(render)
|
|
|
|
self.backgroundR.reparentTo(render)
|
|
|
|
self.sidewalk.reparentTo(render)
|
|
|
|
self.sidewalkL.reparentTo(render)
|
|
|
|
self.sidewalkR.reparentTo(render)
|
|
|
|
self.door.reparentTo(render)
|
|
|
|
size = 20
|
|
|
|
z = -2.5
|
|
|
|
floor = CollisionPolygon(Point3(-size, -size, z), Point3(size, -size, z), Point3(size, size, z), Point3(-size, size, z))
|
|
|
|
floor.setTangible(1)
|
|
|
|
floorNode = CollisionNode('collision_floor')
|
|
|
|
floorNode.addSolid(floor)
|
|
|
|
self.collisionFloor = render.attachNewNode(floorNode)
|
2015-06-24 14:08:15 -05:00
|
|
|
NametagGlobals.setOnscreenChatForced(1)
|
2015-03-03 16:10:12 -06:00
|
|
|
for index in xrange(len(self.ids)):
|
|
|
|
avId = self.ids[index]
|
|
|
|
if self.states[index] != PURCHASE_NO_CLIENT_STATE and self.states[index] != PURCHASE_DISCONNECTED_STATE and avId in base.cr.doId2do:
|
|
|
|
numToons += 1
|
|
|
|
toon = base.cr.doId2do[avId]
|
|
|
|
toon.stopSmooth()
|
|
|
|
self.toons.append(toon)
|
|
|
|
self.toonsKeep.append(DelayDelete.DelayDelete(toon, 'Purchase.enterReward'))
|
|
|
|
counter = DirectLabel(parent=hidden, relief=None, pos=(0.0, 0.0, 0.0), text=str(0), text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -0.1, 0), text_font=ToontownGlobals.getSignFont())
|
|
|
|
counter['image'] = DGG.getDefaultDialogGeom()
|
|
|
|
counter['image_scale'] = (0.33, 1, 0.33)
|
|
|
|
counter.setScale(0.5)
|
|
|
|
counter.count = 0
|
|
|
|
counter.max = self.pointsArray[index]
|
|
|
|
self.counters.append(counter)
|
|
|
|
money = self.playerMoney[index]
|
|
|
|
totalCounter = DirectLabel(parent=hidden, relief=None, pos=(0.0, 0.0, 0.0), text=str(money), text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -0.1, 0), text_font=ToontownGlobals.getSignFont(), image=self.jarImage)
|
|
|
|
totalCounter.setScale(0.5)
|
|
|
|
totalCounter.count = money
|
|
|
|
totalCounter.max = toon.getMaxMoney()
|
|
|
|
self.totalCounters.append(totalCounter)
|
|
|
|
|
|
|
|
self.accept('clientCleanup', self._handleClientCleanup)
|
|
|
|
pos = 0
|
|
|
|
toonLayout = toonLayouts[numToons - 1]
|
|
|
|
for toon in self.toons:
|
|
|
|
thisPos = toonPositions[toonLayout[pos]]
|
|
|
|
toon.setPos(Vec3(thisPos, 1.0, -2.5))
|
|
|
|
toon.setHpr(Vec3(0, 0, 0))
|
|
|
|
toon.setAnimState('neutral', 1)
|
|
|
|
toon.setShadowHeight(0)
|
|
|
|
if not toon.isDisabled():
|
|
|
|
toon.reparentTo(render)
|
|
|
|
self.counters[pos].setPos(thisPos * -0.17, 0, toon.getHeight() / 10 + 0.25)
|
|
|
|
self.counters[pos].reparentTo(aspect2d)
|
|
|
|
self.totalCounters[pos].setPos(thisPos * -0.17, 0, -0.825)
|
|
|
|
self.totalCounters[pos].reparentTo(aspect2d)
|
|
|
|
pos += 1
|
|
|
|
|
|
|
|
self.maxPoints = max(self.pointsArray)
|
|
|
|
|
|
|
|
def reqCountUp(state):
|
|
|
|
self.countUp()
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
countUpDelay = DELAY_BEFORE_COUNT_UP
|
|
|
|
taskMgr.doMethodLater(countUpDelay, reqCountUp, 'countUpTask')
|
|
|
|
|
|
|
|
def reqCountDown(state):
|
|
|
|
self.countDown()
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
countDownDelay = countUpDelay + COUNT_UP_DURATION + DELAY_AFTER_COUNT_UP
|
|
|
|
taskMgr.doMethodLater(countDownDelay, reqCountDown, 'countDownTask')
|
|
|
|
|
|
|
|
def celebrate(task):
|
|
|
|
for counter in task.counters:
|
|
|
|
counter.hide()
|
|
|
|
|
|
|
|
winningPoints = max(task.pointsArray)
|
|
|
|
for i in xrange(len(task.ids)):
|
|
|
|
if task.pointsArray[i] == winningPoints:
|
|
|
|
avId = task.ids[i]
|
|
|
|
if avId in base.cr.doId2do:
|
|
|
|
toon = base.cr.doId2do[avId]
|
|
|
|
toon.setAnimState('jump', 1.0)
|
|
|
|
|
|
|
|
base.playSfx(task.celebrateSound)
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
celebrateDelay = countDownDelay + COUNT_DOWN_DURATION + DELAY_AFTER_COUNT_DOWN
|
|
|
|
celebrateTask = taskMgr.doMethodLater(celebrateDelay, celebrate, 'celebrate')
|
|
|
|
celebrateTask.counters = self.counters
|
|
|
|
celebrateTask.pointsArray = self.pointsArray
|
|
|
|
celebrateTask.ids = self.ids
|
|
|
|
celebrateTask.celebrateSound = self.celebrateSound
|
|
|
|
|
|
|
|
def reqPurchase(state):
|
|
|
|
self.fsm.request('purchase')
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
purchaseDelay = celebrateDelay + DELAY_AFTER_CELEBRATE
|
|
|
|
taskMgr.doMethodLater(purchaseDelay, reqPurchase, 'purchase-trans')
|
|
|
|
if base.skipMinigameReward:
|
|
|
|
self.fsm.request('purchase')
|
|
|
|
return
|
|
|
|
|
|
|
|
def _changeCounterUp(self, task, counter, newCount, toonId):
|
|
|
|
counter.count = newCount
|
|
|
|
counter['text'] = str(counter.count)
|
|
|
|
if toonId == base.localAvatar.doId:
|
|
|
|
now = globalClock.getRealTime()
|
|
|
|
if task.lastSfxT + COUNT_SFX_MIN_DELAY < now:
|
|
|
|
base.playSfx(task.countSound, time=COUNT_SFX_START_T)
|
|
|
|
task.lastSfxT = now
|
|
|
|
|
|
|
|
def _countUpTask(self, task):
|
|
|
|
now = globalClock.getRealTime()
|
|
|
|
startT = task.getStartTime()
|
|
|
|
if now >= startT + task.duration:
|
|
|
|
for counter, toonId in zip(self.counters, self.ids):
|
|
|
|
if counter.count != counter.max:
|
|
|
|
self._changeCounterUp(task, counter, counter.max, toonId)
|
|
|
|
|
|
|
|
return Task.done
|
|
|
|
t = (now - startT) / task.duration
|
|
|
|
for counter, toonId in zip(self.counters, self.ids):
|
|
|
|
curCount = int(t * counter.max)
|
|
|
|
if curCount != counter.count:
|
|
|
|
self._changeCounterUp(task, counter, curCount, toonId)
|
|
|
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def countUp(self):
|
|
|
|
totalDelay = 0
|
|
|
|
if base.cr.newsManager.isHolidayRunning(ToontownGlobals.JELLYBEAN_TROLLEY_HOLIDAY) or base.cr.newsManager.isHolidayRunning(ToontownGlobals.JELLYBEAN_TROLLEY_HOLIDAY_MONTH):
|
|
|
|
self.rewardDoubledJellybeanLabel.show()
|
|
|
|
countUpTask = taskMgr.add(self._countUpTask, 'countUp')
|
|
|
|
countUpTask.duration = COUNT_UP_DURATION
|
|
|
|
countUpTask.countSound = self.countSound
|
|
|
|
countUpTask.lastSfxT = 0
|
|
|
|
|
|
|
|
def _changeCounterDown(self, task, counter, newCount, total, toonId):
|
|
|
|
counter.count = newCount
|
|
|
|
counter['text'] = str(counter.count)
|
|
|
|
total.count = total.startAmount + (counter.max - newCount)
|
|
|
|
if total.count > total.max:
|
|
|
|
total.count = total.max
|
|
|
|
total['text'] = str(total.count)
|
|
|
|
if total.count == total.max:
|
|
|
|
total['text_fg'] = (1, 0, 0, 1)
|
|
|
|
if toonId == base.localAvatar.doId:
|
|
|
|
now = globalClock.getRealTime()
|
|
|
|
if total.count < total.max:
|
|
|
|
minDelay = COUNT_SFX_MIN_DELAY
|
|
|
|
snd = task.countSound
|
|
|
|
startT = COUNT_SFX_START_T
|
|
|
|
else:
|
|
|
|
minDelay = OVERMAX_SFX_MIN_DELAY
|
|
|
|
snd = task.overMaxSound
|
|
|
|
startT = OVERMAX_SFX_START_T
|
|
|
|
if task.lastSfxT + minDelay < now:
|
|
|
|
task.lastSfxT = now
|
|
|
|
base.playSfx(snd, time=startT)
|
|
|
|
|
|
|
|
def _countDownTask(self, task):
|
|
|
|
now = globalClock.getRealTime()
|
|
|
|
startT = task.getStartTime()
|
|
|
|
if now >= startT + task.duration:
|
|
|
|
for counter, total, toonId in zip(self.counters, self.totalCounters, self.ids):
|
|
|
|
if counter.count != 0:
|
|
|
|
self._changeCounterDown(task, counter, 0, total, toonId)
|
|
|
|
|
|
|
|
return Task.done
|
|
|
|
t = (now - startT) / task.duration
|
|
|
|
for counter, total, toonId in zip(self.counters, self.totalCounters, self.ids):
|
|
|
|
curCount = int(counter.max * (1 - t))
|
|
|
|
if curCount != counter.count:
|
|
|
|
self._changeCounterDown(task, counter, curCount, total, toonId)
|
|
|
|
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def countDown(self):
|
|
|
|
totalDelay = 0
|
|
|
|
for total in self.totalCounters:
|
|
|
|
total.startAmount = total.count
|
|
|
|
|
|
|
|
countDownTask = taskMgr.add(self._countDownTask, 'countDown')
|
|
|
|
countDownTask.duration = COUNT_DOWN_DURATION
|
|
|
|
countDownTask.countSound = self.countSound
|
|
|
|
countDownTask.overMaxSound = self.overMaxSound
|
|
|
|
countDownTask.lastSfxT = 0
|
|
|
|
|
|
|
|
def exitReward(self):
|
|
|
|
self.ignore('clientCleanup')
|
|
|
|
taskMgr.remove('countUpTask')
|
|
|
|
taskMgr.remove('countDownTask')
|
|
|
|
taskMgr.remove('celebrate')
|
|
|
|
taskMgr.remove('purchase-trans')
|
|
|
|
taskMgr.remove('delayAdd')
|
|
|
|
taskMgr.remove('delaySubtract')
|
|
|
|
for toon in self.toons:
|
|
|
|
toon.detachNode()
|
|
|
|
|
|
|
|
del self.toons
|
|
|
|
if hasattr(self, 'toonsKeep'):
|
|
|
|
for delayDelete in self.toonsKeep:
|
|
|
|
delayDelete.destroy()
|
|
|
|
|
|
|
|
del self.toonsKeep
|
|
|
|
for counter in self.counters:
|
|
|
|
counter.reparentTo(hidden)
|
|
|
|
|
|
|
|
for total in self.totalCounters:
|
|
|
|
total.reparentTo(hidden)
|
|
|
|
|
|
|
|
self.foreground.reparentTo(hidden)
|
|
|
|
self.backgroundL.reparentTo(hidden)
|
|
|
|
self.backgroundR.reparentTo(hidden)
|
|
|
|
self.sidewalk.reparentTo(hidden)
|
|
|
|
self.sidewalkL.reparentTo(hidden)
|
|
|
|
self.sidewalkR.reparentTo(hidden)
|
|
|
|
self.door.reparentTo(hidden)
|
|
|
|
self.title.reparentTo(self.frame)
|
|
|
|
self.rewardDoubledJellybeanLabel.hide()
|
2015-06-18 08:53:50 -05:00
|
|
|
base.camLens.setMinFov(settings['fov']/(4./3.))
|
2015-06-24 14:08:15 -05:00
|
|
|
NametagGlobals.setOnscreenChatForced(0)
|
2015-03-03 16:10:12 -06:00
|
|
|
|
|
|
|
def _handleClientCleanup(self):
|
|
|
|
if hasattr(self, 'toonsKeep'):
|
|
|
|
for delayDelete in self.toonsKeep:
|
|
|
|
delayDelete.destroy()
|
|
|
|
|
|
|
|
del self.toonsKeep
|
|
|
|
self.ignore('clientCleanup')
|
|
|
|
|
|
|
|
def enterPurchase(self):
|
|
|
|
PurchaseBase.enterPurchase(self)
|
|
|
|
self.rewardDoubledJellybeanLabel.hide()
|
|
|
|
self.bg.reparentTo(render)
|
|
|
|
base.setBackgroundColor(0.78, 0.65, 0.53)
|
|
|
|
self.accept('purchaseStateChange', self.__handleStateChange)
|
|
|
|
self.playAgain.reparentTo(self.toon.inventory.purchaseFrame)
|
|
|
|
self.backToPlayground.reparentTo(self.toon.inventory.purchaseFrame)
|
|
|
|
self.pointDisplay.reparentTo(self.toon.inventory.purchaseFrame)
|
|
|
|
self.statusLabel.reparentTo(self.toon.inventory.purchaseFrame)
|
|
|
|
for headFrame in self.headFrames:
|
|
|
|
headFrame[1].show()
|
|
|
|
headFrame[1].reparentTo(self.toon.inventory.purchaseFrame)
|
|
|
|
|
|
|
|
if not self.tutorialMode:
|
|
|
|
if not config.GetBool('disable-purchase-timer', 0):
|
|
|
|
self.timer.show()
|
|
|
|
self.timer.countdown(self.remain, self.__timerExpired)
|
|
|
|
else:
|
|
|
|
self.timer.hide()
|
|
|
|
self.disablePlayAgain()
|
|
|
|
self.accept('disableGagPanel', Functor(self.toon.inventory.setActivateMode, 'gagTutDisabled', gagTutMode=1))
|
|
|
|
self.accept('disableBackToPlayground', self.disableBackToPlayground)
|
|
|
|
self.accept('enableGagPanel', self.handleEnableGagPanel)
|
|
|
|
self.accept('enableBackToPlayground', self.enableBackToPlayground)
|
|
|
|
for avId, headFrame in self.headFrames:
|
|
|
|
if avId != self.newbieId:
|
|
|
|
headFrame.hide()
|
|
|
|
|
|
|
|
messenger.send('gagScreenIsUp')
|
2015-05-05 13:43:30 -05:00
|
|
|
if base.autoPlayAgain:
|
2015-03-03 16:10:12 -06:00
|
|
|
base.transitions.fadeOut(0)
|
|
|
|
self.__handlePlayAgain()
|
|
|
|
|
|
|
|
def exitPurchase(self):
|
|
|
|
PurchaseBase.exitPurchase(self)
|
|
|
|
self.ignore('disableGagPanel')
|
|
|
|
self.ignore('disableBackToPlayground')
|
|
|
|
self.ignore('enableGagPanel')
|
|
|
|
self.ignore('enableBackToPlayground')
|
|
|
|
self.bg.reparentTo(hidden)
|
|
|
|
self.playAgain.reparentTo(self.frame)
|
|
|
|
self.backToPlayground.reparentTo(self.frame)
|
|
|
|
self.pointDisplay.reparentTo(self.frame)
|
|
|
|
self.statusLabel.reparentTo(self.frame)
|
|
|
|
self.ignore('purchaseStateChange')
|
|
|
|
base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor)
|
2015-05-05 13:43:30 -05:00
|
|
|
if base.autoPlayAgain:
|
2015-03-03 16:10:12 -06:00
|
|
|
base.transitions.fadeIn()
|
|
|
|
|
|
|
|
def disableBackToPlayground(self):
|
|
|
|
self.backToPlayground['state'] = DGG.DISABLED
|
|
|
|
|
|
|
|
def enableBackToPlayground(self):
|
|
|
|
self.backToPlayground['state'] = DGG.NORMAL
|
|
|
|
|
|
|
|
def disablePlayAgain(self):
|
|
|
|
self.playAgain['state'] = DGG.DISABLED
|
|
|
|
|
|
|
|
def enablePlayAgain(self):
|
|
|
|
self.playAgain['state'] = DGG.NORMAL
|
|
|
|
|
|
|
|
def enterTutorialMode(self, newbieId):
|
|
|
|
self.tutorialMode = 1
|
|
|
|
self.newbieId = newbieId
|
|
|
|
|
|
|
|
def handleEnableGagPanel(self):
|
|
|
|
self.toon.inventory.setActivateMode('purchase', gagTutMode=1)
|
|
|
|
self.checkForBroke()
|
|
|
|
|
|
|
|
def handleGagTutorialDone(self):
|
|
|
|
self.enableBackToPlayground()
|
|
|
|
|
|
|
|
def setupUnexpectedExitHooks(self):
|
|
|
|
for avId in self.ids:
|
|
|
|
if avId in base.cr.doId2do:
|
|
|
|
toon = base.cr.doId2do[avId]
|
|
|
|
eventName = toon.uniqueName('disable')
|
|
|
|
self.accept(eventName, self.__handleUnexpectedExit, extraArgs=[avId])
|
|
|
|
self.unexpectedEventNames.append(eventName)
|
|
|
|
|
|
|
|
def cleanupUnexpectedExitHooks(self):
|
|
|
|
for eventName in self.unexpectedEventNames:
|
|
|
|
self.ignore(eventName)
|
|
|
|
|
|
|
|
def __handleUnexpectedExit(self, avId):
|
|
|
|
self.unexpectedExits.append(avId)
|
|
|
|
|
|
|
|
|
|
|
|
class PurchaseHeadFrame(DirectFrame):
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('Purchase')
|
|
|
|
|
|
|
|
def __init__(self, av, purchaseModels):
|
|
|
|
DirectFrame.__init__(self, relief=None, image=purchaseModels.find('**/Char_Pnl'))
|
|
|
|
self.initialiseoptions(PurchaseHeadFrame)
|
|
|
|
self.statusLabel = DirectLabel(parent=self, relief=None, text='', text_scale=TTLocalizer.PstatusLabel, text_wordwrap=7.5, text_fg=(0.05, 0.14, 0.4, 1), text_pos=(0.1, 0, 0))
|
|
|
|
self.av = av
|
|
|
|
self.avKeep = DelayDelete.DelayDelete(av, 'PurchaseHeadFrame.av')
|
|
|
|
self.accept('clientCleanup', self._handleClientCleanup)
|
|
|
|
self.head = self.stateNodePath[0].attachNewNode('head', 20)
|
|
|
|
self.head.setPosHprScale(-0.22, 10.0, -0.1, 180.0, 0.0, 0.0, 0.1, 0.1, 0.1)
|
|
|
|
self.headModel = ToonHead.ToonHead()
|
|
|
|
self.headModel.setupHead(self.av.style, forGui=1)
|
|
|
|
self.headModel.reparentTo(self.head)
|
|
|
|
self.tag2Node = NametagFloat2d()
|
2015-06-24 14:08:15 -05:00
|
|
|
self.tag2Node.setContents(Nametag.CName)
|
|
|
|
self.av.nametag.addNametag(self.tag2Node)
|
2015-03-03 16:10:12 -06:00
|
|
|
self.tag2 = self.attachNewNode(self.tag2Node)
|
|
|
|
self.tag2.setPosHprScale(-0.22, 10.0, 0.12, 0, 0, 0, 0.046, 0.046, 0.046)
|
|
|
|
self.tag1Node = NametagFloat2d()
|
2015-06-24 14:08:15 -05:00
|
|
|
self.tag1Node.setContents(Nametag.CSpeech | Nametag.CThought)
|
|
|
|
self.av.nametag.addNametag(self.tag1Node)
|
2015-03-03 16:10:12 -06:00
|
|
|
self.tag1 = self.attachNewNode(self.tag1Node)
|
|
|
|
self.tag1.setPosHprScale(-0.15, 0, -0.1, 0, 0, 0, 0.046, 0.046, 0.046)
|
|
|
|
self.hide()
|
|
|
|
|
|
|
|
def destroy(self):
|
|
|
|
DirectFrame.destroy(self)
|
|
|
|
del self.statusLabel
|
|
|
|
self.headModel.delete()
|
|
|
|
del self.headModel
|
|
|
|
self.head.removeNode()
|
|
|
|
del self.head
|
2015-06-24 14:08:15 -05:00
|
|
|
self.av.nametag.removeNametag(self.tag1Node)
|
|
|
|
self.av.nametag.removeNametag(self.tag2Node)
|
2015-03-03 16:10:12 -06:00
|
|
|
self.tag1.removeNode()
|
|
|
|
self.tag2.removeNode()
|
|
|
|
del self.tag1
|
|
|
|
del self.tag2
|
|
|
|
del self.tag1Node
|
|
|
|
del self.tag2Node
|
|
|
|
del self.av
|
|
|
|
self.removeAvKeep()
|
|
|
|
|
|
|
|
def setAvatarState(self, state):
|
|
|
|
if state == PURCHASE_DISCONNECTED_STATE:
|
|
|
|
self.statusLabel['text'] = TTLocalizer.GagShopPlayerDisconnected % self.av.getName()
|
|
|
|
self.statusLabel['text_pos'] = (0.015, 0.072, 0)
|
|
|
|
self.head.hide()
|
|
|
|
self.tag1.hide()
|
|
|
|
self.tag2.hide()
|
|
|
|
elif state == PURCHASE_EXIT_STATE:
|
|
|
|
self.statusLabel['text'] = TTLocalizer.GagShopPlayerExited % self.av.getName()
|
|
|
|
self.statusLabel['text_pos'] = (0.015, 0.072, 0)
|
|
|
|
self.head.hide()
|
|
|
|
self.tag1.hide()
|
|
|
|
self.tag2.hide()
|
|
|
|
elif state == PURCHASE_PLAYAGAIN_STATE:
|
|
|
|
self.statusLabel['text'] = TTLocalizer.GagShopPlayerPlayAgain
|
|
|
|
self.statusLabel['text_pos'] = (0.1, -0.12, 0)
|
|
|
|
elif state == PURCHASE_WAITING_STATE:
|
|
|
|
self.statusLabel['text'] = TTLocalizer.GagShopPlayerBuying
|
|
|
|
self.statusLabel['text_pos'] = (0.1, -0.12, 0)
|
|
|
|
elif state == PURCHASE_NO_CLIENT_STATE:
|
|
|
|
Purchase.notify.warning("setAvatarState('no client state'); OK for gag purchase tutorial")
|
|
|
|
else:
|
|
|
|
Purchase.notify.warning('unknown avatar state: %s' % state)
|
|
|
|
|
|
|
|
def _handleClientCleanup(self):
|
|
|
|
self.destroy()
|
|
|
|
|
|
|
|
def removeAvKeep(self):
|
|
|
|
if hasattr(self, 'avKeep'):
|
|
|
|
self.notify.debug('destroying avKeep %s' % self.avKeep)
|
|
|
|
self.avKeep.destroy()
|
|
|
|
del self.avKeep
|
|
|
|
self.ignore('clientCleanup')
|