oldschool-toontown/toontown/cogdominium/CogdoFlyingGame.py
2019-12-30 01:07:56 -05:00

469 lines
20 KiB
Python

from direct.showbase.DirectObject import DirectObject
from direct.task.Task import Task
from direct.showbase.RandomNumGen import RandomNumGen
from direct.interval.FunctionInterval import Wait
from direct.interval.IntervalGlobal import Func
from direct.interval.MetaInterval import Sequence, Parallel
from toontown.toonbase import TTLocalizer
from . import CogdoFlyingGameGlobals as Globals
from .CogdoFlyingLocalPlayer import CogdoFlyingLocalPlayer
from .CogdoGameAudioManager import CogdoGameAudioManager
from .CogdoFlyingPlayer import CogdoFlyingPlayer
from .CogdoFlyingObjects import CogdoFlyingGatherable
from .CogdoFlyingObstacles import CogdoFlyingObstacle
from .CogdoFlyingLegalEagle import CogdoFlyingLegalEagle
from .CogdoFlyingGuiManager import CogdoFlyingGuiManager
from .CogdoFlyingLevel import CogdoFlyingLevelFactory
from .CogdoFlyingGameMovies import CogdoFlyingGameIntro, CogdoFlyingGameFinish
class CogdoFlyingGame(DirectObject):
notify = directNotify.newCategory('CogdoFlyingGame')
UpdateTaskName = 'CogdoFlyingGameUpdate'
FirstPressOfCtrlTaskName = 'FirstPressOfCtrlTask'
def __init__(self, distGame):
self.distGame = distGame
self.toonId2Player = {}
self.players = []
self.index2LegalEagle = {}
self.legalEagles = []
self.isGameComplete = False
self._hints = {'targettedByEagle': False,
'invulnerable': False}
def _initLegalEagles(self):
nestIndex = 1
nests = self.level.root.findAllMatches('**/%s;+s' % Globals.Level.LegalEagleNestName)
for nest in nests:
legalEagle = CogdoFlyingLegalEagle(nest, nestIndex)
self.legalEagles.append(legalEagle)
self.index2LegalEagle[nestIndex] = legalEagle
nestIndex += 1
def initPlayers(self):
for toonId in self.distGame.getToonIds():
toon = self.distGame.getToon(toonId)
i = self.distGame.getToonIds().index(toon.doId)
if toon is not None:
if toon.isLocal():
player = CogdoFlyingLocalPlayer(toon, self, self.level, self.guiMgr)
self.localPlayer = player
self.localPlayer.setPlayerNumber(i)
else:
player = CogdoFlyingPlayer(toon)
player.enable()
self._addPlayer(player)
self.guiMgr.addToonToProgressMeter(toon)
return
def placeEntranceElevator(self, elevator):
loc = self.level.startPlatform._model.find('**/door_loc')
offset = loc.getPos(render)
elevator.setPos(render, offset)
def load(self):
self.accept(self.distGame.getRemoteActionEventName(), self.handleRemoteAction)
self.audioMgr = CogdoGameAudioManager(Globals.Audio.MusicFiles, Globals.Audio.SfxFiles, base.localAvatar, cutoff=Globals.Audio.Cutoff)
factory = CogdoFlyingLevelFactory(render, Globals.Level.QuadLengthUnits, Globals.Level.QuadVisibilityAhead, Globals.Level.QuadVisibilityBehind, rng=RandomNumGen(self.distGame.doId))
self.level = factory.createLevel(self.distGame.getSafezoneId())
self.level.setCamera(camera)
self.guiMgr = CogdoFlyingGuiManager(self.level)
self.levelFog = factory.createLevelFog()
self._initLegalEagles()
def unload(self):
self.guiMgr.destroy()
del self.guiMgr
self.__stopUpdateTask()
for player in self.players:
player.unload()
del self.players[:]
self.toonId2Player.clear()
del self.localPlayer
for eagle in self.legalEagles:
eagle.destroy()
del self.legalEagles[:]
self.index2LegalEagle.clear()
self.levelFog.destroy()
del self.levelFog
self.level.destroy()
del self.level
self.audioMgr.destroy()
del self.audioMgr
self.ignoreAll()
del self.distGame
def onstage(self):
self.level.onstage()
self.levelFog.setVisible(True)
for eagle in self.legalEagles:
eagle.onstage()
self.localPlayer.request('Inactive')
def offstage(self):
self.__stopUpdateTask()
for eagle in self.legalEagles:
eagle.offstage()
self.level.offstage()
self.levelFog.setVisible(False)
def startIntro(self):
self._movie = CogdoFlyingGameIntro(self.level, RandomNumGen(self.distGame.doId))
self._movie.load()
self._movie.play()
self.audioMgr.playMusic('normal')
def endIntro(self):
self._movie.end()
self._movie.unload()
del self._movie
self.localPlayer.ready()
self.level.update(0.0)
def startFinish(self):
self._movie = CogdoFlyingGameFinish(self.level, self.players)
self._movie.load()
self._movie.play()
self.audioMgr.playMusic('end')
def endFinish(self):
self._movie.end()
self._movie.unload()
del self._movie
self.audioMgr.stopMusic()
def start(self):
self.level.start(self.distGame.getStartTime())
self.accept(CogdoFlyingObstacle.EnterEventName, self.handleLocalToonEnterObstacle)
self.accept(CogdoFlyingObstacle.ExitEventName, self.handleLocalToonExitObstacle)
self.accept(CogdoFlyingGatherable.EnterEventName, self.handleLocalToonEnterGatherable)
self.accept(CogdoFlyingLegalEagle.RequestAddTargetEventName, self.handleLocalToonEnterLegalEagleInterest)
self.accept(CogdoFlyingLegalEagle.RequestAddTargetAgainEventName, self.handleLocalToonAgainLegalEagleInterest)
self.accept(CogdoFlyingLegalEagle.RequestRemoveTargetEventName, self.handleLocalToonExitLegalEagleInterest)
self.accept(CogdoFlyingLegalEagle.EnterLegalEagle, self.handleLocalToonEnterLegalEagle)
self.accept(CogdoFlyingLegalEagle.ChargingToAttackEventName, self.handlePlayerBackpackAttacked)
self.accept(CogdoFlyingLegalEagle.LockOnToonEventName, self.handlePlayerBackpackTargeted)
self.accept(CogdoFlyingLegalEagle.CooldownEventName, self.handlePlayerBackpackNormal)
self.accept(CogdoFlyingGuiManager.EagleTargetingLocalPlayerEventName, self.handleLocalPlayerTargetedByEagle)
self.accept(CogdoFlyingGuiManager.EagleAttackingLocalPlayerEventName, self.handleLocalPlayerAttackedByEagle)
self.accept(CogdoFlyingGuiManager.ClearMessageDisplayEventName, self.handleClearGuiMessage)
self.accept(CogdoFlyingGuiManager.InvulnerableEventName, self.handleLocalPlayerInvulnerable)
self.acceptOnce(CogdoFlyingGuiManager.FirstPressOfCtrlEventName, self.handleLocalPlayerFirstPressOfCtrl)
self.acceptOnce(CogdoFlyingGuiManager.PickedUpFirstPropellerEventName, self.handleLocalPlayerPickedUpFirstPropeller)
self.acceptOnce(CogdoFlyingGuiManager.StartRunningOutOfTimeMusicEventName, self.handleTimeRunningOut)
self.acceptOnce(CogdoFlyingLocalPlayer.PlayWaitingMusicEventName, self.handlePlayWaitingMusic)
self.acceptOnce(CogdoFlyingLocalPlayer.RanOutOfTimeEventName, self.handleLocalPlayerRanOutOfTime)
self.__startUpdateTask()
self.isGameComplete = False
if __debug__ and base.config.GetBool('schellgames-dev', True):
self.acceptOnce('end', self.guiMgr.forceTimerDone)
def toggleFog():
self.levelFog.setVisible(not self.levelFog.isVisible())
self.accept('home', toggleFog)
for eagle in self.legalEagles:
eagle.gameStart(self.distGame.getStartTime())
for player in self.players:
player.start()
self.guiMgr.onstage()
if not Globals.Dev.InfiniteTimeLimit:
self.guiMgr.startTimer(Globals.Gameplay.SecondsUntilGameOver, self._handleTimerExpired, keepHidden=True)
def exit(self):
self.ignore(CogdoFlyingObstacle.EnterEventName)
self.ignore(CogdoFlyingObstacle.ExitEventName)
self.ignore(CogdoFlyingGatherable.EnterEventName)
self.ignore(CogdoFlyingLegalEagle.ChargingToAttackEventName)
self.ignore(CogdoFlyingLegalEagle.LockOnToonEventName)
self.ignore(CogdoFlyingLegalEagle.CooldownEventName)
self.ignore(CogdoFlyingLocalPlayer.RanOutOfTimeEventName)
taskMgr.remove(CogdoFlyingGame.FirstPressOfCtrlTaskName)
self.__stopUpdateTask()
self.ignore(CogdoFlyingLegalEagle.EnterLegalEagle)
self.ignore(CogdoFlyingLegalEagle.RequestAddTargetEventName)
self.ignore(CogdoFlyingLegalEagle.RequestAddTargetAgainEventName)
self.ignore(CogdoFlyingLegalEagle.RequestRemoveTargetEventName)
self.ignore(CogdoFlyingLocalPlayer.PlayWaitingMusicEventName)
if __debug__ and base.config.GetBool('schellgames-dev', True):
self.ignore('end')
self.ignore('home')
self.level.update(0.0)
for eagle in self.legalEagles:
eagle.gameEnd()
for player in self.players:
player.exit()
self.guiMgr.offstage()
def _handleTimerExpired(self):
self.localPlayer.handleTimerExpired()
def _addPlayer(self, player):
self.players.append(player)
self.toonId2Player[player.toon.doId] = player
toon = player.toon
self.accept(toon.uniqueName('disable'), self._removePlayer, extraArgs=[toon.doId])
def _removePlayer(self, toonId):
if toonId in self.toonId2Player:
player = self.toonId2Player[toonId]
self.players.remove(player)
del self.toonId2Player[toonId]
self.guiMgr.removeToonFromProgressMeter(player.toon)
player.exit()
player.unload()
def setToonSad(self, toonId):
player = self.toonId2Player[toonId]
self.forceClearLegalEagleInterestInToon(toonId)
if player == self.localPlayer:
player.goSad()
self.exit()
else:
player.exit()
def setToonDisconnect(self, toonId):
player = self.toonId2Player[toonId]
self.forceClearLegalEagleInterestInToon(toonId)
if player == self.localPlayer:
self.exit()
else:
player.exit()
def handleRemoteAction(self, action, data):
if data != self.localPlayer.toon.doId:
if action == Globals.AI.GameActions.GotoWinState:
if self.localPlayer.state in ['WaitingForWin']:
self.localPlayer.request('Win')
def toonDied(self, toonId, elapsedTime):
player = self.toonId2Player[toonId]
if player is not None:
player.died(elapsedTime)
return
def toonSpawn(self, toonId, elapsedTime):
player = self.toonId2Player[toonId]
if player is not None:
player.spawn(elapsedTime)
return
def toonResetBlades(self, toonId):
player = self.toonId2Player[toonId]
if player is not None:
player.resetBlades()
return
def toonSetBlades(self, toonId, fuelState):
player = self.toonId2Player[toonId]
if player is not None:
player.setBlades(fuelState)
return
def toonBladeLost(self, toonId):
player = self.toonId2Player[toonId]
if player is not None:
player.bladeLost()
return
def handleLocalToonEnterGatherable(self, gatherable):
if gatherable.wasPickedUp():
return
if gatherable.isPowerUp() and gatherable.wasPickedUpByToon(self.localPlayer.toon):
return
if gatherable.type in [Globals.Level.GatherableTypes.LaffPowerup, Globals.Level.GatherableTypes.InvulPowerup]:
self.distGame.d_sendRequestPickup(gatherable.serialNum, gatherable.type)
elif gatherable.type == Globals.Level.GatherableTypes.Memo:
self.distGame.d_sendRequestPickup(gatherable.serialNum, gatherable.type)
gatherable.disable()
elif gatherable.type == Globals.Level.GatherableTypes.Propeller and self.localPlayer.fuel < 1.0:
self.distGame.d_sendRequestPickup(gatherable.serialNum, gatherable.type)
def pickUp(self, toonId, pickupNum, elapsedTime = 0.0):
self.notify.debugCall()
player = self.toonId2Player[toonId]
gatherable = self.level.getGatherable(pickupNum)
if gatherable is not None:
if not gatherable.isPowerUp() and not gatherable.wasPickedUp() or gatherable.isPowerUp() and not gatherable.wasPickedUpByToon(player.toon):
gatherable.pickUp(player.toon, elapsedTime)
player.handleEnterGatherable(gatherable, elapsedTime)
if gatherable.type in [Globals.Level.GatherableTypes.InvulPowerup]:
if player.toon.isLocal():
self.audioMgr.playMusic('invul')
else:
self.notify.warning('Trying to pickup gatherable nonetype:%s' % pickupNum)
return
def debuffPowerup(self, toonId, pickupType, elapsedTime):
self.notify.debugCall()
player = self.toonId2Player[toonId]
if player.isBuffActive(pickupType):
if pickupType in [Globals.Level.GatherableTypes.InvulPowerup]:
if self.guiMgr.isTimeRunningOut():
self.audioMgr.playMusic('timeRunningOut')
else:
self.audioMgr.playMusic('normal')
player.handleDebuffPowerup(pickupType, elapsedTime)
def handleLocalToonEnterLegalEagle(self, eagle, collEntry):
if not self.localPlayer.isEnemyHitting() and not self.localPlayer.isInvulnerable():
collPos = collEntry.getSurfacePoint(render)
self.localPlayer.handleEnterEnemyHit(eagle, collPos)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.HitLegalEagle, 0)
def handleLocalToonEnterObstacle(self, obstacle, collEntry):
if self.localPlayer.isInvulnerable():
return
if obstacle.type == Globals.Level.ObstacleTypes.Whirlwind:
self.localPlayer.handleEnterWhirlwind(obstacle)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.HitWhirlwind, 0)
if obstacle.type == Globals.Level.ObstacleTypes.Fan:
self.localPlayer.handleEnterFan(obstacle)
if obstacle.type == Globals.Level.ObstacleTypes.Minion:
if not self.localPlayer.isEnemyHitting():
collPos = collEntry.getSurfacePoint(render)
self.localPlayer.handleEnterEnemyHit(obstacle, collPos)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.HitMinion, 0)
def handleLocalToonExitObstacle(self, obstacle, collEntry):
if obstacle.type == Globals.Level.ObstacleTypes.Fan:
self.localPlayer.handleExitFan(obstacle)
def __startUpdateTask(self):
self.__stopUpdateTask()
taskMgr.add(self.__updateTask, CogdoFlyingGame.UpdateTaskName, 45)
def __stopUpdateTask(self):
taskMgr.remove(CogdoFlyingGame.UpdateTaskName)
def handleTimeRunningOut(self):
if self.localPlayer.state not in ['WaitingForWin']:
self.audioMgr.playMusic('timeRunningOut')
self.guiMgr.presentTimerGui()
self.guiMgr.setTemporaryMessage(TTLocalizer.CogdoFlyingGameTimeIsRunningOut)
def handlePlayWaitingMusic(self):
self.audioMgr.playMusic('waiting')
def handleLocalPlayerFirstPressOfCtrl(self):
self.doMethodLater(3.0, self.guiMgr.setMessage, CogdoFlyingGame.FirstPressOfCtrlTaskName, extraArgs=[''])
def handleLocalPlayerRanOutOfTime(self):
self.guiMgr.setMemoCount(0)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.RanOutOfTimePenalty, 0)
self.guiMgr.setMessage(TTLocalizer.CogdoFlyingGameTakingMemos)
def handleClearGuiMessage(self):
if not self.localPlayer.isInvulnerable():
self.guiMgr.setMessage('')
def handleLocalPlayerInvulnerable(self):
if not self._hints['invulnerable']:
self.guiMgr.setMessage(TTLocalizer.CogdoFlyingGameYouAreInvincible)
self._hints['invulnerable'] = True
def handleLocalPlayerPickedUpFirstPropeller(self):
self.guiMgr.setMessage(TTLocalizer.CogdoFlyingGamePressCtrlToFly)
self.guiMgr.presentRefuelGui()
def handleLocalPlayerTargetedByEagle(self):
if not self.localPlayer.isInvulnerable() and not self._hints['targettedByEagle']:
self.guiMgr.setMessage(TTLocalizer.CogdoFlyingGameLegalEagleTargeting)
self._hints['targettedByEagle'] = True
def handleLocalPlayerAttackedByEagle(self):
if not self.localPlayer.isInvulnerable():
self.guiMgr.setMessage(TTLocalizer.CogdoFlyingGameLegalEagleAttacking)
def handlePlayerBackpackAttacked(self, toonId):
if toonId in self.toonId2Player:
player = self.toonId2Player[toonId]
player.setBackpackState(Globals.Gameplay.BackpackStates.Attacked)
def handlePlayerBackpackTargeted(self, toonId):
if toonId in self.toonId2Player:
player = self.toonId2Player[toonId]
player.setBackpackState(Globals.Gameplay.BackpackStates.Targeted)
def handlePlayerBackpackNormal(self, toonId):
if toonId in self.toonId2Player:
player = self.toonId2Player[toonId]
player.setBackpackState(Globals.Gameplay.BackpackStates.Normal)
def handleLocalToonEnterLegalEagleInterest(self, index):
if index in self.index2LegalEagle:
legalEagle = self.index2LegalEagle[index]
if not self.localPlayer.isLegalEagleInterestRequestSent(index) and not self.localPlayer.isLegalEagleTarget():
if self.localPlayer.state in ['WaitingForWin', 'Win']:
return
self.localPlayer.setLegalEagleInterestRequest(index)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.RequestEnterEagleInterest, index)
else:
self.notify.warning("Legal eagle %i isn't in index2LegalEagle dict" % index)
def handleLocalToonAgainLegalEagleInterest(self, index):
self.handleLocalToonEnterLegalEagleInterest(index)
def handleLocalToonExitLegalEagleInterest(self, index):
if index in self.index2LegalEagle:
legalEagle = self.index2LegalEagle[index]
if self.localPlayer.isLegalEagleInterestRequestSent(index):
self.localPlayer.clearLegalEagleInterestRequest(index)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.RequestExitEagleInterest, index)
else:
self.notify.warning("Legal eagle %i isn't in index2LegalEagle dict" % index)
def forceClearLegalEagleInterestInToon(self, toonId):
player = self.toonId2Player[toonId]
if player:
for legalEagle in self.legalEagles:
index = legalEagle.index
if player.toon.isLocal():
if self.localPlayer.isLegalEagleInterestRequestSent(index):
self.localPlayer.clearLegalEagleInterestRequest(index)
self.distGame.d_sendRequestAction(Globals.AI.GameActions.RequestExitEagleInterest, index)
self.toonClearAsEagleTarget(toonId, index, 0)
def toonSetAsEagleTarget(self, toonId, eagleId, elapsedTime):
if eagleId in self.index2LegalEagle:
legalEagle = self.index2LegalEagle[eagleId]
if toonId in self.toonId2Player:
player = self.toonId2Player[toonId]
player.setAsLegalEagleTarget(legalEagle)
legalEagle.setTarget(player.toon, elapsedTime)
def toonClearAsEagleTarget(self, toonId, eagleId, elapsedTime):
if eagleId in self.index2LegalEagle:
legalEagle = self.index2LegalEagle[eagleId]
if toonId in self.toonId2Player:
player = self.toonId2Player[toonId]
player.removeAsLegalEagleTarget(legalEagle)
if legalEagle.getTarget() == player.toon:
legalEagle.clearTarget(elapsedTime)
def eagleExitCooldown(self, eagleId, elapsedTime):
if eagleId in self.index2LegalEagle:
legalEagle = self.index2LegalEagle[eagleId]
legalEagle.leaveCooldown(elapsedTime)
def gameComplete(self):
self.localPlayer.request('Win')
def __updateTask(self, task):
dt = globalClock.getDt()
self.localPlayer.update(dt)
self.level.update(dt)
for eagle in self.legalEagles:
eagle.update(dt, self.localPlayer)
self.guiMgr.update()
return Task.cont