from otp.ai.AIBaseGlobal import * from toontown.suit import SuitDNA from direct.directnotify import DirectNotifyGlobal from toontown.suit import DistributedSuitAI from toontown.building import SuitBuildingGlobals from toontown.suit.SuitInvasionGlobals import IFSkelecog, IFWaiter, IFV2 import types, math, random BASE_RESERVE = 10 MAX_RESERVES = { 's': BASE_RESERVE * .9, 'm': BASE_RESERVE * 1.1, 'l': BASE_RESERVE * 1.25, 'c': BASE_RESERVE * 1.5, } def filterReviveChance(track, revive): if revive >= 0: return revive return random.randint(config.GetInt('min-lt-vs', 0), config.GetInt('max-lt-vs', 2)) # implements difficulty 19 / LT def getMaxReserves(track): return int(math.ceil(MAX_RESERVES[track])) class SuitPlannerCogdoInteriorAI: notify = DirectNotifyGlobal.directNotify.newCategory('SuitPlannerCogdoInteriorAI') def __init__(self, layout, difficulty, track, zoneId, numFloors = 1): self.zoneId = zoneId self.numFloors = layout.getNumFloors() difficulty = min(difficulty + 4, len(SuitBuildingGlobals.SuitBuildingInfo) - 1) self.respectInvasions = 1 if isinstance(difficulty, types.StringType): self.notify.warning('difficulty is a string!') difficulty = int(difficulty) self._genSuitInfos(numFloors, difficulty, track) def __genJoinChances(self, num): joinChances = [] for currChance in range(num): joinChances.append(random.randint(1, 100)) joinChances.sort(cmp) return joinChances def _genSuitInfos(self, numFloors, difficulty, bldgTrack): self.suitInfos = [] self.notify.debug('\n\ngenerating suitsInfos with numFloors (' + str(numFloors) + ') difficulty (' + str(difficulty) + '+1) and bldgTrack (' + str(bldgTrack) + ')') for currFloor in range(numFloors): infoDict = {} lvls = self.__genLevelList(difficulty, currFloor, numFloors) activeDicts = [] 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[difficulty] if len(bldgInfo) > SuitBuildingGlobals.SUIT_BLDG_INFO_REVIVES: revives = bldgInfo[SuitBuildingGlobals.SUIT_BLDG_INFO_REVIVES][0] else: revives = 0 for currActive in range(numActive - 1, -1, -1): level = lvls[currActive] type = self.__genNormalSuitType(level) activeDict = {} activeDict['type'] = type activeDict['track'] = bldgTrack activeDict['level'] = level activeDict['revives'] = filterReviveChance(bldgTrack, revives) activeDicts.append(activeDict) infoDict['activeSuits'] = activeDicts reserveDicts = [] numReserve = min(len(lvls) - numActive, getMaxReserves(bldgTrack)) joinChances = self.__genJoinChances(numReserve) for currReserve in range(numReserve): level = lvls[currReserve + numActive] type = self.__genNormalSuitType(level) reserveDict = {} reserveDict['type'] = type reserveDict['track'] = bldgTrack reserveDict['level'] = level reserveDict['revives'] = filterReviveChance(bldgTrack, revives) reserveDict['joinChance'] = joinChances[currReserve] reserveDicts.append(reserveDict) infoDict['reserveSuits'] = reserveDicts self.suitInfos.append(infoDict) def __genNormalSuitType(self, lvl): return SuitDNA.getRandomSuitType(lvl) def __genLevelList(self, difficulty, currFloor, numFloors): bldgInfo = SuitBuildingGlobals.SuitBuildingInfo[difficulty] 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 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 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): print 'Generated suits for cogdo: ' for floor, currInfo in enumerate(self.suitInfos): floor += 1 actives = currInfo['activeSuits'] reserves = currInfo['reserveSuits'] print ' Floor %d has %d active suits.' % (floor, len(actives)) print ' Floor %d has %d reserve suits.' % (floor, len(reserves)) for idx, currActive in enumerate(actives): type, track, level, revives = map(lambda x: currActive[x], ('type', 'track', 'level', 'revives')) print '-- Active suit %d is %s, %s and level %d and revives is %d' % (idx, type, track, level, revives) for idx, currReserve in enumerate(reserves): type, track, level, revives, res = map(lambda x: currReserve[x], ('type', 'track', 'level', 'revives', 'joinChance')) print '- Reserve suit %d is %s, %s and level %d and JC = %d and revives is %d' % (idx, type, track, level, res, revives) 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 range(len(self.suitInfos)): floorSuitHandles = self.genFloorSuits(floor) suitHandles.append(floorSuitHandles) return suitHandles