from panda3d.core import * from toontown.toonbase.ToonBaseGlobal import * from direct.interval.IntervalGlobal import * from toontown.toonbase.ToontownGlobals import * from direct.directnotify import DirectNotifyGlobal from direct.fsm import StateData from direct.fsm import ClassicFSM, State from direct.fsm import State import ToonBlitzGlobals from otp.otpbase import OTPGlobals from direct.task.Task import Task from toontown.minigame import TwoDBattleMgr from toontown.racing import RaceHeadFrame COLOR_RED = VBase4(1, 0, 0, 0.3) class TwoDGameToonSD(StateData.StateData): notify = DirectNotifyGlobal.directNotify.newCategory('TwoDGameToonSD') FallBackAnim = 'slip-backward' NeutralAnim = 'neutral' RunAnim = 'run' ShootGun = 'water-gun' Victory = 'victory' animList = [FallBackAnim, NeutralAnim, RunAnim, ShootGun, Victory] ScoreTextGenerator = TextNode('ScoreTextGenerator') def __init__(self, avId, game): self.avId = avId self.game = game self.isLocal = avId == base.localAvatar.doId self.toon = self.game.getAvatar(self.avId) self.unexpectedExit = False self.fallBackIval = None self.fallDownIval = None self.victoryIval = None self.squishIval = None self.fsm = ClassicFSM.ClassicFSM('TwoDGameAnimFSM-%s' % self.avId, [State.State('init', self.enterInit, self.exitInit, ['normal']), State.State('normal', self.enterNormal, self.exitNormal, ['shootGun', 'fallBack', 'fallDown', 'victory', 'squish']), State.State('shootGun', self.enterShootGun, self.exitShootGun, ['normal', 'fallBack', 'fallDown', 'victory', 'squish']), State.State('fallBack', self.enterFallBack, self.exitFallBack, ['normal', 'fallDown', 'squish']), State.State('fallDown', self.enterFallDown, self.exitFallDown, ['normal']), State.State('squish', self.enterSquish, self.exitSquish, ['normal']), State.State('victory', self.enterVictory, self.exitVictory, ['normal', 'fallDown']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'init', 'cleanup') self.scoreText = None self.load() self.progressLineLength = self.game.assetMgr.faceEndPos[0] - self.game.assetMgr.faceStartPos[0] self.conversionRatio = self.progressLineLength / self.game.gameLength return def load(self): for anim in self.animList: self.toon.pose(anim, 0) self.battleMgr = TwoDBattleMgr.TwoDBattleMgr(self.game, self.toon) self.squishSound = base.loadSfx('phase_3.5/audio/dial/AV_' + self.toon.style.getAnimal() + '_exclaim.ogg') def destroy(self): if self.fallBackIval != None: self.fallBackIval.finish() self.fallBackIval = None if self.fallDownIval != None: self.fallDownIval.finish() self.fallDownIval = None if self.squishIval != None: self.squishIval.finish() self.squishIval = None if self.victoryIval != None: self.victoryIval.finish() self.victoryIval = None self.hideScoreText() self.headFrame.destroy() self.battleMgr.destroy() del self.battleMgr del self.fsm return def enter(self): self.fsm.enterInitialState() def exit(self, unexpectedExit = False): self.unexpectedExit = unexpectedExit self.fsm.requestFinalState() def enterInit(self): self.notify.debug('enterInit') self.toon.startBlink() self.toon.stopLookAround() self.toon.useLOD(1000) self.toon.dropShadow.hide() def exitInit(self): pass def enterNormal(self): self.notify.debug('enterNormal') def exitNormal(self): pass def enterFallBack(self): self.notify.debug('enterFallBack') fallBackDist = 9 self.blinkRed = self.blinkColor(COLOR_RED, 2) duration = 4 animName = self.FallBackAnim startFrame = 1 endFrame = 22 totalFrames = self.toon.getNumFrames(animName) frames = totalFrames - 1 - startFrame frameRate = self.toon.getFrameRate(animName) newRate = frames / duration playRate = newRate / frameRate fallBackAnim = Sequence(ActorInterval(self.toon, animName, startTime=startFrame / newRate, endTime=endFrame / newRate, playRate=playRate), ActorInterval(self.toon, animName, startFrame=23, playRate=1), FunctionInterval(self.resume)) self.fallBackIval = Parallel(self.blinkRed, fallBackAnim) if self.isLocal: self.game.ignoreInputs() self.toon.controlManager.currentControls.lifter.setVelocity(12) if self.toon.getH() == 90: endPoint = Point3(self.toon.getX() + fallBackDist, self.toon.getY(), self.toon.getZ()) else: endPoint = Point3(self.toon.getX() - fallBackDist, self.toon.getY(), self.toon.getZ()) enemyHitTrajectory = LerpFunc(self.toon.setX, fromData=self.toon.getX(), toData=endPoint.getX(), duration=0.75, name='enemyHitTrajectory') self.fallBackIval.append(enemyHitTrajectory) base.playSfx(self.game.assetMgr.sndOof) self.fallBackIval.start() def exitFallBack(self): self.fallBackIval.pause() self.blinkRed.finish() if self.isLocal: if self.game.gameFSM.getCurrentState().getName() == 'play': self.game.acceptInputs() def shootGun(self): if self.fsm.getCurrentState().getName() == 'shootGun': self.fsm.request('normal') self.fsm.request('shootGun') def enterShootGun(self): self.battleMgr.shoot() self.fsm.request('normal') def exitShootGun(self): pass def enterFallDown(self): self.notify.debug('enterFallDown') self.fallDownIval = Sequence() self.blinkRed = self.blinkColor(COLOR_RED, 2) if self.isLocal: self.game.ignoreInputs() base.playSfx(self.game.assetMgr.fallSound) pos = self.game.sectionMgr.getLastSpawnPoint() toonRespawnIval = Sequence(Wait(1), Func(base.localAvatar.setPos, pos)) self.fallDownIval.append(toonRespawnIval) self.fallDownIval.append(Func(self.resume)) self.fallDownIval.append(self.blinkRed) self.fallDownIval.start() def exitFallDown(self): if self.isLocal: if self.game.gameFSM.getCurrentState().getName() == 'play': self.game.acceptInputs() def enterSquish(self): self.notify.debug('enterSquish') if self.isLocal: self.game.ignoreInputs() self.toon.setAnimState('Squish') self.toon.stunToon() base.playSfx(self.squishSound, node=self.toon, volume=2) self.blinkRed = self.blinkColor(COLOR_RED, 3) self.squishIval = Parallel(self.blinkRed, Sequence(Wait(2.5), Func(self.resume))) self.squishIval.start() def exitSquish(self): if self.isLocal: if self.game.gameFSM.getCurrentState().getName() == 'play': self.game.acceptInputs() def enterVictory(self): self.notify.debug('enterVictory') outsideElevatorPos = self.game.sectionMgr.exitElevator.find('**/loc_elevator_front').getPos(render) insideElevatorPos = self.game.sectionMgr.exitElevator.find('**/loc_elevator_inside').getPos(render) runToElevator = Parallel(LerpPosInterval(self.toon, self.game.timeToRunToElevator, outsideElevatorPos), ActorInterval(self.toon, self.RunAnim, loop=1, duration=self.game.timeToRunToElevator)) danceIval = Parallel(LerpPosInterval(self.toon, 2, insideElevatorPos), ActorInterval(self.toon, self.Victory, loop=1, duration=ToonBlitzGlobals.GameDuration[self.game.getSafezoneId()])) waitToLand = 0.0 if self.toon.getZ(render) > 13: waitToLand = 1 self.victoryIval = Sequence(Wait(waitToLand), runToElevator, danceIval) self.victoryIval.start() def exitVictory(self): pass def enterCleanup(self): self.notify.debug('enterCleanup') self.toon.stopBlink() self.toon.startLookAround() self.toon.resetLOD() self.toon.dropShadow.show() def exitCleanup(self): pass def resume(self): self.fsm.request('normal') messenger.send('jumpLand') def blinkColor(self, color, duration): blink = Sequence(LerpColorScaleInterval(self.toon, 0.5, color, startColorScale=VBase4(1, 1, 1, 1)), LerpColorScaleInterval(self.toon, 0.5, VBase4(1, 1, 1, 1), startColorScale=color)) track = Sequence(Func(blink.loop), Wait(duration), Func(blink.finish)) return track def setAnimState(self, newState, playRate): if not self.unexpectedExit: self.toon.setAnimState(newState, playRate) def createHeadFrame(self, drawNum): toon = base.cr.doId2do.get(self.avId, None) self.headFrame = RaceHeadFrame.RaceHeadFrame(av=toon) eyes = self.headFrame.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) self.headFrame.configure(geom_scale=(0.5, 0.5, 0.5)) self.headFrame.setZ(self.game.assetMgr.faceStartPos[2]) self.headFrame.setDepthWrite(True) self.headFrame.setDepthTest(True) self.headFrame.reparentTo(self.game.assetMgr.aspect2dRoot) self.headFrame.setY(-drawNum) if self.isLocal: self.headFrame.setScale(0.2) else: self.headFrame.setScale(0.15) self.headFrame.setX(self.game.assetMgr.faceStartPos[0]) return def update(self): toonCurrX = self.toon.getX(render) progress = toonCurrX - self.game.gameStartX headFrameProgress = progress * self.conversionRatio headFrameX = self.game.assetMgr.faceStartPos[0] + headFrameProgress headFrameX = max(self.game.assetMgr.faceStartPos[0], headFrameX) headFrameX = min(self.game.assetMgr.faceEndPos[0], headFrameX) self.headFrame.setX(headFrameX) def showScoreText(self, number, scale = 1.25): if not number == 0: if self.scoreText: self.hideScoreText() self.ScoreTextGenerator.setFont(OTPGlobals.getSignFont()) if number < 0: self.ScoreTextGenerator.setText(str(number)) else: self.ScoreTextGenerator.setText('+' + str(number)) self.ScoreTextGenerator.clearShadow() self.ScoreTextGenerator.setAlign(TextNode.ACenter) if number < 0: r, g, b, a = (0.9, 0, 0, 1) else: r, g, b, a = (0.9, 0.9, 0, 1) self.scoreTextNode = self.ScoreTextGenerator.generate() self.scoreText = self.toon.attachNewNode(self.scoreTextNode) self.scoreText.setScale(scale) self.scoreText.setBillboardPointEye() self.scoreText.setBin('fixed', 100) self.scoreText.setPos(0, 0, self.toon.height / 2) self.scoreText.setTransparency(1) self.scoreText.setColor(r, g, b, a) self.scoreText.setDepthTest(0) self.scoreText.setDepthWrite(0) seq = Sequence(self.scoreText.posInterval(0.5, Point3(0, 0, self.toon.height + 2), blendType='easeOut'), self.scoreText.colorInterval(0.25, Vec4(r, g, b, 0)), Func(self.hideScoreText)) seq.start() def hideScoreText(self): if self.scoreText: taskMgr.remove(self.game.uniqueName('scoreText')) self.scoreText.removeNode() self.scoreText = None return