coghq: Bossbot HQ

This commit is contained in:
Anthony Castelli 2014-05-10 12:30:22 -07:00 committed by Aidan
parent 33d72c826c
commit f75d5465dc
10 changed files with 1363 additions and 99 deletions

View file

@ -9,7 +9,7 @@ from toontown.ai.FishManagerAI import FishManagerAI
from toontown.distributed.ToontownInternalRepository import ToontownInternalRepository
from toontown.toon import NPCToons
from toontown.hood import TTHoodAI, DDHoodAI, DGHoodAI, BRHoodAI, MMHoodAI, DLHoodAI, OZHoodAI, GSHoodAI, GZHoodAI, ZoneUtil
from toontown.hood import SellbotHQAI, CashbotHQAI, LawbotHQAI
from toontown.hood import SellbotHQAI, CashbotHQAI, LawbotHQAI, BossbotHQAI
from toontown.toonbase import ToontownGlobals
from direct.distributed.PyDatagram import *
from otp.ai.AIZoneData import *
@ -202,6 +202,8 @@ class ToontownAIRepository(ToontownInternalRepository):
clearQueue()
self.hoods.append(LawbotHQAI.LawbotHQAI(self))
clearQueue()
self.hoods.append(BossbotHQAI.BossbotHQAI(self))
clearQueue()
for sp in self.suitPlanners.values():
sp.assignInitialSuitBuildings()

View file

@ -1,6 +1,22 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.battle.DistributedBattleFinalAI import DistributedBattleFinalAI
from toontown.battle import DistributedBattleFinalAI
class DistributedBattleDinersAI(DistributedBattleFinalAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedBattleDinersAI")
class DistributedBattleDinersAI(DistributedBattleFinalAI.DistributedBattleFinalAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBattleDinersAI')
def __init__(self, air, bossCog, roundCallback, finishCallback, battleSide):
DistributedBattleFinalAI.DistributedBattleFinalAI.__init__(self, air, bossCog, roundCallback, finishCallback, battleSide)
def startBattle(self, toonIds, suits):
self.joinableFsm.request('Joinable')
for toonId in toonIds:
if self.addToon(toonId):
self.activeToons.append(toonId)
self.d_setMembers()
for suit in suits:
self.pendingSuits.append(suit)
self.d_setMembers()
self.needAdjust = 1
self.b_setState('ReservesJoining')

View file

@ -1,6 +1,23 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.battle.DistributedBattleFinalAI import DistributedBattleFinalAI
from toontown.battle import DistributedBattleFinalAI
class DistributedBattleWaitersAI(DistributedBattleFinalAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedBattleWaitersAI")
class DistributedBattleWaitersAI(DistributedBattleFinalAI.DistributedBattleFinalAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBattleWaitersAI')
def __init__(self, air, bossCog, roundCallback, finishCallback, battleSide):
DistributedBattleFinalAI.DistributedBattleFinalAI.__init__(self, air, bossCog, roundCallback, finishCallback, battleSide)
def startBattle(self, toonIds, suits):
self.joinableFsm.request('Joinable')
for toonId in toonIds:
if self.addToon(toonId):
self.activeToons.append(toonId)
self.d_setMembers()
for suit in suits:
self.pendingSuits.append(suit)
self.d_setMembers()
self.needAdjust = 1
self.b_setState('ReservesJoining')

View file

@ -1,6 +1,17 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.building.DistributedBossElevatorAI import DistributedBossElevatorAI
from ElevatorConstants import *
import DistributedBossElevatorAI
class DistributedBBElevatorAI(DistributedBossElevatorAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedBBElevatorAI")
class DistributedBBElevatorAI(DistributedBossElevatorAI.DistributedBossElevatorAI):
def __init__(self, air, bldg, zone, antiShuffle = 0, minLaff = 0):
DistributedBossElevatorAI.DistributedBossElevatorAI.__init__(self, air, bldg, zone, antiShuffle=antiShuffle, minLaff=0)
self.type = ELEVATOR_BB
self.countdownTime = ElevatorData[self.type]['countdown']
def checkBoard(self, av):
result = 0
if simbase.config.GetBool('allow-ceo-elevator', True):
result = DistributedBossElevatorAI.DistributedBossElevatorAI.checkBoard(self, av)
else:
result = REJECT_NOT_YET_AVAILABLE
return result

View file

@ -1,42 +1,243 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.distributed import DistributedObjectAI
from direct.directnotify import DirectNotifyGlobal
from toontown.coghq import BanquetTableBase
from toontown.toonbase import ToontownGlobals
from direct.fsm import FSM
import random
class DistributedBanquetTableAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedBanquetTableAI")
class DistributedBanquetTableAI(DistributedObjectAI.DistributedObjectAI, FSM.FSM, BanquetTableBase.BanquetTableBase):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBanquetTableAI')
def setIndex(self, todo0):
pass
def __init__(self, air, boss, index, numDiners, dinerLevel):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
FSM.FSM.__init__(self, 'DistributedBanquetTableAI')
self.boss = boss
self.index = index
self.numDiners = numDiners
self.numChairs = 8
self.dinerStatus = {}
self.dinerInfo = {}
for i in xrange(self.numDiners):
self.dinerStatus[i] = self.INACTIVE
diffSettings = ToontownGlobals.BossbotBossDifficultySettings[self.boss.battleDifficulty]
hungryDuration = diffSettings[4]
eatingDuration = diffSettings[5]
hungryDuration += random.uniform(-5, 5)
eatingDuration += random.uniform(-5, 5)
level = 12
if type(dinerLevel) == type(0):
level = dinerLevel
else:
level = random.choice(dinerLevel)
self.dinerInfo[i] = (hungryDuration, eatingDuration, level)
def setNumDiners(self, todo0):
pass
self.transitionTasks = {}
self.numFoodEaten = {}
self.avId = 0
def setBossCogId(self, todo0):
pass
def delete(self):
DistributedObjectAI.DistributedObjectAI.delete(self)
def setDinerInfo(self, todo0, todo1, todo2):
pass
def getBossCogId(self):
return self.boss.doId
def setState(self, todo0, todo1, todo2):
pass
def getIndex(self):
return self.index
def setDinerStatus(self, todo0, todo1):
pass
def getNumDiners(self):
return self.numDiners
def getDinerStatus(self, chairIndex):
retval = self.DEAD
if chairIndex in self.dinerStatus:
retval = self.dinerStatus[chairIndex]
return retval
def setDinerStatus(self, chairIndex, newStatus):
self.dinerStatus[chairIndex] = newStatus
def getDinerInfo(self):
hungryDurations = []
eatingDurations = []
dinerLevels = []
for i in xrange(self.numDiners):
hungryDurations.append(self.dinerInfo[i][0])
eatingDurations.append(self.dinerInfo[i][1])
dinerLevels.append(self.dinerInfo[i][2])
return (hungryDurations, eatingDurations, dinerLevels)
def d_setDinerStatus(self, chairIndex, newStatus):
self.sendUpdate('setDinerStatus', [chairIndex, newStatus])
def b_setDinerStatus(self, chairIndex, newStatus):
self.setDinerStatus(chairIndex, newStatus)
self.d_setDinerStatus(chairIndex, newStatus)
def setState(self, state):
self.request(state)
def d_setState(self, state, avId = 0, extraInfo = 0):
newState = state
if state == 'On':
newState = 'N'
elif state == 'Off':
newState = 'F'
elif state == 'Inactive':
newState = 'I'
elif state == 'Free':
newState = 'R'
elif state == 'Controlled':
newState = 'C'
elif state == 'Flat':
newState = 'L'
self.sendUpdate('setState', [newState, avId, extraInfo])
def b_setState(self, state, avId = 0, extraInfo = 0):
if state == 'Controlled' or state == 'Flat':
self.request(state, avId)
else:
self.request(state)
self.d_setState(state, avId, extraInfo)
def turnOn(self):
self.b_setState('On')
def turnOff(self):
self.b_setState('Off')
def foodServed(self, chairIndex):
self.b_setDinerStatus(chairIndex, self.EATING)
eatingDur = self.dinerInfo[chairIndex][1]
if chairIndex in self.transitionTasks:
self.removeTask(self.transitionTasks[chairIndex])
taskName = self.uniqueName('transition-%d' % chairIndex)
newTask = self.doMethodLater(eatingDur, self.finishedEating, taskName, extraArgs=[chairIndex])
self.transitionTasks[chairIndex] = newTask
def finishedEating(self, chairIndex):
if chairIndex in self.transitionTasks:
self.removeTask(self.transitionTasks[chairIndex])
self.incrementFoodEaten(chairIndex)
if self.numFoodEaten[chairIndex] >= ToontownGlobals.BossbotNumFoodToExplode:
self.b_setDinerStatus(chairIndex, self.DEAD)
self.boss.incrementDinersExploded()
else:
self.b_setDinerStatus(chairIndex, self.HUNGRY)
taskName = self.uniqueName('transition-%d' % chairIndex)
hungryDur = self.dinerInfo[chairIndex][0]
newTask = self.doMethodLater(hungryDur, self.finishedHungry, taskName, extraArgs=[chairIndex])
self.transitionTasks[chairIndex] = newTask
def incrementFoodEaten(self, chairIndex):
numFood = 0
if chairIndex in self.numFoodEaten:
numFood = self.numFoodEaten[chairIndex]
self.numFoodEaten[chairIndex] = numFood + 1
def finishedHungry(self, chairIndex):
self.b_setDinerStatus(chairIndex, self.ANGRY)
self.numFoodEaten[chairIndex] = 0
if chairIndex in self.transitionTasks:
self.removeTask(self.transitionTasks[chairIndex])
def goInactive(self):
self.b_setState('Inactive')
def goFree(self):
self.b_setState('Free')
def goFlat(self):
self.b_setState('Flat', self.avId)
def getNotDeadInfo(self):
notDeadList = []
for i in xrange(self.numDiners):
if self.dinerStatus[i] != self.DEAD:
notDeadList.append((self.index, i, self.dinerInfo[i][2]))
return notDeadList
def requestControl(self):
avId = self.air.getAvatarIdFromSender()
if avId in self.boss.involvedToons and self.avId == 0 and self.state == 'Free':
tableId = self.__getTableId(avId)
if tableId == 0:
grantRequest = True
if self.boss and not self.boss.isToonRoaming(avId):
grantRequest = False
if grantRequest:
self.b_setState('Controlled', avId)
def forceControl(self, avId):
self.notify.debug('forceContrl tableIndex=%d avId=%d' % (self.index, avId))
tableId = self.__getTableId(avId)
if tableId == self.doId:
if self.state == 'Flat':
self.b_setState('Controlled', avId)
else:
self.notify.warning('invalid forceControl from state %s' % self.state)
else:
self.notify.warning('tableId %d != self.doId %d ' % (tableId, self.doId))
def requestFree(self, gotHitByBoss):
avId = self.air.getAvatarIdFromSender()
if avId == self.avId:
if self.state == 'Controlled':
self.b_setState('Free', extraInfo=gotHitByBoss)
if self.boss:
self.boss.toonLeftTable(self.index)
else:
self.notify.debug('requestFree denied in state %s' % self.state)
def __getTableId(self, avId):
if self.boss and self.boss.tables != None:
for table in self.boss.tables:
if table.avId == avId:
return table.doId
return 0
def enterOn(self):
for i in xrange(self.numDiners):
self.b_setDinerStatus(i, self.HUNGRY)
def exitOn(slef):
pass
def requestFree(self, todo0):
def enterOff(self):
pass
def setPitcherPos(self, todo0, todo1, todo2):
def exitOff(self):
pass
def clearSmoothing(self, todo0):
def enterInactive(self):
for task in self.transitionTasks.values():
self.removeTask(task)
self.transitionTasks = {}
def exitInactive(self):
pass
def firingWater(self, todo0, todo1, todo2, todo3, todo4, todo5):
def enterFree(self):
self.notify.debug('enterFree tableIndex=%d' % self.index)
self.avId = 0
def exitFree(self):
pass
def waterHitBoss(self, todo0):
def enterControlled(self, avId):
self.notify.debug('enterControlled tableIndex=%d' % self.index)
self.avId = avId
def exitControlled(self):
pass
def enterFlat(self, avId):
self.notify.debug('enterFlat tableIndex=%d' % self.index)
def exitFlat(self):
pass

View file

@ -1,18 +1,60 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.building.DistributedElevatorExtAI import DistributedElevatorExtAI
from toontown.safezone import DistributedGolfKartAI
from toontown.building import DistributedElevatorExtAI
from toontown.building import ElevatorConstants
from toontown.toonbase import ToontownGlobals
class DistributedCogKartAI(DistributedElevatorExtAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCogKartAI")
class DistributedCogKartAI(DistributedElevatorExtAI.DistributedElevatorExtAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCogKartAI')
def setCountryClubId(self, todo0):
pass
def __init__(self, air, index, x, y, z, h, p, r, bldg, minLaff):
self.posHpr = (x, y, z, h, p, r)
DistributedElevatorExtAI.DistributedElevatorExtAI.__init__(self, air, bldg, minLaff=minLaff)
self.type = ElevatorConstants.ELEVATOR_COUNTRY_CLUB
self.courseIndex = index
if self.courseIndex == 0:
self.countryClubId = ToontownGlobals.BossbotCountryClubIntA
elif self.courseIndex == 1:
self.countryClubId = ToontownGlobals.BossbotCountryClubIntB
elif self.courseIndex == 2:
self.countryClubId = ToontownGlobals.BossbotCountryClubIntC
else:
self.countryClubId = 12500
def setPosHpr(self, todo0, todo1, todo2, todo3, todo4, todo5):
pass
def getPosHpr(self):
return self.posHpr
def setCountryClubInteriorZone(self, todo0):
pass
def elevatorClosed(self):
numPlayers = self.countFullSeats()
if numPlayers > 0:
players = []
for i in self.seats:
if i not in [None, 0]:
players.append(i)
def setCountryClubInteriorZoneForce(self, todo0):
pass
countryClubZone = self.bldg.createCountryClub(self.countryClubId, players)
for seatIndex in range(len(self.seats)):
avId = self.seats[seatIndex]
if avId:
self.sendUpdateToAvatarId(avId, 'setCountryClubInteriorZone', [countryClubZone])
self.clearFullNow(seatIndex)
else:
self.notify.warning('The elevator left, but was empty.')
self.fsm.request('closed')
return
def sendAvatarsToDestination(self, avIdList):
if len(avIdList) > 0:
countryClubZone = self.bldg.createCountryClub(self.countryClubId, avIdList)
for avId in avIdList:
if avId:
self.sendUpdateToAvatarId(avId, 'setCountryClubInteriorZoneForce', [countryClubZone])
def getCountryClubId(self):
return self.countryClubId
def enterClosed(self):
DistributedElevatorExtAI.DistributedElevatorExtAI.enterClosed(self)
self.fsm.request('opening')

View file

@ -1,33 +1,83 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.distributed import DistributedObjectAI
from direct.fsm import FSM
class DistributedGolfSpotAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedGolfSpotAI")
class DistributedGolfSpotAI(DistributedObjectAI.DistributedObjectAI, FSM.FSM):
def setIndex(self, todo0):
pass
def __init__(self, air, boss, index):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
FSM.FSM.__init__(self, 'DistributedGolfSpotAI')
self.boss = boss
self.index = index
self.avId = 0
self.allowControl = True
def setBossCogId(self, todo0):
pass
def delete(self):
DistributedObjectAI.DistributedObjectAI.delete(self)
def setState(self, todo0, todo1, todo2):
pass
def getBossCogId(self):
return self.boss.doId
def setGoingToReward(self):
pass
def getIndex(self):
return self.index
def d_setState(self, state, avId, extraInfo = 0):
self.sendUpdate('setState', [state, avId, extraInfo])
def requestControl(self):
if not self.allowControl:
return
avId = self.air.getAvatarIdFromSender()
if avId in self.boss.involvedToons and self.avId == 0 and self.state != 'Off':
golfSpotId = self.__getGolfSpotId(avId)
if golfSpotId == 0:
grantRequest = True
if self.boss and not self.boss.isToonRoaming(avId):
grantRequest = False
if grantRequest:
self.request('Controlled', avId)
def requestFree(self, gotHitByBoss):
avId = self.air.getAvatarIdFromSender()
if avId == self.avId and self.state == 'Controlled':
self.request('Free', gotHitByBoss)
def forceFree(self):
self.request('Free', 0)
def removeToon(self, avId):
if avId == self.avId:
self.request('Free')
def __getGolfSpotId(self, avId):
if self.boss and self.boss.golfSpots != None:
for golfSpot in self.boss.golfSpots:
if golfSpot.avId == avId:
return golfSpot.doId
return 0
def turnOff(self):
self.request('Off')
self.allowControl = False
def enterOff(self):
self.sendUpdate('setGoingToReward', [])
self.d_setState('O', 0)
def exitOff(self):
pass
def requestFree(self, todo0):
def enterControlled(self, avId):
self.avId = avId
self.d_setState('C', avId)
def exitControlled(self):
pass
def setGolfSpotPos(self, todo0, todo1, todo2):
pass
def clearSmoothing(self, todo0):
pass
def setSwingInfo(self, todo0, todo1, todo2):
def enterFree(self, gotHitByBoss):
self.avId = 0
self.d_setState('F', 0, gotHitByBoss)
def exitFree(self):
pass

View file

@ -0,0 +1,61 @@
from CogHoodAI import CogHoodAI
from toontown.toonbase import ToontownGlobals
from toontown.suit.DistributedBossbotBossAI import DistributedBossbotBossAI
from toontown.building.DistributedBBElevatorAI import DistributedBBElevatorAI
from toontown.coghq.DistributedCogHQDoorAI import DistributedCogHQDoorAI
from toontown.coghq import DistributedCogKartAI
from toontown.building import DoorTypes
from toontown.building import FADoorCodes
class BossbotHQAI(CogHoodAI):
HOOD = ToontownGlobals.BossbotHQ
def __init__(self, air):
CogHoodAI.__init__(self, air)
self.createZone()
def createDoor(self):
interiorDoor = DistributedCogHQDoorAI(self.air, 0, DoorTypes.INT_COGHQ, self.HOOD, doorIndex=0)
exteriorDoor = DistributedCogHQDoorAI(self.air, 0, DoorTypes.EXT_COGHQ, ToontownGlobals.BossbotLobby, doorIndex=0, lockValue=FADoorCodes.CB_DISGUISE_INCOMPLETE)
exteriorDoor.setOtherDoor(interiorDoor)
exteriorDoor.zoneId = self.HOOD
exteriorDoor.generateWithRequired(self.HOOD)
exteriorDoor.sendUpdate('setDoorIndex', [0])
self.doors.append(exteriorDoor)
interiorDoor.setOtherDoor(exteriorDoor)
interiorDoor.zoneId = ToontownGlobals.BossbotLobby
interiorDoor.generateWithRequired(ToontownGlobals.BossbotLobby)
interiorDoor.sendUpdate('setDoorIndex', [0])
self.doors.append(interiorDoor)
def createZone(self):
CogHoodAI.createZone(self)
# Create lobby manager...
self.createLobbyManager(DistributedBossbotBossAI, ToontownGlobals.BossbotLobby)
# Create CEO elevator.
self.ceoElevator = self.createElevator(DistributedBBElevatorAI, self.lobbyMgr, ToontownGlobals.BossbotLobby, ToontownGlobals.BossbotLobby, boss=True)
# Make our doors.
self.createDoor()
# Create Cog Golf Courses.
# kartPos = ((154.762, 37.169, 0), (141.403, -81.887, 0), (-48.44, 15.308, 0))
# hprList = ((110.815, 0, 0), (61.231, 0, 0), (-105.481, 0, 0))
# mins = ToontownGlobals.FactoryLaffMinimums[3]
# self.frontThree = self.createKart(DistributedCogKartAI, self.air.mintMgr, self.HOOD, ToontownGlobals.BossbotCountryClubIntA, 0, minLaff=mins[0])
# self.middleSix = self.createKart(DistributedCogKartAI, self.air.mintMgr, self.HOOD, ToontownGlobals.BossbotCountryClubIntB, 1, minLaff=mins[1])
# self.backNine = self.createKart(DistributedCogKartAI, self.air.mintMgr, self.HOOD, ToontownGlobals.BossbotCountryClubIntC, 2, minLaff=mins[2])
# Enable boarding groups
if simbase.config.GetBool('want-boarding-groups', True):
# CEO Boarding Group
self.createBoardingGroup(self.air, [self.ceoElevator.doId], ToontownGlobals.BossbotLobby, 8)
# Cog Golf Boarding Group's
# self.cogGolfCources = [self.frontThree.doId, self.middleSix.doId, self.backNine.doId]
# self.createBoardingGroup(self.air, self.cogGolfCources, ToontownGlobals.BossbotHQ)

View file

@ -2,6 +2,7 @@ from toontown.toonbase import ToontownGlobals
from HoodAI import HoodAI
from toontown.suit.DistributedSuitPlannerAI import DistributedSuitPlannerAI
from toontown.coghq.DistributedCogHQDoorAI import DistributedCogHQDoorAI
from toontown.coghq import DistributedCogKartAI
from toontown.coghq.LobbyManagerAI import LobbyManagerAI
from toontown.building import DistributedBoardingPartyAI
@ -19,9 +20,9 @@ class CogHoodAI(HoodAI):
HoodAI.__init__(self, air)
self.doors = []
self.elevators = []
self.karts = []
self.suitPlanners = []
self.lobbyMgr = None
# TODO: Boarding groups.
def createElevator(self, dclass, mgr, extZone, intZone, index=0, minLaff=0, boss=False):
if boss:
@ -32,6 +33,12 @@ class CogHoodAI(HoodAI):
self.elevators.append(elevator)
return elevator
def createKart(self, dclass, mgr, extZone, intZone, index=0, minLaff=0, boss=False):
kart = dclass(self.air, mgr, intZone, index, antiShuffle=self.air.config.GetInt('want-anti-shuffle', 0), minLaff=minLaff)
kart.generateWithRequired(extZone)
self.karts.append(kart)
return kart
def createDoor(self):
# Overridable by sub-class.
pass

View file

@ -1,57 +1,914 @@
from pandac.PandaModules import Point3
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.fsm import FSM
from direct.interval.IntervalGlobal import LerpPosInterval
from toontown.coghq import DistributedFoodBeltAI
from toontown.coghq import DistributedBanquetTableAI
from toontown.coghq import DistributedGolfSpotAI
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import ToontownBattleGlobals
from toontown.suit import DistributedBossCogAI
from toontown.suit import DistributedSuitAI
from toontown.suit import SuitDNA
from toontown.building import SuitBuildingGlobals
from toontown.battle import DistributedBattleWaitersAI
from toontown.battle import DistributedBattleDinersAI
from toontown.battle import BattleExperienceAI
from direct.distributed.ClockDelta import globalClockDelta
import random
import math
class DistributedBossbotBossAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedBossbotBossAI")
class DistributedBossbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBossbotBossAI')
maxToonLevels = 77
toonUpLevels = [1, 2, 3, 4]
def setState(self, todo0):
pass
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 'c')
FSM.FSM.__init__(self, 'DistributedBossbotBossAI')
self.battleOneBattlesMade = False
self.battleThreeBattlesMade = False
self.battleFourSetup = False
self.foodBelts = []
self.numTables = 1
self.numDinersPerTable = 3
self.tables = []
self.numGolfSpots = 4
self.golfSpots = []
self.toonFoodStatus = {}
self.bossMaxDamage = ToontownGlobals.BossbotBossMaxDamage
self.threatDict = {}
self.keyStates.append('BattleFour')
self.battleFourStart = 0
self.battleDifficulty = 0
self.movingToTable = False
self.tableDest = -1
self.curTable = -1
self.speedDamage = 0
self.maxSpeedDamage = ToontownGlobals.BossbotMaxSpeedDamage
self.speedRecoverRate = ToontownGlobals.BossbotSpeedRecoverRate
self.speedRecoverStartTime = 0
self.battleFourTimeStarted = 0
self.numDinersExploded = 0
self.numMoveAttacks = 0
self.numGolfAttacks = 0
self.numGearAttacks = 0
self.numGolfAreaAttacks = 0
self.numToonupGranted = 0
self.totalLaffHealed = 0
self.toonupsGranted = []
self.doneOvertimeOneAttack = False
self.doneOvertimeTwoAttack = False
self.overtimeOneTime = simbase.air.config.GetInt('overtime-one-time', 1200)
self.battleFourDuration = simbase.air.config.GetInt('battle-four-duration', 1800)
self.overtimeOneStart = float(self.overtimeOneTime) / self.battleFourDuration
self.moveAttackAllowed = True
def setBattleDifficulty(self, todo0):
pass
def delete(self):
self.notify.debug('DistributedBossbotBossAI.delete')
self.deleteBanquetTables()
self.deleteFoodBelts()
self.deleteGolfSpots()
return DistributedBossCogAI.DistributedBossCogAI.delete(self)
def requestGetFood(self, todo0, todo1, todo2):
pass
def enterElevator(self):
DistributedBossCogAI.DistributedBossCogAI.enterElevator(self)
self.makeBattleOneBattles()
def toonGotFood(self, todo0, todo1, todo2, todo3):
pass
def enterIntroduction(self):
self.arenaSide = None
self.makeBattleOneBattles()
self.barrier = self.beginBarrier('Introduction', self.involvedToons, 45, self.doneIntroduction)
return
def requestServeFood(self, todo0, todo1):
pass
def makeBattleOneBattles(self):
if not self.battleOneBattlesMade:
self.postBattleState = 'PrepareBattleTwo'
self.initializeBattles(1, ToontownGlobals.BossbotBossBattleOnePosHpr)
self.battleOneBattlesMade = True
def toonServeFood(self, todo0, todo1, todo2):
pass
def getHoodId(self):
return ToontownGlobals.LawbotHQ
def hitBoss(self, todo0):
pass
def generateSuits(self, battleNumber):
if battleNumber == 1:
weakenedValue = ((1, 1), (2, 2), (2, 2), (1, 1), (1, 1, 1, 1, 1))
listVersion = list(SuitBuildingGlobals.SuitBuildingInfo)
if simbase.config.GetBool('bossbot-boss-cheat', False):
listVersion[14] = weakenedValue
SuitBuildingGlobals.SuitBuildingInfo = tuple(listVersion)
retval = self.invokeSuitPlanner(14, 0)
return retval
else:
suits = self.generateDinerSuits()
return suits
def hitToon(self, todo0):
pass
def invokeSuitPlanner(self, buildingCode, skelecog):
suits = DistributedBossCogAI.DistributedBossCogAI.invokeSuitPlanner(self, buildingCode, skelecog)
activeSuits = suits['activeSuits'][:]
reserveSuits = suits['reserveSuits'][:]
if len(activeSuits) + len(reserveSuits) >= 4:
while len(activeSuits) < 4:
activeSuits.append(reserveSuits.pop()[0])
def ballHitBoss(self, todo0):
pass
retval = {'activeSuits': activeSuits,
'reserveSuits': reserveSuits}
return retval
def setBossDamage(self, todo0, todo1, todo2):
pass
def makeBattle(self, bossCogPosHpr, battlePosHpr, roundCallback, finishCallback, battleNumber, battleSide):
if battleNumber == 1:
battle = DistributedBattleWaitersAI.DistributedBattleWaitersAI(self.air, self, roundCallback, finishCallback, battleSide)
else:
battle = DistributedBattleDinersAI.DistributedBattleDinersAI(self.air, self, roundCallback, finishCallback, battleSide)
self.setBattlePos(battle, bossCogPosHpr, battlePosHpr)
battle.suitsKilled = self.suitsKilled
battle.battleCalc.toonSkillPtsGained = self.toonSkillPtsGained
battle.toonExp = self.toonExp
battle.toonOrigQuests = self.toonOrigQuests
battle.toonItems = self.toonItems
battle.toonOrigMerits = self.toonOrigMerits
battle.toonMerits = self.toonMerits
battle.toonParts = self.toonParts
battle.helpfulToons = self.helpfulToons
mult = ToontownBattleGlobals.getBossBattleCreditMultiplier(battleNumber)
battle.battleCalc.setSkillCreditMultiplier(mult)
activeSuits = self.activeSuitsA
if battleSide:
activeSuits = self.activeSuitsB
for suit in activeSuits:
battle.addSuit(suit)
def setSpeedDamage(self, todo0, todo1, todo2):
pass
battle.generateWithRequired(self.zoneId)
return battle
def reachedTable(self, todo0):
pass
def initializeBattles(self, battleNumber, bossCogPosHpr):
self.resetBattles()
if not self.involvedToons:
self.notify.warning('initializeBattles: no toons!')
return
self.battleNumber = battleNumber
suitHandles = self.generateSuits(battleNumber)
self.suitsA = suitHandles['activeSuits']
self.activeSuitsA = self.suitsA[:]
self.reserveSuits = suitHandles['reserveSuits']
if battleNumber == 3:
if self.toonsB:
movedSuit = self.suitsA.pop()
self.suitsB = [movedSuit]
self.activeSuitsB = [movedSuit]
self.activeSuitsA.remove(movedSuit)
else:
self.suitsB = []
self.activeSuitsB = []
else:
suitHandles = self.generateSuits(battleNumber)
self.suitsB = suitHandles['activeSuits']
self.activeSuitsB = self.suitsB[:]
self.reserveSuits += suitHandles['reserveSuits']
if self.toonsA:
if battleNumber == 1:
self.battleA = self.makeBattle(bossCogPosHpr, ToontownGlobals.WaiterBattleAPosHpr, self.handleRoundADone, self.handleBattleADone, battleNumber, 0)
self.battleAId = self.battleA.doId
else:
self.battleA = self.makeBattle(bossCogPosHpr, ToontownGlobals.DinerBattleAPosHpr, self.handleRoundADone, self.handleBattleADone, battleNumber, 0)
self.battleAId = self.battleA.doId
else:
self.moveSuits(self.activeSuitsA)
self.suitsA = []
self.activeSuitsA = []
if self.arenaSide == None:
self.b_setArenaSide(0)
if self.toonsB:
if battleNumber == 1:
self.battleB = self.makeBattle(bossCogPosHpr, ToontownGlobals.WaiterBattleBPosHpr, self.handleRoundBDone, self.handleBattleBDone, battleNumber, 1)
self.battleBId = self.battleB.doId
else:
self.battleB = self.makeBattle(bossCogPosHpr, ToontownGlobals.DinerBattleBPosHpr, self.handleRoundBDone, self.handleBattleBDone, battleNumber, 1)
self.battleBId = self.battleB.doId
else:
self.moveSuits(self.activeSuitsB)
self.suitsB = []
self.activeSuitsB = []
if self.arenaSide == None:
self.b_setArenaSide(1)
self.sendBattleIds()
return
def hitTable(self, todo0):
pass
def enterPrepareBattleTwo(self):
self.barrier = self.beginBarrier('PrepareBattleTwo', self.involvedToons, 45, self.__donePrepareBattleTwo)
self.createFoodBelts()
self.createBanquetTables()
def awayFromTable(self, todo0):
pass
def __donePrepareBattleTwo(self, avIds):
self.b_setState('BattleTwo')
def toonGotHealed(self, todo0):
pass
def exitPrepareBattleTwo(self):
self.ignoreBarrier(self.barrier)
def requestGetToonup(self, todo0, todo1, todo2):
pass
def createFoodBelts(self):
if self.foodBelts:
return
for i in xrange(2):
newBelt = DistributedFoodBeltAI.DistributedFoodBeltAI(self.air, self, i)
self.foodBelts.append(newBelt)
newBelt.generateWithRequired(self.zoneId)
def toonGotToonup(self, todo0, todo1, todo2, todo3):
pass
def deleteFoodBelts(self):
for belt in self.foodBelts:
belt.requestDelete()
self.foodBelts = []
def createBanquetTables(self):
if self.tables:
return
self.calcAndSetBattleDifficulty()
diffInfo = ToontownGlobals.BossbotBossDifficultySettings[self.battleDifficulty]
self.diffInfo = diffInfo
self.numTables = diffInfo[0]
self.numDinersPerTable = diffInfo[1]
dinerLevel = diffInfo[2]
for i in xrange(self.numTables):
newTable = DistributedBanquetTableAI.DistributedBanquetTableAI(self.air, self, i, self.numDinersPerTable, dinerLevel)
self.tables.append(newTable)
newTable.generateWithRequired(self.zoneId)
def deleteBanquetTables(self):
for table in self.tables:
table.requestDelete()
self.tables = []
def enterBattleTwo(self):
self.resetBattles()
self.createFoodBelts()
self.createBanquetTables()
for belt in self.foodBelts:
belt.turnOn()
for table in self.tables:
table.turnOn()
self.barrier = self.beginBarrier('BattleTwo', self.involvedToons, ToontownGlobals.BossbotBossServingDuration + 1, self.__doneBattleTwo)
def exitBattleTwo(self):
self.ignoreBarrier(self.barrier)
for table in self.tables:
table.goInactive()
for belt in self.foodBelts:
belt.goInactive()
def __doneBattleTwo(self, avIds):
self.b_setState('PrepareBattleThree')
def requestGetFood(self, beltIndex, foodIndex, foodNum):
grantRequest = False
avId = self.air.getAvatarIdFromSender()
if self.state != 'BattleTwo':
grantRequest = False
elif (beltIndex, foodNum) not in self.toonFoodStatus.values():
if avId not in self.toonFoodStatus:
grantRequest = True
elif self.toonFoodStatus[avId] == None:
grantRequest = True
if grantRequest:
self.toonFoodStatus[avId] = (beltIndex, foodNum)
self.sendUpdate('toonGotFood', [avId,
beltIndex,
foodIndex,
foodNum])
return
def requestServeFood(self, tableIndex, chairIndex):
grantRequest = False
avId = self.air.getAvatarIdFromSender()
if self.state != 'BattleTwo':
grantRequest = False
elif tableIndex < len(self.tables):
table = self.tables[tableIndex]
dinerStatus = table.getDinerStatus(chairIndex)
if dinerStatus in (table.HUNGRY, table.ANGRY):
if self.toonFoodStatus[avId]:
grantRequest = True
if grantRequest:
self.toonFoodStatus[avId] = None
table.foodServed(chairIndex)
self.sendUpdate('toonServeFood', [avId, tableIndex, chairIndex])
return
def enterPrepareBattleThree(self):
self.barrier = self.beginBarrier('PrepareBattleThree', self.involvedToons, ToontownGlobals.BossbotBossServingDuration + 1, self.__donePrepareBattleThree)
self.divideToons()
self.makeBattleThreeBattles()
def exitPrepareBattleThree(self):
self.ignoreBarrier(self.barrier)
def __donePrepareBattleThree(self, avIds):
self.b_setState('BattleThree')
def makeBattleThreeBattles(self):
if not self.battleThreeBattlesMade:
if not self.tables:
self.createBanquetTables()
for table in self.tables:
table.turnOn()
table.goInactive()
notDeadList = []
for table in self.tables:
tableInfo = table.getNotDeadInfo()
notDeadList += tableInfo
self.notDeadList = notDeadList
self.postBattleState = 'PrepareBattleFour'
self.initializeBattles(3, ToontownGlobals.BossbotBossBattleThreePosHpr)
self.battleThreeBattlesMade = True
def generateDinerSuits(self):
diners = []
for i in xrange(len(self.notDeadList)):
if simbase.config.GetBool('bossbot-boss-cheat', False):
suit = self.__genSuitObject(self.zoneId, 2, 'c', 2, 0)
else:
info = self.notDeadList[i]
suitType = info[2] - 4
suitLevel = info[2]
suit = self.__genSuitObject(self.zoneId, suitType, 'c', suitLevel, 1)
diners.append((suit, 100))
active = []
for i in xrange(2):
if simbase.config.GetBool('bossbot-boss-cheat', False):
suit = self.__genSuitObject(self.zoneId, 2, 'c', 2, 0)
else:
suitType = 8
suitLevel = 12
suit = self.__genSuitObject(self.zoneId, suitType, 'c', suitLevel, 1)
active.append(suit)
return {'activeSuits': active, 'reserveSuits': diners}
def __genSuitObject(self, suitZone, suitType, bldgTrack, suitLevel, revives = 0):
newSuit = DistributedSuitAI.DistributedSuitAI(simbase.air, None)
skel = self.__setupSuitInfo(newSuit, bldgTrack, suitLevel, suitType)
if skel:
newSuit.setSkelecog(1)
newSuit.setSkeleRevives(revives)
newSuit.generateWithRequired(suitZone)
newSuit.node().setName('suit-%s' % newSuit.doId)
return newSuit
def __setupSuitInfo(self, suit, bldgTrack, suitLevel, suitType):
dna = SuitDNA.SuitDNA()
dna.newSuitRandom(suitType, bldgTrack)
suit.dna = dna
self.notify.debug('Creating suit type ' + suit.dna.name + ' of level ' + str(suitLevel) + ' from type ' + str(suitType) + ' and track ' + str(bldgTrack))
suit.setLevel(suitLevel)
return False
def enterBattleThree(self):
self.makeBattleThreeBattles()
self.notify.debug('self.battleA = %s' % self.battleA)
if self.battleA:
self.battleA.startBattle(self.toonsA, self.suitsA)
if self.battleB:
self.battleB.startBattle(self.toonsB, self.suitsB)
def exitBattleThree(self):
self.resetBattles()
def enterPrepareBattleFour(self):
self.resetBattles()
self.setupBattleFourObjects()
self.barrier = self.beginBarrier('PrepareBattleFour', self.involvedToons, 45, self.__donePrepareBattleFour)
def __donePrepareBattleFour(self, avIds):
self.b_setState('BattleFour')
def exitPrepareBattleFour(self):
self.ignoreBarrier(self.barrier)
def enterBattleFour(self):
self.battleFourTimeStarted = globalClock.getFrameTime()
self.numToonsAtStart = len(self.involvedToons)
self.resetBattles()
self.setupBattleFourObjects()
self.battleFourStart = globalClock.getFrameTime()
self.waitForNextAttack(5)
def exitBattleFour(self):
self.recordCeoInfo()
for belt in self.foodBelts:
belt.goInactive()
def recordCeoInfo(self):
didTheyWin = 0
if self.bossDamage == self.bossMaxDamage:
didTheyWin = 1
self.battleFourTimeInMin = globalClock.getFrameTime() - self.battleFourTimeStarted
self.battleFourTimeInMin /= 60.0
self.numToonsAtEnd = 0
toonHps = []
for toonId in self.involvedToons:
toon = simbase.air.doId2do.get(toonId)
if toon:
self.numToonsAtEnd += 1
toonHps.append(toon.hp)
self.air.writeServerEvent('ceoInfo', self.doId, '%d|%.2f|%d|%d|%d|%d|%d|%d|%s|%s|%.1f|%d|%d|%d|%d|%d}%d|%s|' % (didTheyWin,
self.battleFourTimeInMin,
self.battleDifficulty,
self.numToonsAtStart,
self.numToonsAtEnd,
self.numTables,
self.numTables * self.numDinersPerTable,
self.numDinersExploded,
toonHps,
self.involvedToons,
self.speedDamage,
self.numMoveAttacks,
self.numGolfAttacks,
self.numGearAttacks,
self.numGolfAreaAttacks,
self.numToonupGranted,
self.totalLaffHealed,
'ceoBugfixes'))
def setupBattleFourObjects(self):
if self.battleFourSetup:
return
if not self.tables:
self.createBanquetTables()
for table in self.tables:
table.goFree()
if not self.golfSpots:
self.createGolfSpots()
self.createFoodBelts()
for belt in self.foodBelts:
belt.goToonup()
self.battleFourSetup = True
def hitBoss(self, bossDamage):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId in self.involvedToons, 'hitBoss from unknown avatar'):
return
self.validate(avId, bossDamage <= 3, 'invalid bossDamage %s' % bossDamage)
if bossDamage < 1:
return
currState = self.getCurrentOrNextState()
if currState != 'BattleFour':
return
bossDamage *= 2
bossDamage = min(self.getBossDamage() + bossDamage, self.bossMaxDamage)
self.b_setBossDamage(bossDamage, 0, 0)
if self.bossDamage >= self.bossMaxDamage:
self.b_setState('Victory')
else:
self.__recordHit(bossDamage)
def __recordHit(self, bossDamage):
now = globalClock.getFrameTime()
self.hitCount += 1
avId = self.air.getAvatarIdFromSender()
self.addThreat(avId, bossDamage)
def getBossDamage(self):
return self.bossDamage
def b_setBossDamage(self, bossDamage, recoverRate, recoverStartTime):
self.d_setBossDamage(bossDamage, recoverRate, recoverStartTime)
self.setBossDamage(bossDamage, recoverRate, recoverStartTime)
def setBossDamage(self, bossDamage, recoverRate, recoverStartTime):
self.bossDamage = bossDamage
self.recoverRate = recoverRate
self.recoverStartTime = recoverStartTime
def d_setBossDamage(self, bossDamage, recoverRate, recoverStartTime):
timestamp = globalClockDelta.localToNetworkTime(recoverStartTime)
self.sendUpdate('setBossDamage', [bossDamage, recoverRate, timestamp])
def getSpeedDamage(self):
now = globalClock.getFrameTime()
elapsed = now - self.speedRecoverStartTime
self.notify.debug('elapsed=%s' % elapsed)
floatSpeedDamage = max(self.speedDamage - self.speedRecoverRate * elapsed / 60.0, 0)
self.notify.debug('floatSpeedDamage = %s' % floatSpeedDamage)
return int(max(self.speedDamage - self.speedRecoverRate * elapsed / 60.0, 0))
def getFloatSpeedDamage(self):
now = globalClock.getFrameTime()
elapsed = now - self.speedRecoverStartTime
floatSpeedDamage = max(self.speedDamage - self.speedRecoverRate * elapsed / 60.0, 0)
self.notify.debug('floatSpeedDamage = %s' % floatSpeedDamage)
return max(self.speedDamage - self.speedRecoverRate * elapsed / 60.0, 0)
def b_setSpeedDamage(self, speedDamage, recoverRate, recoverStartTime):
self.d_setSpeedDamage(speedDamage, recoverRate, recoverStartTime)
self.setSpeedDamage(speedDamage, recoverRate, recoverStartTime)
def setSpeedDamage(self, speedDamage, recoverRate, recoverStartTime):
self.speedDamage = speedDamage
self.speedRecoverRate = recoverRate
self.speedRecoverStartTime = recoverStartTime
def d_setSpeedDamage(self, speedDamage, recoverRate, recoverStartTime):
timestamp = globalClockDelta.localToNetworkTime(recoverStartTime)
self.sendUpdate('setSpeedDamage', [speedDamage, recoverRate, timestamp])
def createGolfSpots(self):
if self.golfSpots:
return
for i in xrange(self.numGolfSpots):
newGolfSpot = DistributedGolfSpotAI.DistributedGolfSpotAI(self.air, self, i)
self.golfSpots.append(newGolfSpot)
newGolfSpot.generateWithRequired(self.zoneId)
newGolfSpot.forceFree()
def deleteGolfSpots(self):
for spot in self.golfSpots:
spot.requestDelete()
self.golfSpots = []
def ballHitBoss(self, speedDamage):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId in self.involvedToons, 'hitBoss from unknown avatar'):
return
if speedDamage < 1:
return
currState = self.getCurrentOrNextState()
if currState != 'BattleFour':
return
now = globalClock.getFrameTime()
newDamage = self.getSpeedDamage() + speedDamage
self.notify.debug('newDamage = %s' % newDamage)
speedDamage = min(self.getFloatSpeedDamage() + speedDamage, self.maxSpeedDamage)
self.b_setSpeedDamage(speedDamage, self.speedRecoverRate, now)
self.addThreat(avId, 0.1)
def enterVictory(self):
self.resetBattles()
for table in self.tables:
table.turnOff()
for golfSpot in self.golfSpots:
golfSpot.turnOff()
self.suitsKilled.append({'type': None,
'level': None,
'track': self.dna.dept,
'isSkelecog': 0,
'isForeman': 0,
'isVP': 1,
'isCFO': 0,
'isSupervisor': 0,
'isVirtual': 0,
'activeToons': self.involvedToons[:]})
self.barrier = self.beginBarrier('Victory', self.involvedToons, 30, self.__doneVictory)
return
def __doneVictory(self, avIds):
self.d_setBattleExperience()
self.b_setState('Reward')
BattleExperienceAI.assignRewards(self.involvedToons, self.toonSkillPtsGained, self.suitsKilled, ToontownGlobals.dept2cogHQ(self.dept), self.helpfulToons)
for toonId in self.involvedToons:
toon = self.air.doId2do.get(toonId)
if toon:
self.givePinkSlipReward(toon)
toon.b_promote(self.deptIndex)
def givePinkSlipReward(self, toon):
self.notify.debug('TODO give pink slip to %s' % toon)
toon.addPinkSlips(self.battleDifficulty + 1)
def getThreat(self, toonId):
if toonId in self.threatDict:
return self.threatDict[toonId]
else:
return 0
def addThreat(self, toonId, threat):
if toonId in self.threatDict:
self.threatDict[toonId] += threat
else:
self.threatDict[toonId] = threat
def subtractThreat(self, toonId, threat):
if toonId in self.threatDict:
self.threatDict[toonId] -= threat
else:
self.threatDict[toonId] = 0
if self.threatDict[toonId] < 0:
self.threatDict[toonId] = 0
def waitForNextAttack(self, delayTime):
currState = self.getCurrentOrNextState()
if currState == 'BattleFour':
taskName = self.uniqueName('NextAttack')
taskMgr.remove(taskName)
taskMgr.doMethodLater(delayTime, self.doNextAttack, taskName)
def doNextAttack(self, task):
attackCode = -1
optionalParam = None
if self.movingToTable:
self.waitForNextAttack(5)
elif self.attackCode == ToontownGlobals.BossCogDizzyNow:
attackCode = ToontownGlobals.BossCogRecoverDizzyAttack
elif self.getBattleFourTime() > self.overtimeOneStart and not self.doneOvertimeOneAttack:
attackCode = ToontownGlobals.BossCogOvertimeAttack
self.doneOvertimeOneAttack = True
optionalParam = 0
elif self.getBattleFourTime() > 1.0 and not self.doneOvertimeTwoAttack:
attackCode = ToontownGlobals.BossCogOvertimeAttack
self.doneOvertimeTwoAttack = True
optionalParam = 1
else:
attackCode = random.choice([ToontownGlobals.BossCogGolfAreaAttack,
ToontownGlobals.BossCogDirectedAttack,
ToontownGlobals.BossCogDirectedAttack,
ToontownGlobals.BossCogDirectedAttack,
ToontownGlobals.BossCogDirectedAttack])
if attackCode == ToontownGlobals.BossCogAreaAttack:
self.__doAreaAttack()
if attackCode == ToontownGlobals.BossCogGolfAreaAttack:
self.__doGolfAreaAttack()
elif attackCode == ToontownGlobals.BossCogDirectedAttack:
self.__doDirectedAttack()
elif attackCode >= 0:
self.b_setAttackCode(attackCode, optionalParam)
return
def progressValue(self, fromValue, toValue):
t0 = float(self.bossDamage) / float(self.bossMaxDamage)
elapsed = globalClock.getFrameTime() - self.battleFourStart
t1 = elapsed / float(self.battleThreeDuration)
t = max(t0, t1)
progVal = fromValue + (toValue - fromValue) * min(t, 1)
self.notify.debug('progVal=%s' % progVal)
import pdb
pdb.set_trace()
return progVal
def __doDirectedAttack(self):
toonId = self.getMaxThreatToon()
self.notify.debug('toonToAttack=%s' % toonId)
unflattenedToons = self.getUnflattenedToons()
attackTotallyRandomToon = random.random() < 0.1
if unflattenedToons and (attackTotallyRandomToon or toonId == 0):
toonId = random.choice(unflattenedToons)
if toonId:
toonThreat = self.getThreat(toonId)
toonThreat *= 0.25
threatToSubtract = max(toonThreat, 10)
self.subtractThreat(toonId, threatToSubtract)
if self.isToonRoaming(toonId):
self.b_setAttackCode(ToontownGlobals.BossCogGolfAttack, toonId)
self.numGolfAttacks += 1
elif self.isToonOnTable(toonId):
doesMoveAttack = simbase.air.config.GetBool('ceo-does-move-attack', 1)
if doesMoveAttack:
chanceToShoot = 0.25
else:
chanceToShoot = 1.0
if not self.moveAttackAllowed:
self.notify.debug('moveAttack is not allowed, doing gearDirectedAttack')
chanceToShoot = 1.0
if random.random() < chanceToShoot:
self.b_setAttackCode(ToontownGlobals.BossCogGearDirectedAttack, toonId)
self.numGearAttacks += 1
else:
tableIndex = self.getToonTableIndex(toonId)
self.doMoveAttack(tableIndex)
else:
self.b_setAttackCode(ToontownGlobals.BossCogGolfAttack, toonId)
else:
uprightTables = self.getUprightTables()
if uprightTables:
tableToMoveTo = random.choice(uprightTables)
self.doMoveAttack(tableToMoveTo)
else:
self.waitForNextAttack(4)
def doMoveAttack(self, tableIndex):
self.numMoveAttacks += 1
self.movingToTable = True
self.tableDest = tableIndex
self.b_setAttackCode(ToontownGlobals.BossCogMoveAttack, tableIndex)
def getUnflattenedToons(self):
result = []
uprightTables = self.getUprightTables()
for toonId in self.involvedToons:
toonTable = self.getToonTableIndex(toonId)
if toonTable >= 0 and toonTable not in uprightTables:
pass
else:
result.append(toonId)
return result
def getMaxThreatToon(self):
returnedToonId = 0
maxThreat = 0
maxToons = []
for toonId in self.threatDict:
curThreat = self.threatDict[toonId]
tableIndex = self.getToonTableIndex(toonId)
if tableIndex > -1 and self.tables[tableIndex].state == 'Flat':
pass
elif curThreat > maxThreat:
maxToons = [toonId]
maxThreat = curThreat
elif curThreat == maxThreat:
maxToons.append(toonId)
if maxToons:
returnedToonId = random.choice(maxToons)
return returnedToonId
def getToonDifficulty(self):
highestCogSuitLevel = 0
totalCogSuitLevels = 0.0
totalNumToons = 0.0
for toonId in self.involvedToons:
toon = simbase.air.doId2do.get(toonId)
if toon:
toonLevel = toon.getNumPromotions(self.dept)
totalCogSuitLevels += toonLevel
totalNumToons += 1
if toon.cogLevels > highestCogSuitLevel:
highestCogSuitLevel = toonLevel
if not totalNumToons:
totalNumToons = 1.0
averageLevel = totalCogSuitLevels / totalNumToons
self.notify.debug('toons average level = %f, highest level = %d' % (averageLevel, highestCogSuitLevel))
retval = min(averageLevel, self.maxToonLevels)
return retval
def calcAndSetBattleDifficulty(self):
self.toonLevels = self.getToonDifficulty()
numDifficultyLevels = len(ToontownGlobals.BossbotBossDifficultySettings)
battleDifficulty = int(self.toonLevels / self.maxToonLevels * numDifficultyLevels)
if battleDifficulty >= numDifficultyLevels:
battleDifficulty = numDifficultyLevels - 1
self.b_setBattleDifficulty(battleDifficulty)
def b_setBattleDifficulty(self, batDiff):
self.setBattleDifficulty(batDiff)
self.d_setBattleDifficulty(batDiff)
def setBattleDifficulty(self, batDiff):
self.battleDifficulty = batDiff
def d_setBattleDifficulty(self, batDiff):
self.sendUpdate('setBattleDifficulty', [batDiff])
def getUprightTables(self):
tableList = []
for table in self.tables:
if table.state != 'Flat':
tableList.append(table.index)
return tableList
def getToonTableIndex(self, toonId):
tableIndex = -1
for table in self.tables:
if table.avId == toonId:
tableIndex = table.index
break
return tableIndex
def getToonGolfSpotIndex(self, toonId):
golfSpotIndex = -1
for golfSpot in self.golfSpots:
if golfSpot.avId == toonId:
golfSpotIndex = golfSpot.index
break
return golfSpotIndex
def isToonOnTable(self, toonId):
result = self.getToonTableIndex(toonId) != -1
return result
def isToonOnGolfSpot(self, toonId):
result = self.getToonGolfSpotIndex(toonId) != -1
return result
def isToonRoaming(self, toonId):
result = not self.isToonOnTable(toonId) and not self.isToonOnGolfSpot(toonId)
return result
def reachedTable(self, tableIndex):
if self.movingToTable and self.tableDest == tableIndex:
self.movingToTable = False
self.curTable = self.tableDest
self.tableDest = -1
def hitTable(self, tableIndex):
self.notify.debug('hitTable tableIndex=%d' % tableIndex)
if tableIndex < len(self.tables):
table = self.tables[tableIndex]
if table.state != 'Flat':
table.goFlat()
def awayFromTable(self, tableIndex):
self.notify.debug('awayFromTable tableIndex=%d' % tableIndex)
if tableIndex < len(self.tables):
taskName = 'Unflatten-%d' % tableIndex
unflattenTime = self.diffInfo[3]
taskMgr.doMethodLater(unflattenTime, self.unflattenTable, taskName, extraArgs=[tableIndex])
def unflattenTable(self, tableIndex):
if tableIndex < len(self.tables):
table = self.tables[tableIndex]
if table.state == 'Flat':
if table.avId and table.avId in self.involvedToons:
table.forceControl(table.avId)
else:
table.goFree()
def incrementDinersExploded(self):
self.numDinersExploded += 1
def magicWordHit(self, damage, avId):
self.hitBoss(damage)
def __doAreaAttack(self):
self.b_setAttackCode(ToontownGlobals.BossCogAreaAttack)
def __doGolfAreaAttack(self):
self.numGolfAreaAttacks += 1
self.b_setAttackCode(ToontownGlobals.BossCogGolfAreaAttack)
def hitToon(self, toonId):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId != toonId, 'hitToon on self'):
return
if avId not in self.involvedToons or toonId not in self.involvedToons:
return
toon = self.air.doId2do.get(toonId)
if toon:
self.healToon(toon, 1)
self.sendUpdate('toonGotHealed', [toonId])
def requestGetToonup(self, beltIndex, toonupIndex, toonupNum):
grantRequest = False
avId = self.air.getAvatarIdFromSender()
if self.state != 'BattleFour':
grantRequest = False
elif (beltIndex, toonupNum) not in self.toonupsGranted:
toon = simbase.air.doId2do.get(avId)
if toon:
grantRequest = True
if grantRequest:
self.toonupsGranted.insert(0, (beltIndex, toonupNum))
if len(self.toonupsGranted) > 8:
self.toonupsGranted = self.toonupsGranted[0:8]
self.sendUpdate('toonGotToonup', [avId,
beltIndex,
toonupIndex,
toonupNum])
if toonupIndex < len(self.toonUpLevels):
self.healToon(toon, self.toonUpLevels[toonupIndex])
self.numToonupGranted += 1
self.totalLaffHealed += self.toonUpLevels[toonupIndex]
else:
self.notify.warning('requestGetToonup this should not happen')
self.healToon(toon, 1)
def toonLeftTable(self, tableIndex):
if self.movingToTable and self.tableDest == tableIndex:
if random.random() < 0.5:
self.movingToTable = False
self.waitForNextAttack(0)
def getBattleFourTime(self):
if self.state != 'BattleFour':
t1 = 0
else:
elapsed = globalClock.getFrameTime() - self.battleFourStart
t1 = elapsed / float(self.battleFourDuration)
return t1
def getDamageMultiplier(self):
mult = 1.0
if self.doneOvertimeOneAttack and not self.doneOvertimeTwoAttack:
mult = 1.25
if self.getBattleFourTime() > 1.0:
mult = self.getBattleFourTime() + 1
return mult
def toggleMove(self):
self.moveAttackAllowed = not self.moveAttackAllowed
return self.moveAttackAllowed