Poodletooth-iLand/toontown/suit/SuitInvasionManagerAI.py

227 lines
8 KiB
Python

import time, random
from toontown.battle import SuitBattleGlobals
from toontown.suit import SuitDNA
from toontown.suit.SuitInvasionGlobals import *
from toontown.toonbase import ToontownGlobals
class SuitInvasionManagerAI:
def __init__(self, air):
self.air = air
self.invading = False
self.start = 0
self.remaining = 0
self.total = 0
self.suitDeptIndex = None
self.suitTypeIndex = None
self.flags = 0
self.air.accept(
'startInvasion', self.handleStartInvasion)
self.air.accept(
'stopInvasion', self.handleStopInvasion)
# We want to handle shard status queries so that a ShardStatusReceiver
# being created after we're created will know where we're at:
self.air.accept('queryShardStatus', self.sendInvasionStatus)
self.sendInvasionStatus()
def getInvading(self):
return self.invading
def getInvadingCog(self):
return (self.suitDeptIndex, self.suitTypeIndex, self.flags)
def startInvasion(self, suitDeptIndex=None, suitTypeIndex=None, flags=0,
type=INVASION_TYPE_NORMAL):
if self.invading:
# An invasion is currently in progress; ignore this request.
return False
if (suitDeptIndex is None) and (suitTypeIndex is None) and (not flags):
# This invasion is no-op.
return False
if (suitDeptIndex is None) and (suitTypeIndex is not None):
# It's impossible to determine the invading Cog.
return False
if flags not in (0, IFV2, IFSkelecog, IFWaiter):
# The provided flag combination is not possible.
return False
if (suitDeptIndex is not None) and (suitDeptIndex >= len(SuitDNA.suitDepts)):
# Invalid suit department.
return False
if (suitTypeIndex is not None) and (suitTypeIndex >= SuitDNA.suitsPerDept):
# Invalid suit type.
return False
if type not in (INVASION_TYPE_NORMAL, INVASION_TYPE_MEGA, INVASION_TYPE_BRUTAL):
# Invalid invasion type.
return False
# Looks like we're all good. Begin the invasion:
self.invading = True
self.start = int(time.time())
self.suitDeptIndex = suitDeptIndex
self.suitTypeIndex = suitTypeIndex
self.flags = flags
# How many suits do we want?
if type == INVASION_TYPE_NORMAL:
self.total = random.randint(1000, 3000)
elif type == INVASION_TYPE_MEGA:
self.total = 5000
elif type == INVASION_TYPE_BRUTAL:
self.total = 10000
self.remaining = self.total
self.flySuits()
self.notifyInvasionStarted()
# Update the invasion tracker on the districts page in the Shticker Book:
if self.suitDeptIndex is not None:
self.air.districtStats.b_setInvasionStatus(self.suitDeptIndex + 1)
else:
self.air.districtStats.b_setInvasionStatus(5)
# If this is a normal invasion, and the players take too long to defeat
# all of the Cogs, we'll want the invasion to timeout:
if type == INVASION_TYPE_NORMAL:
timeout = config.GetInt('invasion-timeout', 1800)
taskMgr.doMethodLater(timeout, self.stopInvasion, 'invasionTimeout')
# If this is a mega invasion, and the players take to long to defeat
# all of the cogs, we want the invasion to take a bit longer to timeout:
if type == INVASION_TYPE_MEGA:
timeout = config.GetInt('invasion-timeout', 3200)
# If this is a brutal invasion, the players will have a very long time to
# Defeat the cogs before the invasion times out:
if type == INVASION_TYPE_BRUTAL:
timeout = config.GetInt('invasion-timeout', 10000)
self.sendInvasionStatus()
return True
def stopInvasion(self, task=None):
if not self.invading:
# We are not currently invading.
return False
# Stop the invasion timeout task:
taskMgr.remove('invasionTimeout')
# Update the invasion tracker on the districts page in the Shticker Book:
self.air.districtStats.b_setInvasionStatus(0)
# Revert what was done when the invasion started:
self.notifyInvasionEnded()
self.invading = False
self.start = 0
self.suitDeptIndex = None
self.suitTypeIndex = None
self.flags = 0
self.total = 0
self.remaining = 0
self.flySuits()
self.sendInvasionStatus()
return True
def getSuitName(self):
if self.suitDeptIndex is not None:
if self.suitTypeIndex is not None:
return SuitDNA.getSuitName(self.suitDeptIndex, self.suitTypeIndex)
else:
return SuitDNA.suitDepts[self.suitDeptIndex]
else:
return SuitDNA.suitHeadTypes[0]
def notifyInvasionStarted(self):
msgType = ToontownGlobals.SuitInvasionBegin
if self.flags & IFSkelecog:
msgType = ToontownGlobals.SkelecogInvasionBegin
elif self.flags & IFWaiter:
msgType = ToontownGlobals.WaiterInvasionBegin
elif self.flags & IFV2:
msgType = ToontownGlobals.V2InvasionBegin
self.air.newsManager.sendUpdate(
'setInvasionStatus',
[msgType, self.getSuitName(), self.total, self.flags])
def notifyInvasionEnded(self):
msgType = ToontownGlobals.SuitInvasionEnd
if self.flags & IFSkelecog:
msgType = ToontownGlobals.SkelecogInvasionEnd
elif self.flags & IFWaiter:
msgType = ToontownGlobals.WaiterInvasionEnd
elif self.flags & IFV2:
msgType = ToontownGlobals.V2InvasionEnd
self.air.newsManager.sendUpdate(
'setInvasionStatus', [msgType, self.getSuitName(), 0, self.flags])
def notifyInvasionUpdate(self):
self.air.newsManager.sendUpdate(
'setInvasionStatus',
[ToontownGlobals.SuitInvasionUpdate, self.getSuitName(),
self.remaining, self.flags])
def notifyInvasionBulletin(self, avId):
msgType = ToontownGlobals.SuitInvasionBulletin
if self.flags & IFSkelecog:
msgType = ToontownGlobals.SkelecogInvasionBulletin
elif self.flags & IFWaiter:
msgType = ToontownGlobals.WaiterInvasionBulletin
elif self.flags & IFV2:
msgType = ToontownGlobals.V2InvasionBulletin
self.air.newsManager.sendUpdateToAvatarId(
avId, 'setInvasionStatus',
[msgType, self.getSuitName(), self.remaining, self.flags])
def flySuits(self):
for suitPlanner in self.air.suitPlanners.values():
suitPlanner.flySuits()
def handleSuitDefeated(self):
self.remaining -= 1
if self.remaining == 0:
self.stopInvasion()
elif self.remaining == (self.total/2):
self.notifyInvasionUpdate()
self.sendInvasionStatus()
def handleStartInvasion(self, shardId, *args):
if shardId == self.air.ourChannel:
self.startInvasion(*args)
def handleStopInvasion(self, shardId):
if shardId == self.air.ourChannel:
self.stopInvasion()
def sendInvasionStatus(self):
if self.invading:
if self.suitDeptIndex is not None:
if self.suitTypeIndex is not None:
type = SuitBattleGlobals.SuitAttributes[self.getSuitName()]['name']
else:
type = SuitDNA.getDeptFullname(self.getSuitName())
else:
type = None
status = {
'invasion': {
'type': type,
'flags': self.flags,
'remaining': self.remaining,
'total': self.total,
'start': self.start
}
}
else:
status = {'invasion': None}
self.air.sendNetEvent('shardStatus', [self.air.ourChannel, status])