from direct.interval.IntervalGlobal import * from direct.distributed.ClockDelta import * from ElevatorConstants import * import ElevatorUtils from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownBattleGlobals from direct.directnotify import DirectNotifyGlobal from direct.fsm import ClassicFSM, State from direct.distributed import DistributedObject from direct.fsm import State from toontown.battle import BattleBase from toontown.hood import ZoneUtil from toontown.suit import SuitDNA class DistributedSuitInterior(DistributedObject.DistributedObject): id = 0 def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) self.toons = [] self.activeIntervals = {} self.openSfx = base.loadSfx('phase_5/audio/sfx/elevator_door_open.ogg') self.closeSfx = base.loadSfx('phase_5/audio/sfx/elevator_door_close.ogg') self.suits = [] self.reserveSuits = [] self.joiningReserves = [] self.distBldgDoId = None self.currentFloor = -1 self.numFloors = None self.elevatorName = self.__uniqueName('elevator') self.floorModel = None self.elevatorOutOpen = 0 self.BottomFloor_SuitPositions = [Point3(0, 15, 0), Point3(10, 20, 0), Point3(-7, 24, 0), Point3(-10, 0, 0)] self.BottomFloor_SuitHs = [75, 170, -91, -44] self.Cubicle_SuitPositions = [Point3(0, 18, 0), Point3(10, 12, 0), Point3(-9, 11, 0), Point3(-3, 13, 0)] self.Cubicle_SuitHs = [170, 56, -52, 10] self.BossOffice_SuitPositions = [Point3(0, 15, 0), Point3(10, 20, 0), Point3(-10, 6, 0), Point3(-17, 34, 11)] self.BossOffice_SuitHs = [170, 120, 12, 38] self.waitMusic = base.loadMusic('phase_7/audio/bgm/encntr_toon_winning_indoor.ogg') self.elevatorMusic = base.loadMusic('phase_7/audio/bgm/tt_elevator.ogg') self.fsm = ClassicFSM.ClassicFSM('DistributedSuitInterior', [State.State('WaitForAllToonsInside', self.enterWaitForAllToonsInside, self.exitWaitForAllToonsInside, ['Elevator']), State.State('Elevator', self.enterElevator, self.exitElevator, ['Battle']), State.State('Battle', self.enterBattle, self.exitBattle, ['Resting', 'Reward', 'ReservesJoining']), State.State('ReservesJoining', self.enterReservesJoining, self.exitReservesJoining, ['Battle']), State.State('Resting', self.enterResting, self.exitResting, ['Elevator']), State.State('Reward', self.enterReward, self.exitReward, ['Off']), State.State('Off', self.enterOff, self.exitOff, ['Elevator', 'WaitForAllToonsInside', 'Battle'])], 'Off', 'Off') self.fsm.enterInitialState() return def __uniqueName(self, name): DistributedSuitInterior.id += 1 return name + '%d' % DistributedSuitInterior.id def generate(self): DistributedObject.DistributedObject.generate(self) self.announceGenerateName = self.uniqueName('generate') self.accept(self.announceGenerateName, self.handleAnnounceGenerate) self.elevatorModelIn = loader.loadModel('phase_4/models/modules/elevator') self.leftDoorIn = self.elevatorModelIn.find('**/left-door') self.rightDoorIn = self.elevatorModelIn.find('**/right-door') self.elevatorModelOut = loader.loadModel('phase_4/models/modules/elevator') self.leftDoorOut = self.elevatorModelOut.find('**/left-door') self.rightDoorOut = self.elevatorModelOut.find('**/right-door') def setElevatorLights(self, elevatorModel): npc = elevatorModel.findAllMatches('**/floor_light_?;+s') for i in xrange(npc.getNumPaths()): np = npc.getPath(i) floor = int(np.getName()[-1:]) - 1 if floor == self.currentFloor: np.setColor(LIGHT_ON_COLOR) elif floor < self.numFloors: np.setColor(LIGHT_OFF_COLOR) else: np.hide() def handleAnnounceGenerate(self, obj): self.ignore(self.announceGenerateName) self.sendUpdate('setAvatarJoined', []) def disable(self): self.fsm.requestFinalState() self.__cleanupIntervals() self.ignoreAll() self.__cleanup() DistributedObject.DistributedObject.disable(self) def delete(self): del self.waitMusic del self.elevatorMusic del self.openSfx del self.closeSfx del self.fsm base.localAvatar.inventory.setBattleCreditMultiplier(1) DistributedObject.DistributedObject.delete(self) def __cleanup(self): self.toons = [] self.suits = [] self.reserveSuits = [] self.joiningReserves = [] if self.elevatorModelIn != None: self.elevatorModelIn.removeNode() if self.elevatorModelOut != None: self.elevatorModelOut.removeNode() if self.floorModel != None: self.floorModel.removeNode() self.leftDoorIn = None self.rightDoorIn = None self.leftDoorOut = None self.rightDoorOut = None return def __addToon(self, toon): self.accept(toon.uniqueName('disable'), self.__handleUnexpectedExit, extraArgs=[toon]) def __handleUnexpectedExit(self, toon): self.notify.warning('handleUnexpectedExit() - toon: %d' % toon.doId) self.__removeToon(toon, unexpected=1) def __removeToon(self, toon, unexpected = 0): if self.toons.count(toon) == 1: self.toons.remove(toon) self.ignore(toon.uniqueName('disable')) def __finishInterval(self, name): if name in self.activeIntervals: interval = self.activeIntervals[name] if interval.isPlaying(): interval.finish() def __cleanupIntervals(self): for interval in self.activeIntervals.values(): interval.finish() self.activeIntervals = {} def __closeInElevator(self): self.leftDoorIn.setPos(3.5, 0, 0) self.rightDoorIn.setPos(-3.5, 0, 0) def getZoneId(self): return self.zoneId def setZoneId(self, zoneId): self.zoneId = zoneId def getExtZoneId(self): return self.extZoneId def setExtZoneId(self, extZoneId): self.extZoneId = extZoneId def getDistBldgDoId(self): return self.distBldgDoId def setDistBldgDoId(self, distBldgDoId): self.distBldgDoId = distBldgDoId def setNumFloors(self, numFloors): self.numFloors = numFloors def setToons(self, toonIds, hack): self.toonIds = toonIds oldtoons = self.toons self.toons = [] for toonId in toonIds: if toonId != 0: if toonId in self.cr.doId2do: toon = self.cr.doId2do[toonId] toon.stopSmooth() self.toons.append(toon) if oldtoons.count(toon) == 0: self.__addToon(toon) else: self.notify.warning('setToons() - no toon: %d' % toonId) for toon in oldtoons: if self.toons.count(toon) == 0: self.__removeToon(toon) def setSuits(self, suitIds, reserveIds, values): oldsuits = self.suits self.suits = [] self.joiningReserves = [] for suitId in suitIds: if suitId in self.cr.doId2do: suit = self.cr.doId2do[suitId] self.suits.append(suit) suit.fsm.request('Battle') suit.buildingSuit = 1 suit.reparentTo(render) if oldsuits.count(suit) == 0: self.joiningReserves.append(suit) else: self.notify.warning('setSuits() - no suit: %d' % suitId) self.reserveSuits = [] for index in xrange(len(reserveIds)): suitId = reserveIds[index] if suitId in self.cr.doId2do: suit = self.cr.doId2do[suitId] self.reserveSuits.append((suit, values[index])) else: self.notify.warning('setSuits() - no suit: %d' % suitId) if len(self.joiningReserves) > 0: self.fsm.request('ReservesJoining') def setState(self, state, timestamp): self.fsm.request(state, [globalClockDelta.localElapsedTime(timestamp)]) def d_elevatorDone(self): self.sendUpdate('elevatorDone', []) def d_reserveJoinDone(self): self.sendUpdate('reserveJoinDone', []) def enterOff(self, ts = 0): return None def exitOff(self): return None def enterWaitForAllToonsInside(self, ts = 0): return None def exitWaitForAllToonsInside(self): return None def __playElevator(self, ts, name, callback): SuitHs = [] SuitPositions = [] DeptName = SuitDNA.suitDeptFilenames[self.suits[0].style.dept] if self.floorModel: self.floorModel.removeNode() if self.currentFloor == 0: self.floorModel = loader.loadModel('phase_7/models/modules/suit_interior_%s' % DeptName) SuitHs = self.BottomFloor_SuitHs SuitPositions = self.BottomFloor_SuitPositions elif self.currentFloor == self.numFloors - 1: self.floorModel = loader.loadModel('phase_7/models/modules/boss_suit_office_%s' % DeptName) SuitHs = self.BossOffice_SuitHs SuitPositions = self.BossOffice_SuitPositions else: self.floorModel = loader.loadModel('phase_7/models/modules/cubicle_room') SuitHs = self.Cubicle_SuitHs SuitPositions = self.Cubicle_SuitPositions self.floorModel.reparentTo(render) elevIn = self.floorModel.find('**/elevator-in') elevOut = self.floorModel.find('**/elevator-out') for index in xrange(len(self.suits)): self.suits[index].setPos(SuitPositions[index]) if len(self.suits) > 2: self.suits[index].setH(SuitHs[index]) else: self.suits[index].setH(170) self.suits[index].loop('neutral') for toon in self.toons: toon.reparentTo(self.elevatorModelIn) index = self.toonIds.index(toon.doId) toon.setPos(ElevatorPoints[index][0], ElevatorPoints[index][1], ElevatorPoints[index][2]) toon.setHpr(180, 0, 0) toon.loop('neutral') self.elevatorModelIn.reparentTo(elevIn) self.leftDoorIn.setPos(3.5, 0, 0) self.rightDoorIn.setPos(-3.5, 0, 0) self.elevatorModelOut.reparentTo(elevOut) self.leftDoorOut.setPos(3.5, 0, 0) self.rightDoorOut.setPos(-3.5, 0, 0) camera.reparentTo(self.elevatorModelIn) camera.setH(180) camera.setPos(0, 14, 4) base.playMusic(self.elevatorMusic, looping=1, volume=0.8) track = Sequence(ElevatorUtils.getRideElevatorInterval(ELEVATOR_NORMAL), ElevatorUtils.getOpenInterval(self, self.leftDoorIn, self.rightDoorIn, self.openSfx, None, type=ELEVATOR_NORMAL), Func(camera.wrtReparentTo, render)) for toon in self.toons: track.append(Func(toon.wrtReparentTo, render)) track.append(Func(callback)) track.start(ts) self.activeIntervals[name] = track return def enterElevator(self, ts = 0): self.currentFloor += 1 self.cr.playGame.getPlace().currentFloor = self.currentFloor self.setElevatorLights(self.elevatorModelIn) self.setElevatorLights(self.elevatorModelOut) self.__playElevator(ts, self.elevatorName, self.__handleElevatorDone) mult = ToontownBattleGlobals.getCreditMultiplier(self.currentFloor) base.localAvatar.inventory.setBattleCreditMultiplier(mult) def __handleElevatorDone(self): self.d_elevatorDone() def exitElevator(self): self.elevatorMusic.stop() self.__finishInterval(self.elevatorName) return None def __playCloseElevatorOut(self, name): track = Sequence(Wait(SUIT_LEAVE_ELEVATOR_TIME), Parallel(SoundInterval(self.closeSfx), LerpPosInterval(self.leftDoorOut, ElevatorData[ELEVATOR_NORMAL]['closeTime'], ElevatorUtils.getLeftClosePoint(ELEVATOR_NORMAL), startPos=Point3(0, 0, 0), blendType='easeOut'), LerpPosInterval(self.rightDoorOut, ElevatorData[ELEVATOR_NORMAL]['closeTime'], ElevatorUtils.getRightClosePoint(ELEVATOR_NORMAL), startPos=Point3(0, 0, 0), blendType='easeOut'))) track.start() self.activeIntervals[name] = track def enterBattle(self, ts = 0): if self.elevatorOutOpen == 1: self.__playCloseElevatorOut(self.uniqueName('close-out-elevator')) camera.setPos(0, -15, 6) camera.headsUp(self.elevatorModelOut) return None def exitBattle(self): if self.elevatorOutOpen == 1: self.__finishInterval(self.uniqueName('close-out-elevator')) self.elevatorOutOpen = 0 return None def __playReservesJoining(self, ts, name, callback): index = 0 for suit in self.joiningReserves: suit.reparentTo(render) suit.setPos(self.elevatorModelOut, Point3(ElevatorPoints[index][0], ElevatorPoints[index][1], ElevatorPoints[index][2])) index += 1 suit.setH(180) suit.loop('neutral') track = Sequence(Func(camera.wrtReparentTo, self.elevatorModelOut), Func(camera.setPos, Point3(0, -8, 2)), Func(camera.setHpr, Vec3(0, 10, 0)), Parallel(SoundInterval(self.openSfx), LerpPosInterval(self.leftDoorOut, ElevatorData[ELEVATOR_NORMAL]['closeTime'], Point3(0, 0, 0), startPos=ElevatorUtils.getLeftClosePoint(ELEVATOR_NORMAL), blendType='easeOut'), LerpPosInterval(self.rightDoorOut, ElevatorData[ELEVATOR_NORMAL]['closeTime'], Point3(0, 0, 0), startPos=ElevatorUtils.getRightClosePoint(ELEVATOR_NORMAL), blendType='easeOut')), Wait(SUIT_HOLD_ELEVATOR_TIME), Func(camera.wrtReparentTo, render), Func(callback)) track.start(ts) self.activeIntervals[name] = track def enterReservesJoining(self, ts = 0): self.__playReservesJoining(ts, self.uniqueName('reserves-joining'), self.__handleReserveJoinDone) return None def __handleReserveJoinDone(self): self.joiningReserves = [] self.elevatorOutOpen = 1 self.d_reserveJoinDone() def exitReservesJoining(self): self.__finishInterval(self.uniqueName('reserves-joining')) return None def enterResting(self, ts = 0): base.playMusic(self.waitMusic, looping=1, volume=0.7) base.localAvatar.questMap.stop() self.__closeInElevator() def exitResting(self): self.waitMusic.stop() def enterReward(self, ts = 0): base.localAvatar.b_setParent(ToontownGlobals.SPHidden) request = {'loader': ZoneUtil.getBranchLoaderName(self.extZoneId), 'where': ZoneUtil.getToonWhereName(self.extZoneId), 'how': 'elevatorIn', 'hoodId': ZoneUtil.getHoodId(self.extZoneId), 'zoneId': self.extZoneId, 'shardId': None, 'avId': base.localAvatar.doId, 'bldgDoId': self.distBldgDoId} messenger.send('DSIDoneEvent', [request]) return def exitReward(self): return None