mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-23 11:42:39 -06:00
638 lines
22 KiB
Python
638 lines
22 KiB
Python
|
import random
|
||
|
from direct.directnotify import DirectNotifyGlobal
|
||
|
from otp.avatar import DistributedAvatarAI
|
||
|
from toontown.battle import BattleExperienceAI
|
||
|
from toontown.toonbase import ToontownGlobals
|
||
|
from toontown.toonbase import ToontownBattleGlobals
|
||
|
from toontown.toon import InventoryBase
|
||
|
from toontown.battle import DistributedBattleFinalAI
|
||
|
from toontown.building import SuitPlannerInteriorAI
|
||
|
from toontown.battle import BattleBase
|
||
|
from panda3d.core import *
|
||
|
import SuitDNA
|
||
|
import random
|
||
|
AllBossCogs = []
|
||
|
|
||
|
BOSS_TO_STAT = {
|
||
|
's': ToontownGlobals.STAT_VP,
|
||
|
'm': ToontownGlobals.STAT_CFO,
|
||
|
'l': ToontownGlobals.STAT_CJ,
|
||
|
'c': ToontownGlobals.STAT_CEO
|
||
|
}
|
||
|
|
||
|
class DistributedBossCogAI(DistributedAvatarAI.DistributedAvatarAI):
|
||
|
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBossCogAI')
|
||
|
|
||
|
def __init__(self, air, dept):
|
||
|
DistributedAvatarAI.DistributedAvatarAI.__init__(self, air)
|
||
|
self.dept = dept
|
||
|
self.dna = SuitDNA.SuitDNA()
|
||
|
self.dna.newBossCog(self.dept)
|
||
|
self.deptIndex = SuitDNA.suitDepts.index(self.dept)
|
||
|
self.resetBattleCounters()
|
||
|
self.looseToons = []
|
||
|
self.involvedToons = []
|
||
|
self.toonsA = []
|
||
|
self.toonsB = []
|
||
|
self.nearToons = []
|
||
|
self.suitsA = []
|
||
|
self.activeSuitsA = []
|
||
|
self.suitsB = []
|
||
|
self.activeSuitsB = []
|
||
|
self.reserveSuits = []
|
||
|
self.barrier = None
|
||
|
self.keyStates = ['BattleOne',
|
||
|
'BattleTwo',
|
||
|
'BattleThree',
|
||
|
'Victory']
|
||
|
self.bossDamage = 0
|
||
|
self.battleThreeStart = 0
|
||
|
self.battleThreeDuration = 1800
|
||
|
self.attackCode = None
|
||
|
self.attackAvId = 0
|
||
|
self.hitCount = 0
|
||
|
self.keyReward = config.GetBool('get-key-reward-always', False) or random.random() <= 0.15
|
||
|
AllBossCogs.append(self)
|
||
|
|
||
|
def delete(self):
|
||
|
self.ignoreAll()
|
||
|
if self in AllBossCogs:
|
||
|
i = AllBossCogs.index(self)
|
||
|
del AllBossCogs[i]
|
||
|
return DistributedAvatarAI.DistributedAvatarAI.delete(self)
|
||
|
|
||
|
def getDNAString(self):
|
||
|
return self.dna.makeNetString()
|
||
|
|
||
|
def avatarEnter(self):
|
||
|
avId = self.air.getAvatarIdFromSender()
|
||
|
self.addToon(avId)
|
||
|
|
||
|
def avatarExit(self):
|
||
|
avId = self.air.getAvatarIdFromSender()
|
||
|
self.removeToon(avId)
|
||
|
|
||
|
def avatarNearEnter(self):
|
||
|
avId = self.air.getAvatarIdFromSender()
|
||
|
if avId not in self.nearToons:
|
||
|
self.nearToons.append(avId)
|
||
|
|
||
|
def avatarNearExit(self):
|
||
|
avId = self.air.getAvatarIdFromSender()
|
||
|
try:
|
||
|
self.nearToons.remove(avId)
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
def __handleUnexpectedExit(self, avId):
|
||
|
self.removeToon(avId)
|
||
|
|
||
|
def addToon(self, avId):
|
||
|
if avId not in self.looseToons and avId not in self.involvedToons:
|
||
|
self.looseToons.append(avId)
|
||
|
event = self.air.getAvatarExitEvent(avId)
|
||
|
self.acceptOnce(event, self.__handleUnexpectedExit, extraArgs=[avId])
|
||
|
|
||
|
def removeToon(self, avId):
|
||
|
if avId in self.looseToons:
|
||
|
self.looseToons.remove(avId)
|
||
|
|
||
|
if avId in self.involvedToons:
|
||
|
self.involvedToons.remove(avId)
|
||
|
|
||
|
if avId in self.toonsA:
|
||
|
self.toonsA.remove(avId)
|
||
|
|
||
|
if avId in self.toonsB:
|
||
|
self.toonsB.remove(avId)
|
||
|
|
||
|
if avId in self.nearToons:
|
||
|
self.nearToons.remove(avId)
|
||
|
|
||
|
event = self.air.getAvatarExitEvent(avId)
|
||
|
self.ignore(event)
|
||
|
if not self.hasToons():
|
||
|
taskMgr.doMethodLater(10, self.__bossDone, self.uniqueName('BossDone'))
|
||
|
|
||
|
def __bossDone(self, task):
|
||
|
self.b_setState('Off')
|
||
|
messenger.send(self.uniqueName('BossDone'))
|
||
|
self.ignoreAll()
|
||
|
|
||
|
def hasToons(self):
|
||
|
return self.looseToons or self.involvedToons
|
||
|
|
||
|
def hasToonsAlive(self):
|
||
|
alive = 0
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = self.air.doId2do.get(toonId)
|
||
|
if toon:
|
||
|
hp = toon.getHp()
|
||
|
if hp > 0:
|
||
|
alive = 1
|
||
|
|
||
|
return alive
|
||
|
|
||
|
def sendBattleIds(self):
|
||
|
self.sendUpdate('setBattleIds', [self.battleNumber, self.battleAId, self.battleBId])
|
||
|
|
||
|
def sendToonIds(self):
|
||
|
self.sendUpdate('setToonIds', [self.involvedToons, self.toonsA, self.toonsB])
|
||
|
|
||
|
def damageToon(self, toon, deduction):
|
||
|
toon.takeDamage(deduction)
|
||
|
if toon.getHp() <= 0:
|
||
|
self.sendUpdate('toonDied', [toon.doId])
|
||
|
empty = InventoryBase.InventoryBase(toon)
|
||
|
toon.b_setInventory(empty.makeNetString())
|
||
|
self.removeToon(toon.doId)
|
||
|
|
||
|
def healToon(self, toon, increment):
|
||
|
toon.toonUp(increment)
|
||
|
|
||
|
def d_setBattleExperience(self):
|
||
|
self.sendUpdate('setBattleExperience', self.getBattleExperience())
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = simbase.air.doId2do.get(toonId)
|
||
|
if toon:
|
||
|
self.air.topToonsMgr.toonKilledBoss(toon, self.BossName)
|
||
|
|
||
|
def getBattleExperience(self):
|
||
|
result = BattleExperienceAI.getBattleExperience(8, self.involvedToons, self.toonExp, self.toonSkillPtsGained, self.toonOrigQuests, self.toonItems, self.toonOrigMerits, self.toonMerits, self.toonParts, self.suitsKilled, self.helpfulToons)
|
||
|
return result
|
||
|
|
||
|
def b_setArenaSide(self, arenaSide):
|
||
|
self.setArenaSide(arenaSide)
|
||
|
self.d_setArenaSide(arenaSide)
|
||
|
|
||
|
def setArenaSide(self, arenaSide):
|
||
|
self.arenaSide = arenaSide
|
||
|
|
||
|
def d_setArenaSide(self, arenaSide):
|
||
|
self.sendUpdate('setArenaSide', [arenaSide])
|
||
|
|
||
|
def b_setState(self, state):
|
||
|
self.setState(state)
|
||
|
self.d_setState(state)
|
||
|
|
||
|
def d_setState(self, state):
|
||
|
self.sendUpdate('setState', [state])
|
||
|
|
||
|
def setState(self, state):
|
||
|
self.demand(state)
|
||
|
if self.air:
|
||
|
if state in self.keyStates:
|
||
|
self.air.writeServerEvent('bossBattle', self.doId, '%s|%s|%s|%s' % (self.dept,
|
||
|
state,
|
||
|
self.involvedToons,
|
||
|
self.formatReward()))
|
||
|
|
||
|
def getState(self):
|
||
|
return self.state
|
||
|
|
||
|
def getKeyReward(self):
|
||
|
return self.keyReward
|
||
|
|
||
|
def formatReward(self):
|
||
|
return 'unspecified'
|
||
|
|
||
|
def enterOff(self):
|
||
|
self.resetBattles()
|
||
|
self.resetToons()
|
||
|
self.resetBattleCounters()
|
||
|
|
||
|
def exitOff(self):
|
||
|
pass
|
||
|
|
||
|
def enterWaitForToons(self):
|
||
|
self.acceptNewToons()
|
||
|
self.barrier = self.beginBarrier('WaitForToons', self.involvedToons, 5, self.__doneWaitForToons)
|
||
|
|
||
|
def __doneWaitForToons(self, toons):
|
||
|
self.b_setState('Elevator')
|
||
|
|
||
|
def exitWaitForToons(self):
|
||
|
self.ignoreBarrier(self.barrier)
|
||
|
|
||
|
def enterElevator(self):
|
||
|
if self.notify.getDebug():
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = simbase.air.doId2do.get(toonId)
|
||
|
if toon:
|
||
|
self.notify.debug('%s. involved toon %s, %s/%s' % (self.doId,
|
||
|
toonId,
|
||
|
toon.getHp(),
|
||
|
toon.getMaxHp()))
|
||
|
|
||
|
self.resetBattles()
|
||
|
self.barrier = self.beginBarrier('Elevator', self.involvedToons, 30, self.__doneElevator)
|
||
|
|
||
|
def __doneElevator(self, avIds):
|
||
|
self.b_setState('Introduction')
|
||
|
|
||
|
def exitElevator(self):
|
||
|
self.ignoreBarrier(self.barrier)
|
||
|
|
||
|
def enterIntroduction(self):
|
||
|
self.resetBattles()
|
||
|
self.arenaSide = None
|
||
|
self.makeBattleOneBattles()
|
||
|
self.barrier = self.beginBarrier('Introduction', self.involvedToons, 50, self.doneIntroduction)
|
||
|
|
||
|
def doneIntroduction(self, avIds):
|
||
|
self.b_setState('BattleOne')
|
||
|
|
||
|
def exitIntroduction(self):
|
||
|
self.ignoreBarrier(self.barrier)
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = simbase.air.doId2do.get(toonId)
|
||
|
if toon:
|
||
|
toon.b_setCogIndex(-1)
|
||
|
|
||
|
def enterBattleOne(self):
|
||
|
if self.battleA:
|
||
|
self.battleA.startBattle(self.toonsA, self.suitsA)
|
||
|
if self.battleB:
|
||
|
self.battleB.startBattle(self.toonsB, self.suitsB)
|
||
|
|
||
|
def exitBattleOne(self):
|
||
|
self.resetBattles()
|
||
|
|
||
|
def enterReward(self):
|
||
|
self.resetBattles()
|
||
|
self.barrier = self.beginBarrier('Reward', self.involvedToons, BattleBase.BUILDING_REWARD_TIMEOUT, self.__doneReward)
|
||
|
|
||
|
def __doneReward(self, avIds):
|
||
|
self.b_setState('Epilogue')
|
||
|
|
||
|
def exitReward(self):
|
||
|
pass
|
||
|
|
||
|
def enterEpilogue(self):
|
||
|
self.giveKeyReward()
|
||
|
|
||
|
def exitEpilogue(self):
|
||
|
pass
|
||
|
|
||
|
def enterFrolic(self):
|
||
|
self.resetBattles()
|
||
|
|
||
|
def exitFrolic(self):
|
||
|
pass
|
||
|
|
||
|
def resetBattleCounters(self):
|
||
|
self.battleNumber = 0
|
||
|
self.battleA = None
|
||
|
self.battleAId = 0
|
||
|
self.battleB = None
|
||
|
self.battleBId = 0
|
||
|
self.arenaSide = None
|
||
|
self.toonSkillPtsGained = {}
|
||
|
self.toonExp = {}
|
||
|
self.toonOrigQuests = {}
|
||
|
self.toonItems = {}
|
||
|
self.toonOrigMerits = {}
|
||
|
self.toonMerits = {}
|
||
|
self.toonParts = {}
|
||
|
self.suitsKilled = []
|
||
|
self.helpfulToons = []
|
||
|
return
|
||
|
|
||
|
def resetBattles(self):
|
||
|
sendReset = 0
|
||
|
if self.battleA:
|
||
|
self.battleA.requestDelete()
|
||
|
self.battleA = None
|
||
|
self.battleAId = 0
|
||
|
sendReset = 1
|
||
|
if self.battleB:
|
||
|
self.battleB.requestDelete()
|
||
|
self.battleB = None
|
||
|
self.battleBId = 0
|
||
|
sendReset = 1
|
||
|
for suit in self.suitsA + self.suitsB:
|
||
|
suit.requestDelete()
|
||
|
|
||
|
for suit, joinChance in self.reserveSuits:
|
||
|
suit.requestDelete()
|
||
|
|
||
|
self.suitsA = []
|
||
|
self.activeSuitsA = []
|
||
|
self.suitsB = []
|
||
|
self.activeSuitsB = []
|
||
|
self.reserveSuits = []
|
||
|
self.battleNumber = 0
|
||
|
if sendReset:
|
||
|
self.sendBattleIds()
|
||
|
return
|
||
|
|
||
|
def resetToons(self):
|
||
|
if self.toonsA or self.toonsB:
|
||
|
self.looseToons = self.looseToons + self.involvedToons
|
||
|
self.involvedToons = []
|
||
|
self.toonsA = []
|
||
|
self.toonsB = []
|
||
|
self.sendToonIds()
|
||
|
|
||
|
def divideToons(self):
|
||
|
toons = self.involvedToons[:]
|
||
|
random.shuffle(toons)
|
||
|
numToons = min(len(toons), 8)
|
||
|
if numToons < 4:
|
||
|
numToonsB = numToons / 2
|
||
|
else:
|
||
|
numToonsB = (numToons + random.choice([0, 1])) / 2
|
||
|
self.toonsA = toons[numToonsB:numToons]
|
||
|
self.toonsB = toons[:numToonsB]
|
||
|
self.looseToons += toons[numToons:]
|
||
|
self.sendToonIds()
|
||
|
|
||
|
def acceptNewToons(self):
|
||
|
sourceToons = self.looseToons
|
||
|
self.looseToons = []
|
||
|
for toonId in sourceToons:
|
||
|
toon = self.air.doId2do.get(toonId)
|
||
|
if toon and not toon.ghostMode:
|
||
|
self.involvedToons.append(toonId)
|
||
|
else:
|
||
|
self.looseToons.append(toonId)
|
||
|
|
||
|
for avId in self.involvedToons:
|
||
|
toon = self.air.doId2do.get(avId)
|
||
|
if toon:
|
||
|
p = []
|
||
|
for t in ToontownBattleGlobals.Tracks:
|
||
|
p.append(toon.experience.getExp(t))
|
||
|
|
||
|
self.toonExp[avId] = p
|
||
|
self.toonOrigMerits[avId] = toon.cogMerits[:]
|
||
|
|
||
|
self.divideToons()
|
||
|
|
||
|
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']
|
||
|
suitHandles = self.generateSuits(battleNumber)
|
||
|
self.suitsB = suitHandles['activeSuits']
|
||
|
self.activeSuitsB = self.suitsB[:]
|
||
|
self.reserveSuits += suitHandles['reserveSuits']
|
||
|
if self.toonsA:
|
||
|
self.battleA = self.makeBattle(bossCogPosHpr, ToontownGlobals.BossCogBattleAPosHpr, 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:
|
||
|
self.battleB = self.makeBattle(bossCogPosHpr, ToontownGlobals.BossCogBattleBPosHpr, 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 makeBattle(self, bossCogPosHpr, battlePosHpr, roundCallback, finishCallback, battleNumber, battleSide):
|
||
|
battle = DistributedBattleFinalAI.DistributedBattleFinalAI(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)
|
||
|
battle.generateWithRequired(self.zoneId)
|
||
|
return battle
|
||
|
|
||
|
def setBattlePos(self, battle, cogPosHpr, battlePosHpr):
|
||
|
bossNode = NodePath('bossNode')
|
||
|
bossNode.setPosHpr(*cogPosHpr)
|
||
|
battleNode = bossNode.attachNewNode('battleNode')
|
||
|
battleNode.setPosHpr(*battlePosHpr)
|
||
|
suitNode = battleNode.attachNewNode('suitNode')
|
||
|
suitNode.setPos(0, 1, 0)
|
||
|
battle.pos = battleNode.getPos(NodePath())
|
||
|
battle.initialSuitPos = suitNode.getPos(NodePath())
|
||
|
|
||
|
def moveSuits(self, active):
|
||
|
for suit in active:
|
||
|
self.reserveSuits.append((suit, 0))
|
||
|
|
||
|
def handleRoundADone(self, toonIds, totalHp, deadSuits):
|
||
|
if self.battleA:
|
||
|
self.handleRoundDone(self.battleA, self.suitsA, self.activeSuitsA, toonIds, totalHp, deadSuits)
|
||
|
|
||
|
def handleRoundBDone(self, toonIds, totalHp, deadSuits):
|
||
|
if self.battleB:
|
||
|
self.handleRoundDone(self.battleB, self.suitsB, self.activeSuitsB, toonIds, totalHp, deadSuits)
|
||
|
|
||
|
def handleBattleADone(self, zoneId, toonIds):
|
||
|
if self.battleA:
|
||
|
self.battleA.requestDelete()
|
||
|
self.battleA = None
|
||
|
self.battleAId = 0
|
||
|
self.sendBattleIds()
|
||
|
if self.arenaSide == None:
|
||
|
self.b_setArenaSide(0)
|
||
|
if not self.battleB and self.hasToons() and self.hasToonsAlive():
|
||
|
self.b_setState(self.postBattleState)
|
||
|
return
|
||
|
|
||
|
def handleBattleBDone(self, zoneId, toonIds):
|
||
|
if self.battleB:
|
||
|
self.battleB.requestDelete()
|
||
|
self.battleB = None
|
||
|
self.battleBId = 0
|
||
|
self.sendBattleIds()
|
||
|
if self.arenaSide == None:
|
||
|
self.b_setArenaSide(1)
|
||
|
if not self.battleA and self.hasToons() and self.hasToonsAlive():
|
||
|
self.b_setState(self.postBattleState)
|
||
|
return
|
||
|
|
||
|
def invokeSuitPlanner(self, buildingCode, skelecog, skelecogRandom=0):
|
||
|
planner = SuitPlannerInteriorAI.SuitPlannerInteriorAI(1, buildingCode, self.dna.dept, self.zoneId)
|
||
|
planner.respectInvasions = 0
|
||
|
suits = planner.genFloorSuits(0)
|
||
|
if skelecog:
|
||
|
for suit in suits['activeSuits']:
|
||
|
wantSkelecog = 1
|
||
|
if skelecogRandom:
|
||
|
wantSkelecog = random.randint(0, 1)
|
||
|
suit.b_setSkelecog(wantSkelecog)
|
||
|
|
||
|
for reserve in suits['reserveSuits']:
|
||
|
wantSkelecog = 1
|
||
|
if skelecogRandom:
|
||
|
wantSkelecog = random.randint(0, 1)
|
||
|
suit = reserve[0]
|
||
|
suit.b_setSkelecog(wantSkelecog)
|
||
|
|
||
|
return suits
|
||
|
|
||
|
def generateSuits(self, battleNumber):
|
||
|
raise StandardError, 'generateSuits unimplemented'
|
||
|
|
||
|
def handleRoundDone(self, battle, suits, activeSuits, toonIds, totalHp, deadSuits):
|
||
|
totalMaxHp = 0
|
||
|
for suit in suits:
|
||
|
totalMaxHp += suit.maxHP
|
||
|
|
||
|
for suit in deadSuits:
|
||
|
activeSuits.remove(suit)
|
||
|
|
||
|
joinedReserves = []
|
||
|
if len(self.reserveSuits) > 0 and len(activeSuits) < 4:
|
||
|
hpPercent = 100 - totalHp / totalMaxHp * 100.0
|
||
|
for info in self.reserveSuits:
|
||
|
if info[1] <= hpPercent and len(activeSuits) < 4:
|
||
|
suits.append(info[0])
|
||
|
activeSuits.append(info[0])
|
||
|
joinedReserves.append(info)
|
||
|
|
||
|
for info in joinedReserves:
|
||
|
self.reserveSuits.remove(info)
|
||
|
|
||
|
battle.resume(joinedReserves)
|
||
|
|
||
|
def getBattleThreeTime(self):
|
||
|
elapsed = globalClock.getFrameTime() - self.battleThreeStart
|
||
|
t1 = elapsed / float(self.battleThreeDuration)
|
||
|
return t1
|
||
|
|
||
|
def progressValue(self, fromValue, toValue):
|
||
|
t0 = float(self.bossDamage) / float(self.bossMaxDamage)
|
||
|
elapsed = globalClock.getFrameTime() - self.battleThreeStart
|
||
|
t1 = elapsed / float(self.battleThreeDuration)
|
||
|
t = max(t0, t1)
|
||
|
return fromValue + (toValue - fromValue) * min(t, 1)
|
||
|
|
||
|
def progressRandomValue(self, fromValue, toValue, radius = 0.2):
|
||
|
t = self.progressValue(0, 1)
|
||
|
radius = radius * (1.0 - abs(t - 0.5) * 2.0)
|
||
|
t += radius * random.uniform(-1, 1)
|
||
|
t = max(min(t, 1.0), 0.0)
|
||
|
return fromValue + (toValue - fromValue) * t
|
||
|
|
||
|
def reportToonHealth(self):
|
||
|
if self.notify.getDebug():
|
||
|
str = ''
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = self.air.doId2do.get(toonId)
|
||
|
if toon:
|
||
|
str += ', %s (%s/%s)' % (toonId, toon.getHp(), toon.getMaxHp())
|
||
|
|
||
|
self.notify.debug('%s.toons = %s' % (self.doId, str[2:]))
|
||
|
|
||
|
def getDamageMultiplier(self):
|
||
|
return 1.0
|
||
|
|
||
|
def zapToon(self, x, y, z, h, p, r, bpx, bpy, attackCode, timestamp):
|
||
|
avId = self.air.getAvatarIdFromSender()
|
||
|
if not self.validate(avId, avId in self.involvedToons, 'zapToon from unknown avatar'):
|
||
|
return
|
||
|
if attackCode == ToontownGlobals.BossCogLawyerAttack and self.dna.dept != 'l':
|
||
|
self.notify.warning('got lawyer attack but not in CJ boss battle')
|
||
|
return
|
||
|
toon = simbase.air.doId2do.get(avId)
|
||
|
if toon:
|
||
|
self.d_showZapToon(avId, x, y, z, h, p, r, attackCode, timestamp)
|
||
|
damage = ToontownGlobals.BossCogDamageLevels.get(attackCode)
|
||
|
if damage == None:
|
||
|
self.notify.warning('No damage listed for attack code %s' % attackCode)
|
||
|
damage = 5
|
||
|
damage *= self.getDamageMultiplier()
|
||
|
self.damageToon(toon, damage)
|
||
|
currState = self.getCurrentOrNextState()
|
||
|
if attackCode == ToontownGlobals.BossCogElectricFence and (currState == 'RollToBattleTwo' or currState == 'BattleThree') and self.attackCode not in (ToontownGlobals.BossCogDizzy, ToontownGlobals.BossCogDizzyNow):
|
||
|
if bpy < 0 and abs(bpx / bpy) > 0.5:
|
||
|
if bpx < 0:
|
||
|
self.b_setAttackCode(ToontownGlobals.BossCogSwatRight)
|
||
|
else:
|
||
|
self.b_setAttackCode(ToontownGlobals.BossCogSwatLeft)
|
||
|
return
|
||
|
|
||
|
def d_showZapToon(self, avId, x, y, z, h, p, r, attackCode, timestamp):
|
||
|
self.sendUpdate('showZapToon', [avId,
|
||
|
x,
|
||
|
y,
|
||
|
z,
|
||
|
h,
|
||
|
p,
|
||
|
r,
|
||
|
attackCode,
|
||
|
timestamp])
|
||
|
|
||
|
def b_setAttackCode(self, attackCode, avId = 0):
|
||
|
self.d_setAttackCode(attackCode, avId)
|
||
|
self.setAttackCode(attackCode, avId)
|
||
|
|
||
|
def setAttackCode(self, attackCode, avId = 0):
|
||
|
self.attackCode = attackCode
|
||
|
self.attackAvId = avId
|
||
|
if attackCode == ToontownGlobals.BossCogDizzy or attackCode == ToontownGlobals.BossCogDizzyNow:
|
||
|
delayTime = self.progressValue(20, 5)
|
||
|
self.hitCount = 0
|
||
|
elif attackCode == ToontownGlobals.BossCogSlowDirectedAttack:
|
||
|
delayTime = ToontownGlobals.BossCogAttackTimes.get(attackCode)
|
||
|
delayTime += self.progressValue(10, 0)
|
||
|
else:
|
||
|
delayTime = ToontownGlobals.BossCogAttackTimes.get(attackCode)
|
||
|
if delayTime == None:
|
||
|
return
|
||
|
if self.dept == 'm' and attackCode == ToontownGlobals.BossCogAreaAttack:
|
||
|
delayTime += 5.0
|
||
|
self.waitForNextAttack(delayTime)
|
||
|
|
||
|
def d_setAttackCode(self, attackCode, avId = 0):
|
||
|
self.sendUpdate('setAttackCode', [attackCode, avId])
|
||
|
|
||
|
def waitForNextAttack(self, delayTime):
|
||
|
currState = self.getCurrentOrNextState()
|
||
|
if currState == 'BattleThree':
|
||
|
taskName = self.uniqueName('NextAttack')
|
||
|
taskMgr.remove(taskName)
|
||
|
taskMgr.doMethodLater(delayTime, self.doNextAttack, taskName)
|
||
|
|
||
|
def stopAttacks(self):
|
||
|
taskName = self.uniqueName('NextAttack')
|
||
|
taskMgr.remove(taskName)
|
||
|
|
||
|
def doNextAttack(self, task):
|
||
|
self.b_setAttackCode(ToontownGlobals.BossCogNoAttack)
|
||
|
|
||
|
def giveKeyReward(self):
|
||
|
if not self.keyReward:
|
||
|
return
|
||
|
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = self.air.doId2do.get(toonId)
|
||
|
|
||
|
if toon:
|
||
|
toon.addCrateKeys(1)
|
||
|
|
||
|
def addStats(self):
|
||
|
stat = BOSS_TO_STAT[self.dept]
|
||
|
|
||
|
for toonId in self.involvedToons:
|
||
|
toon = self.air.doId2do.get(toonId)
|
||
|
|
||
|
if toon:
|
||
|
toon.addStat(stat)
|