historical/toontown-classic.git/toontown/estate/EstateLoader.py
2024-01-16 11:20:27 -06:00

345 lines
13 KiB
Python

from panda3d.core import *
from toontown.toonbase.ToontownGlobals import *
from direct.interval.IntervalGlobal import *
from direct.fsm import ClassicFSM, State
from toontown.safezone import SafeZoneLoader
import random
from toontown.launcher import DownloadForceAcknowledge
import House
import Estate
import HouseGlobals
import random
import math
from toontown.coghq import MovingPlatform
from direct.directnotify import DirectNotifyGlobal
class EstateLoader(SafeZoneLoader.SafeZoneLoader):
notify = DirectNotifyGlobal.directNotify.newCategory('EstateLoader')
def __init__(self, hood, parentFSM, doneEvent):
SafeZoneLoader.SafeZoneLoader.__init__(self, hood, parentFSM, doneEvent)
del self.fsm
self.fsm = ClassicFSM.ClassicFSM('EstateLoader', [State.State('start', self.enterStart, self.exitStart, ['quietZone', 'estate', 'house']),
State.State('estate', self.enterEstate, self.exitEstate, ['quietZone']),
State.State('house', self.enterHouse, self.exitHouse, ['quietZone']),
State.State('quietZone', self.enterQuietZone, self.exitQuietZone, ['house', 'estate']),
State.State('final', self.enterFinal, self.exitFinal, ['start'])], 'start', 'final')
self.musicFile = 'phase_5.5/audio/bgm/estate_SZ.ogg'
self.activityMusicFile = 'phase_3.5/audio/bgm/TC_SZ_activity.ogg'
self.dnaFile = 'phase_5.5/dna/estate_1.dna'
self.safeZoneStorageDNAFile = None
self.cloudSwitch = 0
self.id = MyEstate
self.estateOwnerId = None
self.branchZone = None
self.houseDoneEvent = 'houseDone'
self.estateDoneEvent = 'estateDone'
self.enteredHouse = None
self.houseNode = [None] * 6
self.houseModels = [None] * HouseGlobals.NUM_HOUSE_TYPES
self.houseId2house = {}
self.barrel = None
self.clouds = []
self.cloudTrack = None
self.sunMoonNode = None
self.fsm.enterInitialState()
return
def load(self):
SafeZoneLoader.SafeZoneLoader.load(self)
self.music = base.loader.loadMusic(self.musicFile)
self.underwaterSound = base.loader.loadSfx('phase_4/audio/sfx/AV_ambient_water.ogg')
self.swimSound = base.loader.loadSfx('phase_4/audio/sfx/AV_swim_single_stroke.ogg')
self.submergeSound = base.loader.loadSfx('phase_5.5/audio/sfx/AV_jump_in_water.ogg')
self.birdSound = map(base.loader.loadSfx, ['phase_4/audio/sfx/SZ_TC_bird1.ogg', 'phase_4/audio/sfx/SZ_TC_bird2.ogg', 'phase_4/audio/sfx/SZ_TC_bird3.ogg'])
self.cricketSound = map(base.loader.loadSfx, ['phase_4/audio/sfx/SZ_TC_bird1.ogg', 'phase_4/audio/sfx/SZ_TC_bird2.ogg', 'phase_4/audio/sfx/SZ_TC_bird3.ogg'])
if base.goonsEnabled:
invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons')
self.invModels = []
from toontown.toonbase import ToontownBattleGlobals
for track in xrange(len(ToontownBattleGlobals.AvPropsNew)):
itemList = []
for item in xrange(len(ToontownBattleGlobals.AvPropsNew[track])):
itemList.append(invModel.find('**/' + ToontownBattleGlobals.AvPropsNew[track][item]))
self.invModels.append(itemList)
invModel.removeNode()
del invModel
def unload(self):
self.ignoreAll()
base.cr.estateMgr.leaveEstate()
self.estateOwnerId = None
self.estateZoneId = None
if self.place:
self.place.exit()
self.place.unload()
del self.place
del self.underwaterSound
del self.swimSound
del self.submergeSound
del self.birdSound
del self.cricketSound
for node in self.houseNode:
node.removeNode()
del self.houseNode
for model in self.houseModels:
model.removeNode()
del self.houseModels
del self.houseId2house
if self.sunMoonNode:
self.sunMoonNode.removeNode()
del self.sunMoonNode
self.sunMoonNode = None
if self.clouds:
for cloud in self.clouds:
cloud[0].removeNode()
del cloud[1]
del self.clouds
if self.barrel:
self.barrel.removeNode()
SafeZoneLoader.SafeZoneLoader.unload(self)
return
def enter(self, requestStatus):
self.estateOwnerId = requestStatus.get('ownerId', base.localAvatar.doId)
base.localAvatar.inEstate = 1
self.loadCloudPlatforms()
if base.cloudPlatformsEnabled and 0:
self.setCloudSwitch(1)
if self.cloudSwitch:
self.setCloudSwitch(self.cloudSwitch)
SafeZoneLoader.SafeZoneLoader.enter(self, requestStatus)
def exit(self):
self.ignoreAll()
base.cr.cache.flush()
base.localAvatar.stopChat()
base.localAvatar.inEstate = 0
SafeZoneLoader.SafeZoneLoader.exit(self)
def createSafeZone(self, dnaFile):
SafeZoneLoader.SafeZoneLoader.createSafeZone(self, dnaFile)
self.loadHouses()
self.loadSunMoon()
def loadHouses(self):
for i in xrange(HouseGlobals.NUM_HOUSE_TYPES):
self.houseModels[i] = loader.loadModel(HouseGlobals.houseModels[i])
for i in xrange(6):
posHpr = HouseGlobals.houseDrops[i]
self.houseNode[i] = self.geom.attachNewNode('esHouse_' + str(i))
self.houseNode[i].setPosHpr(*posHpr)
def loadSunMoon(self):
self.sun = loader.loadModel('phase_4/models/props/sun.bam')
self.moon = loader.loadModel('phase_5.5/models/props/moon.bam')
self.sunMoonNode = self.geom.attachNewNode('sunMoon')
self.sunMoonNode.setPosHpr(0, 0, 0, 0, 0, 0)
if self.sun:
self.sun.reparentTo(self.sunMoonNode)
self.sun.setY(270)
self.sun.setScale(2)
self.sun.setBillboardPointEye()
if self.moon:
self.moon.setP(180)
self.moon.reparentTo(self.sunMoonNode)
self.moon.setY(-270)
self.moon.setScale(15)
self.moon.setBillboardPointEye()
self.sunMoonNode.setP(30)
def enterEstate(self, requestStatus):
self.notify.debug('enterEstate: requestStatus = %s' % requestStatus)
ownerId = requestStatus.get('ownerId')
if ownerId:
self.estateOwnerId = ownerId
zoneId = requestStatus['zoneId']
self.notify.debug('enterEstate, ownerId = %s, zoneId = %s' % (self.estateOwnerId, zoneId))
self.accept(self.estateDoneEvent, self.handleEstateDone)
self.place = Estate.Estate(self, self.estateOwnerId, zoneId, self.fsm.getStateNamed('estate'), self.estateDoneEvent)
base.cr.playGame.setPlace(self.place)
self.place.load()
self.place.enter(requestStatus)
self.estateZoneId = zoneId
def exitEstate(self):
self.notify.debug('exitEstate')
self.ignore(self.estateDoneEvent)
self.place.exit()
self.place.unload()
self.place = None
base.cr.playGame.setPlace(self.place)
base.cr.cache.flush()
return
def handleEstateDone(self, doneStatus = None):
if not doneStatus:
doneStatus = self.place.getDoneStatus()
how = doneStatus['how']
shardId = doneStatus['shardId']
hoodId = doneStatus['hoodId']
zoneId = doneStatus['zoneId']
avId = doneStatus.get('avId', -1)
ownerId = doneStatus.get('ownerId', -1)
if shardId != None or hoodId != MyEstate:
self.notify.debug('estate done, and we are backing out to a different hood/shard')
self.notify.debug('hoodId = %s, avId = %s' % (hoodId, avId))
self.doneStatus = doneStatus
messenger.send(self.doneEvent)
return
if how in ['tunnelIn',
'teleportIn',
'doorIn',
'elevatorIn']:
self.notify.debug('staying in estateloader')
self.fsm.request('quietZone', [doneStatus])
else:
self.notify.error('Exited hood with unexpected mode %s' % how)
return
def enterHouse(self, requestStatus):
ownerId = requestStatus.get('ownerId')
if ownerId:
self.estateOwnerId = ownerId
self.acceptOnce(self.houseDoneEvent, self.handleHouseDone)
self.place = House.House(self, self.estateOwnerId, self.fsm.getStateNamed('house'), self.houseDoneEvent)
base.cr.playGame.setPlace(self.place)
self.place.load()
self.place.enter(requestStatus)
def exitHouse(self):
self.ignore(self.houseDoneEvent)
self.place.exit()
self.place.unload()
self.place = None
base.cr.playGame.setPlace(self.place)
return
def handleHouseDone(self, doneStatus = None):
if not doneStatus:
doneStatus = self.place.getDoneStatus()
shardId = doneStatus['shardId']
hoodId = doneStatus['hoodId']
if shardId != None or hoodId != MyEstate:
self.doneStatus = doneStatus
messenger.send(self.doneEvent)
return
how = doneStatus['how']
if how in ['tunnelIn',
'teleportIn',
'doorIn',
'elevatorIn']:
self.fsm.request('quietZone', [doneStatus])
else:
self.notify.error('Exited hood with unexpected mode %s' % how)
return
def handleQuietZoneDone(self):
status = self.quietZoneStateData.getRequestStatus()
self.fsm.request(status['where'], [status])
def atMyEstate(self):
if self.estateOwnerId != None:
if self.estateOwnerId == base.localAvatar.getDoId():
return 1
else:
return 0
else:
self.notify.warning("We aren't in an estate")
return
def setHouse(self, houseId):
try:
houseDo = base.cr.doId2do[houseId]
self.enteredHouse = houseDo.house
except KeyError:
self.notify.debug("can't find house: %d" % houseId)
def startCloudPlatforms(self):
return
if len(self.clouds):
self.cloudTrack = self.__cloudTrack()
self.cloudTrack.loop()
def stopCloudPlatforms(self):
if self.cloudTrack:
self.cloudTrack.pause()
del self.cloudTrack
self.cloudTrack = None
return
def __cloudTrack(self):
track = Parallel()
for cloud in self.clouds:
axis = cloud[1]
pos = cloud[0].getPos(render)
newPos = pos + axis * 30
reversePos = pos - axis * 30
track.append(Sequence(LerpPosInterval(cloud[0], 10, newPos), LerpPosInterval(cloud[0], 20, reversePos), LerpPosInterval(cloud[0], 10, pos)))
return track
def debugGeom(self, decomposed):
print 'numPrimitives = %d' % decomposed.getNumPrimitives()
for primIndex in xrange(decomposed.getNumPrimitives()):
prim = decomposed.getPrimitive(primIndex)
print 'prim = %s' % prim
print 'isIndexed = %d' % prim.isIndexed()
print 'prim.getNumPrimitives = %d' % prim.getNumPrimitives()
for basicPrim in xrange(prim.getNumPrimitives()):
print '%d start=%d' % (basicPrim, prim.getPrimitiveStart(basicPrim))
print '%d end=%d' % (basicPrim, prim.getPrimitiveEnd(basicPrim))
def loadOnePlatform(self, version, radius, zOffset, score, multiplier):
self.notify.debug('loadOnePlatform version=%d' % version)
cloud = NodePath('cloud-%d-%d' % (score, multiplier))
cloudModel = loader.loadModel('phase_5.5/models/estate/bumper_cloud')
cc = cloudModel.copyTo(cloud)
colCube = cc.find('**/collision')
colCube.setName('cloudSphere-0')
dTheta = 2.0 * math.pi / self.numClouds
cloud.reparentTo(self.cloudOrigin)
axes = [Vec3(1, 0, 0), Vec3(0, 1, 0), Vec3(0, 0, 1)]
cloud.setPos(radius * math.cos(version * dTheta), radius * math.sin(version * dTheta), 4 * random.random() + zOffset)
cloud.setScale(4.0)
self.clouds.append([cloud, random.choice(axes)])
def loadSkyCollision(self):
plane = CollisionPlane(Plane(Vec3(0, 0, -1), Point3(0, 0, 300)))
plane.setTangible(0)
planeNode = CollisionNode('cloudSphere-0')
planeNode.addSolid(plane)
self.cloudOrigin.attachNewNode(planeNode)
def loadCloudPlatforms(self):
self.cloudOrigin = self.geom.attachNewNode('cloudOrigin')
self.cloudOrigin.setZ(30)
self.loadSkyCollision()
self.numClouds = 12
pinballScore = PinballScoring[PinballCloudBumperLow]
for i in xrange(12):
self.loadOnePlatform(i, 40, 0, pinballScore[0], pinballScore[1])
pinballScore = PinballScoring[PinballCloudBumperMed]
for i in xrange(12):
self.loadOnePlatform(i, 60, 40, pinballScore[0], pinballScore[1])
pinballScore = PinballScoring[PinballCloudBumperHigh]
for i in xrange(12):
self.loadOnePlatform(i, 20, 80, pinballScore[0], pinballScore[1])
self.cloudOrigin.stash()
def setCloudSwitch(self, on):
self.cloudSwitch = on
if hasattr(self, 'cloudOrigin'):
if on:
self.cloudOrigin.unstash()
else:
self.cloudOrigin.stash()