toontown-just-works/toontown/coghq/LevelSuitPlannerAI.py
2024-07-07 18:08:39 -05:00

217 lines
8.1 KiB
Python

from panda3d.core import *
from direct.showbase import DirectObject
from toontown.suit import SuitDNA
from direct.directnotify import DirectNotifyGlobal
import LevelBattleManagerAI
import types
import random
class LevelSuitPlannerAI(DirectObject.DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory('LevelSuitPlannerAI')
def __init__(self, air, level, cogCtor, battleCtor, cogSpecs, reserveCogSpecs, battleCellSpecs, battleExpAggreg = None):
self.air = air
self.level = level
self.cogCtor = cogCtor
self.cogSpecs = cogSpecs
if simbase.config.GetBool('level-reserve-suits', 0):
self.reserveCogSpecs = reserveCogSpecs
else:
self.reserveCogSpecs = []
self.battleCellSpecs = battleCellSpecs
self.__genSuitInfos(self.level.getCogLevel(), self.level.getCogTrack())
self.battleMgr = LevelBattleManagerAI.LevelBattleManagerAI(self.air, self.level, battleCtor, battleExpAggreg)
self.battleCellId2suits = {}
for id in self.battleCellSpecs.keys():
self.battleCellId2suits[id] = []
def destroy(self):
self.battleMgr.destroyBattleMgr()
del self.battleMgr
self.battleCellId2suits = {}
self.ignoreAll()
del self.cogSpecs
del self.cogCtor
del self.level
del self.air
def __genJoinChances(self, num):
joinChances = []
for currChance in xrange(num):
joinChances.append(random.randint(1, 100))
joinChances.sort(cmp)
return joinChances
def __genSuitInfos(self, level, track):
def getSuitDict(spec, cogId, level = level, track = track):
suitDict = {}
suitDict['track'] = track
suitDict.update(spec)
suitDict['zoneId'] = self.level.getEntityZoneId(spec['parentEntId'])
suitDict['level'] += level
suitDict['cogId'] = cogId
return suitDict
self.suitInfos = {}
self.suitInfos['activeSuits'] = []
for i in xrange(len(self.cogSpecs)):
spec = self.cogSpecs[i]
self.suitInfos['activeSuits'].append(getSuitDict(spec, i))
numReserve = len(self.reserveCogSpecs)
joinChances = self.__genJoinChances(numReserve)
self.suitInfos['reserveSuits'] = []
for i in xrange(len(self.reserveCogSpecs)):
spec = self.reserveCogSpecs[i]
suitDict = getSuitDict(spec, i)
suitDict['joinChance'] = joinChances[i]
self.suitInfos['reserveSuits'].append(suitDict)
def __genSuitObject(self, suitDict, reserve):
suit = self.cogCtor(simbase.air, self)
dna = SuitDNA.SuitDNA()
dna.newSuitRandom(level=SuitDNA.getRandomSuitType(suitDict['level']), dept=suitDict['track'])
suit.dna = dna
suit.setLevel(suitDict['level'])
suit.setSkeleRevives(suitDict.get('revives'))
suit.setLevelDoId(self.level.doId)
suit.setCogId(suitDict['cogId'])
suit.setReserve(reserve)
if suitDict['skeleton']:
suit.setSkelecog(1)
suit.generateWithRequired(suitDict['zoneId'])
suit.boss = suitDict['boss']
return suit
def genSuits(self):
suitHandles = {}
activeSuits = []
for activeSuitInfo in self.suitInfos['activeSuits']:
suit = self.__genSuitObject(activeSuitInfo, 0)
suit.setBattleCellIndex(activeSuitInfo['battleCell'])
activeSuits.append(suit)
suitHandles['activeSuits'] = activeSuits
reserveSuits = []
for reserveSuitInfo in self.suitInfos['reserveSuits']:
suit = self.__genSuitObject(reserveSuitInfo, 1)
reserveSuits.append([suit, reserveSuitInfo['joinChance'], reserveSuitInfo['battleCell']])
suitHandles['reserveSuits'] = reserveSuits
return suitHandles
def __suitCanJoinBattle(self, cellId):
battle = self.battleMgr.getBattle(cellId)
if not battle.suitCanJoin():
return 0
return 1
def requestBattle(self, suit, toonId):
cellIndex = suit.getBattleCellIndex()
cellSpec = self.battleCellSpecs[cellIndex]
pos = cellSpec['pos']
zone = self.level.getZoneId(self.level.getEntityZoneEntId(cellSpec['parentEntId']))
maxSuits = 4
self.battleMgr.newBattle(cellIndex, zone, pos, suit, toonId, self.__handleRoundFinished, self.__handleBattleFinished, maxSuits)
for otherSuit in self.battleCellId2suits[cellIndex]:
if otherSuit is not suit:
if self.__suitCanJoinBattle(cellIndex):
self.battleMgr.requestBattleAddSuit(cellIndex, otherSuit)
else:
battle = self.battleMgr.getBattle(cellIndex)
if battle:
self.notify.warning('battle not joinable: numSuits=%s, joinable=%s, fsm=%s, toonId=%s' % (len(battle.suits),
battle.isJoinable(),
battle.fsm.getCurrentState().getName(),
toonId))
else:
self.notify.warning('battle not joinable: no battle for cell %s, toonId=%s' % (cellIndex, toonId))
return 0
return 1
def __handleRoundFinished(self, cellId, toonIds, totalHp, deadSuits):
totalMaxHp = 0
level = self.level
battle = self.battleMgr.cellId2battle[cellId]
for suit in battle.suits:
totalMaxHp += suit.maxHP
for suit in deadSuits:
level.suits.remove(suit)
cellReserves = []
for info in level.reserveSuits:
if info[2] == cellId:
cellReserves.append(info)
numSpotsAvailable = 4 - len(battle.suits)
if len(cellReserves) > 0 and numSpotsAvailable > 0:
self.joinedReserves = []
if len(battle.suits) == 0:
hpPercent = 100
else:
hpPercent = 100 - totalHp / totalMaxHp * 100.0
for info in cellReserves:
if info[1] <= hpPercent and len(self.joinedReserves) < numSpotsAvailable:
level.suits.append(info[0])
self.joinedReserves.append(info)
info[0].setBattleCellIndex(cellId)
for info in self.joinedReserves:
level.reserveSuits.remove(info)
if len(self.joinedReserves) > 0:
self.reservesJoining(battle)
level.d_setSuits()
return
if len(battle.suits) == 0:
if battle:
battle.resume()
else:
battle = self.battleMgr.cellId2battle.get(cellId)
if battle:
battle.resume()
def __handleBattleFinished(self, zoneId):
pass
def reservesJoining(self, battle):
for info in self.joinedReserves:
battle.suitRequestJoin(info[0])
battle.resume()
self.joinedReserves = []
def getDoId(self):
return 0
def removeSuit(self, suit):
suit.requestDelete()
def suitBattleCellChange(self, suit, oldCell, newCell):
if oldCell is not None:
if oldCell in self.battleCellId2suits:
self.battleCellId2suits[oldCell].remove(suit)
else:
self.notify.warning('FIXME crash bandaid suitBattleCellChange suit.doId =%s, oldCell=%s not in battleCellId2Suits.keys %s' % (suit.doId, oldCell, self.battleCellId2suits.keys()))
blocker = self.battleMgr.battleBlockers.get(oldCell)
if blocker:
blocker.removeSuit(suit)
if newCell is not None:
self.battleCellId2suits[newCell].append(suit)
def addSuitToBlocker(self = self):
blocker = self.battleMgr.battleBlockers.get(newCell)
if blocker:
blocker.addSuit(suit)
return 1
return 0
if not addSuitToBlocker():
self.accept(self.getBattleBlockerEvent(newCell), addSuitToBlocker)
return
def getBattleBlockerEvent(self, cellId):
return 'battleBlockerAdded-' + str(self.level.doId) + '-' + str(cellId)