ToonTownRewritten/toontown/election/DistributedElectionEvent.py

1135 lines
60 KiB
Python

from pandac.PandaModules import *
from otp.nametag.NametagConstants import *
from direct.distributed.ClockDelta import *
from direct.interval.IntervalGlobal import *
from direct.distributed.DistributedObject import DistributedObject
from direct.fsm.FSM import FSM
from direct.actor import Actor
from direct.task import Task
from toontown.toon import NPCToons
from toontown.suit import DistributedSuitBase, SuitDNA
from toontown.toonbase import ToontownGlobals
from toontown.battle import BattleProps
from otp.margins.WhisperPopup import *
import ElectionGlobals
from direct.directnotify import DirectNotifyGlobal
from random import choice
# Interactive Flippy
from otp.speedchat import SpeedChatGlobals
class DistributedElectionEvent(DistributedObject, FSM):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedElectionEvent")
def __init__(self, cr):
DistributedObject.__init__(self, cr)
FSM.__init__(self, 'ElectionFSM')
self.cr.election = self
self.interactiveOn = False
self.showFloor = NodePath('ShowFloor')
self.showFloor.setPos(80, 0, 4)
#Stage
stage = loader.loadModel('phase_4/models/events/election_stage')
stage.reparentTo(self.showFloor)
stage.setHpr(270, 0, 0)
stage.setScale(2.0, 1.8, 1.5)
podium = loader.loadModel('phase_4/models/events/election_stagePodium')
podium.reparentTo(self.showFloor)
podium.setPosHpr(-6, 0, 3, 270, -2, 5)
podium.setScale(0.65)
self.counterLeft = Actor.Actor('phase_4/models/events/election_counterLeft-mod', {'body': 'phase_4/models/events/election_counterLeft-countSeq'})
self.counterLeft.reparentTo(self.showFloor)
self.counterLeft.setPosHpr(13.5, 10, 2.95, 270, 0, 0)
self.counterLeft.setScale(2.0)
self.counterRight = Actor.Actor('phase_4/models/events/election_counterRight-mod', {'body': 'phase_4/models/events/election_counterRight-countSeq'})
self.counterRight.reparentTo(self.showFloor)
self.counterRight.setPosHpr(13.5, -10, 3.25, 270, 0, 0)
self.counterRight.setScale(2.0)
rope = loader.loadModel('phase_4/models/events/election_rope')
rope.reparentTo(self.showFloor)
rope.setPosHpr(-34, 18, 0.46, 270, 0, 0)
rope.setScale(2, 2, 2)
rc = CollisionSphere(8.2, 15.5, 2.0, 13.5)
rc2 = CollisionBox(Point3(8.88, 28.76, 0.00), 4.44, 6.38, 9.00)
ropeCollision = rope.attachNewNode(CollisionNode('collision'))
ropeCollision.node().addSolid(rc)
ropeCollision.node().addSolid(rc2)
#Campaign stands
self.flippyStand = Actor.Actor('phase_4/models/events/election_flippyStand-mod', {'idle': 'phase_4/models/events/election_flippyStand-idle'})
self.flippyStand.reparentTo(self.showFloor)
self.flippyStand.setPosHprScale(-43.6, -24.5, 0.01, 200, 0, 0, 0.55, 0.55, 0.55)
self.flippyStand.exposeJoint(None,"modelRoot", "LInnerShoulder")
flippyTable = self.flippyStand.find('**/LInnerShoulder')
self.flippyStand.exposeJoint(None,"modelRoot", "Box_Joint")
wheelbarrowJoint = self.flippyStand.find('**/Box_Joint').attachNewNode('Pie_Joint')
wheelbarrow = self.flippyStand.find('**/Box')
wheelbarrow.setPosHprScale(-2.39, 0.00, 1.77, 0.00, 0.00, 6.00, 1.14, 1.54, 0.93)
self.slappyStand = Actor.Actor('phase_4/models/events/election_slappyStand-mod', {
'idle': 'phase_4/models/events/election_slappyStand-idle',
'watch-idle': 'phase_4/models/events/election_slappyStand-watch-idle',
'sad': 'phase_4/models/events/election_slappyStand-reaction',
})
self.slappyStand.reparentTo(self.showFloor)
self.slappyStand.setPosHprScale(-62.45, 14.39, 0.01, 325, 0, 0, 0.55, 0.55, 0.55)
# Let's give FlippyStand a bunch of pies.
# Pies on/around the stand.
pie = loader.loadModel('phase_3.5/models/props/tart')
pieS = pie.copyTo(flippyTable)
pieS.setPosHprScale(-2.61, -0.37, -1.99, 355.60, 90.00, 4.09, 1.6, 1.6, 1.6)
# Pies in the wheelbarrow.
for pieSettings in ElectionGlobals.FlippyWheelbarrowPies:
pieModel = pie.copyTo(wheelbarrowJoint)
pieModel.setPosHprScale(*pieSettings)
wheelbarrowJoint.setPosHprScale(3.94, 0.00, 1.06, 270.00, 344.74, 0.00, 1.43, 1.12, 1.0)
self.restockSfx = loader.loadSfx('phase_9/audio/sfx/CHQ_SOS_pies_restock.ogg')
self.splashSfx = loader.loadSfx('phase_9/audio/sfx/CHQ_FACT_paint_splash.ogg')
# Find FlippyStand's collision to give people pies.
# The new animated model doesn't have any collisions, so this needs to be replaced with a collision box. Harv did it once, just need to look back in the commit history.
cs = CollisionBox(Point3(7, 0, 0), 12, 5, 18)
self.pieCollision = self.flippyStand.attachNewNode(CollisionNode('wheelbarrow_collision'))
self.pieCollision.node().addSolid(cs)
self.accept('enter' + self.pieCollision.node().getName(), self.handleWheelbarrowCollisionSphereEnter)
csSlappy = CollisionBox(Point3(-4.2, 0, 0), 9.5, 5.5, 18)
self.goopCollision = self.slappyStand.attachNewNode(CollisionNode('goop_collision'))
self.goopCollision.node().addSolid(csSlappy)
# Hi NPCs!
self.alec = NPCToons.createLocalNPC(2022)
self.slappy = NPCToons.createLocalNPC(2021)
self.flippy = NPCToons.createLocalNPC(2001)
# Sometimes they all need to do the same thing.
self.characters = [self.alec, self.slappy, self.flippy]
self.flippyStand.loop('idle')
self.slappyStand.loop('idle')
self.alecNode = None
self.surlee = NPCToons.createLocalNPC(20191)
# We want Surlee to use Prepostera's animation since he is the star of the PreShow, but Surlee is a different size.
# Since Disney didn't include Prepostera's animation for Surlee's size, we have to make him small an painstakingly scale him
self.surlee.useLOD(1000)
self.surlee.find('**/250').remove()
self.surlee.find('**/500').remove()
surleeLegs = self.surlee.find('**/legs')
surleeLegs.setScale(1, 1, 1.5)
surleeLegs.setZ(-0.26)
self.surlee.find('**/__Actor_torso').setZ(1.1)
self.surlee.find('**/torso-top').setPosHprScale(0.00, 0.00, -0.45, 0.00, 0.00, 0.00, 1.00, 0.98, 1.96)
self.surlee.find('**/__Actor_head').setZ(0.7)
self.surlee.find('**/neck').setZ(0.7)
self.surlee.find('**/sleeves').setZ(0.7)
self.surlee.find('**/arms').setZ(0.7)
self.surlee.find('**/hands').setZ(0.7)
self.surlee.setPos(-22, 7, 0)
self.surlee.setH(110)
rHand = self.surlee.find('**/def_joint_right_hold')
clipBoard = loader.loadModel('phase_4/models/props/tt_m_prp_acs_clipboard')
placeholder = rHand.attachNewNode('ClipBoard')
clipBoard.instanceTo(placeholder)
placeholder.setH(180)
placeholder.setScale(render, 1.0)
placeholder.setPos(0.5, 0.6, -0.1)
placeholder.setScale(1.3)
# And now for the real Surlee
self.surleeR = NPCToons.createLocalNPC(2019)
self.surleeR.useLOD(1000)
self.surleeR.setPos(-22, 7, 0)
self.surleeR.setH(110)
self.surleeR.head = self.surleeR.find('**/__Actor_head')
self.surleeR.initializeBodyCollisions('toon')
# Now the same for Prepostera
self.prepostera = NPCToons.createLocalNPC(20201)
self.prepostera.useLOD(1000)
self.prepostera.find('**/250').remove()
self.prepostera.find('**/500').remove()
preposteraLegs = self.prepostera.find('**/legs')
preposteraLegs.setScale(1, 1, 0.5)
self.prepostera.find('**/__Actor_torso').setZ(-0.9)
self.prepostera.find('**/torso-top').setPosHprScale(0.00, 0.00, 0.2, 0.00, 0.00, 0.00, 1.00, 0.98, 0.5)
self.prepostera.find('**/__Actor_head').setZ(-0.7)
self.prepostera.find('**/neck').setZ(-0.7)
self.prepostera.find('**/sleeves').setZ(-0.7)
preposteraArms = self.prepostera.find('**/arms')
preposteraArms.setZ(-0.4)
preposteraArms.setScale(1, 1, 0.8)
preposteraHands = self.prepostera.find('**/hands')
preposteraHands.setZ(-0.4)
preposteraHands.setScale(1, 1, 0.8)
self.prepostera.setPos(-70, 10, 0.0)
self.prepostera.setH(-50)
self.prepostera.initializeBodyCollisions('toon')
rHand = self.prepostera.find('**/def_joint_right_hold')
clipBoard = loader.loadModel('phase_4/models/props/tt_m_prp_acs_clipboard')
placeholder = rHand.attachNewNode('ClipBoard')
clipBoard.instanceTo(placeholder)
placeholder.setH(180)
placeholder.setScale(render, 1.0)
placeholder.setPos(0, -0.3, 0.3)
# And his buddies
self.dimm = NPCToons.createLocalNPC(2018)
self.dimm.useLOD(1000)
self.dimm.find('**/250').remove()
self.dimm.find('**/500').remove()
self.dimm.setPos(-72.36, 10.46, 0.00)
self.dimm.setH(-50)
self.dimm.initializeBodyCollisions('toon')
rHand1 = self.dimm.find('**/def_joint_right_hold')
sillyReader = loader.loadModel('phase_4/models/props/tt_m_prp_acs_sillyReader')
placeholder1 = rHand1.attachNewNode('SillyReader')
sillyReader.instanceTo(placeholder1)
placeholder1.setH(180)
placeholder1.setScale(render, 1.0)
placeholder1.setPos(0, 0, 0.1)
self.surlee.reparentTo(self.showFloor)
self.surleeR.reparentTo(self.showFloor)
self.prepostera.reparentTo(self.showFloor)
self.dimm.reparentTo(self.showFloor)
self.surlee.hide()
self.surleeR.hide()
self.prepostera.addActive()
self.prepostera.startBlink()
self.prepostera.loop('scientistWork')
self.dimm.addActive()
self.dimm.startBlink()
self.dimm.loop('scientistWork')
# The first cog created, as seen in the original intro video - a Yesman
self.suit = DistributedSuitBase.DistributedSuitBase(cr)
suitDNA = SuitDNA.SuitDNA()
suitDNA.newSuit('ym')
self.suit.setDNA(suitDNA)
self.suit.setDisplayName('Yesman\nBossbot\nLevel 3')
self.suit.setPickable(0)
# Cog speeches, for when we want to manually define it
phasePath = 'phase_3.5/audio/dial/'
self.speechMurmurSfx = loader.loadSfx(phasePath + 'COG_VO_murmur.ogg')
self.speechStatementSfx = loader.loadSfx(phasePath + 'COG_VO_statement.ogg')
self.speechQuestionSfx = loader.loadSfx(phasePath + 'COG_VO_question.ogg')
self.speechGruntSfx = loader.loadSfx(phasePath + 'COG_VO_grunt.ogg')
# We'll use these to check and see if a certain state has already happened
self.finishedPreShow = False
self.finishedBegin = False
self.finishedAlecSpeech = False
self.finishedCogLanding = False
self.finishedInvasion = False
self.finishedInvasionEnding = False
def enterOff(self, offset):
base.cr.parentMgr.unregisterParent(ToontownGlobals.SPSlappysBalloon)
self.showFloor.reparentTo(hidden)
def exitOff(self):
self.showFloor.reparentTo(render)
def __cleanupNPCs(self):
npcs = [self.flippy, self.slappy, self.alec, self.surlee, self.surleeR, self.prepostera, self.dimm, self.suit]
for npc in npcs:
if npc:
npc.removeActive()
def delete(self):
self.demand('Off', 0.)
self.ignore('entercnode')
# Clean up everything...
self.showFloor.removeNode()
self.stopInteractiveFlippy()
self.ignore('enter' + self.pieCollision.node().getName())
self.__cleanupNPCs()
DistributedObject.delete(self)
'''
PRE-ELECTION CAMPAIGNS
These bits are for things used before Election Day, and mostly unrelated to the Election Sequence.
'''
def enterIdle(self, offset):
if config.GetBool('want-doomsday', False):
# We're waiting for the election to start, so Surlee comes by to keep us occupied during his studies of "sillyness".
self.surlee.show()
self.surlee.addActive()
self.surlee.startBlink()
self.surlee.loop('scientistEmcee')
self.surleeIntroInterval = Sequence(
Wait(10),
Func(self.surlee.setChatAbsolute, 'Oh, uh, Hello! I suppose it\'s election time already?', CFSpeech|CFTimeout),
Wait(5),
Func(self.surlee.setChatAbsolute, 'We\'re just minutes away from the most important event in the history of our town.', CFSpeech|CFTimeout),
Wait(8),
Func(self.surlee.setChatAbsolute, 'Alec Tinn is inside Toon Hall right now with the two candidates preparing for the announcement.', CFSpeech|CFTimeout),
Wait(8),
Func(self.surlee.setChatAbsolute, 'When the clock strikes two we\'ll see them march through those doors and onto the stage. Are you toons ready?', CFSpeech|CFTimeout),
Wait(8),
Func(self.surlee.setChatAbsolute, 'I must say, surprisingly, the silliness around here couldn\'t be higher at this time.', CFSpeech|CFTimeout),
Wait(8),
Func(self.surlee.setChatAbsolute, 'My fellow scientists of silliness, Professor Prepostera and Doctor Dimm, are over there tracking the amount of silliness being taken in from the campaign stands.', CFSpeech|CFTimeout),
Wait(8),
Func(self.surlee.setChatAbsolute, 'At least, I think they are. You never know with those goofs.', CFSpeech|CFTimeout),
Wait(8),
Func(self.surlee.setChatAbsolute, 'I hope you haven\'t been standing here long, because I\'m going to have to start repeating myself soon.', CFSpeech|CFTimeout),
)
self.surleeIntroInterval.loop()
self.surleeIntroInterval.setT(offset)
self.counterLeft.pose('body', 0)
self.counterRight.pose('body', 0)
def exitIdle(self):
if config.GetBool('want-doomsday', False):
self.surleeIntroInterval.finish()
def startInteractiveFlippy(self):
self.flippy.reparentTo(self.showFloor)
self.flippy.setPosHpr(-40.6, -18.5, 0.01, 20, 0, 0)
self.flippy.initializeBodyCollisions('toon')
self.interactiveOn = True
self.flippyPhrase = None
self.accept(SpeedChatGlobals.SCStaticTextMsgEvent, self.phraseSaidToFlippy)
def stopInteractiveFlippy(self):
self.ignore(SpeedChatGlobals.SCStaticTextMsgEvent)
self.interactiveOn = False
def phraseSaidToFlippy(self, phraseId):
# Check distance...
if self.flippy.nametag.getChat() != '':
# Flippy is already responding to someone, ignore them.
return
if Vec3(base.localAvatar.getPos(self.flippy)).length() > 10:
# Too far away.
return
# Check if the phrase is something that Flippy should respond to.
for phraseIdList in ElectionGlobals.FlippyPhraseIds:
if phraseId in phraseIdList:
self.sendUpdate('phraseSaidToFlippy', [phraseId])
break
def flippySpeech(self, avId, phraseId):
av = self.cr.doId2do.get(avId)
if not av:
# An avatar we don't know about interacted with Flippy... odd.
self.notify.warning("Received unknown avId in flippySpeech from the AI.")
return
if not self.interactiveOn:
self.notify.warning("Received flippySpeech from AI while Interactive Flippy is disabled on our client.")
return
if self.flippy.nametag.getChat() != '':
# Flippy is alredy responding to someone, ignore.
return
if phraseId == 1: # Someone requested pies... Lets pray that we don't need phraseId 1...
taskMgr.doMethodLater(ElectionGlobals.FlippyDelayResponse, self.flippy.setChatAbsolute, 'interactive-flippy-chat-task',
extraArgs = [choice(ElectionGlobals.FlippyGibPies).replace("__NAME__", av.getName()), CFSpeech | CFTimeout])
return
if len(ElectionGlobals.FlippyPhraseIds) != len(ElectionGlobals.FlippyPhrases):
# There is a mismatch in the number of phrases and the phraseIds we're looking out for...
# If this ever occurs on the live client, then clearly this wasn't tested and someone needs a slap.
raise Exception("There is a mismatch in the number of phraseIds and the number of phrases for Flippy Interactive!")
return
for index, phraseIdList in enumerate(ElectionGlobals.FlippyPhraseIds):
for pid in phraseIdList:
if pid == phraseId:
# This could potentially lead to a crash if there is a mismatch in the number (indexes) of
# phraseIdLists and phrases. Could possibly use a python dict ( { key : value } ) to
# prevent this...
taskMgr.doMethodLater(ElectionGlobals.FlippyDelayResponse, self.flippy.setChatAbsolute, 'interactive-flippy-chat-task',
extraArgs = [ElectionGlobals.FlippyPhrases[index].replace("__NAME__", av.getName()), CFSpeech | CFTimeout])
return
def handleWheelbarrowCollisionSphereEnter(self, collEntry):
if base.localAvatar.numPies >= 0 and base.localAvatar.numPies < 20:
# We need to give them more pies! Send a request to the server.
self.sendUpdate('wheelbarrowAvatarEnter', [])
self.restockSfx.play()
def handleSlappyCollisionSphereEnter(self, collEntry):
if base.localAvatar.savedCheesyEffect != 15:
# Splash some of Slappy's green goop on them
self.sendUpdate('slappyAvatarEnter', [])
self.splashSfx.play()
'''
ELETION DAY SEQUENCE
Next up we have the things that relate to the election sequence, which is controlled by both the AI and client.
The AI has the global timer, which will fire off which state should be played and when. Sort of like checkpoints.
The client has the sequences themselves, though, just in case anyone has any network lag when watching it.
The client also shoots a message to the AI to ask how much time has elapsed since the sequence started so that late-joining clients can stay in sync with the sequence.
Get ready, this code is a doozy to read. Lots of sequences.
'''
def enterEvent(self, offset):
base.cr.playGame.hood.loader.music.stop()
def catchUp(self):
# This is used to get us up to date if we missed out on some of the sequences.
if self.finishedPreShow:
self.cameras = []
for cameraId in base.cr.cameraManager.cameraIds:
if cameraId in base.cr.doId2do:
self.cameras.append(base.cr.doId2do[cameraId])
self.surlee.hide()
self.surlee.removeActive()
self.surleeR.show()
self.surleeR.addActive()
self.surleeR.startBlink()
self.surleeR.setPosHpr(-32, -15, 0, -40, 0, 0)
base.cr.cameraManager.tv.show()
base.cr.cameraManager.tv.setPos(87.85, -0.25, 21.0)
base.cr.cameraManager.tvIdle.loop()
if self.finishedBegin:
for character in self.characters:
character.reparentTo(self.showFloor)
character.useLOD(1000)
character.addActive()
character.startBlink()
character.initializeBodyCollisions('toon')
character.head = character.find('**/__Actor_head')
character.setH(90)
self.slappyStand.loop('watch-idle')
self.ignore('enter' + self.pieCollision.node().getName())
self.alec.setPos(-4.5, -0.14, 3.13)
self.slappy.setPos(1, 9, 3.03)
self.flippy.setPos(2, -10, 3.23)
if self.finishedCogLanding:
self.slappyStand.pose('sad', 249)
self.flippy.setPosHpr(-15, -12, 0, 0, 0, 0)
self.alec.setPos(-1.5, -0.14, 3.13)
self.slappy.hide()
self.slappy.removeActive()
self.surlee.setPosHpr(-32, -15, 0, 40, 0, 0)
self.accept('enter' + self.pieCollision.node().getName(), self.handleWheelbarrowCollisionSphereEnter)
if self.finishedInvasion:
base.cr.cameraManager.disableScreen()
self.surlee.setPosHpr(-32, -15, 0, 40, 0, 0)
self.flippy.setPosHpr(-38, -18.5, 0, 75, 0, 0)
self.alec.setPosHpr(18.0, 41.2, 0, -130, 0, 0)
if self.finishedInvasionEnding:
self.alec.setPosHpr(3, -7, 3.23, 165, 0, 0)
self.flippy.setPos(2, -10, 3.23)
self.flippy.setH(90)
def enterPreShow(self, offset):
# And now for the Pre-election sequence
self.cameras = []
for cameraId in base.cr.cameraManager.cameraIds:
self.cameras.append(base.cr.doId2do[cameraId])
self.surleeLeaveInterval = Sequence(
Wait(7),
#ton of camera setup
# 0 = alec
# 1 = slappy
# 2 = flippy
# 3 = surlee
# 4 = general #2
Parallel(Func(self.moveCamera, 3, 49, 14, 8, 213, 0), Func(base.cr.cameraManager.setMainCamera, self.cameras[3].getDoId())),
Func(self.moveCamera, 0, 59, 12, 9, 237, 0),
Parallel(Func(self.moveCamera, 1, 80, 20, 9.2, -180, 0), Func(self.moveCamera, 2, 72.5, -18, 9, 314, 0)),
# Let's do a quick swap for the real Surlee, now that his animation is done
Parallel(Func(self.surlee.removeActive), Func(self.surlee.hide), Func(self.surleeR.show), Func(self.surleeR.addActive), Func(self.surleeR.startBlink)),
Wait(3),
Func(self.surleeR.setChatAbsolute, 'Hrm, you heard the HQ. I better get out of the way before Alec arrives.', CFSpeech|CFTimeout),
Wait(1),
Parallel(Func(self.surleeR.loop, 'walk'), self.surleeR.posHprInterval(4, (-20, 0, 0), (190, 0, 0)), Func(base.cr.cameraManager.tvFlyIn.start)),
# TV Flies down behind Surlee
Parallel(Func(self.surleeR.loop, 'neutral'), self.surleeR.head.hprInterval(1, (75, 30, 0), blendType='easeInOut')),
Wait(1),
Func(self.surleeR.setChatAbsolute, 'Oh, do you like it? Designed it myself. Don\'t worry about getting close to the ropes; the TV will be showing a live feed for everyone to get a great view.', CFSpeech|CFTimeout),
Func(self.surleeR.loop, 'walk'),
Parallel(self.surleeR.hprInterval(1, (80, 0, 0)), self.surleeR.head.hprInterval(1, (0, 0, 0), blendType='easeInOut')),
Func(self.surleeR.loop, 'neutral'),
Wait(8),
Func(self.surleeR.setChatAbsolute, 'I know you all will keep trying to jump on top of each other for a better view anyway, though, so try not to hurt anyone.', CFSpeech|CFTimeout),
Wait(3),
Func(base.cr.cameraManager.setMainCamera, self.cameras[0].getDoId()),
Func(self.moveCamera, 3, 39, -2, 7, 572, 0),
Func(self.surleeR.loop, 'run'),
self.surleeR.posHprInterval(2, (-17, -7, 0), (180, 0, 0)),
self.surleeR.posHprInterval(1.5, (-15, -15, 0), (190, 0, 0)),
Func(self.surleeR.loop, 'walk'),
self.surleeR.posHprInterval(2, (-20, -18, 0), (90, 0, 0)),
self.surleeR.posHprInterval(3.5, (-32, -19, 0), (35, 0, 0)),
self.surleeR.posHprInterval(1, (-34, -17, 0), (0, 0, 0)),
self.surleeR.posHprInterval(1.5, (-32, -15, 0), (-40, 0, 0)),
Func(self.surleeR.loop, 'neutral')
)
self.surleeLeaveInterval.start()
self.surleeLeaveInterval.setT(offset)
def enterBegin(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.catchUp()
# Oh boy, here come the candidates
for character in self.characters:
character.reparentTo(self.showFloor)
character.setPosHpr(35, -0.3, 0, 90, 0, 0)
character.useLOD(1000)
character.addActive()
character.startBlink()
character.head = character.find('**/__Actor_head')
musicIntro = base.loadMusic(ElectionGlobals.IntroMusic)
self.slappyStand.loop('watch-idle')
self.ignore('enter' + self.pieCollision.node().getName())
self.alecHallInterval = Sequence(
Parallel(Func(self.alec.loop, 'walk'), Func(base.playMusic, musicIntro, looping=0, volume=0.8)),
self.alec.posInterval(3, (12.96, -0.38, 0)),
self.alec.posInterval(2, (4.2, -0.25, 3.13)),
self.alec.posInterval(2, (-4.5, -0.14, 3.13)),
Func(self.alec.loop, 'neutral'),
)
self.slappyHallInterval = Sequence(
Wait(1),
Func(self.slappy.loop, 'walk'),
self.slappy.posInterval(2.5, (12.96, -0.38, 0)),
self.slappy.posHprInterval(2, (4.3, 2.72, 3.13), (70, 0, 0)),
self.slappy.posHprInterval(1, (2.36, 5.18, 3.08), (40, 0, 0)),
self.slappy.posHprInterval(1, (1, 9, 3.03), (90, 0, 0)),
Func(self.slappy.loop, 'neutral'),
)
self.flippyHallInterval = Sequence(
Wait(2),
Func(self.flippy.loop, 'walk'),
self.flippy.posInterval(3, (12.96, -0.38, 0)),
self.flippy.posHprInterval(1, (3.3, -2.39, 3.13), (120, 0, 0)),
self.flippy.posHprInterval(1, (2.49, -6.09, 3.17), (155, 0, 0)),
self.flippy.posHprInterval(1, (2, -10, 3.23), (90, 0, 0)),
Func(self.flippy.loop, 'neutral'),
)
self.alecHallInterval.start()
self.alecHallInterval.setT(offset)
self.slappyHallInterval.start()
self.slappyHallInterval.setT(offset)
self.flippyHallInterval.start()
self.flippyHallInterval.setT(offset)
def exitBegin(self):
self.alecHallInterval.finish()
self.slappyHallInterval.finish()
self.flippyHallInterval.finish()
# This is still going on when Begin starts. Just cleaning it up here rather than PreShow.
self.surleeLeaveInterval.finish()
def enterAlecSpeech(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.catchUp()
self.alecSpeech = Sequence(
# Alec drones on about how much he loves elections, the candidates give their speeches
Func(self.alec.setChatAbsolute, 'Hellooo Toontown~!', CFSpeech|CFTimeout),
Wait(1),
self.flippy.head.hprInterval(1, (-25, 0, 0), blendType='easeInOut'),
Wait(1),
self.slappy.head.hprInterval(1, (20, 3, 0), blendType='easeInOut'),
Wait(1),
Func(self.alec.setChatAbsolute, 'As many of you know, I\'m your Hilarious Host and Eccentric Elector: Alec Tinn!', CFSpeech|CFTimeout),
Wait(8.5),
Func(self.alec.setChatAbsolute, 'And of course, we can\'t forget about our two toonerific toons who have been selected to fight for the Presidency...', CFSpeech|CFTimeout),
Wait(9),
Func(self.alec.setChatAbsolute, 'Slappy Quackintosh, and Flippy Doggenbottom!', CFSpeech|CFTimeout),
Wait(3.3),
Func(self.slappy.play, 'wave'),
self.flippy.head.hprInterval(1, (-70, 0, 0), blendType='easeInOut'),
Wait(1.2),
self.flippy.head.hprInterval(1, (0, 0, 0), blendType='easeInOut'),
Func(self.slappy.loop, 'neutral'),
Func(self.alec.setChatAbsolute, 'I must say, this turnout is absolutely, positivley, extra-tooneriffically, astounding!', CFSpeech|CFTimeout),
Wait(6),
Func(self.alec.setChatAbsolute, 'It\'s truly an honor to be here on this day, and I\'m sure I speak for all of us when I thank you for coming.', CFSpeech|CFTimeout),
Wait(8),
Func(self.alec.setChatAbsolute, 'Now, the votes are almost ready to be tallied! Flippy, Slappy, do either of you have anything to say before the moment of truth?', CFSpeech|CFTimeout),
Wait(10),
Func(base.cr.cameraManager.setMainCamera, self.cameras[1].getDoId()),
Func(self.slappy.setChatAbsolute, 'The only thing I have to say, no matter who wins...', CFSpeech|CFTimeout),
Wait(2),
Parallel(
self.flippy.head.hprInterval(1, (-70, 0, 0), blendType='easeInOut'),
Sequence(
Wait(0.5),
self.alec.head.hprInterval(1, (-70, 0, 0), blendType='easeInOut')
)
),
Wait(3),
Func(self.slappy.setChatAbsolute, 'I know that Toontown is going to grow to be even more... "Toontastic" than ever before.', CFSpeech|CFTimeout),
Wait(8),
Func(self.slappy.setChatAbsolute, 'All of you are truer-than-truly the best!', CFSpeech|CFTimeout),
Wait(7),
self.flippy.head.hprInterval(1, (0, 0, 0), blendType='easeInOut'),
Wait(1),
Func(base.cr.cameraManager.setMainCamera, self.cameras[2].getDoId()),
Func(self.flippy.setChatAbsolute, 'Like Slappy said, I can\'t even begin to thank all of you Toontastic toons for this.', CFSpeech|CFTimeout),
Wait(1),
self.alec.head.hprInterval(2, (70, 0, 0), blendType='easeInOut'),
Wait(5),
Func(self.flippy.setChatAbsolute, 'Even after all of this terrific time together, I\'m still speechless that I\'m here today.', CFSpeech|CFTimeout),
Wait(8),
Func(self.flippy.setChatAbsolute, 'Here\'s to Toontown, Slappy, and all of you!', CFSpeech|CFTimeout),
Wait(3),
self.slappy.head.hprInterval(1, (70, 0, 0), blendType='easeInOut'),
Wait(3),
Func(base.cr.cameraManager.setMainCamera, self.cameras[0].getDoId()),
Func(self.alec.setChatAbsolute, 'Well said, the both of you!', CFSpeech|CFTimeout),
self.alec.head.hprInterval(1, (0, 0, 0), blendType='easeInOut'),
Wait(1),
self.flippy.head.hprInterval(1, (-25, 0, 0), blendType='easeInOut'),
Wait(1),
self.slappy.head.hprInterval(1, (20, 3, 0), blendType='easeInOut'),
Wait(1),
Func(self.alec.setChatAbsolute, 'Ooh, I\'m just jittering with excitement. Are you toons ready to hear the winners?', CFSpeech|CFTimeout),
Wait(7),
Func(self.alec.setChatAbsolute, 'Without further ado, it is now time to start the GRAND ELECTORAL COUNTERS!', CFSpeech|CFTimeout),
Wait(8),
Func(self.alec.setChatAbsolute, 'Here we gooooo...', CFSpeech|CFTimeout),
Wait(4),
)
self.alecSpeech.start()
self.alecSpeech.setT(offset)
def exitAlecSpeech(self):
self.alecSpeech.finish()
def enterVoteBuildup(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.catchUp()
# And now it's time to announce the winner
musicAnnouncement = base.loadMusic(ElectionGlobals.AnnouncementMusic)
sfxDrumroll = loader.loadSfx('phase_4/audio/sfx/EE_Drumroll.ogg')
self.buildupSequence = Sequence(
# Alec builds up some hype before...
Func(self.alec.setChatAbsolute, 'The winner is...', CFSpeech|CFTimeout),
Wait(4),
Parallel(Func(self.counterLeft.play, 'body'), Func(self.counterRight.play, 'body')),
Wait(3.7),
Func(base.playSfx, sfxDrumroll),
Wait(3.3),
Func(self.alec.setChatAbsolute, 'Oh boy, you can feel the suspense!', CFSpeech|CFTimeout),
Wait(9),
Func(self.alec.setChatAbsolute, 'It\'s...', CFSpeech|CFTimeout),
Wait(4),
Func(self.alec.setChatAbsolute, 'HOLY SMOKES!', CFSpeech|CFTimeout),
Wait(7),
Func(self.alec.setChatAbsolute, 'Well, there you have it. The new President of the Toon Council...', CFSpeech|CFTimeout),
Wait(5),
Func(base.playMusic, musicAnnouncement, looping=0, volume=0.8),
self.alec.head.hprInterval(1, (-70, 0, 0), blendType='easeInOut'),
Wait(1),
# Slappy's victory!
Func(self.alec.setChatAbsolute, 'SLAPPYYYY~ QUACKINTOSH!', CFSpeech|CFTimeout),
Wait(2),
self.flippy.head.hprInterval(1, (-60, 0, 0), blendType='easeInOut'),
Func(self.slappy.showLaughMuzzle),
Func(base.cr.cameraManager.setMainCamera, self.cameras[1].getDoId()),
ActorInterval(self.slappy, 'good-putt'),
ActorInterval(self.slappy, 'happy-dance'),
Func(self.slappy.loop, 'neutral'),
)
self.buildupSequence.start()
self.buildupSequence.setT(offset)
def enterWinnerAnnounce(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.catchUp()
# Slappy won! Lets give him some victory time before his rude interruption.
musicVictory = base.loadMusic(ElectionGlobals.VictoryMusic)
self.victorySequence = Sequence(
Func(base.playMusic, musicVictory, looping=0, volume=0.8),
Wait(0.3),
Func(self.slappy.setChatAbsolute, 'Holy smokes... I don\'t even know where to begin!', CFSpeech|CFTimeout),
Wait(4),
Func(self.slappy.setChatAbsolute, 'I know without any doubt that I hereby accept my duty as your President...', CFSpeech|CFTimeout),
Wait(5),
Func(self.slappy.setChatAbsolute, '...and will Presently Preside with full Presidential Priorities of this Presidentliness!', CFSpeech|CFTimeout),
)
self.victorySequence.start()
self.victorySequence.setT(offset)
def exitWinnerAnnounce(self):
self.victorySequence.finish()
def enterCogLanding(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.catchUp()
# Huh, what's that thing?
musicSad = base.loadMusic(ElectionGlobals.SadMusic)
sfxSad = loader.loadSfx('phase_5/audio/sfx/ENC_Lose.ogg')
mtrack = self.suit.beginSupaFlyMove(Point3(65, 3.6, 4.0), 1, 'fromSky', walkAfterLanding=False)
self.slappyStandDie = Sequence(
ActorInterval(self.slappyStand, 'sad')
)
self.pie = BattleProps.globalPropPool.getProp('creampie')
self.cogSequence = Sequence(
Parallel(Func(self.moveCamera, 1, 56, 26, 9, 204, 0), Func(base.cr.cameraManager.setMainCamera, self.cameras[1].getDoId())),
Parallel(Func(self.suit.reparentTo, render), Func(self.suit.addActive), Func(mtrack.start, offset)),
self.flippy.head.hprInterval(1, (-15, -10, 0), blendType='easeInOut'),
Wait(1),
self.alec.head.hprInterval(1, (-15, -5, 0), blendType='easeInOut'),
Func(self.slappy.setChatAbsolute, 'I will ensure- Uhh...', CFSpeech|CFTimeout),
Func(self.slappy.hideLaughMuzzle),
Wait(2),
# The cog has landed. Surlee knows what's coming.
Func(self.surleeR.sadEyes),
Wait(3),
Func(self.alec.setChatAbsolute, 'Wha- What is that...?', CFSpeech|CFTimeout),
Wait(5),
Func(self.slappy.setChatAbsolute, 'Err... Hey there, fella!', CFSpeech|CFTimeout),
Func(self.slappy.loop, 'walk'),
self.slappy.posHprInterval(1, (-4, 8.5, 3.03), (110, 0, 0)),
Func(self.slappy.play, 'jump'),
Wait(0.45),
self.slappy.posInterval(0.2, (-7.5, 8.3, 3.5)),
self.slappy.posHprInterval(0.4, (-13, 8, 0), (125, 0, 0)),
Wait(0.8),
Func(self.slappy.loop, 'neutral'),
self.slappy.head.hprInterval(0.5, (-3, 5, 0)),
Func(self.slappy.setChatAbsolute, 'My name is Slappy, the newly elected President of the Toon Council in this Toonerrific Town.', CFSpeech|CFTimeout),
Wait(5),
Func(self.suit.setChatAbsolute, 'President, you say? Just the Toon I need to speak with.', CFSpeech|CFTimeout, dialogue = self.speechStatementSfx),
Wait(5),
Func(self.slappy.setChatAbsolute, "Boy, that's some propeller you have there! You know, it looks a lot like the one on that TV.", CFSpeech|CFTimeout),
Wait(5),
Func(self.suit.setChatAbsolute, 'Yes. Now as I began to-', CFSpeech|CFTimeout, dialogue = self.speechQuestionSfx),
Wait(1),
Func(self.slappy.setChatAbsolute, "Ooh, and the suit too. Where did you come from, anyway? It can't be Loony Labs, they're off today.", CFSpeech|CFTimeout),
Wait(5),
Func(self.suit.setChatAbsolute, 'See here, Toon. I am-', CFSpeech|CFTimeout, dialogue = self.speechStatementSfx),
Wait(1),
Func(self.slappy.setChatAbsolute, "No, don't tell me. Let me guess. Errrr... Montana. Final answer. No, no, nevermind. They wouldn't have that fancy of a suit there. Hrmm...", CFSpeech|CFTimeout),
Wait(1),
ActorInterval(self.slappy, 'think', startFrame=0, endFrame=46),
ActorInterval(self.slappy, 'think', startFrame=46, endFrame=0),
Func(self.slappy.loop, 'neutral'),
Wait(1),
Func(self.suit.setChatAbsolute, 'STOP!', CFSpeech|CFTimeout, dialogue = self.speechGruntSfx),
Wait(4),
Func(self.suit.setChatAbsolute, 'I like your lingo, Toon. You know how to schmooze.', CFSpeech|CFTimeout, dialogue = self.speechMurmurSfx),
Wait(6),
Func(self.suit.setChatAbsolute, 'However, you seem to need a smear of Positive Reinforcement.', CFSpeech|CFTimeout, dialogue = self.speechStatementSfx),
#Func(self.suit.play, 'speak'),
Wait(3),
self.slappy.head.hprInterval(1, (0, 0, 0)),
Func(self.slappy.sadEyes),
Wait(1),
# Mother of Walt, he's dead
Func(self.slappy.play, 'lose'),
Wait(2),
#Func(self.suit.loop, 'neutral'),
Func(base.playSfx, sfxSad, volume=0.6),
Wait(1.8),
Func(base.playMusic, musicSad, looping=0),
Wait(0.5),
Parallel(Func(self.slappyStandDie.start), Func(self.slappyStandDie.setT, offset)),
Func(self.flippy.setChatAbsolute, "Slappy, NO!", CFSpeech|CFTimeout),
Wait(0.5),
Func(self.alec.setChatAbsolute, "Oh my goodness- he...", CFSpeech|CFTimeout),
self.slappy.scaleInterval(1.5, VBase3(0.01, 0.01, 0.01), blendType='easeInOut'),
Wait(2),
Parallel(Func(self.alec.setChatAbsolute, "No. Nonono, no. This isn't happening.", CFSpeech|CFTimeout), Func(self.alec.loop, 'walk')),
Parallel(self.alec.posInterval(2, (-1.5, -0.14, 3.13))),
Func(self.alec.loop, 'neutral'),
# Flippy isn't happy at all, he's going histerical
Parallel(Func(self.moveCamera, 2, 77, -23, 9, 398, 0), Func(base.cr.cameraManager.setMainCamera, self.cameras[2].getDoId())),
Parallel(Func(self.flippy.setChatAbsolute, "What have you done?!", CFSpeech|CFTimeout), Func(self.flippy.loop, 'run')),
Wait(0.5),
Parallel(self.flippy.posHprInterval(0.5, (-4.2, -9.5, 3.23), (70, 0, 0)), self.flippy.head.hprInterval(0.5, (0, 0, 0), blendType='easeInOut')),
Wait(0.45),
Func(self.flippy.play, 'jump'),
Wait(0.45),
self.flippy.posInterval(0.2, (-7.5, -9.2, 3.5)),
self.flippy.posHprInterval(0.4, (-14, -9, 0), (50, 0, 0)),
Wait(0.2),
Func(self.flippy.loop, 'run'),
Func(self.suit.loop, 'walk'),
Parallel(self.suit.hprInterval(1, (180, 0, 0)), self.flippy.posHprInterval(1, (-15, -1, 0), (0, 0, 0))),
Func(self.suit.loop, 'neutral'),
Parallel(Func(self.flippy.setChatAbsolute, "Where did you send him?! Where is he?!", CFSpeech|CFTimeout), Func(self.flippy.loop, 'neutral')),
Wait(2.5),
Func(self.alec.setChatAbsolute, "Flippy, NO! Get away from it!", CFSpeech|CFTimeout),
self.alec.head.hprInterval(1, (-5, -5, 0), blendType='easeInOut'),
Wait(5),
Func(self.flippy.setChatAbsolute, "What... What are you?", CFSpeech|CFTimeout),
Wait(4),
# The Yesman has found a new business partner
Func(self.suit.setChatAbsolute, 'I don\'t like your tone. Perhaps you need a drop of Positive Reinforcement as well.', CFSpeech|CFTimeout, dialogue = self.speechStatementSfx),
Wait(3),
Parallel(Func(self.flippy.setChatAbsolute, "No.. No, get away. I don't need your help.", CFSpeech|CFTimeout), ActorInterval(self.flippy, 'walk', loop=1, playRate=-1, duration=3), self.flippy.posInterval(3, (-15, -7, 0)), self.alec.head.hprInterval(1, (0, -5, 0), blendType='easeInOut')),
Func(self.flippy.loop, 'neutral'),
Wait(1.5),
Func(self.suit.loop, 'walk'),
Parallel(Func(self.suit.setChatAbsolute, 'Let me confirm our meeting to discuss this. I won\'t take no for an answer.', CFSpeech|CFTimeout, dialogue = self.speechMurmurSfx), self.suit.posInterval(2, (65, -1, 4.0))),
Func(self.suit.loop, 'neutral'),
Parallel(Func(self.flippy.setChatAbsolute, "Stop it, this isn't fun!", CFSpeech|CFTimeout), self.alec.head.hprInterval(1, (10, -5, 0), blendType='easeInOut'), ActorInterval(self.flippy, 'walk', loop=1, playRate=-1, duration=2), self.flippy.posInterval(2, (-15, -12, 0))),
Func(self.flippy.loop, 'neutral'),
Func(self.suit.loop, 'walk'),
Parallel(Func(self.suit.setChatAbsolute, 'Fun cannot exist without order.', CFSpeech|CFTimeout, dialogue = self.speechStatementSfx), self.suit.posInterval(2, (65, -5, 4.0))),
Func(self.suit.loop, 'neutral'),
# Flippy makes a last minute attempt to try and slow him down. It... kills him?
Parallel(ActorInterval(self.flippy, 'throw', startFrame=0, endFrame=46), Func(self.flippy.setChatAbsolute, "I'm warning you, stay back. Please.", CFSpeech|CFTimeout), Func(self.pie.reparentTo, self.flippy.rightHand)),
Wait(1),
Func(self.suit.setChatAbsolute, 'Don\'t worry, I haven\'t been wrong yet.', CFSpeech|CFTimeout, dialogue = self.speechStatementSfx),
#Func(self.suit.play, 'speak'),
Wait(1.5),
Parallel(
Sequence(
ActorInterval(self.flippy, 'throw', startFrame=47, endFrame=91),
Func(self.flippy.loop, 'neutral')
),
Func(self.flippy.setChatAbsolute, "Stay AWAY from me!", CFSpeech|CFTimeout),
Func(self.surleeR.normalEyes),
Sequence(
Wait(0.6),
Func(self.pie.wrtReparentTo, render),
ProjectileInterval(self.pie, endPos=Point3(65, -5, 9.0), duration=0.1),
Func(self.pie.removeNode),
Parallel(
Func(self.sendUpdate, 'setSuitDamage', [36, False]),
Func(self.suit.hide),
Func(self.suit.removeActive)
)
)
)
)
self.cogSequence.start()
self.cogSequence.setT(offset)
def exitCogLanding(self):
self.cogSequence.finish()
def enterInvasion(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.finishedCogLanding = True
self.catchUp()
# Everyone is stunned by the explosion, but Surlee knows what is to come.
# He grabs their attention as the cogs begin landing.
self.accept('enter' + self.pieCollision.node().getName(), self.handleWheelbarrowCollisionSphereEnter)
self.surleeAnimation = Sequence(
ActorInterval(self.surlee, 'scientistEmcee', startFrame=251, endFrame=314),
ActorInterval(self.surlee, 'scientistEmcee', startFrame=314, endFrame=251)
)
# TODO: Make Alec say things when you get near him.
# He is hiding, and scared of anyone who gets near.
self.alecRunAway = Sequence(
Func(self.alec.loop, 'walk'),
self.alec.posInterval(1, (4.2, -0.25, 3.13)),
self.alec.posHprInterval(3, (12.9, -3.3, 0), (0, 0, 0)),
Func(self.alec.loop, 'neutral'),
Wait(0.5),
Func(self.alec.loop, 'run'),
self.alec.posInterval(3, (18.0, 41.2, 0)),
Func(self.alec.loop, 'walk'),
self.alec.hprInterval(1.3, (-130, 0, 0)),
Func(self.alec.loop, 'neutral'),
Func(self.startInteractiveAlec)
)
self.surleeIntroInterval = Sequence(
Func(base.cr.cameraManager.setMainCamera, self.cameras[3].getDoId()),
Func(self.moveCamera, 4, 10, -31, 7, 651, 0),
Func(self.surleeR.loop, 'walk'),
Func(self.surleeR.setChatAbsolute, 'Everyone, listen. There\'s no time to explain!', CFSpeech|CFTimeout),
self.surleeR.posHprInterval(1, (-32, -15, 0), (50, 0, 0)),
Func(self.surleeR.loop, 'neutral'),
Func(self.cameras[4].setState, 'Move', globalClockDelta.getRealNetworkTime(), 10, -24, 7, -263, 0, 0),
Parallel(self.alec.head.hprInterval(1, (15, 0, 0), blendType='easeInOut')), self.flippy.head.hprInterval(1, (80, 0 , 0), blendType='easeInOut'),
Parallel(Func(self.flippy.loop, 'walk'), self.flippy.hprInterval(2, (95, 0, 0)), self.flippy.head.hprInterval(2, (0, 0, 0))),
Func(self.flippy.loop, 'neutral'),
Wait(2),
Func(self.surleeR.setChatAbsolute, 'Grab the pies, they seem to be the weakness of these...', CFSpeech|CFTimeout),
Wait(5),
Func(self.surleeR.setChatAbsolute, '..."Cogs."', CFSpeech|CFTimeout),
Wait(3),
Func(self.surleeR.setChatAbsolute, 'Now take up arms, there\'s more on the way!', CFSpeech|CFTimeout),
Wait(3),
Func(self.alecRunAway.start, offset),
Wait(2),
Func(self.surleeR.setChatAbsolute, 'Fight for our town. Fight for Slappy!', CFSpeech|CFTimeout),
Wait(7),
Func(base.cr.cameraManager.disableScreen),
Wait(3),
Parallel(
Func(self.surlee.show),
Func(self.surlee.addActive),
Func(self.surleeR.hide),
Func(self.surleeR.removeActive),
Func(self.surleeAnimation.loop, offset)
),
Func(self.surlee.setChatAbsolute, 'Flippy, I\'m going to need you over here to help with the pies. Can you get cooking?', CFSpeech|CFTimeout),
Wait(7),
Func(base.cr.cameraManager.setMainCamera, self.cameras[4].getDoId()),
Func(self.flippy.setChatAbsolute, 'I can certainly try.', CFSpeech|CFTimeout),
Wait(1),
Func(self.flippy.loop, 'run'),
self.flippy.posHprInterval(3.5, (-38, -18.5, 0), (100, 0, 0)),
Func(self.flippy.loop, 'walk'),
self.flippy.posHprInterval(1.5, (-38, -18.5, 0), (75, 0, 0)),
Func(self.flippy.loop, 'neutral')
)
self.surleeIntroInterval.start()
self.surleeIntroInterval.setT(offset)
def exitInvasion(self):
self.surleeIntroInterval.finish()
self.surleeAnimation.finish()
def enterInvasionEnd(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.finishedCogLanding = True
self.finishedInvasion = True
self.catchUp()
#Flippy now runs onto the stage and throws a cake at the boss, killing him
pie = BattleProps.globalPropPool.getProp('creampie')
pie.setScale(0)
cake = BattleProps.globalPropPool.getProp('birthday-cake')
cake.setScale(0)
weddingcake = BattleProps.globalPropPool.getProp('wedding-cake')
weddingcake.setScale(0)
sfxCake = loader.loadSfx('phase_5/audio/sfx/AA_throw_wedding_cake.ogg')
sfxCakeSplat = loader.loadSfx('phase_5/audio/sfx/AA_throw_wedding_cake_cog.ogg')
sfxPieSplat = loader.loadSfx('phase_3.5/audio/sfx/AA_tart_only.ogg')
messenger.send('invasionEndSequence', [offset])
cakeSeq = Sequence(
Func(self.flippy.loop, 'walk'),
self.flippy.hprInterval(2, (0, 0, 0)),
Func(self.flippy.loop, 'neutral'),
Func(self.flippy.setChatAbsolute, 'Here we go...', CFSpeech|CFTimeout),
Wait(3),
Func(self.flippy.loop, 'run'),
Parallel(self.flippy.posHprInterval(2.5, (-14, -9, 0), (-90, 0, 0)), self.flippy.head.hprInterval(0.5, (-65, 0, 0), blendType='easeInOut')),
Func(self.flippy.play, 'jump'),
Wait(0.45),
self.flippy.posInterval(0.2, (-7.5, -9.2, 3.5)),
self.flippy.posInterval(0.4, (-4.2, -9.5, 3.23)),
Func(self.flippy.loop, 'run'),
Parallel(self.flippy.posHprInterval(1, (2, -10, 3.23), (75, 0, 0)), self.flippy.head.hprInterval(0.5, (-5, 0, 0), blendType='easeInOut')),
Func(self.flippy.loop, 'neutral'),
Wait(5.5),
Parallel(ActorInterval(self.flippy, 'throw', startFrame=0, endFrame=46), Func(pie.reparentTo, self.flippy.rightHand), pie.scaleInterval(0.5, (1))),
Parallel(
Sequence(
ActorInterval(self.flippy, 'throw', startFrame=47, endFrame=91),
Func(self.flippy.loop, 'neutral')
),
Sequence(
Wait(0.6),
Func(self.flippy.setChatAbsolute, 'That\'s for the election!', CFSpeech|CFTimeout),
Func(pie.wrtReparentTo, render),
ProjectileInterval(pie, endPos=Point3(36.5, -1.9, 11.0), duration=0.3),
Func(base.playSfx, sfxPieSplat, volume=0.8),
Func(self.sendUpdate, 'setSuitDamage', [36, False]),
Func(pie.removeNode)
)
),
Wait(1),
Parallel(ActorInterval(self.flippy, 'throw', startFrame=0, endFrame=46), Func(cake.reparentTo, self.flippy.rightHand), cake.scaleInterval(0.5, (1))),
Parallel(
Sequence(
ActorInterval(self.flippy, 'throw', startFrame=47, endFrame=91),
Func(self.flippy.loop, 'neutral')
),
Sequence(
Wait(0.6),
Func(self.flippy.setChatAbsolute, 'THAT\'S for Slappy!', CFSpeech|CFTimeout),
Func(cake.wrtReparentTo, render),
ProjectileInterval(cake, endPos=Point3(36.5, -1.9, 11.0), duration=0.3),
Func(base.playSfx, sfxPieSplat, volume=1.0),
Func(self.sendUpdate, 'setSuitDamage', [100, False]),
Func(cake.removeNode)
)
),
Wait(1),
Parallel(Func(base.playSfx, sfxCake, volume=0.9), ActorInterval(self.flippy, 'throw', startFrame=0, endFrame=46), Func(weddingcake.reparentTo, self.flippy.rightHand), weddingcake.scaleInterval(0.5, (1.4))),
Parallel(
Sequence(
ActorInterval(self.flippy, 'throw', startFrame=47, endFrame=91),
Func(self.flippy.loop, 'neutral')
),
Sequence(
Wait(0.6),
Func(self.flippy.setChatAbsolute, 'AND THIS IS FOR TOONTOWN!', CFSpeech|CFTimeout),
Func(weddingcake.wrtReparentTo, render),
ProjectileInterval(weddingcake, endPos=Point3(36.5, -1.9, 11.0), duration=0.3),
Func(base.playSfx, sfxCakeSplat, volume=0.8),
Func(self.sendUpdate, 'setSuitDamage', [200, True]),
Func(weddingcake.removeNode)
)
),
Wait(10),
Func(self.alec.loop, 'run'),
Func(self.alec.setChatAbsolute, 'Flippy, you did it!', CFSpeech|CFTimeout),
self.alec.posHprInterval(5, (12.9, -0.3, 0), (180, 0, 0)),
Parallel(self.alec.posHprInterval(1, (4.2, -3.25, 3.13), (90, 0, 0)), Func(self.flippy.loop, 'walk'), self.flippy.hprInterval(1, (0, 0, 0)), self.flippy.head.hprInterval(1, (15, 0, 0))),
Func(self.flippy.loop, 'neutral'),
self.alec.posHprInterval(1, (3, -7, 3.23), (165, 0, 0)),
Func(self.alec.loop, 'neutral'),
Wait(4),
Func(self.surleeR.setChatAbsolute, 'Don\'t get too excited... We\'ve only driven them back to the streets.', CFSpeech|CFTimeout),
Wait(3),
Func(self.flippy.loop, 'walk'),
Parallel(self.flippy.hprInterval(1, (90, 0, 0)), self.flippy.head.hprInterval(1, (0, 0, 0))),
Func(self.flippy.loop, 'neutral'),
Wait(4),
Func(self.surleeR.setChatAbsolute, 'The Cogs will be back, but I doubt we\'ll be seeing them in the playgrounds again after this battle.', CFSpeech|CFTimeout),
Wait(7),
Func(self.surleeR.setChatAbsolute, 'All of you here today are heros, you\'re survivors!', CFSpeech|CFTimeout),
Wait(7),
Func(self.surleeR.setChatAbsolute, 'And I\'m sure our new President is very grateful.', CFSpeech|CFTimeout),
Wait(6),
Func(self.flippy.setChatAbsolute, 'Surlee, I...', CFSpeech|CFTimeout),
Wait(5),
Func(self.alec.setChatAbsolute, 'He\'s right, Flippy. You\'re a hero, and you\'re the only leader we have left.', CFSpeech|CFTimeout),
Wait(7),
Func(self.flippy.setChatAbsolute, 'With a heavy heart, I hereby accept the Toon Council Presidency.', CFSpeech|CFTimeout),
Wait(7),
Func(self.flippy.setChatAbsolute, 'Only until these Cogs are gone, though.', CFSpeech|CFTimeout),
Wait(7),
Func(self.flippy.setChatAbsolute, 'If we\'re going to get rid of them, we have to stand together.', CFSpeech|CFTimeout),
Wait(7),
)
cakeSeq.start()
cakeSeq.setT(offset)
def enterWrapUp(self, offset):
# Get ourselves caught up with what just happened
self.finishedPreShow = True
self.finishedBegin = True
self.finishedCogLanding = True
self.finishedInvasion = True
self.finishedInvasionEnding = True
self.catchUp()
self.stopInteractiveAlec() # Gotta clean up
# Tell the credits our toon name and dna.
NodePath(base.marginManager).hide()
base.cr.credits.setLocalToonDetails(base.localAvatar.getName(), base.localAvatar.style)
# This starts here so that we can drift towards Flippy for his speech,
# but some of it should be moved over to the real credits sequence which is called after this.
# A safe time to cut to the real sequence would be after the portable hole nosedive, or right when the camera arrives at Flippy before "Toons of the world... UNITE!"
musicCredits = base.loadMusic(ElectionGlobals.CreditsMusic)
base.localAvatar.stopUpdateSmartCamera()
base.camera.wrtReparentTo(render)
self.logo = loader.loadModel('phase_3/models/gui/toontown-logo')
self.logo.reparentTo(aspect2d)
self.logo.setTransparency(1)
self.logo.setScale(0.6)
self.logo.setPos(0, 1, 0.3)
self.logo.setColorScale(1, 1, 1, 0)
self.portal = loader.loadModel('phase_3.5/models/props/portal-mod')
self.portal.reparentTo(render)
self.portal.setPosHprScale(93.1, 0.4, 4, 4, 355, 45, 0, 0, 0)
# To prevent some jittering when loading the credits, we'll load the first scene here.
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from toontown.credits import AlphaCredits
self.shockley = AlphaCredits.Shockley(True)
self.shockley.load()
self.wrapUpSequence = Sequence(
Func(base.cr.cameraManager.tv.hide),
Func(self.flippy.setChatAbsolute, 'Toons of the world...', CFSpeech|CFTimeout),
Func(base.playMusic, musicCredits, looping=0, volume=0.8),
Wait(4.5),
Func(self.flippy.setChatAbsolute, 'UNITE!', CFSpeech|CFTimeout),
Func(self.flippy.stopBlink),
ActorInterval(self.flippy, 'victory', playRate=0.75, startFrame=0, endFrame=9),
Func(base.camera.setPosHpr, 73, -9.5, 16, -90, -35, 0),
Func(base.takeScreenShot),
Wait(7.5),
ActorInterval(self.flippy, 'victory', playRate=0.75, startFrame=9, endFrame=0),
Wait(7.5),
Parallel(self.shockley.title.colorScaleInterval(0.5, (1, 1, 1, 1)), self.shockley.description.colorScaleInterval(0.5, (1, 1, 1, 1)), self.shockley.image.colorScaleInterval(0.5, (1, 1, 1, 1))),
Func(base.cr.loginFSM.request, 'credits')
)
self.cameraSequence = Sequence(
# Begin to slowly drift towards Flippy as he delivers his speech (He currently doesn't have a speech)
base.camera.posHprInterval(10, (75, -9.5, 12), (-90, -10, 0), blendType='easeInOut'),
Func(self.wrapUpSequence.start),
Wait(12),
# Dramatically fade in the logo as the camera rises
Parallel(self.logo.posHprScaleInterval(6.5, (0, 0, 0.5), (0), (1), blendType='easeOut'), self.logo.colorScaleInterval(6.5, Vec4(1, 1, 1, 1), blendType='easeOut'), base.camera.posHprInterval(7.5, (70, 0.6, 42.2), (-90, 0, 0), blendType='easeInOut')),
# Take a nosedive into a portable hole
Parallel(self.logo.colorScaleInterval(0.3, Vec4(1, 1, 1, 0)), base.camera.posHprInterval(0.3, (85, 0, 42), (-90, -30, 0), blendType='easeIn')),
Parallel(base.camera.posHprInterval(0.9, (95, 0.6, 6), (-90, -90, 0), blendType='easeOut'), self.portal.scaleInterval(0.5, (2)))
)
self.cameraSequence.start()
self.cameraSequence.setT(offset)
def exitWrapUp(self):
self.logo.removeNode()
self.portal.removeNode()
self.shockley.title.removeNode()
self.shockley.description.removeNode()
self.shockley.image.removeNode()
self.wrapUpSequence.finish()
self.cameraSequence.finish()
def startInteractiveAlec(self):
cs = CollisionSphere(0, 0, 0, 3)
self.alecNode = self.alec.attachNewNode(CollisionNode('cnode'))
self.alecNode.node().addSolid(cs)
self.accept('enter' + self.alecNode.node().getName(), self.handleAlecCollision)
def handleAlecCollision(self, collEntry):
self.cowardSequence = Sequence(
Parallel(
ActorInterval(self.alec, 'cringe'),
Func(self.alec.setChatAbsolute, 'Don\'t hurt me!! Oh, phew. It\'s only you.', CFSpeech|CFTimeout)
)
)
self.cowardSequence.start()
def stopInteractiveAlec(self):
if self.alecNode:
self.ignore('enter' + self.alecNode.node().getName())
'''
ELECTION DAY MISC.
Just a few other bits and pieces we need for Election Day, unrelated to the main sequence.
'''
def moveCamera(self, id, x, y, z, h, p):
self.cameras[id].setState('Move', globalClockDelta.getRealNetworkTime(), x, y, z, h, p, 0)
def saySurleePhrase(self, phrase, interrupt, broadcast):
self.surlee.setChatAbsolute(phrase, CFSpeech|CFTimeout, interrupt = interrupt)
# If we want everyone to see this message, even if not near Surlee, we'll send it as a whisper.
if broadcast and Vec3(base.localAvatar.getPos(self.surleeR)).length() >= 15:
base.localAvatar.setSystemMessage(0, self.surleeR.getName()+ ': ' + phrase, WTEmote)
def setState(self, state, timestamp):
self.request(state, globalClockDelta.localElapsedTime(timestamp))