oldschool-toontown/toontown/suit/DistributedLawbotBossAI.py

883 lines
34 KiB
Python
Raw Normal View History

2019-11-02 17:27:54 -05:00
from otp.ai.AIBaseGlobal import *
from direct.distributed.ClockDelta import *
2019-12-30 20:28:09 -06:00
from toontown.suit import DistributedBossCogAI
2019-11-02 17:27:54 -05:00
from direct.directnotify import DirectNotifyGlobal
from otp.avatar import DistributedAvatarAI
2019-12-30 20:28:09 -06:00
from toontown.suit import DistributedSuitAI
2019-11-02 17:27:54 -05:00
from toontown.battle import BattleExperienceAI
from direct.fsm import FSM
from toontown.toonbase import ToontownGlobals
from toontown.toon import InventoryBase
from toontown.toonbase import TTLocalizer
from toontown.battle import BattleBase
from toontown.toon import NPCToons
from toontown.building import SuitBuildingGlobals
2019-12-30 20:28:09 -06:00
from toontown.suit import SuitDNA
2019-12-30 12:03:23 -06:00
import random
2019-11-02 17:27:54 -05:00
from toontown.coghq import DistributedLawbotBossGavelAI
from toontown.suit import DistributedLawbotBossSuitAI
from toontown.coghq import DistributedLawbotCannonAI
from toontown.coghq import DistributedLawbotChairAI
from toontown.toonbase import ToontownBattleGlobals
class DistributedLawbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedLawbotBossAI')
limitHitCount = 6
hitCountDamage = 35
numPies = 10
maxToonLevels = 77
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 'l')
FSM.FSM.__init__(self, 'DistributedLawbotBossAI')
self.lawyers = []
self.cannons = None
self.chairs = None
self.gavels = None
self.cagedToonNpcId = random.choice(list(NPCToons.npcFriends.keys()))
2019-11-02 17:27:54 -05:00
self.bossMaxDamage = ToontownGlobals.LawbotBossMaxDamage
self.recoverRate = 0
self.recoverStartTime = 0
self.bossDamage = ToontownGlobals.LawbotBossInitialDamage
self.useCannons = 1
self.numToonJurorsSeated = 0
self.cannonBallsLeft = {}
self.toonLevels = 0
if 'Defeat' not in self.keyStates:
self.keyStates.append('Defeat')
self.toonupValue = 1
self.bonusState = False
self.bonusTimeStarted = 0
self.numBonusStates = 0
self.battleThreeTimeStarted = 0
self.battleThreeTimeInMin = 0
self.numAreaAttacks = 0
self.lastAreaAttackTime = 0
self.weightPerToon = {}
self.cannonIndexPerToon = {}
self.battleDifficulty = 0
return
def delete(self):
self.notify.debug('DistributedLawbotBossAI.delete')
self.__deleteBattleThreeObjects()
self.__deleteBattleTwoObjects()
taskName = self.uniqueName('clearBonus')
taskMgr.remove(taskName)
return DistributedBossCogAI.DistributedBossCogAI.delete(self)
def getHoodId(self):
return ToontownGlobals.LawbotHQ
def getCagedToonNpcId(self):
return self.cagedToonNpcId
def magicWordHit(self, damage, avId):
if self.attackCode != ToontownGlobals.BossCogDizzyNow:
self.hitBossInsides()
self.hitBoss(damage)
def hitBoss(self, bossDamage):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId in self.involvedToons, 'DistributedLawbotbossAI.hitBoss from unknown avatar'):
return
self.validate(avId, bossDamage == 1, 'invalid bossDamage %s' % bossDamage)
if bossDamage < 1:
return
currState = self.getCurrentOrNextState()
if currState != 'BattleThree':
return
if bossDamage <= 12:
newWeight = self.weightPerToon.get(avId)
if newWeight:
bossDamage = newWeight
if self.bonusState and bossDamage <= 12:
bossDamage *= ToontownGlobals.LawbotBossBonusWeightMultiplier
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()
def healBoss(self, bossHeal):
bossDamage = -bossHeal
avId = self.air.getAvatarIdFromSender()
currState = self.getCurrentOrNextState()
if currState != 'BattleThree':
return
bossDamage = min(self.getBossDamage() + bossDamage, self.bossMaxDamage)
bossDamage = max(bossDamage, 0)
self.b_setBossDamage(bossDamage, 0, 0)
if self.bossDamage == 0:
self.b_setState('Defeat')
else:
self.__recordHit()
def hitBossInsides(self):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId in self.involvedToons, 'hitBossInsides from unknown avatar'):
return
currState = self.getCurrentOrNextState()
if currState != 'BattleThree':
return
self.b_setAttackCode(ToontownGlobals.BossCogDizzyNow)
self.b_setBossDamage(self.getBossDamage(), 0, 0)
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, self.toonupValue)
self.sendUpdate('toonGotHealed', [toonId])
def touchCage(self):
avId = self.air.getAvatarIdFromSender()
currState = self.getCurrentOrNextState()
if currState != 'BattleThree' and currState != 'NearVictory':
return
if not self.validate(avId, avId in self.involvedToons, 'touchCage from unknown avatar'):
return
toon = simbase.air.doId2do.get(avId)
if toon:
toon.b_setNumPies(self.numPies)
toon.__touchedCage = 1
def touchWitnessStand(self):
self.touchCage()
def finalPieSplat(self):
self.notify.debug('finalPieSplat')
if self.state != 'NearVictory':
return
self.b_setState('Victory')
def doTaunt(self):
if not self.state == 'BattleThree':
return
tauntIndex = random.randrange(len(TTLocalizer.LawbotBossTaunts))
extraInfo = 0
if tauntIndex == 0 and self.involvedToons:
extraInfo = random.randrange(len(self.involvedToons))
self.sendUpdate('setTaunt', [tauntIndex, extraInfo])
def doNextAttack(self, task):
for lawyer in self.lawyers:
lawyer.doNextAttack(self)
self.waitForNextAttack(ToontownGlobals.LawbotBossLawyerCycleTime)
timeSinceLastAttack = globalClock.getFrameTime() - self.lastAreaAttackTime
allowedByTime = 15 < timeSinceLastAttack or self.lastAreaAttackTime == 0
doAttack = random.randrange(1,101)
self.notify.debug('allowedByTime=%d doAttack=%d' % (allowedByTime, doAttack))
if doAttack <= ToontownGlobals.LawbotBossChanceToDoAreaAttack and allowedByTime:
self.__doAreaAttack()
self.numAreaAttacks += 1
self.lastAreaAttackTime = globalClock.getFrameTime()
else:
chanceToDoTaunt = ToontownGlobals.LawbotBossChanceForTaunt
action = random.randrange(1,101)
if action <= chanceToDoTaunt:
self.doTaunt()
pass
return
if self.attackCode == ToontownGlobals.BossCogDizzyNow:
attackCode = ToontownGlobals.BossCogRecoverDizzyAttack
else:
attackCode = random.choice([ToontownGlobals.BossCogAreaAttack,
ToontownGlobals.BossCogFrontAttack,
ToontownGlobals.BossCogDirectedAttack,
ToontownGlobals.BossCogDirectedAttack,
ToontownGlobals.BossCogDirectedAttack,
ToontownGlobals.BossCogDirectedAttack])
if attackCode == ToontownGlobals.BossCogAreaAttack:
self.__doAreaAttack()
elif attackCode == ToontownGlobals.BossCogDirectedAttack:
self.__doDirectedAttack()
else:
self.b_setAttackCode(attackCode)
def __doAreaAttack(self):
self.b_setAttackCode(ToontownGlobals.BossCogAreaAttack)
def __doDirectedAttack(self):
if self.nearToons:
toonId = random.choice(self.nearToons)
self.b_setAttackCode(ToontownGlobals.BossCogDirectedAttack, toonId)
else:
self.__doAreaAttack()
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 getBossDamage(self):
now = globalClock.getFrameTime()
elapsed = now - self.recoverStartTime
return int(max(self.bossDamage - self.recoverRate * elapsed / 60.0, 0))
def d_setBossDamage(self, bossDamage, recoverRate, recoverStartTime):
timestamp = globalClockDelta.localToNetworkTime(recoverStartTime)
self.sendUpdate('setBossDamage', [bossDamage, recoverRate, timestamp])
def waitForNextStrafe(self, delayTime):
currState = self.getCurrentOrNextState()
if currState == 'BattleThree':
taskName = self.uniqueName('NextStrafe')
taskMgr.remove(taskName)
taskMgr.doMethodLater(delayTime, self.doNextStrafe, taskName)
def stopStrafes(self):
taskName = self.uniqueName('NextStrafe')
taskMgr.remove(taskName)
def doNextStrafe(self, task):
if self.attackCode != ToontownGlobals.BossCogDizzyNow:
side = random.choice([0, 1])
direction = random.choice([0, 1])
self.sendUpdate('doStrafe', [side, direction])
delayTime = 9
self.waitForNextStrafe(delayTime)
def __sendLawyerIds(self):
lawyerIds = []
for suit in self.lawyers:
lawyerIds.append(suit.doId)
self.sendUpdate('setLawyerIds', [lawyerIds])
def d_cagedToonBattleThree(self, index, avId):
self.sendUpdate('cagedToonBattleThree', [index, avId])
def formatReward(self):
return str(self.cagedToonNpcId)
def makeBattleOneBattles(self):
self.postBattleState = 'RollToBattleTwo'
self.initializeBattles(1, ToontownGlobals.LawbotBossBattleOnePosHpr)
@staticmethod
def getEndOfBattleMovieDuration():
return 5
2019-11-02 17:27:54 -05:00
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('lawbot-boss-cheat', 0):
listVersion[13] = weakenedValue
SuitBuildingGlobals.SuitBuildingInfo = tuple(listVersion)
return self.invokeSuitPlanner(13, 0)
else:
return self.invokeSuitPlanner(13, 1)
def removeToon(self, avId):
toon = simbase.air.doId2do.get(avId)
if toon:
toon.b_setNumPies(0)
DistributedBossCogAI.DistributedBossCogAI.removeToon(self, avId)
def enterOff(self):
self.notify.debug('enterOff')
DistributedBossCogAI.DistributedBossCogAI.enterOff(self)
self.__deleteBattleThreeObjects()
self.__resetLawyers()
def enterElevator(self):
self.notify.debug('enterElevatro')
DistributedBossCogAI.DistributedBossCogAI.enterElevator(self)
self.b_setBossDamage(ToontownGlobals.LawbotBossInitialDamage, 0, 0)
def enterIntroduction(self):
self.notify.debug('enterIntroduction')
DistributedBossCogAI.DistributedBossCogAI.enterIntroduction(self)
self.b_setBossDamage(ToontownGlobals.LawbotBossInitialDamage, 0, 0)
self.__makeChairs()
def exitIntroduction(self):
self.notify.debug('exitIntroduction')
DistributedBossCogAI.DistributedBossCogAI.exitIntroduction(self)
def enterRollToBattleTwo(self):
self.divideToons()
self.__makeCannons()
self.barrier = self.beginBarrier('RollToBattleTwo', self.involvedToons, 50, self.__doneRollToBattleTwo)
def __doneRollToBattleTwo(self, avIds):
self.b_setState('PrepareBattleTwo')
def exitRollToBattleTwo(self):
self.ignoreBarrier(self.barrier)
def enterPrepareBattleTwo(self):
self.__makeCannons()
self.barrier = self.beginBarrier('PrepareBattleTwo', self.involvedToons, 45, self.__donePrepareBattleTwo)
self.makeBattleTwoBattles()
def __donePrepareBattleTwo(self, avIds):
self.b_setState('BattleTwo')
def exitPrepareBattleTwo(self):
self.ignoreBarrier(self.barrier)
def __makeCannons(self):
if self.cannons == None:
self.cannons = []
startPt = Point3(*ToontownGlobals.LawbotBossCannonPosA)
endPt = Point3(*ToontownGlobals.LawbotBossCannonPosB)
totalDisplacement = endPt - startPt
self.notify.debug('totalDisplacement=%s' % totalDisplacement)
numToons = len(self.involvedToons)
stepDisplacement = totalDisplacement / (numToons + 1)
for index in range(numToons):
newPos = stepDisplacement * (index + 1)
self.notify.debug('curDisplacement = %s' % newPos)
newPos += startPt
self.notify.debug('newPos = %s' % newPos)
cannon = DistributedLawbotCannonAI.DistributedLawbotCannonAI(self.air, self, index, newPos[0], newPos[1], newPos[2], -90, 0, 0)
cannon.generateWithRequired(self.zoneId)
self.cannons.append(cannon)
return
def __makeChairs(self):
if self.chairs == None:
self.chairs = []
for index in range(12):
chair = DistributedLawbotChairAI.DistributedLawbotChairAI(self.air, self, index)
chair.generateWithRequired(self.zoneId)
self.chairs.append(chair)
return
def __makeBattleTwoObjects(self):
self.__makeCannons()
self.__makeChairs()
def __deleteCannons(self):
if self.cannons != None:
for cannon in self.cannons:
cannon.requestDelete()
self.cannons = None
return
def __deleteChairs(self):
if self.chairs != None:
for chair in self.chairs:
chair.requestDelete()
self.chairs = None
return
def __stopChairs(self):
if self.chairs != None:
for chair in self.chairs:
chair.stopCogs()
return
def __deleteBattleTwoObjects(self):
self.__deleteCannons()
self.__deleteChairs()
def getCannonBallsLeft(self, avId):
if avId in self.cannonBallsLeft:
2019-11-02 17:27:54 -05:00
return self.cannonBallsLeft[avId]
else:
self.notify.warning('getCannonBalsLeft invalid avId: %d' % avId)
return 0
def decrementCannonBallsLeft(self, avId):
if avId in self.cannonBallsLeft:
2019-11-02 17:27:54 -05:00
self.cannonBallsLeft[avId] -= 1
if self.cannonBallsLeft[avId] < 0:
self.notify.warning('decrementCannonBallsLeft <0 cannonballs for %d' % avId)
self.cannonBallsLeft[avId] = 0
else:
self.notify.warning('decrementCannonBallsLeft invalid avId: %d' % avId)
def makeBattleTwoBattles(self):
self.postBattleState = 'RollToBattleThree'
if self.useCannons:
self.__makeBattleTwoObjects()
else:
self.initializeBattles(2, ToontownGlobals.LawbotBossBattleTwoPosHpr)
def enterBattleTwo(self):
if self.useCannons:
self.cannonBallsLeft = {}
for toonId in self.involvedToons:
self.cannonBallsLeft[toonId] = ToontownGlobals.LawbotBossCannonBallMax
for chair in self.chairs:
chair.requestEmptyJuror()
self.barrier = self.beginBarrier('BattleTwo', self.involvedToons, ToontownGlobals.LawbotBossJuryBoxMoveTime + 1, self.__doneBattleTwo)
if not self.useCannons:
if self.battleA:
self.battleA.startBattle(self.toonsA, self.suitsA)
if self.battleB:
self.battleB.startBattle(self.toonsB, self.suitsB)
def __doneBattleTwo(self, avIds):
if self.useCannons:
self.b_setState('PrepareBattleThree')
else:
self.b_setState('RollToBattleThree')
def exitBattleTwo(self):
self.resetBattles()
self.numToonJurorsSeated = 0
for chair in self.chairs:
self.notify.debug('chair.state==%s' % chair.state)
if chair.state == 'ToonJuror':
self.numToonJurorsSeated += 1
self.notify.debug('numToonJurorsSeated=%d' % self.numToonJurorsSeated)
self.air.writeServerEvent('jurorsSeated', self.doId, '%s|%s|%s' % (self.dept, self.involvedToons, self.numToonJurorsSeated))
self.__deleteCannons()
self.__stopChairs()
def enterRollToBattleThree(self):
self.divideToons()
self.barrier = self.beginBarrier('RollToBattleThree', self.involvedToons, 20, self.__doneRollToBattleThree)
def __doneRollToBattleThree(self, avIds):
self.b_setState('PrepareBattleThree')
def exitRollToBattleThree(self):
self.ignoreBarrier(self.barrier)
def enterPrepareBattleThree(self):
self.calcAndSetBattleDifficulty()
self.barrier = self.beginBarrier('PrepareBattleThree', self.involvedToons, 45, self.__donePrepareBattleThree)
def __donePrepareBattleThree(self, avIds):
self.b_setState('BattleThree')
def exitPrepareBattleThree(self):
self.ignoreBarrier(self.barrier)
def enterBattleThree(self):
self.battleThreeTimeStarted = globalClock.getFrameTime()
self.calcAndSetBattleDifficulty()
self.calculateWeightPerToon()
diffSettings = ToontownGlobals.LawbotBossDifficultySettings[self.battleDifficulty]
self.ammoCount = diffSettings[0]
self.numGavels = diffSettings[1]
if self.numGavels >= len(ToontownGlobals.LawbotBossGavelPosHprs):
self.numGavels = len(ToontownGlobals.LawbotBossGavelPosHprs)
self.numLawyers = diffSettings[2]
if self.numLawyers >= len(ToontownGlobals.LawbotBossLawyerPosHprs):
self.numLawyers = len(ToontownGlobals.LawbotBossLawyerPosHprs)
self.toonupValue = diffSettings[3]
self.notify.debug('diffLevel=%d ammoCount=%d gavels=%d lawyers = %d, toonup=%d' % (self.battleDifficulty, self.ammoCount, self.numGavels, self.numLawyers, self.toonupValue))
self.air.writeServerEvent('lawbotBossSettings', self.doId, '%s|%s|%s|%s|%s|%s' % (self.dept, self.battleDifficulty, self.ammoCount, self.numGavels, self.numLawyers, self.toonupValue))
self.__makeBattleThreeObjects()
self.__makeLawyers()
self.numPies = self.ammoCount
self.resetBattles()
self.setPieType()
jurorsOver = self.numToonJurorsSeated - ToontownGlobals.LawbotBossJurorsForBalancedScale
dmgAdjust = jurorsOver * ToontownGlobals.LawbotBossDamagePerJuror
self.b_setBossDamage(ToontownGlobals.LawbotBossInitialDamage + dmgAdjust, 0, 0)
if simbase.config.GetBool('lawbot-boss-cheat', 0):
self.b_setBossDamage(ToontownGlobals.LawbotBossMaxDamage - 1, 0, 0)
self.battleThreeStart = globalClock.getFrameTime()
for toonId in self.involvedToons:
toon = simbase.air.doId2do.get(toonId)
if toon:
toon.__touchedCage = 0
for aGavel in self.gavels:
aGavel.turnOn()
self.waitForNextAttack(5)
self.notify.debug('battleDifficulty = %d' % self.battleDifficulty)
self.numToonsAtStart = len(self.involvedToons)
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
2020-01-11 00:05:30 -06:00
if toonLevel > highestCogSuitLevel:
2019-11-02 17:27:54 -05:00
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 __saySomething(self, task=None):
index = None
avId = 0
if len(self.involvedToons) == 0:
return
avId = random.choice(self.involvedToons)
toon = simbase.air.doId2do.get(avId)
if toon.__touchedCage:
if self.cagedToonDialogIndex <= TTLocalizer.CagedToonBattleThreeMaxAdvice:
index = self.cagedToonDialogIndex
self.cagedToonDialogIndex += 1
elif random.random() < 0.2:
index = random.randrange(100, TTLocalizer.CagedToonBattleThreeMaxAdvice + 1)
else:
index = random.randrange(20, TTLocalizer.CagedToonBattleThreeMaxTouchCage + 1)
if index:
self.d_cagedToonBattleThree(index, avId)
self.__saySomethingLater()
return
def __saySomethingLater(self, delayTime=15):
taskName = self.uniqueName('CagedToonSaySomething')
taskMgr.remove(taskName)
taskMgr.doMethodLater(delayTime, self.__saySomething, taskName)
def __goodJump(self, avId):
currState = self.getCurrentOrNextState()
if currState != 'BattleThree':
return
index = random.randrange(10, TTLocalizer.CagedToonBattleThreeMaxGivePies + 1)
self.d_cagedToonBattleThree(index, avId)
self.__saySomethingLater()
def __makeBattleThreeObjects(self):
if self.gavels == None:
self.gavels = []
for index in range(self.numGavels):
gavel = DistributedLawbotBossGavelAI.DistributedLawbotBossGavelAI(self.air, self, index)
gavel.generateWithRequired(self.zoneId)
self.gavels.append(gavel)
return
def __deleteBattleThreeObjects(self):
if self.gavels != None:
for gavel in self.gavels:
gavel.request('Off')
gavel.requestDelete()
self.gavels = None
return
def doBattleThreeInfo(self):
didTheyWin = 0
if self.bossDamage == ToontownGlobals.LawbotBossMaxDamage:
didTheyWin = 1
self.battleThreeTimeInMin = globalClock.getFrameTime() - self.battleThreeTimeStarted
self.battleThreeTimeInMin /= 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('b3Info', self.doId, '%d|%.2f|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d|%s|%s' % (didTheyWin, self.battleThreeTimeInMin, self.numToonsAtStart, self.numToonsAtEnd, self.numToonJurorsSeated, self.battleDifficulty, self.ammoCount, self.numGavels, self.numLawyers, self.toonupValue, self.numBonusStates, self.numAreaAttacks, toonHps, self.weightPerToon))
def exitBattleThree(self):
self.doBattleThreeInfo()
self.stopAttacks()
self.stopStrafes()
taskName = self.uniqueName('CagedToonSaySomething')
taskMgr.remove(taskName)
self.__resetLawyers()
self.__deleteBattleThreeObjects()
def enterNearVictory(self):
self.resetBattles()
def exitNearVictory(self):
pass
def enterVictory(self):
self.resetBattles()
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)
preferredDept = random.randrange(len(SuitDNA.suitDepts))
typeWeights = ['single'] * 70 + ['building'] * 27 + ['invasion'] * 3
preferredSummonType = random.choice(typeWeights)
for toonId in self.involvedToons:
toon = self.air.doId2do.get(toonId)
if toon:
self.giveCogSummonReward(toon, preferredDept, preferredSummonType)
toon.b_promote(self.deptIndex)
def giveCogSummonReward(self, toon, prefDeptIndex, prefSummonType):
cogLevel = int(self.toonLevels / self.maxToonLevels * SuitDNA.suitsPerDept)
cogLevel = min(cogLevel, SuitDNA.suitsPerDept - 1)
deptIndex = prefDeptIndex
summonType = prefSummonType
hasSummon = toon.hasParticularCogSummons(prefDeptIndex, cogLevel, prefSummonType)
if hasSummon:
self.notify.debug('trying to find another reward')
if not toon.hasParticularCogSummons(prefDeptIndex, cogLevel, 'single'):
summonType = 'single'
elif not toon.hasParticularCogSummons(prefDeptIndex, cogLevel, 'building'):
summonType = 'building'
elif not toon.hasParticularCogSummons(prefDeptIndex, cogLevel, 'invasion'):
summonType = 'invasion'
else:
foundOne = False
for curDeptIndex in range(len(SuitDNA.suitDepts)):
if not toon.hasParticularCogSummons(curDeptIndex, cogLevel, prefSummonType):
deptIndex = curDeptIndex
foundOne = True
break
elif not toon.hasParticularCogSummons(curDeptIndex, cogLevel, 'single'):
deptIndex = curDeptIndex
summonType = 'single'
foundOne = True
break
elif not toon.hasParticularCogSummons(curDeptIndex, cogLevel, 'building'):
deptIndex = curDeptIndex
summonType = 'building'
foundOne = True
break
elif not toon.hasParticularCogSummons(curDeptIndex, cogLevel, 'invasion'):
summonType = 'invasion'
deptIndex = curDeptIndex
foundOne = True
break
possibleCogLevel = list(range(SuitDNA.suitsPerDept))
possibleDeptIndex = list(range(len(SuitDNA.suitDepts)))
2019-11-02 17:27:54 -05:00
possibleSummonType = ['single', 'building', 'invasion']
typeWeights = [
'single'] * 70 + ['building'] * 27 + ['invasion'] * 3
if not foundOne:
for i in range(5):
randomCogLevel = random.choice(possibleCogLevel)
randomSummonType = random.choice(typeWeights)
randomDeptIndex = random.choice(possibleDeptIndex)
if not toon.hasParticularCogSummons(randomDeptIndex, randomCogLevel, randomSummonType):
foundOne = True
cogLevel = randomCogLevel
summonType = randomSummonType
deptIndex = randomDeptIndex
break
for curType in possibleSummonType:
if foundOne:
break
for curCogLevel in possibleCogLevel:
if foundOne:
break
for curDeptIndex in possibleDeptIndex:
if foundOne:
break
if not toon.hasParticularCogSummons(curDeptIndex, curCogLevel, curType):
foundOne = True
cogLevel = curCogLevel
summonType = curType
deptIndex = curDeptIndex
if not foundOne:
cogLevel = None
summonType = None
deptIndex = None
toon.assignNewCogSummons(cogLevel, summonType, deptIndex)
return
def exitVictory(self):
self.takeAwayPies()
def enterDefeat(self):
self.resetBattles()
self.barrier = self.beginBarrier('Defeat', self.involvedToons, 10, self.__doneDefeat)
def __doneDefeat(self, avIds):
for toonId in self.involvedToons:
toon = self.air.doId2do.get(toonId)
if toon:
toon.b_setHp(0)
def exitDefeat(self):
self.takeAwayPies()
def enterFrolic(self):
DistributedBossCogAI.DistributedBossCogAI.enterFrolic(self)
self.b_setBossDamage(0, 0, 0)
def setPieType(self):
for toonId in self.involvedToons:
toon = simbase.air.doId2do.get(toonId)
if toon:
toon.d_setPieType(ToontownBattleGlobals.MAX_TRACK_INDEX + 1)
def takeAwayPies(self):
for toonId in self.involvedToons:
toon = simbase.air.doId2do.get(toonId)
if toon:
toon.b_setNumPies(0)
def __recordHit(self):
now = globalClock.getFrameTime()
self.hitCount += 1
if self.hitCount < self.limitHitCount or self.bossDamage < self.hitCountDamage:
return
def __resetLawyers(self):
for suit in self.lawyers:
suit.requestDelete()
self.lawyers = []
def __makeLawyers(self):
self.__resetLawyers()
lawCogChoices = [
'b', 'dt', 'ac', 'bs', 'sd', 'le', 'bw']
for i in range(self.numLawyers):
suit = DistributedLawbotBossSuitAI.DistributedLawbotBossSuitAI(self.air, None)
suit.dna = SuitDNA.SuitDNA()
lawCog = random.choice(lawCogChoices)
suit.dna.newSuit(lawCog)
suit.setPosHpr(*ToontownGlobals.LawbotBossLawyerPosHprs[i])
suit.setBoss(self)
suit.generateWithRequired(self.zoneId)
self.lawyers.append(suit)
self.__sendLawyerIds()
return
def hitChair(self, chairIndex, npcToonIndex):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId in self.involvedToons, 'hitChair from unknown avatar'):
return
if not self.chairs:
return
if chairIndex < 0 or chairIndex >= len(self.chairs):
self.notify.warning('invalid chairIndex = %d' % chairIndex)
return
if not self.state == 'BattleTwo':
return
self.chairs[chairIndex].b_setToonJurorIndex(npcToonIndex)
self.chairs[chairIndex].requestToonJuror()
def clearBonus(self, taskName):
if self and hasattr(self, 'bonusState'):
self.bonusState = False
def startBonusState(self):
self.notify.debug('startBonusState')
self.bonusTimeStarted = globalClock.getFrameTime()
self.bonusState = True
self.numBonusStates += 1
for toonId in self.involvedToons:
toon = self.air.doId2do.get(toonId)
if toon:
self.healToon(toon, ToontownGlobals.LawbotBossBonusToonup)
taskMgr.doMethodLater(ToontownGlobals.LawbotBossBonusDuration, self.clearBonus, self.uniqueName('clearBonus'))
self.sendUpdate('enteredBonusState', [])
def areAllLawyersStunned(self):
for lawyer in self.lawyers:
if not lawyer.stunned:
return False
return True
def checkForBonusState(self):
if self.bonusState:
return
if not self.areAllLawyersStunned():
return
curTime = globalClock.getFrameTime()
delta = curTime - self.bonusTimeStarted
if ToontownGlobals.LawbotBossBonusWaitTime < delta:
self.startBonusState()
def toonEnteredCannon(self, toonId, cannonIndex):
self.cannonIndexPerToon[toonId] = cannonIndex
def numJurorsSeatedByCannon(self, cannonIndex):
retVal = 0
for chair in self.chairs:
if chair.state == 'ToonJuror':
if chair.toonJurorIndex == cannonIndex:
retVal += 1
return retVal
def calculateWeightPerToon(self):
for toonId in self.involvedToons:
defaultWeight = 1
bonusWeight = 0
cannonIndex = self.cannonIndexPerToon.get(toonId)
if not cannonIndex == None:
diffSettings = ToontownGlobals.LawbotBossDifficultySettings[self.battleDifficulty]
if diffSettings[4]:
bonusWeight = self.numJurorsSeatedByCannon(cannonIndex) - diffSettings[5]
if bonusWeight < 0:
bonusWeight = 0
newWeight = defaultWeight + bonusWeight
self.weightPerToon[toonId] = newWeight
self.notify.debug('toon %d has weight of %d' % (toonId, newWeight))
return
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 calcAndSetBattleDifficulty(self):
self.toonLevels = self.getToonDifficulty()
numDifficultyLevels = len(ToontownGlobals.LawbotBossDifficultySettings)
battleDifficulty = int(self.toonLevels / self.maxToonLevels * numDifficultyLevels)
if battleDifficulty >= numDifficultyLevels:
battleDifficulty = numDifficultyLevels - 1
self.b_setBattleDifficulty(battleDifficulty)
def getNextState(self):
currState = self.getCurrentOrNextState()
if currState == "Elevator":
return "Introduction"
elif currState == "Introduction":
return "BattleOne"
elif currState == "BattleOne":
return "RollToBattleTwo"
elif currState == "RollToBattleTwo":
return "PrepareBattleTwo"
elif currState in ("PrepareBattleTwo", "BattleTwo"):
return "PrepareBattleThree"
elif currState in ("PrepareBattleThree", "BattleThree", "NearVictory"):
return "Victory"
# Do not skip Victory, weird stuff may happen, like not collecting their rewards.
elif currState == "Reward":
return "Epilogue"
return None