toontown-just-works/toontown/cogdominium/DistCogdoMazeGameAI.py
2024-07-07 18:08:39 -05:00

239 lines
8.6 KiB
Python

from direct.directnotify import DirectNotifyGlobal
from toontown.cogdominium.DistCogdoGameAI import DistCogdoGameAI
import CogdoMazeGameGlobals
from direct.distributed.ClockDelta import *
from direct.task import Timer
from toontown.battle import BattleBase
from toontown.building.ElevatorConstants import *
ALL_ABOARD_LAG = 3.7
BASE_TOON_UP = 10
JOKE_TOON_UP = 5
class DistCogdoMazeGameAI(DistCogdoGameAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistCogdoMazeGameAI")
delayIntro = BattleBase.ELEVATOR_T + ElevatorData[ELEVATOR_FIELD]['openTime']
def __init__(self, air):
DistCogdoGameAI.__init__(self, air)
self.numSuits = (0,0,0)
self.timer = Timer.Timer()
self.doorRevealed = False
self.toonsInDoor = []
self.bosses = {}
self.fastMinions = {}
self.slowMinions = {}
self.suitTypes = [self.bosses, self.fastMinions, self.slowMinions]
self.numJokes = {}
def announceGenerate(self):
DistCogdoGameAI.announceGenerate(self)
self.setupSuitsAI()
def setupSuitsAI(self):
bossHp = CogdoMazeGameGlobals.SuitData[0]['hp']
fastMiniHp = CogdoMazeGameGlobals.SuitData[1]['hp']
slowMiniHp = CogdoMazeGameGlobals.SuitData[2]['hp']
serialNum = 0
for i in xrange(self.numSuits[0]):
self.bosses[serialNum] = bossHp
serialNum += 1
for i in xrange(self.numSuits[1]):
self.fastMinions[serialNum] = fastMiniHp
serialNum += 1
for i in xrange(self.numSuits[2]):
self.slowMinions[serialNum] = slowMiniHp
serialNum += 1
def setNumSuits(self, num):
self.numSuits = num
def getNumSuits(self):
return self.numSuits
def requestUseGag(self, x, y, h, timestamp):
avId = self.air.getAvatarIdFromSender()
self.sendUpdate('toonUsedGag', [avId, x, y, h, globalClockDelta.getRealNetworkTime()])
def requestSuitHitByGag(self, suitType, suitNum):
hitAI = self.hitSuitAI(suitType, suitNum)
if not hitAI:
self.notify.warning('Cannot hit suit!')
return
avId = self.air.getAvatarIdFromSender()
self.sendUpdate('suitHitByGag', [avId, suitType, suitNum])
def requestHitBySuit(self, suitType, suitNum, nettime):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
lostHp = CogdoMazeGameGlobals.SuitData[suitType]['toonDamage'] * self.getDifficulty() * 10
av.takeDamage(lostHp)
networkTime = globalClockDelta.getRealNetworkTime()
self.sendUpdate('toonHitBySuit', [avId, suitType, suitNum, networkTime])
if av.getHp() < 1:
self.toonWentSad(avId)
def requestHitByDrop(self):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
lostHp = CogdoMazeGameGlobals.DropDamage
av.takeDamage(lostHp)
self.sendUpdate('toonHitByDrop', [avId])
def requestPickUp(self, pickupNum):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
now = globalClockDelta.getRealNetworkTime()
if avId in self.numJokes:
self.numJokes[avId] += 1
else:
self.numJokes[avId] = 1
self.sendUpdate('pickUp', [avId, pickupNum, now])
def requestGag(self, coolerIndex):
avId = self.air.getAvatarIdFromSender()
self.sendUpdate('hasGag', [avId, globalClockDelta.getRealNetworkTime()])
def hitSuitAI(self, suitType, suitNum):
cogKey = None
for cogNum in self.suitTypes[suitType].keys():
if cogNum == suitNum:
cogKey = cogNum
break
if cogKey == None:
return 0
cogHp = self.suitTypes[suitType][cogKey]
cogHp -= 1
self.suitTypes[suitType][cogKey] = cogHp
if cogHp <= 0:
del self.suitTypes[suitType][cogKey]
return 1
def handleStart(self):
taskMgr.add(self.__checkGameDone, self.taskName('check-game-done'))
taskMgr.add(self.__checkPlayersTask, self.taskName('check-players-task'))
serverDelay = 1.0
self.timer.startCallback(CogdoMazeGameGlobals.SecondsUntilTimeout + serverDelay, self.__handleGameOver)
taskMgr.doMethodLater(serverDelay, self.clientCountdown, self.taskName('client_countdown'))
taskMgr.add(self.__timeWarningTask, self.taskName('time-warning-task'))
def clientCountdown(self, task):
self.doAction(CogdoMazeGameGlobals.GameActions.Countdown, 0)
return task.done
def __handleGameOver(self):
self.removeAll()
self.gameDone(failed=True)
def __checkGameDone(self, task):
bossesLeft = self.bosses
if len(bossesLeft) == 0:
self.timer.stop()
self.doAction(CogdoMazeGameGlobals.GameActions.OpenDoor, 0)
self.__startTimeout()
return task.done
return task.again
def __startTimeout(self):
self.timer.startCallback(CogdoMazeGameGlobals.SecondsUntilGameEnds, self.__handleTimeout)
def __handleTimeout(self):
for toon in self.toons:
if not toon in self.toonsInDoor:
self.killToon(toon)
self.removeAll()
self.gameDone()
def __timeWarningTask(self, task):
if self.timer.getT() <= CogdoMazeGameGlobals.SecondsForTimeAlert:
self.doAction(CogdoMazeGameGlobals.GameActions.TimeAlert, 0)
return task.done
return task.again
def killToon(self, avId):
av = self.air.doId2do.get(avId)
if av:
if av.getHp() > 0:
av.takeDamage(av.getHp())
self.toonWentSad(avId)
self.__playerDisconnected(avId)
def __checkPlayersTask(self, task):
for toonId in self.toons:
toon = self.air.doId2do.get(toonId)
if not toon:
self.__playerDisconnected(toonId)
return task.again
def __playerDisconnected(self, avId):
self.sendUpdate('setToonDisconnect', [avId])
self.toons.pop(self.toons.index(avId))
if len(self.toons) == 0:
self.removeAll()
self.gameDone(failed=True)
def doAction(self, action, data):
self.sendUpdate('doAction', [action, data, globalClockDelta.getRealNetworkTime()])
def requestAction(self, action, data):
Globals = CogdoMazeGameGlobals
avId = self.air.getAvatarIdFromSender()
if action == Globals.GameActions.RevealDoor:
if not self.doorRevealed:
self.doAction(action, avId)
self.doorRevealed = True
else:
self.notify.warning('Toon tried to reveal door but it\'s already revealed! Ignoring.')
elif action == Globals.GameActions.EnterDoor:
if not avId in self.toonsInDoor:
self.doAction(action, avId)
self.toonsInDoor.append(avId)
self.toonUpToon(avId)
else:
self.notify.warning('Toon tried to enter into door but already entered! Ignoring.')
return
if len(self.toonsInDoor) >= len(self.toons):
self.__handleAllAboard()
else:
self.notify.warning('Client requested unknown action \'%s\'' %action)
def __handleAllAboard(self):
if len(self.toonsInDoor) != len(self.toons):
self.notify.warning('__handleAllAboard expect all toons aboard!')
return
self.removeAll()
taskMgr.doMethodLater(ALL_ABOARD_LAG, lambda t: self.gameDone(), self.taskName('all-aboard-delay'))
def toonUpToon(self, toonId):
if toonId in self.toonsInDoor:
toon = self.air.doId2do.get(toonId)
if toon:
val = min(BASE_TOON_UP + JOKE_TOON_UP * self.numJokes.get(toonId, 0), toon.getMaxHp())
toon.toonUp(val)
def removeAll(self):
taskMgr.remove(self.taskName('check-game-done'))
taskMgr.remove(self.taskName('check-players-task'))
taskMgr.remove(self.taskName('time-warning-task'))
taskMgr.remove(self.taskName('all-aboard-delay'))
self.timer.stop()
def disable(self):
DistCogdoGameAI.disable(self)
self.removeAll()
from otp.ai.MagicWordGlobal import *
@magicWord(category=CATEGORY_PROGRAMMER)
def endMaze():
if hasattr(simbase.air, 'cogdoGame'):
maze = simbase.air.cogdoGame
maze.doAction(CogdoMazeGameGlobals.GameActions.OpenDoor, 0)
return 'Finished cogdo maze game!'