441 lines
18 KiB
Python
441 lines
18 KiB
Python
from panda3d.core import *
|
|
from toontown.toonbase.ToonBaseGlobal import *
|
|
from direct.gui.DirectGui 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.task.Task import Task
|
|
from toontown.toonbase import TTLocalizer
|
|
import random
|
|
import cPickle
|
|
import time
|
|
import HouseGlobals
|
|
from toontown.estate import GardenGlobals
|
|
from toontown.estate import FlowerSellGUI
|
|
from toontown.toontowngui import TTDialog
|
|
from toontown.fishing import FishSellGUI
|
|
|
|
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 = []
|
|
self.flowerGuiDoneEvent = 'flowerGuiDone'
|
|
self.fishGuiDoneEvent = 'fishGuiDone'
|
|
|
|
def disable(self):
|
|
self.notify.debug('disable')
|
|
self.__stopBirds()
|
|
self.__stopCrickets()
|
|
DistributedObject.DistributedObject.disable(self)
|
|
self.ignoreAll()
|
|
|
|
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')
|
|
if base.cr.newsManager.isHolidayRunning(ToontownGlobals.HALLOWEEN):
|
|
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))
|
|
|
|
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
|
|
|
|
def announceGenerate(self):
|
|
DistributedObject.DistributedObject.announceGenerate(self)
|
|
|
|
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(TTLocalizer.EstatePlaneReturn)
|
|
self.bn = self.banner.attachNewNode(bannerText.generate())
|
|
self.bn.setHpr(180, 0, 0)
|
|
self.bn.setPos(-5.8, 0.1, -0.25)
|
|
self.bn.setScale(0.95)
|
|
self.bn.setDepthTest(1)
|
|
self.bn.setDepthWrite(1)
|
|
self.bn.setDepthOffset(500)
|
|
|
|
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)
|
|
self.airplane.find('**/').setH(180)
|
|
bannerText = TextNode('bannerText')
|
|
bannerText.setTextColor(1, 0, 0, 1)
|
|
bannerText.setAlign(bannerText.ACenter)
|
|
bannerText.setFont(ToontownGlobals.getSignFont())
|
|
bannerText.setText(TTLocalizer.EstatePlaneHoliday)
|
|
self.bn = self.airplane.attachNewNode(bannerText.generate())
|
|
self.bn.setPos(-20.0, -.1, 0)
|
|
self.bn.setH(180)
|
|
self.bn.setScale(2.35)
|
|
self.bn.setDepthTest(1)
|
|
self.bn.setDepthWrite(1)
|
|
self.bn.setDepthOffset(500)
|
|
|
|
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(TTLocalizer.EstatePlaneReturn)
|
|
self.bn = self.banner.attachNewNode(bannerText.generate())
|
|
self.bn.setHpr(180, 0, 0)
|
|
self.bn.setPos(-5.8, 0.1, -0.25)
|
|
self.bn.setScale(0.95)
|
|
self.bn.setDepthTest(1)
|
|
self.bn.setDepthWrite(1)
|
|
self.bn.setDepthOffset(500)
|
|
|
|
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 setEstateType(self, index):
|
|
self.estateType = index
|
|
|
|
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
|
|
|
|
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.reparentTo(hidden)
|
|
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)
|
|
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.2, 0.2, 0.4, 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.5, 0.5, 0.6, 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 = base.cr.playGame.hood.loader.cricketSound
|
|
track = Sequence(Func(base.playSfx, random.choice(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 __handleSaleDone(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.__handleSaleDone)
|
|
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):
|
|
if sell:
|
|
self.sendUpdate('completeFishSale')
|
|
else:
|
|
base.localAvatar.setSystemMessage(0, TTLocalizer.STOREOWNER_NOFISH)
|
|
|
|
base.setCellsAvailable(base.bottomCells, 1)
|
|
base.cr.playGame.getPlace().setState('walk')
|
|
self.ignore(self.fishGuiDoneEvent)
|
|
self.ignore('stoppedAsleep')
|
|
self.fishGui.destroy()
|
|
self.fishGui = None
|
|
|
|
def popupFishGUI(self):
|
|
base.setCellsAvailable(base.bottomCells, 0)
|
|
base.cr.playGame.getPlace().setState('stopped')
|
|
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)
|
|
|
|
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)
|