toontown-just-works/toontown/estate/DistributedEstate.py

442 lines
18 KiB
Python
Raw Normal View History

2024-07-07 18:08:39 -05:00
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)