685 lines
28 KiB
Python
685 lines
28 KiB
Python
from toontown.toonbase.ToonBaseGlobal import *
|
|
from pandac.PandaModules import *
|
|
from direct.interval.IntervalGlobal import *
|
|
from direct.distributed.ClockDelta import *
|
|
from toontown.toonbase import ToontownGlobals
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from direct.fsm import ClassicFSM, State
|
|
from direct.distributed import DistributedObject
|
|
from toontown.hood import ZoneUtil
|
|
from toontown.suit import Suit
|
|
from toontown.distributed import DelayDelete
|
|
import FADoorCodes
|
|
from direct.task.Task import Task
|
|
import DoorTypes
|
|
from toontown.toontowngui import TTDialog
|
|
from toontown.toonbase import TTLocalizer
|
|
from toontown.toontowngui import TeaserPanel
|
|
from toontown.distributed.DelayDeletable import DelayDeletable
|
|
from otp.nametag.NametagGroup import NametagGroup
|
|
from otp.nametag.Nametag import Nametag
|
|
from toontown.election import SafezoneInvasionGlobals
|
|
|
|
if (__debug__):
|
|
import pdb
|
|
|
|
class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable):
|
|
|
|
def __init__(self, cr):
|
|
DistributedObject.DistributedObject.__init__(self, cr)
|
|
self.openSfx = base.loadSfx('phase_3.5/audio/sfx/Door_Open_1.ogg')
|
|
self.closeSfx = base.loadSfx('phase_3.5/audio/sfx/Door_Close_1.ogg')
|
|
self.nametag = None
|
|
self.fsm = ClassicFSM.ClassicFSM('DistributedDoor_right', [State.State('off', self.enterOff, self.exitOff, ['closing',
|
|
'closed',
|
|
'opening',
|
|
'open']),
|
|
State.State('closing', self.enterClosing, self.exitClosing, ['closed', 'opening']),
|
|
State.State('closed', self.enterClosed, self.exitClosed, ['opening']),
|
|
State.State('opening', self.enterOpening, self.exitOpening, ['open']),
|
|
State.State('open', self.enterOpen, self.exitOpen, ['closing', 'open'])], 'off', 'off')
|
|
self.fsm.enterInitialState()
|
|
self.exitDoorFSM = ClassicFSM.ClassicFSM('DistributedDoor_left', [State.State('off', self.exitDoorEnterOff, self.exitDoorExitOff, ['closing',
|
|
'closed',
|
|
'opening',
|
|
'open']),
|
|
State.State('closing', self.exitDoorEnterClosing, self.exitDoorExitClosing, ['closed', 'opening']),
|
|
State.State('closed', self.exitDoorEnterClosed, self.exitDoorExitClosed, ['opening']),
|
|
State.State('opening', self.exitDoorEnterOpening, self.exitDoorExitOpening, ['open']),
|
|
State.State('open', self.exitDoorEnterOpen, self.exitDoorExitOpen, ['closing', 'open'])], 'off', 'off')
|
|
self.exitDoorFSM.enterInitialState()
|
|
self.specialDoorTypes = {DoorTypes.EXT_HQ: 0,
|
|
DoorTypes.EXT_COGHQ: 0,
|
|
DoorTypes.INT_COGHQ: 0,
|
|
DoorTypes.EXT_KS: 0,
|
|
DoorTypes.INT_KS: 0}
|
|
self.doorX = 1.5
|
|
return
|
|
|
|
def generate(self):
|
|
DistributedObject.DistributedObject.generate(self)
|
|
self.avatarTracks = []
|
|
self.avatarExitTracks = []
|
|
self.avatarIDList = []
|
|
self.avatarExitIDList = []
|
|
self.doorTrack = None
|
|
self.doorExitTrack = None
|
|
return
|
|
|
|
def disable(self):
|
|
self.clearNametag()
|
|
taskMgr.remove(self.checkIsDoorHitTaskName())
|
|
self.ignore(self.getEnterTriggerEvent())
|
|
self.ignore(self.getExitTriggerEvent())
|
|
self.ignore('clearOutToonInterior')
|
|
self.fsm.request('off')
|
|
self.exitDoorFSM.request('off')
|
|
if self.__dict__.has_key('building'):
|
|
del self.building
|
|
self.finishAllTracks()
|
|
self.avatarIDList = []
|
|
self.avatarExitIDList = []
|
|
if hasattr(self, 'tempDoorNodePath'):
|
|
self.tempDoorNodePath.removeNode()
|
|
del self.tempDoorNodePath
|
|
DistributedObject.DistributedObject.disable(self)
|
|
|
|
def delete(self):
|
|
del self.fsm
|
|
del self.exitDoorFSM
|
|
del self.openSfx
|
|
del self.closeSfx
|
|
DistributedObject.DistributedObject.delete(self)
|
|
|
|
def wantsNametag(self):
|
|
return not ZoneUtil.isInterior(self.zoneId)
|
|
|
|
def setupNametag(self):
|
|
if not self.wantsNametag():
|
|
return
|
|
if self.nametag == None:
|
|
self.nametag = NametagGroup()
|
|
self.nametag.setFont(ToontownGlobals.getBuildingNametagFont())
|
|
if TTLocalizer.BuildingNametagShadow:
|
|
self.nametag.setShadow(*TTLocalizer.BuildingNametagShadow)
|
|
self.nametag.setContents(Nametag.CName)
|
|
self.nametag.setColorCode(NametagGroup.CCToonBuilding)
|
|
self.nametag.setActive(0)
|
|
self.nametag.setAvatar(self.getDoorNodePath())
|
|
self.nametag.setObjectCode(self.block)
|
|
name = self.cr.playGame.dnaData.getBlock(self.block).title
|
|
self.nametag.setName(name)
|
|
self.nametag.manage(base.marginManager)
|
|
return
|
|
|
|
def clearNametag(self):
|
|
if self.nametag != None:
|
|
self.nametag.unmanage(base.marginManager)
|
|
self.nametag.setAvatar(NodePath())
|
|
self.nametag.destroy()
|
|
self.nametag = None
|
|
return
|
|
|
|
def getTriggerName(self):
|
|
if self.doorType == DoorTypes.INT_HQ or self.specialDoorTypes.has_key(self.doorType):
|
|
return 'door_trigger_' + str(self.block) + '_' + str(self.doorIndex)
|
|
else:
|
|
return 'door_trigger_' + str(self.block)
|
|
|
|
def getTriggerName_wip(self):
|
|
name = 'door_trigger_%d' % (self.doId,)
|
|
return name
|
|
|
|
def getEnterTriggerEvent(self):
|
|
return 'enter' + self.getTriggerName()
|
|
|
|
def getExitTriggerEvent(self):
|
|
return 'exit' + self.getTriggerName()
|
|
|
|
def hideDoorParts(self):
|
|
if self.specialDoorTypes.has_key(self.doorType):
|
|
self.hideIfHasFlat(self.findDoorNode('rightDoor'))
|
|
self.hideIfHasFlat(self.findDoorNode('leftDoor'))
|
|
self.findDoorNode('doorFrameHoleRight').hide()
|
|
self.findDoorNode('doorFrameHoleLeft').hide()
|
|
else:
|
|
return
|
|
|
|
def setTriggerName(self):
|
|
if self.specialDoorTypes.has_key(self.doorType):
|
|
building = self.getBuilding()
|
|
doorTrigger = building.find('**/door_' + str(self.doorIndex) + '/**/door_trigger*')
|
|
doorTrigger.node().setName(self.getTriggerName())
|
|
else:
|
|
return
|
|
|
|
def fixTrigger(self):
|
|
if self.doorType in [DoorTypes.EXT_STANDARD, DoorTypes.EXT_COGHQ]:
|
|
building = self.getBuilding()
|
|
doorTrigger = building.find('**/' + self.getTriggerName())
|
|
if not doorTrigger.isEmpty():
|
|
TRIGGER_SHIFT_Y = 0.25
|
|
TRIGGER_SHIFT_Z = 1.00
|
|
if "_gag_shop_" in building.getName():
|
|
# Some dipshit put the triggers on backwards for the
|
|
# gag shop compared to every other building.
|
|
doorTrigger.setY(doorTrigger.getY() + TRIGGER_SHIFT_Y)
|
|
else:
|
|
doorTrigger.setY(doorTrigger.getY() - TRIGGER_SHIFT_Y)
|
|
doorTrigger.setZ(doorTrigger.getZ() + TRIGGER_SHIFT_Z)
|
|
|
|
def setTriggerName_wip(self):
|
|
building = self.getBuilding()
|
|
doorTrigger = building.find('**/door_%d/**/door_trigger_%d' % (self.doorIndex, self.block))
|
|
if doorTrigger.isEmpty():
|
|
doorTrigger = building.find('**/door_trigger_%d' % (self.block,))
|
|
if doorTrigger.isEmpty():
|
|
doorTrigger = building.find('**/door_%d/**/door_trigger_*' % (self.doorIndex,))
|
|
if doorTrigger.isEmpty():
|
|
doorTrigger = building.find('**/door_trigger_*')
|
|
doorTrigger.node().setName(self.getTriggerName())
|
|
|
|
def setZoneIdAndBlock(self, zoneId, block):
|
|
self.zoneId = zoneId
|
|
self.block = block
|
|
|
|
def setDoorType(self, doorType):
|
|
self.notify.debug('Door type = ' + str(doorType) + ' on door #' + str(self.doId))
|
|
self.doorType = doorType
|
|
|
|
def setDoorIndex(self, doorIndex):
|
|
self.doorIndex = doorIndex
|
|
|
|
def setSwing(self, flags):
|
|
self.leftSwing = flags & 1 != 0
|
|
self.rightSwing = flags & 2 != 0
|
|
|
|
def setOtherZoneIdAndDoId(self, zoneId, distributedObjectID):
|
|
self.otherZoneId = zoneId
|
|
self.otherDoId = distributedObjectID
|
|
|
|
def setState(self, state, timestamp):
|
|
self.fsm.request(state, [globalClockDelta.localElapsedTime(timestamp)])
|
|
|
|
def setExitDoorState(self, state, timestamp):
|
|
self.exitDoorFSM.request(state, [globalClockDelta.localElapsedTime(timestamp)])
|
|
|
|
def announceGenerate(self):
|
|
DistributedObject.DistributedObject.announceGenerate(self)
|
|
self.doPostAnnounceGenerate()
|
|
|
|
def doPostAnnounceGenerate(self):
|
|
if self.doorType == DoorTypes.INT_STANDARD:
|
|
self.bHasFlat = True
|
|
else:
|
|
self.bHasFlat = not self.findDoorNode('door*flat', True).isEmpty()
|
|
self.hideDoorParts()
|
|
self.setTriggerName()
|
|
self.fixTrigger()
|
|
self.accept(self.getEnterTriggerEvent(), self.doorTrigger)
|
|
self.acceptOnce('clearOutToonInterior', self.doorTrigger)
|
|
self.setupNametag()
|
|
|
|
def getBuilding(self):
|
|
if not self.__dict__.has_key('building'):
|
|
if self.doorType == DoorTypes.INT_STANDARD:
|
|
door = render.find('**/leftDoor;+s')
|
|
self.building = door.getParent()
|
|
elif self.doorType == DoorTypes.INT_HQ:
|
|
door = render.find('**/door_0')
|
|
self.building = door.getParent()
|
|
elif self.doorType == DoorTypes.INT_KS:
|
|
self.building = render.find('**/KartShop_Interior*')
|
|
elif self.doorType == DoorTypes.EXT_STANDARD or self.doorType == DoorTypes.EXT_HQ or self.doorType == DoorTypes.EXT_KS:
|
|
self.building = self.cr.playGame.hood.loader.geom.find('**/??' + str(self.block) + ':*_landmark_*_DNARoot;+s')
|
|
if self.building.isEmpty():
|
|
self.building = self.cr.playGame.hood.loader.geom.find('**/??' + str(self.block) + ':animated_building_*_DNARoot;+s')
|
|
elif self.doorType == DoorTypes.EXT_COGHQ or self.doorType == DoorTypes.INT_COGHQ:
|
|
self.building = self.cr.playGame.hood.loader.geom
|
|
else:
|
|
self.notify.error('No such door type as ' + str(self.doorType))
|
|
return self.building
|
|
|
|
def getBuilding_wip(self):
|
|
if not self.__dict__.has_key('building'):
|
|
if self.__dict__.has_key('block'):
|
|
self.building = self.cr.playGame.hood.loader.geom.find('**/??' + str(self.block) + ':*_landmark_*_DNARoot;+s')
|
|
else:
|
|
self.building = self.cr.playGame.hood.loader.geom
|
|
print '---------------- door is interior -------'
|
|
return self.building
|
|
|
|
def readyToExit(self):
|
|
base.transitions.fadeScreen(1.0)
|
|
self.sendUpdate('requestExit')
|
|
|
|
def avatarEnterDoorTrack(self, avatar, duration):
|
|
trackName = 'avatarEnterDoor-%d-%d' % (self.doId, avatar.doId)
|
|
track = Parallel(name=trackName)
|
|
otherNP = self.getDoorNodePath()
|
|
print self.getBuilding()
|
|
if hasattr(avatar, 'stopSmooth'):
|
|
avatar.stopSmooth()
|
|
if avatar.doId == base.localAvatar.doId:
|
|
track.append(LerpPosHprInterval(nodePath=camera, other=avatar, duration=duration, pos=Point3(0, -8, avatar.getHeight()), hpr=VBase3(0, 0, 0), blendType='easeInOut'))
|
|
finalPos = avatar.getParent().getRelativePoint(otherNP, Point3(self.doorX, 2, ToontownGlobals.FloorOffset))
|
|
moveHere = Sequence(self.getAnimStateInterval(avatar, 'walk'), LerpPosInterval(nodePath=avatar, duration=duration, pos=finalPos, blendType='easeIn'))
|
|
track.append(moveHere)
|
|
if avatar.doId == base.localAvatar.doId:
|
|
track.append(Sequence(Wait(duration * 0.5), Func(base.transitions.irisOut, duration * 0.5), Wait(duration * 0.5), Func(avatar.b_setParent, ToontownGlobals.SPHidden)))
|
|
track.delayDelete = DelayDelete.DelayDelete(avatar, 'avatarEnterDoorTrack')
|
|
return track
|
|
|
|
def avatarEnqueueTrack(self, avatar, duration):
|
|
if hasattr(avatar, 'stopSmooth'):
|
|
avatar.stopSmooth()
|
|
back = -5.0 - 2.0 * len(self.avatarIDList)
|
|
if back < -9.0:
|
|
back = -9.0
|
|
offset = Point3(self.doorX, back, ToontownGlobals.FloorOffset)
|
|
otherNP = self.getDoorNodePath()
|
|
walkLike = ActorInterval(avatar, 'walk', startTime=1, duration=duration, endTime=0.0001)
|
|
standHere = Sequence(LerpPosHprInterval(nodePath=avatar, other=otherNP, duration=duration, pos=offset, hpr=VBase3(0, 0, 0), blendType='easeInOut'), self.getAnimStateInterval(avatar, 'neutral'))
|
|
trackName = 'avatarEnqueueDoor-%d-%d' % (self.doId, avatar.doId)
|
|
track = Parallel(walkLike, standHere, name=trackName)
|
|
track.delayDelete = DelayDelete.DelayDelete(avatar, 'avatarEnqueueTrack')
|
|
return track
|
|
|
|
def getAnimStateInterval(self, avatar, animName):
|
|
isSuit = isinstance(avatar, Suit.Suit)
|
|
if isSuit:
|
|
return Func(avatar.loop, animName, 0)
|
|
else:
|
|
return Func(avatar.setAnimState, animName)
|
|
|
|
def isDoorHit(self):
|
|
vec = base.localAvatar.getRelativeVector(self.currentDoorNp, self.currentDoorVec)
|
|
netScale = self.currentDoorNp.getNetTransform().getScale()
|
|
yToTest = vec.getY() / netScale[1]
|
|
return yToTest < -0.5
|
|
|
|
def enterDoor(self):
|
|
if config.GetBool('want-doomsday', False):
|
|
base.localAvatar.disableAvatarControls()
|
|
self.confirm = TTDialog.TTGlobalDialog(doneEvent='confirmDone', message=SafezoneInvasionGlobals.LeaveToontownCentralAlert, style=TTDialog.Acknowledge)
|
|
self.confirm.show()
|
|
self.accept('confirmDone', self.handleConfirm)
|
|
return
|
|
|
|
if self.allowedToEnter():
|
|
messenger.send('DistributedDoor_doorTrigger')
|
|
self.sendUpdate('requestEnter')
|
|
else:
|
|
place = base.cr.playGame.getPlace()
|
|
if place:
|
|
place.fsm.request('stopped')
|
|
self.dialog = TeaserPanel.TeaserPanel(pageName='otherHoods', doneFunc=self.handleOkTeaser)
|
|
|
|
def handleConfirm(self):
|
|
status = self.confirm.doneStatus
|
|
self.ignore('confirmDone')
|
|
self.confirm.cleanup()
|
|
del self.confirm
|
|
if status == 'ok':
|
|
base.localAvatar.enableAvatarControls()
|
|
self.accept(self.getExitTriggerEvent(), self.cancelCheckIsDoorHitTask) # Incase people want to try again
|
|
|
|
def handleOkTeaser(self):
|
|
self.accept(self.getEnterTriggerEvent(), self.doorTrigger)
|
|
self.dialog.destroy()
|
|
del self.dialog
|
|
place = base.cr.playGame.getPlace()
|
|
if place:
|
|
place.fsm.request('walk')
|
|
|
|
def allowedToEnter(self, zoneId = None):
|
|
allowed = False
|
|
if hasattr(base, 'ttAccess') and base.ttAccess:
|
|
if zoneId:
|
|
allowed = base.ttAccess.canAccess(zoneId)
|
|
else:
|
|
allowed = base.ttAccess.canAccess()
|
|
return allowed
|
|
|
|
def checkIsDoorHitTaskName(self):
|
|
return 'checkIsDoorHit' + self.getTriggerName()
|
|
|
|
def checkIsDoorHitTask(self, task):
|
|
if self.isDoorHit():
|
|
self.ignore(self.checkIsDoorHitTaskName())
|
|
self.ignore(self.getExitTriggerEvent())
|
|
self.enterDoor()
|
|
return Task.done
|
|
return Task.cont
|
|
|
|
def cancelCheckIsDoorHitTask(self, args):
|
|
taskMgr.remove(self.checkIsDoorHitTaskName())
|
|
del self.currentDoorNp
|
|
del self.currentDoorVec
|
|
self.ignore(self.getExitTriggerEvent())
|
|
self.accept(self.getEnterTriggerEvent(), self.doorTrigger)
|
|
|
|
def doorTrigger(self, args = None):
|
|
self.ignore(self.getEnterTriggerEvent())
|
|
if args == None:
|
|
self.enterDoor()
|
|
else:
|
|
self.currentDoorNp = NodePath(args.getIntoNodePath())
|
|
self.currentDoorVec = Vec3(args.getSurfaceNormal(self.currentDoorNp))
|
|
if self.isDoorHit():
|
|
self.enterDoor()
|
|
else:
|
|
self.accept(self.getExitTriggerEvent(), self.cancelCheckIsDoorHitTask)
|
|
taskMgr.add(self.checkIsDoorHitTask, self.checkIsDoorHitTaskName())
|
|
return
|
|
|
|
def avatarEnter(self, avatarID):
|
|
avatar = self.cr.doId2do.get(avatarID, None)
|
|
if avatar:
|
|
avatar.setAnimState('neutral')
|
|
track = self.avatarEnqueueTrack(avatar, 0.5)
|
|
track.start()
|
|
self.avatarTracks.append(track)
|
|
self.avatarIDList.append(avatarID)
|
|
return
|
|
|
|
def rejectEnter(self, reason):
|
|
message = FADoorCodes.reasonDict[reason]
|
|
if message:
|
|
self.__faRejectEnter(message)
|
|
else:
|
|
self.__basicRejectEnter()
|
|
|
|
def __basicRejectEnter(self):
|
|
self.accept(self.getEnterTriggerEvent(), self.doorTrigger)
|
|
if self.cr.playGame.getPlace():
|
|
self.cr.playGame.getPlace().setState('walk')
|
|
|
|
def __faRejectEnter(self, message):
|
|
self.rejectDialog = TTDialog.TTGlobalDialog(message=message, doneEvent='doorRejectAck', style=TTDialog.Acknowledge)
|
|
self.rejectDialog.show()
|
|
self.rejectDialog.delayDelete = DelayDelete.DelayDelete(self, '__faRejectEnter')
|
|
event = 'clientCleanup'
|
|
self.acceptOnce(event, self.__handleClientCleanup)
|
|
base.cr.playGame.getPlace().setState('stopped')
|
|
self.acceptOnce('doorRejectAck', self.__handleRejectAck)
|
|
self.acceptOnce('stoppedAsleep', self.__handleFallAsleepDoor)
|
|
|
|
def __handleClientCleanup(self):
|
|
if hasattr(self, 'rejectDialog') and self.rejectDialog:
|
|
self.rejectDialog.doneStatus = 'ok'
|
|
self.__handleRejectAck()
|
|
|
|
def __handleFallAsleepDoor(self):
|
|
self.rejectDialog.doneStatus = 'ok'
|
|
self.__handleRejectAck()
|
|
|
|
def __handleRejectAck(self):
|
|
self.ignore('doorRejectAck')
|
|
self.ignore('stoppedAsleep')
|
|
self.ignore('clientCleanup')
|
|
doneStatus = self.rejectDialog.doneStatus
|
|
if doneStatus != 'ok':
|
|
self.notify.error('Unrecognized doneStatus: ' + str(doneStatus))
|
|
self.__basicRejectEnter()
|
|
self.rejectDialog.delayDelete.destroy()
|
|
self.rejectDialog.cleanup()
|
|
del self.rejectDialog
|
|
|
|
def getDoorNodePath(self):
|
|
if self.doorType == DoorTypes.INT_STANDARD:
|
|
otherNP = render.find('**/door_origin')
|
|
elif self.doorType == DoorTypes.EXT_STANDARD:
|
|
otherNP = self.getBuilding().find('**/*door_origin')
|
|
elif self.specialDoorTypes.has_key(self.doorType):
|
|
building = self.getBuilding()
|
|
otherNP = building.find('**/door_origin_' + str(self.doorIndex))
|
|
elif self.doorType == DoorTypes.INT_HQ:
|
|
otherNP = render.find('**/door_origin_' + str(self.doorIndex))
|
|
else:
|
|
self.notify.error('No such door type as ' + str(self.doorType))
|
|
return otherNP
|
|
|
|
def avatarExitTrack(self, avatar, duration):
|
|
if hasattr(avatar, 'stopSmooth'):
|
|
avatar.stopSmooth()
|
|
otherNP = self.getDoorNodePath()
|
|
trackName = 'avatarExitDoor-%d-%d' % (self.doId, avatar.doId)
|
|
track = Sequence(name=trackName)
|
|
track.append(self.getAnimStateInterval(avatar, 'walk'))
|
|
track.append(PosHprInterval(avatar, Point3(-self.doorX, 0, ToontownGlobals.FloorOffset), VBase3(179, 0, 0), other=otherNP))
|
|
track.append(Func(avatar.setParent, ToontownGlobals.SPRender))
|
|
if avatar.doId == base.localAvatar.doId:
|
|
track.append(PosHprInterval(camera, VBase3(-self.doorX, 5, avatar.getHeight()), VBase3(180, 0, 0), other=otherNP))
|
|
if avatar.doId == base.localAvatar.doId:
|
|
finalPos = render.getRelativePoint(otherNP, Point3(-self.doorX, -6, ToontownGlobals.FloorOffset))
|
|
else:
|
|
finalPos = render.getRelativePoint(otherNP, Point3(-self.doorX, -3, ToontownGlobals.FloorOffset))
|
|
track.append(LerpPosInterval(nodePath=avatar, duration=duration, pos=finalPos, blendType='easeInOut'))
|
|
if avatar.doId == base.localAvatar.doId:
|
|
track.append(Func(self.exitCompleted))
|
|
track.append(Func(base.transitions.irisIn))
|
|
if hasattr(avatar, 'startSmooth'):
|
|
track.append(Func(avatar.startSmooth))
|
|
track.delayDelete = DelayDelete.DelayDelete(avatar, 'DistributedDoor.avatarExitTrack')
|
|
return track
|
|
|
|
def exitCompleted(self):
|
|
base.localAvatar.setAnimState('neutral')
|
|
place = self.cr.playGame.getPlace()
|
|
if place:
|
|
place.setState('walk')
|
|
base.localAvatar.d_setParent(ToontownGlobals.SPRender)
|
|
|
|
def avatarExit(self, avatarID):
|
|
if avatarID in self.avatarIDList:
|
|
self.avatarIDList.remove(avatarID)
|
|
if avatarID == base.localAvatar.doId:
|
|
self.exitCompleted()
|
|
else:
|
|
self.avatarExitIDList.append(avatarID)
|
|
|
|
def finishDoorTrack(self):
|
|
if self.doorTrack:
|
|
self.doorTrack.finish()
|
|
self.doorTrack = None
|
|
return
|
|
|
|
def finishDoorExitTrack(self):
|
|
if self.doorExitTrack:
|
|
self.doorExitTrack.finish()
|
|
self.doorExitTrack = None
|
|
return
|
|
|
|
def finishAllTracks(self):
|
|
self.finishDoorTrack()
|
|
self.finishDoorExitTrack()
|
|
for t in self.avatarTracks:
|
|
t.finish()
|
|
DelayDelete.cleanupDelayDeletes(t)
|
|
|
|
self.avatarTracks = []
|
|
for t in self.avatarExitTracks:
|
|
t.finish()
|
|
DelayDelete.cleanupDelayDeletes(t)
|
|
|
|
self.avatarExitTracks = []
|
|
|
|
def enterOff(self):
|
|
pass
|
|
|
|
def exitOff(self):
|
|
pass
|
|
|
|
def getRequestStatus(self):
|
|
zoneId = self.otherZoneId
|
|
request = {'loader': ZoneUtil.getBranchLoaderName(zoneId),
|
|
'where': ZoneUtil.getToonWhereName(zoneId),
|
|
'how': 'doorIn',
|
|
'hoodId': ZoneUtil.getHoodId(zoneId),
|
|
'zoneId': zoneId,
|
|
'shardId': None,
|
|
'avId': -1,
|
|
'allowRedirect': 0,
|
|
'doorDoId': self.otherDoId}
|
|
return request
|
|
|
|
def enterClosing(self, ts):
|
|
doorFrameHoleRight = self.findDoorNode('doorFrameHoleRight')
|
|
if doorFrameHoleRight.isEmpty():
|
|
self.notify.warning('enterClosing(): did not find doorFrameHoleRight')
|
|
return
|
|
rightDoor = self.findDoorNode('rightDoor')
|
|
if rightDoor.isEmpty():
|
|
self.notify.warning('enterClosing(): did not find rightDoor')
|
|
return
|
|
otherNP = self.getDoorNodePath()
|
|
trackName = 'doorClose-%d' % self.doId
|
|
if self.rightSwing:
|
|
h = 100
|
|
else:
|
|
h = -100
|
|
self.finishDoorTrack()
|
|
self.doorTrack = Sequence(LerpHprInterval(nodePath=rightDoor, duration=1.0, hpr=VBase3(0, 0, 0), startHpr=VBase3(h, 0, 0), other=otherNP, blendType='easeInOut'), Func(doorFrameHoleRight.hide), Func(self.hideIfHasFlat, rightDoor), SoundInterval(self.closeSfx, node=rightDoor), name=trackName)
|
|
self.doorTrack.start(ts)
|
|
if hasattr(self, 'done'):
|
|
request = self.getRequestStatus()
|
|
messenger.send('doorDoneEvent', [request])
|
|
|
|
def exitClosing(self):
|
|
pass
|
|
|
|
def enterClosed(self, ts):
|
|
pass
|
|
|
|
def exitClosed(self):
|
|
pass
|
|
|
|
def enterOpening(self, ts):
|
|
doorFrameHoleRight = self.findDoorNode('doorFrameHoleRight')
|
|
if doorFrameHoleRight.isEmpty():
|
|
self.notify.warning('enterOpening(): did not find doorFrameHoleRight')
|
|
return
|
|
rightDoor = self.findDoorNode('rightDoor')
|
|
if rightDoor.isEmpty():
|
|
self.notify.warning('enterOpening(): did not find rightDoor')
|
|
return
|
|
otherNP = self.getDoorNodePath()
|
|
trackName = 'doorOpen-%d' % self.doId
|
|
if self.rightSwing:
|
|
h = 100
|
|
else:
|
|
h = -100
|
|
self.finishDoorTrack()
|
|
self.doorTrack = Parallel(SoundInterval(self.openSfx, node=rightDoor), Sequence(HprInterval(rightDoor, VBase3(0, 0, 0), other=otherNP), Wait(0.4), Func(rightDoor.show), Func(doorFrameHoleRight.show), LerpHprInterval(nodePath=rightDoor, duration=0.6, hpr=VBase3(h, 0, 0), startHpr=VBase3(0, 0, 0), other=otherNP, blendType='easeInOut')), name=trackName)
|
|
self.doorTrack.start(ts)
|
|
|
|
def exitOpening(self):
|
|
pass
|
|
|
|
def enterOpen(self, ts):
|
|
for avatarID in self.avatarIDList:
|
|
avatar = self.cr.doId2do.get(avatarID)
|
|
if avatar:
|
|
track = self.avatarEnterDoorTrack(avatar, 1.0)
|
|
track.start(ts)
|
|
self.avatarTracks.append(track)
|
|
if avatarID == base.localAvatar.doId:
|
|
self.done = 1
|
|
|
|
self.avatarIDList = []
|
|
|
|
def exitOpen(self):
|
|
for track in self.avatarTracks:
|
|
track.finish()
|
|
DelayDelete.cleanupDelayDeletes(track)
|
|
|
|
self.avatarTracks = []
|
|
|
|
def exitDoorEnterOff(self):
|
|
pass
|
|
|
|
def exitDoorExitOff(self):
|
|
pass
|
|
|
|
def exitDoorEnterClosing(self, ts):
|
|
doorFrameHoleLeft = self.findDoorNode('doorFrameHoleLeft')
|
|
if doorFrameHoleLeft.isEmpty():
|
|
self.notify.warning('enterOpening(): did not find flatDoors')
|
|
return
|
|
if self.leftSwing:
|
|
h = -100
|
|
else:
|
|
h = 100
|
|
leftDoor = self.findDoorNode('leftDoor')
|
|
if not leftDoor.isEmpty():
|
|
otherNP = self.getDoorNodePath()
|
|
trackName = 'doorExitTrack-%d' % self.doId
|
|
self.finishDoorExitTrack()
|
|
self.doorExitTrack = Sequence(LerpHprInterval(nodePath=leftDoor, duration=1.0, hpr=VBase3(0, 0, 0), startHpr=VBase3(h, 0, 0), other=otherNP, blendType='easeInOut'), Func(doorFrameHoleLeft.hide), Func(self.hideIfHasFlat, leftDoor), SoundInterval(self.closeSfx, node=leftDoor), name=trackName)
|
|
self.doorExitTrack.start(ts)
|
|
|
|
def exitDoorExitClosing(self):
|
|
pass
|
|
|
|
def exitDoorEnterClosed(self, ts):
|
|
pass
|
|
|
|
def exitDoorExitClosed(self):
|
|
pass
|
|
|
|
def exitDoorEnterOpening(self, ts):
|
|
doorFrameHoleLeft = self.findDoorNode('doorFrameHoleLeft')
|
|
if doorFrameHoleLeft.isEmpty():
|
|
self.notify.warning('enterOpening(): did not find flatDoors')
|
|
return
|
|
leftDoor = self.findDoorNode('leftDoor')
|
|
if self.leftSwing:
|
|
h = -100
|
|
else:
|
|
h = 100
|
|
if not leftDoor.isEmpty():
|
|
otherNP = self.getDoorNodePath()
|
|
trackName = 'doorDoorExitTrack-%d' % self.doId
|
|
self.finishDoorExitTrack()
|
|
self.doorExitTrack = Parallel(SoundInterval(self.openSfx, node=leftDoor), Sequence(Func(leftDoor.show), Func(doorFrameHoleLeft.show), LerpHprInterval(nodePath=leftDoor, duration=0.6, hpr=VBase3(h, 0, 0), startHpr=VBase3(0, 0, 0), other=otherNP, blendType='easeInOut')), name=trackName)
|
|
self.doorExitTrack.start(ts)
|
|
else:
|
|
self.notify.warning('exitDoorEnterOpening(): did not find leftDoor')
|
|
|
|
def exitDoorExitOpening(self):
|
|
pass
|
|
|
|
def exitDoorEnterOpen(self, ts):
|
|
for avatarID in self.avatarExitIDList:
|
|
avatar = self.cr.doId2do.get(avatarID)
|
|
if avatar:
|
|
track = self.avatarExitTrack(avatar, 0.2)
|
|
track.start()
|
|
self.avatarExitTracks.append(track)
|
|
|
|
self.avatarExitIDList = []
|
|
|
|
def exitDoorExitOpen(self):
|
|
for track in self.avatarExitTracks:
|
|
track.finish()
|
|
DelayDelete.cleanupDelayDeletes(track)
|
|
|
|
self.avatarExitTracks = []
|
|
|
|
def findDoorNode(self, string, allowEmpty = False):
|
|
building = self.getBuilding()
|
|
if not building:
|
|
self.notify.warning('getBuilding() returned None, avoiding crash, remark 896029')
|
|
foundNode = None
|
|
else:
|
|
foundNode = building.find('**/door_' + str(self.doorIndex) + '/**/' + string + '*;+s+i')
|
|
if foundNode.isEmpty():
|
|
foundNode = building.find('**/' + string + '*;+s+i')
|
|
if allowEmpty:
|
|
return foundNode
|
|
return foundNode
|
|
|
|
def hideIfHasFlat(self, node):
|
|
if self.bHasFlat:
|
|
node.hide()
|