Poodletooth-iLand/toontown/suit/DistributedSellbotBoss.py

1285 lines
54 KiB
Python
Raw Normal View History

2015-03-03 16:10:12 -06:00
from direct.directnotify import DirectNotifyGlobal
from direct.directutil import Mopath
from direct.distributed.ClockDelta import *
from direct.fsm import ClassicFSM, State
from direct.fsm import FSM
from direct.gui.DirectGui import *
from direct.interval.IntervalGlobal import *
from direct.showbase.PythonUtil import Functor
from direct.showutil import Rope
from direct.task import Task
import math
from pandac.PandaModules import *
import random
import DistributedBossCog
import SuitDNA
from toontown.battle import BattleBase
from toontown.battle import MovieToonVictory
from toontown.battle import RewardPanel
from toontown.battle import SuitBattleGlobals
from toontown.battle.BattleProps import *
from toontown.chat.ChatGlobals import *
from toontown.coghq import CogDisguiseGlobals
from toontown.distributed import DelayDelete
from toontown.nametag.NametagGlobals import *
from toontown.suit import SellbotBossGlobals
from toontown.toon import NPCToons
from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownBattleGlobals
from toontown.toonbase import ToontownGlobals
OneBossCog = None
class DistributedSellbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedSellbotBoss')
cageHeights = [100,
81,
63,
44,
25,
18]
def __init__(self, cr):
DistributedBossCog.DistributedBossCog.__init__(self, cr)
FSM.FSM.__init__(self, 'DistributedSellbotBoss')
self.cagedToonNpcId = None
self.doobers = []
self.dooberRequest = None
self.bossDamage = 0
self.attackCode = None
self.attackAvId = 0
self.recoverRate = 0
self.recoverStartTime = 0
self.bossDamageMovie = None
self.cagedToon = None
self.cageShadow = None
self.cageIndex = 0
self.everThrownPie = 0
self.battleThreeMusicTime = 0
self.insidesANodePath = None
self.insidesBNodePath = None
self.rampA = None
self.rampB = None
self.rampC = None
self.strafeInterval = None
self.onscreenMessage = None
self.toonMopathInterval = []
self.nerfed = ToontownGlobals.SELLBOT_NERF_HOLIDAY in base.cr.newsManager.getHolidayIdList()
self.localToonPromoted = True
self.resetMaxDamage()
def announceGenerate(self):
global OneBossCog
DistributedBossCog.DistributedBossCog.announceGenerate(self)
self.setName(TTLocalizer.SellbotBossName)
nameInfo = TTLocalizer.BossCogNameWithDept % {'name': self.name,
'dept': SuitDNA.getDeptFullname(self.style.dept)}
self.setDisplayName(nameInfo)
self.cageDoorSfx = loader.loadSfx('phase_5/audio/sfx/CHQ_SOS_cage_door.ogg')
self.cageLandSfx = loader.loadSfx('phase_9/audio/sfx/CHQ_SOS_cage_land.ogg')
self.cageLowerSfx = loader.loadSfx('phase_5/audio/sfx/CHQ_SOS_cage_lower.ogg')
self.piesRestockSfx = loader.loadSfx('phase_9/audio/sfx/CHQ_SOS_pies_restock.ogg')
self.rampSlideSfx = loader.loadSfx('phase_9/audio/sfx/CHQ_VP_ramp_slide.ogg')
self.strafeSfx = []
for i in xrange(10):
self.strafeSfx.append(loader.loadSfx('phase_3.5/audio/sfx/SA_shred.ogg'))
render.setTag('pieCode', str(ToontownGlobals.PieCodeNotBossCog))
insidesA = CollisionPolygon(Point3(4.0, -2.0, 5.0), Point3(-4.0, -2.0, 5.0), Point3(-4.0, -2.0, 0.5), Point3(4.0, -2.0, 0.5))
insidesANode = CollisionNode('BossZap')
insidesANode.addSolid(insidesA)
insidesANode.setCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.WallBitmask)
self.insidesANodePath = self.axle.attachNewNode(insidesANode)
self.insidesANodePath.setTag('pieCode', str(ToontownGlobals.PieCodeBossInsides))
self.insidesANodePath.stash()
insidesB = CollisionPolygon(Point3(-4.0, 2.0, 5.0), Point3(4.0, 2.0, 5.0), Point3(4.0, 2.0, 0.5), Point3(-4.0, 2.0, 0.5))
insidesBNode = CollisionNode('BossZap')
insidesBNode.addSolid(insidesB)
insidesBNode.setCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.WallBitmask)
self.insidesBNodePath = self.axle.attachNewNode(insidesBNode)
self.insidesBNodePath.setTag('pieCode', str(ToontownGlobals.PieCodeBossInsides))
self.insidesBNodePath.stash()
target = CollisionTube(0, -1, 4, 0, -1, 9, 3.5)
targetNode = CollisionNode('BossZap')
targetNode.addSolid(target)
targetNode.setCollideMask(ToontownGlobals.PieBitmask)
self.targetNodePath = self.pelvis.attachNewNode(targetNode)
self.targetNodePath.setTag('pieCode', str(ToontownGlobals.PieCodeBossCog))
shield = CollisionTube(0, 1, 4, 0, 1, 7, 3.5)
shieldNode = CollisionNode('BossZap')
shieldNode.addSolid(shield)
shieldNode.setCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask)
shieldNodePath = self.pelvis.attachNewNode(shieldNode)
disk = loader.loadModel('phase_9/models/char/bossCog-gearCollide')
disk.find('**/+CollisionNode').setName('BossZap')
disk.reparentTo(self.pelvis)
disk.setZ(0.8)
self.loadEnvironment()
self.__makeCagedToon()
self.__loadMopaths()
if OneBossCog is not None:
self.notify.warning('Multiple BossCogs visible.')
OneBossCog = self
def disable(self):
global OneBossCog
DistributedBossCog.DistributedBossCog.disable(self)
self.request('Off')
self.unloadEnvironment()
self.__unloadMopaths()
self.__cleanupCagedToon()
self.__clearOnscreenMessage()
taskMgr.remove(self.uniqueName('PieAdvice'))
self.__cleanupStrafe()
render.clearTag('pieCode')
self.targetNodePath.detachNode()
self.cr.relatedObjectMgr.abortRequest(self.dooberRequest)
self.dooberRequest = None
self.betweenBattleMusic.stop()
self.promotionMusic.stop()
self.stingMusic.stop()
self.battleTwoMusic.stop()
self.battleThreeMusic.stop()
self.epilogueMusic.stop()
while len(self.toonMopathInterval):
toonMopath = self.toonMopathInterval[0]
toonMopath.finish()
toonMopath.destroy()
self.toonMopathInterval.remove(toonMopath)
if OneBossCog == self:
OneBossCog = None
def resetMaxDamage(self):
if self.nerfed:
self.bossMaxDamage = ToontownGlobals.SellbotBossMaxDamageNerfed
else:
self.bossMaxDamage = ToontownGlobals.SellbotBossMaxDamage
def d_hitBoss(self, bossDamage):
self.sendUpdate('hitBoss', [bossDamage])
def d_hitBossInsides(self):
self.sendUpdate('hitBossInsides', [])
def d_hitToon(self, toonId):
self.sendUpdate('hitToon', [toonId])
def setCagedToonNpcId(self, npcId):
self.cagedToonNpcId = npcId
def gotToon(self, toon):
stateName = self.state
if stateName == 'Elevator':
self.placeToonInElevator(toon)
def setDooberIds(self, dooberIds):
self.doobers = []
self.cr.relatedObjectMgr.abortRequest(self.dooberRequest)
self.dooberRequest = self.cr.relatedObjectMgr.requestObjects(dooberIds, allCallback=self.__gotDoobers)
def __gotDoobers(self, doobers):
self.dooberRequest = None
self.doobers = doobers
def setBossDamage(self, bossDamage, recoverRate, timestamp):
recoverStartTime = globalClockDelta.networkToLocalTime(timestamp)
self.bossDamage = bossDamage
self.recoverRate = recoverRate
self.recoverStartTime = recoverStartTime
taskName = 'RecoverBossDamage'
taskMgr.remove(taskName)
if self.bossDamageMovie:
if self.bossDamage >= self.bossMaxDamage:
self.bossDamageMovie.resumeUntil(self.bossDamageMovie.getDuration())
else:
self.bossDamageMovie.resumeUntil(self.bossDamage * self.bossDamageToMovie)
if self.recoverRate:
taskMgr.add(self.__recoverBossDamage, taskName)
def getBossDamage(self):
now = globalClock.getFrameTime()
elapsed = now - self.recoverStartTime
return max(self.bossDamage - self.recoverRate * elapsed / 60.0, 0)
def __recoverBossDamage(self, task):
self.bossDamageMovie.setT(self.getBossDamage() * self.bossDamageToMovie)
return Task.cont
def __makeCagedToon(self):
if self.cagedToon:
return
self.cagedToon = NPCToons.createLocalNPC(self.cagedToonNpcId)
self.cagedToon.addActive()
self.cagedToon.reparentTo(self.cage)
self.cagedToon.setPosHpr(0, -2, 0, 180, 0, 0)
self.cagedToon.loop('neutral')
self.cagedToon.setActiveShadow(0)
touch = CollisionPolygon(
Point3(-3.0382, 3.0382, -1), Point3(3.0382, 3.0382, -1),
Point3(3.0382, -3.0382, -1), Point3(-3.0382, -3.0382, -1))
touch.setTangible(0)
touchNode = CollisionNode('Cage')
touchNode.setCollideMask(ToontownGlobals.WallBitmask)
touchNode.addSolid(touch)
self.cage.attachNewNode(touchNode)
def __cleanupCagedToon(self):
if self.cagedToon:
self.cagedToon.removeActive()
self.cagedToon.delete()
self.cagedToon = None
def __walkToonToPromotion(self, toonId, delay, mopath, track, delayDeletes):
toon = base.cr.doId2do.get(toonId)
if toon:
destPos = toon.getPos()
self.placeToonInElevator(toon)
toon.wrtReparentTo(render)
walkMopath = MopathInterval(mopath, toon)
ival = Sequence(Wait(delay), Func(toon.suit.setPlayRate, 1, 'walk'), Func(toon.suit.loop, 'walk'), toon.posInterval(1, Point3(0, 90, 20)), ParallelEndTogether(walkMopath, toon.posInterval(2, destPos, blendType='noBlend')), Func(toon.suit.loop, 'neutral'))
self.toonMopathInterval.append(walkMopath)
track.append(ival)
delayDeletes.append(DelayDelete.DelayDelete(toon, 'SellbotBoss.__walkToonToPromotion'))
def __walkDoober(self, suit, delay, turnPos, track, delayDeletes):
turnPos = Point3(*turnPos)
turnPosDown = Point3(*ToontownGlobals.SellbotBossDooberTurnPosDown)
flyPos = Point3(*ToontownGlobals.SellbotBossDooberFlyPos)
seq = Sequence(Func(suit.headsUp, turnPos), Wait(delay), Func(suit.loop, 'walk', 0), self.__walkSuitToPoint(suit, suit.getPos(), turnPos), self.__walkSuitToPoint(suit, turnPos, turnPosDown), self.__walkSuitToPoint(suit, turnPosDown, flyPos), suit.beginSupaFlyMove(flyPos, 0, 'flyAway'), Func(suit.fsm.request, 'Off'))
track.append(seq)
delayDeletes.append(DelayDelete.DelayDelete(suit, 'SellbotBoss.__walkDoober'))
def __walkSuitToPoint(self, node, fromPos, toPos):
vector = Vec3(toPos - fromPos)
distance = vector.length()
time = distance / (ToontownGlobals.SuitWalkSpeed * 1.8)
return Sequence(Func(node.setPos, fromPos), Func(node.headsUp, toPos), node.posInterval(time, toPos))
def makeIntroductionMovie(self, delayDeletes):
track = Parallel()
camera.reparentTo(render)
camera.setPosHpr(0, 25, 30, 0, 0, 0)
localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov)
dooberTrack = Parallel()
if self.doobers:
self.__doobersToPromotionPosition(self.doobers[:4], self.battleANode)
self.__doobersToPromotionPosition(self.doobers[4:], self.battleBNode)
turnPosA = ToontownGlobals.SellbotBossDooberTurnPosA
turnPosB = ToontownGlobals.SellbotBossDooberTurnPosB
self.__walkDoober(self.doobers[0], 0, turnPosA, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[1], 4, turnPosA, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[2], 8, turnPosA, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[3], 12, turnPosA, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[7], 2, turnPosB, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[6], 6, turnPosB, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[5], 10, turnPosB, dooberTrack, delayDeletes)
self.__walkDoober(self.doobers[4], 14, turnPosB, dooberTrack, delayDeletes)
toonTrack = Parallel()
self.__toonsToPromotionPosition(self.toonsA, self.battleANode)
self.__toonsToPromotionPosition(self.toonsB, self.battleBNode)
delay = 0
for toonId in self.toonsA:
self.__walkToonToPromotion(toonId, delay, self.toonsEnterA, toonTrack, delayDeletes)
delay += 1
for toonId in self.toonsB:
self.__walkToonToPromotion(toonId, delay, self.toonsEnterB, toonTrack, delayDeletes)
delay += 1
toonTrack.append(Sequence(Wait(delay), self.closeDoors))
self.rampA.request('extended')
self.rampB.request('extended')
self.rampC.request('retracted')
self.clearChat()
self.cagedToon.clearChat()
promoteDoobers = TTLocalizer.BossCogPromoteDoobers % SuitDNA.getDeptFullnameP(self.style.dept)
doobersAway = TTLocalizer.BossCogDoobersAway[self.style.dept]
welcomeToons = TTLocalizer.BossCogWelcomeToons
promoteToons = TTLocalizer.BossCogPromoteToons % SuitDNA.getDeptFullnameP(self.style.dept)
discoverToons = TTLocalizer.BossCogDiscoverToons
attackToons = TTLocalizer.BossCogAttackToons
interruptBoss = TTLocalizer.CagedToonInterruptBoss
rescueQuery = TTLocalizer.CagedToonRescueQuery
bossAnimTrack = Sequence(
ActorInterval(self, 'Ff_speech', startTime=2, duration=10, loop=1),
ActorInterval(self, 'ltTurn2Wave', duration=2),
ActorInterval(self, 'wave', duration=4, loop=1),
ActorInterval(self, 'ltTurn2Wave', startTime=2, endTime=0),
ActorInterval(self, 'Ff_speech', duration=7, loop=1))
track.append(bossAnimTrack)
dialogTrack = Track(
(0, Parallel(
camera.posHprInterval(8, Point3(-22, -100, 35), Point3(-10, -13, 0), blendType='easeInOut'),
IndirectInterval(toonTrack, 0, 18))),
(5.6, Func(self.setChatAbsolute, promoteDoobers, CFSpeech)),
(9, IndirectInterval(dooberTrack, 0, 9)),
(10, Sequence(
Func(self.clearChat),
Func(camera.setPosHpr, -23.1, 15.7, 17.2, -160, -2.4, 0))),
(12, Func(self.setChatAbsolute, doobersAway, CFSpeech)),
(16, Parallel(
Func(self.clearChat),
Func(camera.setPosHpr, -25, -99, 10, -14, 10, 0),
IndirectInterval(dooberTrack, 14),
IndirectInterval(toonTrack, 30))),
(18, Func(self.setChatAbsolute, welcomeToons, CFSpeech)),
(22, Func(self.setChatAbsolute, promoteToons, CFSpeech)),
(22.2, Sequence(
Func(self.cagedToon.nametag3d.setScale, 2),
Func(self.cagedToon.setChatAbsolute, interruptBoss, CFSpeech),
ActorInterval(self.cagedToon, 'wave'),
Func(self.cagedToon.loop, 'neutral'))),
(25, Sequence(
Func(self.clearChat),
Func(self.cagedToon.clearChat),
Func(camera.setPosHpr, -12, -15, 27, -151, -15, 0),
ActorInterval(self, 'Ff_lookRt'))),
(27, Sequence(
Func(self.cagedToon.setChatAbsolute, rescueQuery, CFSpeech),
Func(camera.setPosHpr, -12, 48, 94, -26, 20, 0),
ActorInterval(self.cagedToon, 'wave'),
Func(self.cagedToon.loop, 'neutral'))),
(31, Sequence(
Func(camera.setPosHpr, -20, -35, 10, -88, 25, 0),
Func(self.setChatAbsolute, discoverToons, CFSpeech),
Func(self.cagedToon.nametag3d.setScale, 1),
Func(self.cagedToon.clearChat),
ActorInterval(self, 'turn2Fb'))),
(34, Sequence(
Func(self.clearChat),
self.loseCogSuits(self.toonsA, self.battleANode, (0, 18, 5, -180, 0, 0)),
self.loseCogSuits(self.toonsB, self.battleBNode, (0, 18, 5, -180, 0, 0)))),
(37, Sequence(
self.toonNormalEyes(self.involvedToons),
Func(camera.setPosHpr, -23.4, -145.6, 44.0, -10.0, -12.5, 0),
Func(self.loop, 'Fb_neutral'),
Func(self.rampA.request, 'retract'),
Func(self.rampB.request, 'retract'),
Parallel(self.backupToonsToBattlePosition(self.toonsA, self.battleANode),
self.backupToonsToBattlePosition(self.toonsB, self.battleBNode),
Sequence(
Wait(2),
Func(self.setChatAbsolute, attackToons, CFSpeech))))))
track.append(dialogTrack)
return Sequence(Func(self.stickToonsToFloor), track, Func(self.unstickToons), name=self.uniqueName('Introduction'))
def __makeRollToBattleTwoMovie(self):
startPos = Point3(ToontownGlobals.SellbotBossBattleOnePosHpr[0], ToontownGlobals.SellbotBossBattleOnePosHpr[1], ToontownGlobals.SellbotBossBattleOnePosHpr[2])
if self.arenaSide:
topRampPos = Point3(*ToontownGlobals.SellbotBossTopRampPosB)
topRampTurnPos = Point3(*ToontownGlobals.SellbotBossTopRampTurnPosB)
p3Pos = Point3(*ToontownGlobals.SellbotBossP3PosB)
else:
topRampPos = Point3(*ToontownGlobals.SellbotBossTopRampPosA)
topRampTurnPos = Point3(*ToontownGlobals.SellbotBossTopRampTurnPosA)
p3Pos = Point3(*ToontownGlobals.SellbotBossP3PosA)
battlePos = Point3(ToontownGlobals.SellbotBossBattleTwoPosHpr[0], ToontownGlobals.SellbotBossBattleTwoPosHpr[1], ToontownGlobals.SellbotBossBattleTwoPosHpr[2])
battleHpr = VBase3(ToontownGlobals.SellbotBossBattleTwoPosHpr[3], ToontownGlobals.SellbotBossBattleTwoPosHpr[4], ToontownGlobals.SellbotBossBattleTwoPosHpr[5])
bossTrack = Sequence()
bossTrack.append(Func(self.getGeomNode().setH, 180))
bossTrack.append(Func(self.loop, 'Fb_neutral'))
track, hpr = self.rollBossToPoint(startPos, None, topRampPos, None, 0)
bossTrack.append(track)
track, hpr = self.rollBossToPoint(topRampPos, hpr, topRampTurnPos, None, 0)
bossTrack.append(track)
track, hpr = self.rollBossToPoint(topRampTurnPos, hpr, p3Pos, None, 0)
bossTrack.append(track)
track, hpr = self.rollBossToPoint(p3Pos, hpr, battlePos, None, 0)
bossTrack.append(track)
return Sequence(bossTrack, Func(self.getGeomNode().setH, 0), name=self.uniqueName('BattleTwo'))
def cagedToonMovieFunction(self, instruct, cageIndex):
self.notify.debug('cagedToonMovieFunction()')
if not (hasattr(self, 'cagedToon') and hasattr(self.cagedToon, 'nametag') and hasattr(self.cagedToon, 'nametag3d')):
return
if instruct == 1:
self.cagedToon.nametag3d.setScale(2)
elif instruct == 2:
self.cagedToon.setChatAbsolute(TTLocalizer.CagedToonDrop[cageIndex], CFSpeech)
elif instruct == 3:
self.cagedToon.nametag3d.setScale(1)
elif instruct == 4:
self.cagedToon.clearChat()
def makeEndOfBattleMovie(self, hasLocalToon):
name = self.uniqueName('CageDrop')
seq = Sequence(name=name)
seq.append(Func(self.cage.setPos, self.cagePos[self.cageIndex]))
if hasLocalToon:
seq += [Func(camera.reparentTo, render),
Func(camera.setPosHpr, self.cage, 0, -50, 0, 0, 0, 0),
Func(localAvatar.setCameraFov, ToontownGlobals.CogHQCameraFov),
Func(self.hide)]
seq += [Wait(0.5),
Parallel(self.cage.posInterval(1, self.cagePos[self.cageIndex + 1], blendType='easeInOut'), SoundInterval(self.cageLowerSfx, duration=1)),
Func(self.cagedToonMovieFunction, 1, self.cageIndex),
Func(self.cagedToonMovieFunction, 2, self.cageIndex),
Wait(3),
Func(self.cagedToonMovieFunction, 3, self.cageIndex),
Func(self.cagedToonMovieFunction, 4, self.cageIndex)]
if hasLocalToon:
seq += [Func(self.show),
Func(camera.reparentTo, localAvatar),
Func(camera.setPos, localAvatar.cameraPositions[0][0]),
Func(camera.setHpr, 0, 0, 0)]
self.cageIndex += 1
return seq
def __makeBossDamageMovie(self):
startPos = Point3(ToontownGlobals.SellbotBossBattleTwoPosHpr[0], ToontownGlobals.SellbotBossBattleTwoPosHpr[1], ToontownGlobals.SellbotBossBattleTwoPosHpr[2])
startHpr = Point3(*ToontownGlobals.SellbotBossBattleThreeHpr)
bottomPos = Point3(*ToontownGlobals.SellbotBossBottomPos)
deathPos = Point3(*ToontownGlobals.SellbotBossDeathPos)
self.setPosHpr(startPos, startHpr)
bossTrack = Sequence()
bossTrack.append(Func(self.loop, 'Fb_neutral'))
track, hpr = self.rollBossToPoint(startPos, startHpr, bottomPos, None, 1)
bossTrack.append(track)
track, hpr = self.rollBossToPoint(bottomPos, startHpr, deathPos, None, 1)
bossTrack.append(track)
duration = bossTrack.getDuration()
return bossTrack
def __talkAboutPromotion(self, speech):
if self.prevCogSuitLevel < ToontownGlobals.MaxCogSuitLevel:
deptIndex = CogDisguiseGlobals.dept2deptIndex(self.style.dept)
cogLevels = base.localAvatar.getCogLevels()
newCogSuitLevel = cogLevels[deptIndex]
cogTypes = base.localAvatar.getCogTypes()
maxCogSuitLevel = (SuitDNA.levelsPerSuit-1) + cogTypes[deptIndex]
if self.prevCogSuitLevel != maxCogSuitLevel:
speech += TTLocalizer.CagedToonLevelPromotion
if newCogSuitLevel == maxCogSuitLevel:
if newCogSuitLevel != ToontownGlobals.MaxCogSuitLevel:
suitIndex = (SuitDNA.suitsPerDept*deptIndex) + cogTypes[deptIndex]
cogTypeStr = SuitDNA.suitHeadTypes[suitIndex]
cogName = SuitBattleGlobals.SuitAttributes[cogTypeStr]['name']
speech += TTLocalizer.CagedToonSuitPromotion % cogName
else:
speech += TTLocalizer.CagedToonMaxed % (ToontownGlobals.MaxCogSuitLevel + 1)
return speech
def __makeCageOpenMovie(self):
speech = TTLocalizer.CagedToonThankYou
speech = self.__talkAboutPromotion(speech)
name = self.uniqueName('CageOpen')
seq = Sequence(
Func(self.cage.setPos, self.cagePos[4]),
Func(self.cageDoor.setHpr, VBase3(0, 0, 0)),
Func(self.cagedToon.setPos, Point3(0, -2, 0)),
Parallel(
self.cage.posInterval(0.5, self.cagePos[5], blendType='easeOut'),
SoundInterval(self.cageLowerSfx, duration=0.5)),
Parallel(
self.cageDoor.hprInterval(0.5, VBase3(0, 90, 0), blendType='easeOut'),
Sequence(SoundInterval(self.cageDoorSfx), duration=0)),
Wait(0.2),
Func(self.cagedToon.loop, 'walk'),
self.cagedToon.posInterval(0.8, Point3(0, -6, 0)),
Func(self.cagedToon.setChatAbsolute, TTLocalizer.CagedToonYippee, CFSpeech),
ActorInterval(self.cagedToon, 'jump'),
Func(self.cagedToon.loop, 'neutral'),
Func(self.cagedToon.headsUp, localAvatar),
Func(self.cagedToon.setLocalPageChat, speech, 0),
Func(camera.reparentTo, localAvatar),
Func(camera.setPos, 0, -9, 9),
Func(camera.lookAt, self.cagedToon, Point3(0, 0, 2)), name=name)
return seq
def __showOnscreenMessage(self, text):
if self.onscreenMessage:
self.onscreenMessage.destroy()
self.onscreenMessage = None
self.onscreenMessage = DirectLabel(text=text, text_fg=VBase4(1, 1, 1, 1), text_align=TextNode.ACenter, relief=None, pos=(0, 0, 0.35), scale=0.1)
def __clearOnscreenMessage(self):
if self.onscreenMessage:
self.onscreenMessage.destroy()
self.onscreenMessage = None
def __showWaitingMessage(self, task):
self.__showOnscreenMessage(TTLocalizer.BuildingWaitingForVictors)
def __placeCageShadow(self):
if self.cageShadow == None:
self.cageShadow = loader.loadModel('phase_3/models/props/drop_shadow')
self.cageShadow.setPos(0, 77.9, 18)
self.cageShadow.setColorScale(1, 1, 1, 0.6)
self.cageShadow.reparentTo(render)
def __removeCageShadow(self):
if self.cageShadow != None:
self.cageShadow.detachNode()
def setCageIndex(self, cageIndex):
self.cageIndex = cageIndex
self.cage.setPos(self.cagePos[self.cageIndex])
if self.cageIndex >= 4:
self.__placeCageShadow()
else:
self.__removeCageShadow()
def loadEnvironment(self):
DistributedBossCog.DistributedBossCog.loadEnvironment(self)
self.geom = loader.loadModel('phase_9/models/cogHQ/BossRoomHQ')
self.rampA = self.__findRamp('rampA', '**/west_ramp2')
self.rampB = self.__findRamp('rampB', '**/west_ramp')
self.rampC = self.__findRamp('rampC', '**/west_ramp1')
self.cage = self.geom.find('**/cage')
elevatorEntrance = self.geom.find('**/elevatorEntrance')
elevatorEntrance.getChildren().detach()
elevatorEntrance.setScale(1)
elevatorModel = loader.loadModel('phase_9/models/cogHQ/cogHQ_elevator')
elevatorModel.reparentTo(elevatorEntrance)
self.setupElevator(elevatorModel)
pos = self.cage.getPos()
self.cagePos = []
for height in self.cageHeights:
self.cagePos.append(Point3(pos[0], pos[1], height))
self.cageDoor = self.geom.find('**/cage_door')
self.cage.setScale(1)
self.rope = Rope.Rope(name='supportChain')
self.rope.reparentTo(self.cage)
self.rope.setup(2, ((self.cage, (0.15, 0.13, 16)), (self.geom, (0.23, 78, 120))))
self.rope.ropeNode.setRenderMode(RopeNode.RMBillboard)
self.rope.ropeNode.setUvMode(RopeNode.UVDistance)
self.rope.ropeNode.setUvDirection(0)
self.rope.ropeNode.setUvScale(0.8)
self.rope.setTexture(self.cage.findTexture('hq_chain'))
self.rope.setTransparency(1)
self.promotionMusic = base.loadMusic('phase_7/audio/bgm/encntr_suit_winning_indoor.ogg')
self.betweenBattleMusic = base.loadMusic('phase_9/audio/bgm/encntr_toon_winning.ogg')
self.battleTwoMusic = base.loadMusic('phase_7/audio/bgm/encntr_suit_winning_indoor.ogg')
self.battleThreeMusic = base.loadMusic('phase_9/audio/bgm/encntr_vp_boss.ogg')
self.geom.reparentTo(render)
def unloadEnvironment(self):
DistributedBossCog.DistributedBossCog.unloadEnvironment(self)
self.geom.removeNode()
del self.geom
del self.cage
self.rampA.requestFinalState()
self.rampB.requestFinalState()
self.rampC.requestFinalState()
del self.rampA
del self.rampB
del self.rampC
def __loadMopaths(self):
self.toonsEnterA = Mopath.Mopath()
self.toonsEnterA.loadFile('phase_9/paths/bossBattle-toonsEnterA')
self.toonsEnterA.fFaceForward = 1
self.toonsEnterA.timeScale = 35
self.toonsEnterB = Mopath.Mopath()
self.toonsEnterB.loadFile('phase_9/paths/bossBattle-toonsEnterB')
self.toonsEnterB.fFaceForward = 1
self.toonsEnterB.timeScale = 35
def __unloadMopaths(self):
self.toonsEnterA.reset()
self.toonsEnterB.reset()
def __findRamp(self, name, path):
ramp = self.geom.find(path)
children = ramp.getChildren()
animate = ramp.attachNewNode(name)
children.reparentTo(animate)
fsm = ClassicFSM.ClassicFSM(name, [
State.State('extend',
Functor(self.enterRampExtend, animate),
Functor(self.exitRampExtend, animate), [
'extended',
'retract',
'retracted']),
State.State('extended',
Functor(self.enterRampExtended, animate),
Functor(self.exitRampExtended, animate), [
'retract',
'retracted']),
State.State('retract',
Functor(self.enterRampRetract, animate),
Functor(self.exitRampRetract, animate), [
'extend',
'extended',
'retracted']),
State.State('retracted',
Functor(self.enterRampRetracted, animate),
Functor(self.exitRampRetracted, animate), [
'extend',
'extended']),
State.State('off',
Functor(self.enterRampOff, animate),
Functor(self.exitRampOff, animate))],
'off', 'off', onUndefTransition=ClassicFSM.ClassicFSM.DISALLOW)
fsm.enterInitialState()
return fsm
def enterRampExtend(self, animate):
intervalName = self.uniqueName('extend-%s' % animate.getName())
adjustTime = 2.0 * animate.getX() / 18.0
ival = Parallel(SoundInterval(self.rampSlideSfx, node=animate), animate.posInterval(adjustTime, Point3(0, 0, 0), blendType='easeInOut', name=intervalName))
ival.start()
self.storeInterval(ival, intervalName)
def exitRampExtend(self, animate):
intervalName = self.uniqueName('extend-%s' % animate.getName())
self.clearInterval(intervalName)
def enterRampExtended(self, animate):
animate.setPos(0, 0, 0)
def exitRampExtended(self, animate):
pass
def enterRampRetract(self, animate):
intervalName = self.uniqueName('retract-%s' % animate.getName())
adjustTime = 2.0 * (18 - animate.getX()) / 18.0
ival = Parallel(SoundInterval(self.rampSlideSfx, node=animate), animate.posInterval(adjustTime, Point3(18, 0, 0), blendType='easeInOut', name=intervalName))
ival.start()
self.storeInterval(ival, intervalName)
def exitRampRetract(self, animate):
intervalName = self.uniqueName('retract-%s' % animate.getName())
self.clearInterval(intervalName)
def enterRampRetracted(self, animate):
animate.setPos(18, 0, 0)
def exitRampRetracted(self, animate):
pass
def enterRampOff(self, animate):
pass
def exitRampOff(self, animate):
pass
def enterOff(self):
DistributedBossCog.DistributedBossCog.enterOff(self)
if self.cagedToon:
self.cagedToon.clearChat()
if self.rampA:
self.rampA.request('off')
if self.rampB:
self.rampB.request('off')
if self.rampC:
self.rampC.request('off')
def enterWaitForToons(self):
DistributedBossCog.DistributedBossCog.enterWaitForToons(self)
self.geom.hide()
self.cagedToon.removeActive()
def exitWaitForToons(self):
DistributedBossCog.DistributedBossCog.exitWaitForToons(self)
self.geom.show()
self.cagedToon.addActive()
def enterElevator(self):
DistributedBossCog.DistributedBossCog.enterElevator(self)
self.rampA.request('extended')
self.rampB.request('extended')
self.rampC.request('retracted')
self.setCageIndex(0)
self.reparentTo(render)
self.setPosHpr(*ToontownGlobals.SellbotBossBattleOnePosHpr)
self.happy = 1
self.raised = 1
self.forward = 1
self.doAnimate()
self.cagedToon.removeActive()
base.camLens.setMinFov(ToontownGlobals.VPElevatorFov/(4./3.))
def exitElevator(self):
DistributedBossCog.DistributedBossCog.exitElevator(self)
self.cagedToon.addActive()
def enterIntroduction(self):
self.reparentTo(render)
self.setPosHpr(*ToontownGlobals.SellbotBossBattleOnePosHpr)
self.stopAnimate()
DistributedBossCog.DistributedBossCog.enterIntroduction(self)
self.rampA.request('extended')
self.rampB.request('extended')
self.rampC.request('retracted')
self.setCageIndex(0)
base.playMusic(self.promotionMusic, looping=1, volume=0.9)
def exitIntroduction(self):
DistributedBossCog.DistributedBossCog.exitIntroduction(self)
self.promotionMusic.stop()
def enterBattleOne(self):
DistributedBossCog.DistributedBossCog.enterBattleOne(self)
self.reparentTo(render)
self.setPosHpr(*ToontownGlobals.SellbotBossBattleOnePosHpr)
self.clearChat()
self.cagedToon.clearChat()
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('retract')
if self.battleA == None or self.battleB == None:
cageIndex = 1
else:
cageIndex = 0
self.setCageIndex(cageIndex)
def exitBattleOne(self):
DistributedBossCog.DistributedBossCog.exitBattleOne(self)
def enterRollToBattleTwo(self):
self.disableToonCollision()
self.releaseToons()
if self.arenaSide:
self.rampA.request('retract')
self.rampB.request('extend')
else:
self.rampA.request('extend')
self.rampB.request('retract')
self.rampC.request('retract')
self.reparentTo(render)
self.setCageIndex(2)
self.stickBossToFloor()
intervalName = 'RollToBattleTwo'
seq = Sequence(self.__makeRollToBattleTwoMovie(), Func(self.__onToPrepareBattleTwo), name=intervalName)
seq.start()
self.storeInterval(seq, intervalName)
base.playMusic(self.betweenBattleMusic, looping=1, volume=0.9)
self.__showEasyBarrels()
taskMgr.doMethodLater(0.5, self.enableToonCollision, 'enableToonCollision')
def __onToPrepareBattleTwo(self):
self.disableToonCollision()
self.unstickBoss()
self.setPosHpr(*ToontownGlobals.SellbotBossBattleTwoPosHpr)
self.doneBarrier('RollToBattleTwo')
def exitRollToBattleTwo(self):
self.unstickBoss()
intervalName = 'RollToBattleTwo'
self.clearInterval(intervalName)
self.betweenBattleMusic.stop()
def disableToonCollision(self):
base.localAvatar.collisionsOff()
def enableToonCollision(self, task):
base.localAvatar.collisionsOn()
def enterPrepareBattleTwo(self):
self.cleanupIntervals()
self.__hideEasyBarrels()
self.controlToons()
self.clearChat()
self.cagedToon.clearChat()
self.reparentTo(render)
if self.arenaSide:
self.rampA.request('retract')
self.rampB.request('extend')
else:
self.rampA.request('extend')
self.rampB.request('retract')
self.rampC.request('retract')
self.reparentTo(render)
self.setCageIndex(2)
camera.reparentTo(render)
camera.setPosHpr(self.cage, 0, -17, 3.3, 0, 0, 0)
(localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov),)
self.hide()
self.acceptOnce('doneChatPage', self.__onToBattleTwo)
self.cagedToon.setLocalPageChat(TTLocalizer.CagedToonPrepareBattleTwo, 1)
base.playMusic(self.stingMusic, looping=0, volume=1.0)
taskMgr.doMethodLater(0.5, self.enableToonCollision, 'enableToonCollision')
def __onToBattleTwo(self, elapsed):
self.doneBarrier('PrepareBattleTwo')
taskMgr.doMethodLater(1, self.__showWaitingMessage, self.uniqueName('WaitingMessage'))
def exitPrepareBattleTwo(self):
self.show()
taskMgr.remove(self.uniqueName('WaitingMessage'))
self.ignore('doneChatPage')
self.__clearOnscreenMessage()
self.stingMusic.stop()
def enterBattleTwo(self):
self.cleanupIntervals()
mult = ToontownBattleGlobals.getBossBattleCreditMultiplier(2)
localAvatar.inventory.setBattleCreditMultiplier(mult)
self.reparentTo(render)
self.setPosHpr(*ToontownGlobals.SellbotBossBattleTwoPosHpr)
self.clearChat()
self.cagedToon.clearChat()
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('retract')
self.releaseToons()
self.toonsToBattlePosition(self.toonsA, self.battleANode)
self.toonsToBattlePosition(self.toonsB, self.battleBNode)
if self.battleA == None or self.battleB == None:
cageIndex = 3
else:
cageIndex = 2
self.setCageIndex(cageIndex)
base.playMusic(self.battleTwoMusic, looping=1, volume=0.9)
def exitBattleTwo(self):
intervalName = self.uniqueName('cageDrop')
self.clearInterval(intervalName)
self.cleanupBattles()
self.battleTwoMusic.stop()
localAvatar.inventory.setBattleCreditMultiplier(1)
def enterPrepareBattleThree(self):
self.cleanupIntervals()
self.controlToons()
self.clearChat()
self.cagedToon.clearChat()
self.reparentTo(render)
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('extend')
self.setCageIndex(4)
camera.reparentTo(render)
camera.setPosHpr(self.cage, 0, -17, 3.3, 0, 0, 0)
(localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov),)
self.hide()
self.acceptOnce('doneChatPage', self.__onToBattleThree)
self.cagedToon.setLocalPageChat(TTLocalizer.CagedToonPrepareBattleThree, 1)
base.playMusic(self.betweenBattleMusic, looping=1, volume=0.9)
def __onToBattleThree(self, elapsed):
self.doneBarrier('PrepareBattleThree')
taskMgr.doMethodLater(1, self.__showWaitingMessage, self.uniqueName('WaitingMessage'))
def exitPrepareBattleThree(self):
self.show()
taskMgr.remove(self.uniqueName('WaitingMessage'))
self.ignore('doneChatPage')
intervalName = 'PrepareBattleThree'
self.clearInterval(intervalName)
self.__clearOnscreenMessage()
self.betweenBattleMusic.stop()
def enterBattleThree(self):
DistributedBossCog.DistributedBossCog.enterBattleThree(self)
self.clearChat()
self.cagedToon.clearChat()
self.reparentTo(render)
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('extend')
self.setCageIndex(4)
self.happy = 0
self.raised = 1
self.forward = 1
self.doAnimate()
self.accept('enterCage', self.__touchedCage)
self.accept('pieSplat', self.__pieSplat)
self.accept('localPieSplat', self.__localPieSplat)
self.accept('outOfPies', self.__outOfPies)
self.accept('begin-pie', self.__foundPieButton)
localAvatar.setCameraFov(ToontownGlobals.BossBattleCameraFov)
taskMgr.doMethodLater(30, self.__howToGetPies, self.uniqueName('PieAdvice'))
self.stickBossToFloor()
self.bossDamageMovie = self.__makeBossDamageMovie()
bossDoneEventName = self.uniqueName('DestroyedBoss')
self.bossDamageMovie.setDoneEvent(bossDoneEventName)
self.acceptOnce(bossDoneEventName, self.__doneBattleThree)
self.resetMaxDamage()
self.bossDamageToMovie = self.bossDamageMovie.getDuration() / self.bossMaxDamage
self.bossDamageMovie.setT(self.bossDamage * self.bossDamageToMovie)
base.playMusic(self.battleThreeMusic, looping=1, volume=0.9)
def __doneBattleThree(self):
self.setState('NearVictory')
self.unstickBoss()
def exitBattleThree(self):
DistributedBossCog.DistributedBossCog.exitBattleThree(self)
bossDoneEventName = self.uniqueName('DestroyedBoss')
self.ignore(bossDoneEventName)
taskMgr.remove(self.uniqueName('StandUp'))
self.ignore('enterCage')
self.ignore('pieSplat')
self.ignore('localPieSplat')
self.ignore('outOfPies')
self.ignore('begin-pie')
self.__clearOnscreenMessage()
taskMgr.remove(self.uniqueName('PieAdvice'))
localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov)
self.__removeCageShadow()
self.bossDamageMovie.finish()
self.bossDamageMovie = None
self.unstickBoss()
taskName = 'RecoverBossDamage'
taskMgr.remove(taskName)
self.battleThreeMusicTime = self.battleThreeMusic.getTime()
self.battleThreeMusic.stop()
def enterNearVictory(self):
self.cleanupIntervals()
self.reparentTo(render)
self.setPos(*ToontownGlobals.SellbotBossDeathPos)
self.setHpr(*ToontownGlobals.SellbotBossBattleThreeHpr)
self.clearChat()
self.cagedToon.clearChat()
self.setCageIndex(4)
self.releaseToons(finalBattle=1)
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('extend')
self.accept('enterCage', self.__touchedCage)
self.accept('pieSplat', self.__finalPieSplat)
self.accept('localPieSplat', self.__localPieSplat)
self.accept('outOfPies', self.__outOfPies)
localAvatar.setCameraFov(ToontownGlobals.BossBattleCameraFov)
self.happy = 0
self.raised = 0
self.forward = 1
self.doAnimate()
self.setDizzy(1)
base.playMusic(self.battleThreeMusic, looping=1, volume=0.9, time=self.battleThreeMusicTime)
def exitNearVictory(self):
self.ignore('enterCage')
self.ignore('pieSplat')
self.ignore('localPieSplat')
self.ignore('outOfPies')
self.__clearOnscreenMessage()
taskMgr.remove(self.uniqueName('PieAdvice'))
localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov)
self.__removeCageShadow()
self.setDizzy(0)
self.battleThreeMusicTime = self.battleThreeMusic.getTime()
self.battleThreeMusic.stop()
def enterVictory(self):
self.cleanupIntervals()
localAvatar.setCameraFov(ToontownGlobals.BossBattleCameraFov)
self.reparentTo(render)
self.setPos(*ToontownGlobals.SellbotBossDeathPos)
self.setHpr(*ToontownGlobals.SellbotBossBattleThreeHpr)
self.clearChat()
self.cagedToon.clearChat()
self.setCageIndex(4)
self.releaseToons(finalBattle=1)
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('extend')
self.happy = 0
self.raised = 0
self.forward = 1
self.doAnimate('Fb_fall', now=1)
self.acceptOnce(self.animDoneEvent, self.__continueVictory)
base.playMusic(self.battleThreeMusic, looping=1, volume=0.9, time=self.battleThreeMusicTime)
def __continueVictory(self):
self.stopAnimate()
self.stash()
self.doneBarrier('Victory')
def exitVictory(self):
self.stopAnimate()
self.unstash()
self.__removeCageShadow()
localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov)
self.battleThreeMusicTime = self.battleThreeMusic.getTime()
self.battleThreeMusic.stop()
def enterReward(self):
self.cleanupIntervals()
self.clearChat()
self.cagedToon.clearChat()
self.stash()
self.stopAnimate()
self.setCageIndex(4)
self.releaseToons(finalBattle=1)
self.toMovieMode()
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('extend')
panelName = self.uniqueName('reward')
self.rewardPanel = RewardPanel.RewardPanel(panelName)
victory, camVictory, skipper = MovieToonVictory.doToonVictory(1, self.involvedToons, self.toonRewardIds, self.toonRewardDicts, self.deathList, self.rewardPanel, allowGroupShot=0, uberList=self.uberList, noSkip=True)
ival = Sequence(Parallel(victory, camVictory), Func(self.__doneReward))
intervalName = 'RewardMovie'
delayDeletes = []
for toonId in self.involvedToons:
toon = self.cr.doId2do.get(toonId)
if toon:
delayDeletes.append(DelayDelete.DelayDelete(toon, 'SellbotBoss.enterReward'))
ival.delayDeletes = delayDeletes
ival.start()
self.storeInterval(ival, intervalName)
base.playMusic(self.battleThreeMusic, looping=1, volume=0.9, time=self.battleThreeMusicTime)
def __doneReward(self):
self.doneBarrier('Reward')
self.toWalkMode()
def exitReward(self):
intervalName = 'RewardMovie'
self.clearInterval(intervalName)
self.unstash()
self.rewardPanel.destroy()
del self.rewardPanel
self.__removeCageShadow()
self.battleThreeMusicTime = 0
self.battleThreeMusic.stop()
def enterEpilogue(self):
self.cleanupIntervals()
self.clearChat()
self.cagedToon.clearChat()
self.stash()
self.stopAnimate()
self.setCageIndex(4)
self.controlToons()
self.rampA.request('retract')
self.rampB.request('retract')
self.rampC.request('extend')
self.__arrangeToonsAroundCage()
camera.reparentTo(render)
camera.setPosHpr(-24, 52, 27.5, -53, -13, 0)
intervalName = 'EpilogueMovie'
seq = Sequence(self.__makeCageOpenMovie(), name=intervalName)
seq.start()
self.storeInterval(seq, intervalName)
self.accept('nextChatPage', self.__epilogueChatNext)
self.accept('doneChatPage', self.__epilogueChatDone)
base.playMusic(self.epilogueMusic, looping=1, volume=0.9)
def __epilogueChatNext(self, pageNumber, elapsed):
if pageNumber == 2:
if self.cagedToon.style.torso[1] == 'd':
track = ActorInterval(self.cagedToon, 'curtsy')
else:
track = ActorInterval(self.cagedToon, 'bow')
track = Sequence(track, Func(self.cagedToon.loop, 'neutral'))
intervalName = 'EpilogueMovieToonAnim'
self.storeInterval(track, intervalName)
track.start()
def __epilogueChatDone(self, elapsed):
self.cagedToon.setChatAbsolute(TTLocalizer.CagedToonGoodbye, CFSpeech)
self.ignore('nextChatPage')
self.ignore('doneChatPage')
intervalName = 'EpilogueMovieToonAnim'
self.clearInterval(intervalName)
track = Parallel(Sequence(ActorInterval(self.cagedToon, 'wave'), Func(self.cagedToon.loop, 'neutral')), Sequence(Wait(0.5), Func(self.localToonToSafeZone)))
self.storeInterval(track, intervalName)
track.start()
def exitEpilogue(self):
self.clearInterval('EpilogueMovieToonAnim')
self.unstash()
self.__removeCageShadow()
self.epilogueMusic.stop()
def __arrangeToonsAroundCage(self):
radius = 15
numToons = len(self.involvedToons)
center = (numToons - 1) / 2.0
for i in xrange(numToons):
toon = base.cr.doId2do.get(self.involvedToons[i])
if toon:
angle = 270 - 15 * (i - center)
radians = angle * math.pi / 180.0
x = math.cos(radians) * radius
y = math.sin(radians) * radius
toon.setPos(self.cage, x, y, 0)
toon.setZ(18.0)
toon.headsUp(self.cage)
def enterFrolic(self):
DistributedBossCog.DistributedBossCog.enterFrolic(self)
self.setPosHpr(*ToontownGlobals.SellbotBossBattleOnePosHpr)
def doorACallback(self, isOpen):
if self.insidesANodePath:
if isOpen:
self.insidesANodePath.unstash()
else:
self.insidesANodePath.stash()
def doorBCallback(self, isOpen):
if self.insidesBNodePath:
if isOpen:
self.insidesBNodePath.unstash()
else:
self.insidesBNodePath.stash()
def __toonsToPromotionPosition(self, toonIds, battleNode):
points = BattleBase.BattleBase.toonPoints[len(toonIds) - 1]
for i in xrange(len(toonIds)):
toon = base.cr.doId2do.get(toonIds[i])
if toon:
toon.reparentTo(render)
pos, h = points[i]
toon.setPosHpr(battleNode, pos[0], pos[1] + 10, pos[2], h, 0, 0)
def __doobersToPromotionPosition(self, doobers, battleNode):
points = BattleBase.BattleBase.toonPoints[len(doobers) - 1]
for i in xrange(len(doobers)):
suit = doobers[i]
suit.fsm.request('neutral')
suit.loop('neutral')
pos, h = points[i]
suit.setPosHpr(battleNode, pos[0], pos[1] + 10, pos[2], h, 0, 0)
def __touchedCage(self, entry):
self.sendUpdate('touchCage', [])
self.__clearOnscreenMessage()
taskMgr.remove(self.uniqueName('PieAdvice'))
base.playSfx(self.piesRestockSfx)
if not self.everThrownPie:
taskMgr.doMethodLater(30, self.__howToThrowPies, self.uniqueName('PieAdvice'))
def __outOfPies(self):
self.__showOnscreenMessage(TTLocalizer.BossBattleNeedMorePies)
taskMgr.doMethodLater(20, self.__howToGetPies, self.uniqueName('PieAdvice'))
def __howToGetPies(self, task):
self.__showOnscreenMessage(TTLocalizer.BossBattleHowToGetPies)
def __howToThrowPies(self, task):
self.__showOnscreenMessage(TTLocalizer.BossBattleHowToThrowPies)
def __foundPieButton(self):
self.everThrownPie = 1
self.__clearOnscreenMessage()
taskMgr.remove(self.uniqueName('PieAdvice'))
def __pieSplat(self, toon, pieCode):
if base.config.GetBool('easy-vp', 0):
if not self.dizzy:
pieCode = ToontownGlobals.PieCodeBossInsides
if pieCode == ToontownGlobals.PieCodeBossInsides:
if toon == localAvatar:
self.d_hitBossInsides()
self.flashRed()
elif pieCode == ToontownGlobals.PieCodeBossCog:
if toon == localAvatar:
self.d_hitBoss(1)
if self.dizzy:
self.flashRed()
self.doAnimate('hit', now=1)
def __localPieSplat(self, pieCode, entry):
if pieCode != ToontownGlobals.PieCodeToon:
return
avatarDoId = entry.getIntoNodePath().getNetTag('avatarDoId')
if avatarDoId == '':
self.notify.warning('Toon %s has no avatarDoId tag.' % repr(entry.getIntoNodePath()))
return
doId = int(avatarDoId)
if doId != localAvatar.doId:
self.d_hitToon(doId)
def __finalPieSplat(self, toon, pieCode):
if pieCode != ToontownGlobals.PieCodeBossCog:
return
self.sendUpdate('finalPieSplat', [])
self.ignore('pieSplat')
def cagedToonBattleThree(self, index, avId):
str = TTLocalizer.CagedToonBattleThree.get(index)
if str:
toonName = ''
if avId:
toon = self.cr.doId2do.get(avId)
if not toon:
self.cagedToon.clearChat()
return
toonName = toon.getName()
text = str % {'toon': toonName}
self.cagedToon.setChatAbsolute(text, CFSpeech | CFTimeout)
else:
self.cagedToon.clearChat()
def cleanupAttacks(self):
self.__cleanupStrafe()
def __cleanupStrafe(self):
if self.strafeInterval:
self.strafeInterval.finish()
self.strafeInterval = None
def doStrafe(self, side, direction):
gearRoot = self.rotateNode.attachNewNode('gearRoot')
if side == 0:
gearRoot.setPos(0, -7, 3)
gearRoot.setHpr(180, 0, 0)
door = self.doorA
else:
gearRoot.setPos(0, 7, 3)
door = self.doorB
gearRoot.setTag('attackCode', str(ToontownGlobals.BossCogStrafeAttack))
gearModel = self.getGearFrisbee()
gearModel.setScale(0.1)
t = self.getBossDamage() / 100.0
gearTrack = Parallel()
numGears = int(4 + 6 * t + 0.5)
time = 5.0 - 4.0 * t
spread = 60 * math.pi / 180.0
if direction == 1:
spread = -spread
dist = 50
rate = time / numGears
for i in xrange(numGears):
node = gearRoot.attachNewNode(str(i))
node.hide()
node.setPos(0, 0, 0)
gear = gearModel.instanceTo(node)
angle = (float(i) / (numGears - 1) - 0.5) * spread
x = dist * math.sin(angle)
y = dist * math.cos(angle)
h = random.uniform(-720, 720)
gearTrack.append(Sequence(Wait(i * rate), Func(node.show), Parallel(node.posInterval(1, Point3(x, y, 0), fluid=1), node.hprInterval(1, VBase3(h, 0, 0), fluid=1), Sequence(SoundInterval(self.strafeSfx[i], volume=0.2, node=self), duration=0)), Func(node.detachNode)))
seq = Sequence(Func(door.request, 'open'), Wait(0.7), gearTrack, Func(door.request, 'close'))
self.__cleanupStrafe()
self.strafeInterval = seq
seq.start()
def __showEasyBarrels(self):
barrelNodes = hidden.findAllMatches('**/Distributed*Barrel-*')
if not barrelNodes or barrelNodes.isEmpty():
return
if render.find('barrelsRootNode'):
self.notify.warning('__showEasyBarrels(): barrelsRootNode already exists')
return
self.barrelsRootNode = render.attachNewNode('barrelsRootNode')
self.barrelsRootNode.setPos(*SellbotBossGlobals.BarrelsStartPos)
if self.arenaSide == 0:
self.barrelsRootNode.setHpr(180, 0, 0)
else:
self.barrelsRootNode.setHpr(0, 0, 0)
for i, barrelNode in enumerate(barrelNodes):
barrel = base.cr.doId2do.get(int(barrelNode.getNetTag('doId')))
SellbotBossGlobals.setBarrelAttr(barrel, barrel.entId)
if hasattr(barrel, 'applyLabel'):
barrel.applyLabel()
barrel.setPosHpr(barrel.pos, barrel.hpr)
barrel.reparentTo(self.barrelsRootNode)
intervalName = 'MakeBarrelsAppear'
seq = Sequence(LerpPosInterval(self.barrelsRootNode, 0.5, Vec3(*SellbotBossGlobals.BarrelsFinalPos), blendType='easeInOut'), name=intervalName)
seq.start()
self.storeInterval(seq, intervalName)
def __hideEasyBarrels(self):
if hasattr(self, 'barrelsRootNode'):
self.barrelsRootNode.removeNode()
intervalName = 'MakeBarrelsAppear'
self.clearInterval(intervalName)
def toonPromoted(self, promoted):
self.localToonPromoted = promoted