from pandac.PandaModules import * from toontown.toonbase.ToonBaseGlobal import * from direct.gui.DirectGui import * from pandac.PandaModules import * from direct.distributed.ClockDelta import * from direct.interval.IntervalGlobal import * import math from toontown.toonbase import ToontownGlobals from direct.distributed import DistributedObject from direct.directnotify import DirectNotifyGlobal from direct.fsm import ClassicFSM from direct.fsm import State from toontown.toon import Toon from direct.showbase import RandomNumGen from direct.task.Task import Task from toontown.toonbase import TTLocalizer import random import cPickle import time from direct.showbase import PythonUtil from toontown.hood import Place import Estate import HouseGlobals from toontown.estate import GardenGlobals from toontown.estate import DistributedFlower from toontown.estate import DistributedGagTree from toontown.estate import DistributedStatuary import GardenDropGame import GardenProgressMeter from toontown.estate import FlowerSellGUI from toontown.fishing import FishSellGUI from toontown.toontowngui import TTDialog class DistributedEstate(DistributedObject.DistributedObject): notify = directNotify.newCategory('DistributedEstate') def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) self.closestHouse = 0 self.ground = None self.dayTrack = None self.sunTrack = None self.airplane = None self.flowerSellBox = None self.estateDoneEvent = 'estateDone' self.load() self.initCamera() self.plotTable = [] self.idList = [] base.estate = self self.flowerGuiDoneEvent = 'flowerGuiDone' self.fishGuiDoneEvent = 'fishGuiDone' return def disable(self): self.notify.debug('disable') self.__stopBirds() self.__stopCrickets() DistributedObject.DistributedObject.disable(self) self.ignore('enterFlowerSellBox') self.ignore('enterFishSellBox') def delete(self): self.notify.debug('delete') self.unload() DistributedObject.DistributedObject.delete(self) def load(self): self.defaultSignModel = loader.loadModel('phase_13/models/parties/eventSign') self.activityIconsModel = loader.loadModel('phase_4/models/parties/eventSignIcons') self.lt = base.localAvatar newsManager = base.cr.newsManager if newsManager: holidayIds = base.cr.newsManager.getDecorationHolidayId() if ToontownGlobals.HALLOWEEN_COSTUMES in holidayIds or ToontownGlobals.SPOOKY_COSTUMES in holidayIds: self.loadWitch() else: self.loadAirplane() self.loadFlowerSellBox() self.loadFishSellBox() self.oldClear = base.win.getClearColor() base.win.setClearColor(Vec4(0.09, 0.55, 0.21, 1.0)) if config.GetBool('want-garden-game', False): self.startGame() def unload(self): self.ignoreAll() base.win.setClearColor(self.oldClear) self.__killAirplaneTask() self.__killDaytimeTask() self.__stopBirds() self.__stopCrickets() if self.dayTrack: self.dayTrack.pause() self.dayTrack = None self.__killSunTask() if self.sunTrack: self.sunTrack.pause() self.sunTrack = None if self.ground: self.ground.removeNode() del self.ground if self.airplane: self.airplane.removeNode() del self.airplane self.airplane = None if self.flowerSellBox: self.flowerSellBox.removeNode() del self.flowerSellBox self.flowerSellBox = None if self.fishSellBox: self.fishSellBox.removeNode() del self.fishSellBox self.fishSellBox = None if config.GetBool('want-garden-game', False): GardenDropGame.GardenDropGame().endGame() return def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) self.accept('gardenGame', self.startGame) def startGame(self): if config.GetBool('want-garden-game', False): self.game = GardenDropGame.GardenDropGame().playGardenDrop() else: self.game = GardenDropGame.GardenDropGame() def loadAirplane(self): self.airplane = loader.loadModel('phase_4/models/props/airplane.bam') self.airplane.setScale(4) self.airplane.setPos(0, 0, 1) self.banner = self.airplane.find('**/*banner') bannerText = TextNode('bannerText') bannerText.setTextColor(1, 0, 0, 1) bannerText.setAlign(bannerText.ACenter) bannerText.setFont(ToontownGlobals.getSignFont()) bannerText.setText('Cog invasion!!!') self.bn = self.banner.attachNewNode(bannerText.generate()) self.bn.setHpr(180, 0, 0) self.bn.setPos(-1.8, 0.1, 0) self.bn.setScale(0.35) self.banner.hide() def loadWitch(self): if not self.airplane: self.airplane = loader.loadModel('phase_4/models/props/tt_m_prp_ext_flyingWitch.bam') def __replaceAirplane__(): self.airplane.reparentTo(hidden) del self.airplane self.airplane = loader.loadModel('phase_4/models/props/tt_m_prp_ext_flyingWitch.bam') self.airplane.setScale(2) self.airplane.setPos(0, 0, 1) bannerText = TextNode('bannerText') bannerText.setTextColor(1, 0, 0, 1) bannerText.setAlign(bannerText.ACenter) bannerText.setFont(ToontownGlobals.getSignFont()) bannerText.setText('Happy halloween!!!') self.bn = self.airplane.attachNewNode(bannerText.generate()) self.bn.setHpr(0, 0, 0) self.bn.setPos(20.0, -.1, 0) self.bn.setScale(2.35) replacement = Sequence(LerpColorScaleInterval(self.airplane, 0.1, Vec4(1, 1, 1, 0)), Func(__replaceAirplane__), LerpColorScaleInterval(self.airplane, 0.1, Vec4(1, 1, 1, 1))) replacement.start() def unloadWitch(self): def __replaceWitch__(): self.airplane.reparentTo(hidden) del self.airplane del self.bn self.airplane = loader.loadModel('phase_4/models/props/airplane.bam') self.airplane.setScale(4) self.airplane.setPos(0, 0, 1) self.banner = self.airplane.find('**/*banner') bannerText = TextNode('bannerText') bannerText.setTextColor(1, 0, 0, 1) bannerText.setAlign(bannerText.ACenter) bannerText.setFont(ToontownGlobals.getSignFont()) bannerText.setText('Happy halloween!!!') self.bn = self.banner.attachNewNode(bannerText.generate()) self.bn.setHpr(180, 0, 0) self.bn.setPos(-1.8, 0.1, 0) self.bn.setScale(0.35) self.banner.hide() replacement = Sequence(LerpColorScaleInterval(self.airplane, 0.1, Vec4(1, 1, 1, 0)), Func(__replaceWitch__), LerpColorScaleInterval(self.airplane, 0.1, Vec4(1, 1, 1, 1))) replacement.start() def initCamera(self): initCamPos = VBase3(0, -10, 5) initCamHpr = VBase3(0, -10, 0) def setHouseInfo(self, houseInfo): self.notify.debug('setHouseInfo') houseType, housePos = cPickle.loads(houseInfo) self.loadEstate(houseType, housePos) def loadEstate(self, indexList, posList): self.notify.debug('loadEstate') self.houseType = indexList self.housePos = posList self.numHouses = len(self.houseType) self.house = [None] * self.numHouses return def __startAirplaneTask(self): self.theta = 0 self.phi = 0 taskMgr.remove(self.taskName('estate-airplane')) taskMgr.add(self.airplaneFlyTask, self.taskName('estate-airplane')) def __pauseAirplaneTask(self): pause = 45 self.phi = 0 self.airplane.hide() self.theta = (self.theta + 10) % 360 taskMgr.remove(self.taskName('estate-airplane')) taskMgr.doMethodLater(pause, self.airplaneFlyTask, self.taskName('estate-airplane')) def __killAirplaneTask(self): taskMgr.remove(self.taskName('estate-airplane')) def airplaneFlyTask(self, task): rad = 300.0 amp = 80.0 self.theta += 0.25 self.phi += 0.005 sinPhi = math.sin(self.phi) if sinPhi <= 0: self.__pauseAirplaneTask() angle = math.pi * self.theta / 180.0 x = rad * math.cos(angle) y = rad * math.sin(angle) z = amp * sinPhi self.airplane.reparentTo(render) self.airplane.setH(90 + self.theta + 180) self.airplane.setPos(x, y, z) return Task.cont def sendHouseColor(self, index, r, g, b, a): self.house[index].setColor(r, g, b, a) def setTreasureIds(self, doIds): self.flyingTreasureId = [] for id in doIds: self.flyingTreasureId.append(id) def setDawnTime(self, ts): self.notify.debug('setDawnTime') self.dawnTime = ts self.sendUpdate('requestServerTime', []) def setServerTime(self, ts): self.notify.debug('setServerTime') self.serverTime = ts self.clientTime = time.time() % HouseGlobals.DAY_NIGHT_PERIOD self.deltaTime = self.clientTime - self.serverTime if base.dayNightEnabled: self.__initDaytimeTask() self.__initSunTask() self.__startAirplaneTask() def getDeltaTime(self): curTime = time.time() % HouseGlobals.DAY_NIGHT_PERIOD dawnTime = self.dawnTime dT = (curTime - dawnTime - self.deltaTime) % HouseGlobals.DAY_NIGHT_PERIOD self.notify.debug( 'getDeltaTime = %s. curTime=%s. dawnTime=%s. serverTime=%s. deltaTime=%s' % (dT, curTime, dawnTime, self.serverTime, self.deltaTime)) return dT def __initDaytimeTask(self): self.__killDaytimeTask() task = Task(self.__dayTimeTask) dT = self.getDeltaTime() task.ts = dT taskMgr.add(task, self.taskName('daytime')) def __killDaytimeTask(self): taskMgr.remove(self.taskName('daytime')) def __dayTimeTask(self, task): taskName = self.taskName('daytime') track = Sequence(Parallel(LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, HouseGlobals.HALF_DAY_PERIOD, Vec4(1, 0.6, 0.6, 1)), LerpColorScaleInterval(base.cr.playGame.hood.sky, HouseGlobals.HALF_DAY_PERIOD, Vec4(1, 0.8, 0.8, 1))), Parallel(LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, HouseGlobals.HALF_NIGHT_PERIOD, Vec4(0.2, 0.2, 0.5, 1)), LerpColorScaleInterval(base.cr.playGame.hood.sky, HouseGlobals.HALF_NIGHT_PERIOD, Vec4(0.4, 0.4, 0.6, 1))), Parallel(LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, HouseGlobals.HALF_NIGHT_PERIOD, Vec4(0.6, 0.6, 0.8, 1)), LerpColorScaleInterval(base.cr.playGame.hood.sky, HouseGlobals.HALF_NIGHT_PERIOD, Vec4(0.7, 0.7, 0.8, 1))), Parallel(LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, HouseGlobals.HALF_DAY_PERIOD, Vec4(1, 1, 1, 1)), LerpColorScaleInterval(base.cr.playGame.hood.sky, HouseGlobals.HALF_DAY_PERIOD, Vec4(1, 1, 1, 1))), Func(base.cr.playGame.hood.loader.geom.clearColorScale), Func(base.cr.playGame.hood.sky.clearColorScale)) if self.dayTrack: self.dayTrack.finish() self.dayTrack = track ts = 0 if hasattr(task, 'ts'): ts = task.ts self.dayTrack.start(ts) taskMgr.doMethodLater(HouseGlobals.DAY_NIGHT_PERIOD - ts, self.__dayTimeTask, self.taskName('daytime')) return Task.done def __initSunTask(self): self.__killSunTask() task = Task(self.__sunTask) dT = self.getDeltaTime() task.ts = dT taskMgr.add(task, self.taskName('sunTask')) def __killSunTask(self): taskMgr.remove(self.taskName('sunTask')) def __sunTask(self, task): sunMoonNode = base.cr.playGame.hood.loader.sunMoonNode sun = base.cr.playGame.hood.loader.sun h = 30 halfPeriod = HouseGlobals.DAY_NIGHT_PERIOD / 2.0 track = Sequence(Parallel(LerpHprInterval(sunMoonNode, HouseGlobals.HALF_DAY_PERIOD, Vec3(0, 0, 0)), LerpColorScaleInterval(sun, HouseGlobals.HALF_DAY_PERIOD, Vec4(1, 1, 0.5, 1))), Func(sun.clearColorScale), Func(self.__stopBirds), LerpHprInterval(sunMoonNode, 0.2, Vec3(0, -h - 3, 0)), LerpHprInterval(sunMoonNode, 0.1, Vec3(0, -h + 2, 0)), LerpHprInterval(sunMoonNode, 0.1, Vec3(0, -h - 1.5, 0)), LerpHprInterval(sunMoonNode, 0.1, Vec3(0, -h, 0)), Func(self.notify.debug, 'night'), Wait(HouseGlobals.HALF_NIGHT_PERIOD - 0.5), LerpHprInterval(sunMoonNode, HouseGlobals.HALF_NIGHT_PERIOD, Vec3(0, 0, 0)), Func(self.__startBirds), LerpHprInterval(sunMoonNode, 0.2, Vec3(0, h + 3, 0)), LerpHprInterval(sunMoonNode, 0.1, Vec3(0, h - 2, 0)), LerpHprInterval(sunMoonNode, 0.1, Vec3(0, h + 1.5, 0)), LerpHprInterval(sunMoonNode, 0.1, Vec3(0, h, 0)), Func(self.notify.debug, 'day'), Func(sunMoonNode.setHpr, 0, h, 0), Wait(HouseGlobals.HALF_DAY_PERIOD - 0.5)) if self.sunTrack: self.sunTrack.finish() self.sunTrack = track ts = 0 if hasattr(task, 'ts'): ts = task.ts if ts > HouseGlobals.HALF_DAY_PERIOD and ts < HouseGlobals.DAY_NIGHT_PERIOD - HouseGlobals.HALF_DAY_PERIOD: self.__stopBirds() self.__startCrickets() else: self.__stopCrickets() self.__startBirds() self.sunTrack.start(ts) taskMgr.doMethodLater(HouseGlobals.DAY_NIGHT_PERIOD - ts, self.__sunTask, self.taskName('sunTask')) return Task.done def __stopBirds(self): taskMgr.remove('estate-birds') def __startBirds(self): self.__stopBirds() taskMgr.doMethodLater(1, self.__birds, 'estate-birds') def __birds(self, task): base.playSfx(random.choice(base.cr.playGame.hood.loader.birdSound)) t = random.random() * 20.0 + 1 taskMgr.doMethodLater(t, self.__birds, 'estate-birds') return Task.done def __stopCrickets(self): taskMgr.remove('estate-crickets') def __startCrickets(self): self.__stopCrickets() taskMgr.doMethodLater(1, self.__crickets, 'estate-crickets') def __crickets(self, task): sfx = random.choice(base.cr.playGame.hood.loader.cricketSound) track = Sequence(Func(base.playSfx, sfx), Wait(1)) track.start() t = random.random() * 20.0 + 1 taskMgr.doMethodLater(t, self.__crickets, 'estate-crickets') return Task.done def getLastEpochTimeStamp(self): return self.lastEpochTimeStamp def setLastEpochTimeStamp(self, ts): self.lastEpochTimeStamp = ts def getIdList(self): return self.idList def setIdList(self, idList): self.idList = idList def loadFlowerSellBox(self): self.flowerSellBox = loader.loadModel('phase_5.5/models/estate/wheelbarrel.bam') self.flowerSellBox.setPos(-142.586, 4.353, 0.025) self.flowerSellBox.reparentTo(render) colNode = self.flowerSellBox.find('**/collision') colNode.setName('FlowerSellBox') self.accept('enterFlowerSellBox', self.__touchedFlowerSellBox) def __touchedFlowerSellBox(self, entry): if base.localAvatar.doId in self.idList: if len(base.localAvatar.flowerBasket.flowerList): self.popupFlowerGUI() def __handleFlowerSaleDone(self, sell = 0): self.ignore(self.flowerGuiDoneEvent) self.sendUpdate('completeFlowerSale', [sell]) self.ignore('stoppedAsleep') self.flowerGui.destroy() self.flowerGui = None def popupFlowerGUI(self): self.acceptOnce(self.flowerGuiDoneEvent, self.__handleFlowerSaleDone) self.flowerGui = FlowerSellGUI.FlowerSellGUI(self.flowerGuiDoneEvent) self.accept('stoppedAsleep', self.__handleSaleDone) def loadFishSellBox(self): self.fishSellBox = loader.loadModel('phase_4/models/minigames/treasure_chest.bam') self.fishSellBox.setPos(45, -165.75, 0.025) self.fishSellBox.setH(210) self.fishSellBox.reparentTo(render) cSphere = CollisionSphere(0.0, 0.0, 0.0, 2.25) cSphere.setTangible(0) colNode = CollisionNode('FishSellBox') colNode.addSolid(cSphere) cSpherePath = self.fishSellBox.attachNewNode(colNode) cSpherePath.hide() cSpherePath.setCollideMask(ToontownGlobals.WallBitmask) self.accept('enterFishSellBox', self.__touchedFishSellBox) def __touchedFishSellBox(self, entry): if base.localAvatar.doId in self.idList: if base.localAvatar.fishTank.getFish(): self.popupFishGUI() def __handleFishSaleDone(self, sell=0): self.ignore(self.fishGuiDoneEvent) self.sendUpdate('completeFishSale', [sell]) self.ignore('stoppedAsleep') self.fishGui.destroy() self.fishGui = None def popupFishGUI(self): self.acceptOnce(self.fishGuiDoneEvent, self.__handleFishSaleDone) self.fishGui = FishSellGUI.FishSellGUI(self.fishGuiDoneEvent) self.accept('stoppedAsleep', self.__handleFishSaleDone) def thankSeller(self, mode, fish, maxFish): if mode == ToontownGlobals.FISHSALE_TROPHY: base.localAvatar.setSystemMessage(0, TTLocalizer.STOREOWNER_TROPHY % (fish, maxFish)) elif mode == ToontownGlobals.FISHSALE_COMPLETE: base.localAvatar.setSystemMessage(0, TTLocalizer.STOREOWNER_THANKSFISH) elif mode == ToontownGlobals.FISHSALE_NONE: base.localAvatar.setSystemMessage(0, TTLocalizer.STOREOWNER_NOFISH) def closedAwardDialog(self, value): self.awardDialog.destroy() base.cr.playGame.getPlace().detectedGardenPlotDone() def awardedTrophy(self, avId): if base.localAvatar.doId == avId: base.cr.playGame.getPlace().detectedGardenPlotUse() msg = TTLocalizer.GardenTrophyAwarded % (len(base.localAvatar.getFlowerCollection()), GardenGlobals.getNumberOfFlowerVarieties()) self.awardDialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=msg, command=self.closedAwardDialog) def setClouds(self, clouds): self.clouds = clouds base.cr.playGame.hood.loader.setCloudSwitch(clouds) def getClouds(self): if hasattr(self, 'clouds'): return self.clouds else: return 0 def cannonsOver(self, arg = None): base.localAvatar.setSystemMessage(0, TTLocalizer.EstateCannonGameEnd) def gameTableOver(self, arg = None): base.localAvatar.setSystemMessage(0, TTLocalizer.GameTableRentalEnd)