from direct.directnotify import DirectNotifyGlobal import random import types import SuitBuildingGlobals from otp.ai.AIBaseGlobal import * from toontown.suit import DistributedSuitAI from toontown.suit import SuitDNA from toontown.suit.SuitInvasionGlobals import IFSkelecog, IFWaiter, IFV2 class SuitPlannerInteriorAI: notify = DirectNotifyGlobal.directNotify.newCategory('SuitPlannerInteriorAI') def __init__(self, numFloors, bldgLevel, bldgTrack, zone): self.dbg_4SuitsPerFloor = config.GetBool('4-suits-per-floor', 0) self.dbg_1SuitPerFloor = config.GetBool('1-suit-per-floor', 0) self.zoneId = zone self.numFloors = numFloors self.respectInvasions = 1 dbg_defaultSuitName = simbase.config.GetString('suit-type', 'random') if dbg_defaultSuitName == 'random': self.dbg_defaultSuitType = None else: self.dbg_defaultSuitType = SuitDNA.getSuitType(dbg_defaultSuitName) if isinstance(bldgLevel, types.StringType): self.notify.warning('bldgLevel is a string!') bldgLevel = int(bldgLevel) self._genSuitInfos(numFloors, bldgLevel, bldgTrack) return def __genJoinChances(self, num): joinChances = [] for currChance in xrange(num): joinChances.append(random.randint(1, 100)) joinChances.sort(cmp) return joinChances def _genSuitInfos(self, numFloors, bldgLevel, bldgTrack): self.suitInfos = [] self.notify.debug('\n\ngenerating suitsInfos with numFloors (' + str(numFloors) + ') bldgLevel (' + str(bldgLevel) + '+1) and bldgTrack (' + str(bldgTrack) + ')') for currFloor in xrange(numFloors): infoDict = {} lvls = self.__genLevelList(bldgLevel, currFloor, numFloors) activeDicts = [] if self.dbg_4SuitsPerFloor: numActive = 4 else: numActive = random.randint(1, min(4, len(lvls))) if currFloor + 1 == numFloors and len(lvls) > 1: origBossSpot = len(lvls) - 1 if numActive == 1: newBossSpot = numActive - 1 else: newBossSpot = numActive - 2 tmp = lvls[newBossSpot] lvls[newBossSpot] = lvls[origBossSpot] lvls[origBossSpot] = tmp bldgInfo = SuitBuildingGlobals.SuitBuildingInfo[bldgLevel] if len(bldgInfo) > SuitBuildingGlobals.SUIT_BLDG_INFO_REVIVES: revives = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_REVIVES][0] else: revives = 0 for currActive in xrange(numActive - 1, -1, -1): level = lvls[currActive] type = self.__genNormalSuitType(level) activeDict = {} activeDict['type'] = type activeDict['track'] = bldgTrack activeDict['level'] = level activeDict['revives'] = revives activeDicts.append(activeDict) infoDict['activeSuits'] = activeDicts reserveDicts = [] numReserve = len(lvls) - numActive joinChances = self.__genJoinChances(numReserve) for currReserve in xrange(numReserve): level = lvls[currReserve + numActive] type = self.__genNormalSuitType(level) reserveDict = {} reserveDict['type'] = type reserveDict['track'] = bldgTrack reserveDict['level'] = level reserveDict['revives'] = revives reserveDict['joinChance'] = joinChances[currReserve] reserveDicts.append(reserveDict) infoDict['reserveSuits'] = reserveDicts self.suitInfos.append(infoDict) def __genNormalSuitType(self, lvl): if self.dbg_defaultSuitType != None: return self.dbg_defaultSuitType return SuitDNA.getRandomSuitType(lvl) def __genLevelList(self, bldgLevel, currFloor, numFloors): bldgInfo = SuitBuildingGlobals.SuitBuildingInfo[bldgLevel] if self.dbg_1SuitPerFloor: return [1] elif self.dbg_4SuitsPerFloor: return [5, 6, 7, 10] lvlPoolRange = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_LVL_POOL] maxFloors = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_FLOORS][1] lvlPoolMults = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_LVL_POOL_MULTS] floorIdx = min(currFloor, maxFloors - 1) lvlPoolMin = lvlPoolRange[0] * lvlPoolMults[floorIdx] lvlPoolMax = lvlPoolRange[1] * lvlPoolMults[floorIdx] lvlPool = random.randint(int(lvlPoolMin), int(lvlPoolMax)) lvlMin = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_SUIT_LVLS][0] lvlMax = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_SUIT_LVLS][1] self.notify.debug('Level Pool: ' + str(lvlPool)) lvlList = [] while lvlPool >= lvlMin: newLvl = random.randint(lvlMin, min(lvlPool, lvlMax)) lvlList.append(newLvl) lvlPool -= newLvl if currFloor + 1 == numFloors: bossLvlRange = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_BOSS_LVLS] newLvl = random.randint(bossLvlRange[0], bossLvlRange[1]) lvlList.append(newLvl) lvlList.sort(cmp) self.notify.debug('LevelList: ' + repr(lvlList)) return lvlList def __setupSuitInfo(self, suit, bldgTrack, suitLevel, suitType): suitDeptIndex, suitTypeIndex, flags = simbase.air.suitInvasionManager.getInvadingCog() if self.respectInvasions: if suitDeptIndex is not None: bldgTrack = SuitDNA.suitDepts[suitDeptIndex] if suitTypeIndex is not None: suitName = SuitDNA.getSuitName(suitDeptIndex, suitTypeIndex) suitType = SuitDNA.getSuitType(suitName) suitLevel = min(max(suitLevel, suitType), suitType + 4) dna = SuitDNA.SuitDNA() dna.newSuitRandom(suitType, bldgTrack) suit.dna = dna suit.setLevel(suitLevel) return flags def __genSuitObject(self, suitZone, suitType, bldgTrack, suitLevel, revives = 0): newSuit = DistributedSuitAI.DistributedSuitAI(simbase.air, None) flags = self.__setupSuitInfo(newSuit, bldgTrack, suitLevel, suitType) if flags & IFSkelecog: newSuit.setSkelecog(1) newSuit.setSkeleRevives(revives) newSuit.generateWithRequired(suitZone) if flags & IFWaiter: newSuit.b_setWaiter(1) if flags & IFV2: newSuit.b_setSkeleRevives(1) newSuit.node().setName('suit-%s' % newSuit.doId) return newSuit def myPrint(self): self.notify.info('Generated suits for building: ') for currInfo in suitInfos: whichSuitInfo = suitInfos.index(currInfo) + 1 self.notify.debug(' Floor ' + str(whichSuitInfo) + ' has ' + str(len(currInfo[0])) + ' active suits.') for currActive in xrange(len(currInfo[0])): self.notify.debug(' Active suit ' + str(currActive + 1) + ' is of type ' + str(currInfo[0][currActive][0]) + ' and of track ' + str(currInfo[0][currActive][1]) + ' and of level ' + str(currInfo[0][currActive][2])) self.notify.debug(' Floor ' + str(whichSuitInfo) + ' has ' + str(len(currInfo[1])) + ' reserve suits.') for currReserve in xrange(len(currInfo[1])): self.notify.debug(' Reserve suit ' + str(currReserve + 1) + ' is of type ' + str(currInfo[1][currReserve][0]) + ' and of track ' + str(currInfo[1][currReserve][1]) + ' and of lvel ' + str(currInfo[1][currReserve][2]) + ' and has ' + str(currInfo[1][currReserve][3]) + '% join restriction.') def genFloorSuits(self, floor): suitHandles = {} floorInfo = self.suitInfos[floor] activeSuits = [] for activeSuitInfo in floorInfo['activeSuits']: suit = self.__genSuitObject(self.zoneId, activeSuitInfo['type'], activeSuitInfo['track'], activeSuitInfo['level'], activeSuitInfo['revives']) activeSuits.append(suit) suitHandles['activeSuits'] = activeSuits reserveSuits = [] for reserveSuitInfo in floorInfo['reserveSuits']: suit = self.__genSuitObject(self.zoneId, reserveSuitInfo['type'], reserveSuitInfo['track'], reserveSuitInfo['level'], reserveSuitInfo['revives']) reserveSuits.append((suit, reserveSuitInfo['joinChance'])) suitHandles['reserveSuits'] = reserveSuits return suitHandles def genSuits(self): suitHandles = [] for floor in xrange(len(self.suitInfos)): floorSuitHandles = self.genFloorSuits(floor) suitHandles.append(floorSuitHandles) return suitHandles