toontown-just-works/toontown/suit/DistributedSellbotBoss.py
2024-07-07 18:08:39 -05:00

1288 lines
54 KiB
Python

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 panda3d.core 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.coghq import CogDisguiseGlobals
from toontown.distributed import DelayDelete
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
from otp.nametag.NametagConstants import *
from otp.nametag import NametagGlobals
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 = base.cr.newsManager.isHolidayRunning(ToontownGlobals.SELLBOT_NERF_HOLIDAY)
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)
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),
camera.posHprInterval(5, (-0.3, -105.1, 5.4), (0, 0, 0), blendType='easeInOut'))),
(12, Func(self.setChatAbsolute, doobersAway, CFSpeech)),
(16, Parallel(
Func(self.clearChat),
camera.posHprInterval(4, (-25, -99, 10), (-14, 10, 0), blendType='easeInOut'),
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(
camera.posHprInterval(1, (-20, -35, 10), (-88, 25, 0), blendType='easeOut'),
Func(self.setChatAbsolute, discoverToons, CFSpeech),
Func(self.cagedToon.nametag3d.setScale, 1),
Func(self.cagedToon.clearChat),
ActorInterval(self, 'turn2Fb'))),
(35, 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)))),
(38, Sequence(
self.toonNormalEyes(self.involvedToons),
camera.posHprInterval(1, (-23.4, -145.6, 44.0), (-10.0, -12.5, 0), blendType='easeInOut'),
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(3),
camera.posHprInterval(1, (-25, -35, 20.5), (-90, 0, 0), blendType='easeOut'),
Func(self.setChatAbsolute, attackToons, CFSpeech),
Wait(3))))))
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.setChatAbsolute, TTLocalizer.VPRampMessage, CFSpeech | CFTimeout))
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 not self.localToonPromoted:
pass
elif self.prevCogSuitLevel < ToontownGlobals.MaxCogSuitLevel:
speech += TTLocalizer.CagedToonPromotion
newCogSuitLevel = localAvatar.getCogLevels()[CogDisguiseGlobals.dept2deptIndex(self.style.dept)]
if newCogSuitLevel == ToontownGlobals.MaxCogSuitLevel:
speech += TTLocalizer.CagedToonLastPromotion % (ToontownGlobals.MaxCogSuitLevel + 1)
if newCogSuitLevel in ToontownGlobals.CogSuitHPLevels:
speech += TTLocalizer.CagedToonHPBoost
else:
speech += TTLocalizer.CagedToonMaxed % (ToontownGlobals.MaxCogSuitLevel + 1)
if self.keyReward:
speech += TTLocalizer.BossRTKeyReward
return speech
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.WaitingForOtherToons)
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_7/audio/bgm/encntr_suit_winning_indoor.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.setChatAbsolute(TTLocalizer.VPDeathTaunt, CFSpeech | CFTimeout)
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