444 lines
20 KiB
Python
444 lines
20 KiB
Python
from panda3d.core import *
|
|
from direct.interval.IntervalGlobal import *
|
|
from direct.distributed.ClockDelta import *
|
|
from toontown.toonbase import ToontownGlobals
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
import DistributedDoorEntityBase
|
|
from direct.fsm import FourState
|
|
from direct.fsm import ClassicFSM
|
|
from otp.level import DistributedEntity
|
|
from toontown.toonbase import TTLocalizer
|
|
from otp.level import BasicEntities
|
|
from direct.fsm import State
|
|
from otp.level import VisibilityBlocker
|
|
|
|
class DistributedDoorEntityLock(DistributedDoorEntityBase.LockBase, FourState.FourState):
|
|
slideLeft = Vec3(-7.5, 0.0, 0.0)
|
|
slideRight = Vec3(7.5, 0.0, 0.0)
|
|
|
|
def __init__(self, door, lockIndex, lockedNodePath, leftNodePath, rightNodePath, stateIndex):
|
|
self.door = door
|
|
self.lockIndex = lockIndex
|
|
self.lockedNodePath = lockedNodePath
|
|
self.leftNodePath = leftNodePath
|
|
self.rightNodePath = rightNodePath
|
|
self.initialStateIndex = stateIndex
|
|
FourState.FourState.__init__(self, self.stateNames, self.stateDurations)
|
|
|
|
def delete(self):
|
|
self.takedown()
|
|
del self.door
|
|
|
|
def setup(self):
|
|
self.setLockState(self.initialStateIndex)
|
|
del self.initialStateIndex
|
|
|
|
def takedown(self):
|
|
if self.track is not None:
|
|
self.track.pause()
|
|
self.track = None
|
|
for i in self.states.keys():
|
|
del self.states[i]
|
|
|
|
self.states = []
|
|
self.fsm = None
|
|
return
|
|
|
|
def setLockState(self, stateIndex):
|
|
if self.stateIndex != stateIndex:
|
|
state = self.states.get(stateIndex)
|
|
if state is not None:
|
|
self.fsm.request(state)
|
|
return
|
|
|
|
def isUnlocked(self):
|
|
return self.isOn()
|
|
|
|
def enterState1(self):
|
|
FourState.FourState.enterState1(self)
|
|
beat = self.duration * 0.05
|
|
slideSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_arms_retracting.ogg')
|
|
self.setTrack(Sequence(Wait(beat * 2.0), Parallel(SoundInterval(slideSfx, node=self.door.node, volume=0.8), Sequence(ShowInterval(self.leftNodePath), ShowInterval(self.rightNodePath), Parallel(LerpPosInterval(nodePath=self.leftNodePath, other=self.lockedNodePath, duration=beat * 16.0, pos=Vec3(0.0), blendType='easeIn'), LerpPosInterval(nodePath=self.rightNodePath, other=self.lockedNodePath, duration=beat * 16.0, pos=Vec3(0.0), blendType='easeIn')), HideInterval(self.leftNodePath), HideInterval(self.rightNodePath), ShowInterval(self.lockedNodePath)))))
|
|
|
|
def enterState2(self):
|
|
FourState.FourState.enterState2(self)
|
|
self.setTrack(None)
|
|
self.leftNodePath.setPos(self.lockedNodePath, Vec3(0.0))
|
|
self.rightNodePath.setPos(self.lockedNodePath, Vec3(0.0))
|
|
self.leftNodePath.hide()
|
|
self.rightNodePath.hide()
|
|
self.lockedNodePath.show()
|
|
return
|
|
|
|
def enterState3(self):
|
|
FourState.FourState.enterState3(self)
|
|
unlockSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_unlock.ogg')
|
|
slideSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_arms_retracting.ogg')
|
|
beat = self.duration * 0.05
|
|
self.setTrack(Sequence(Wait(beat * 2), Parallel(SoundInterval(unlockSfx, node=self.door.node, volume=0.8), SoundInterval(slideSfx, node=self.door.node, volume=0.8), Sequence(HideInterval(self.lockedNodePath), ShowInterval(self.leftNodePath), ShowInterval(self.rightNodePath), Parallel(LerpPosInterval(nodePath=self.leftNodePath, other=self.lockedNodePath, duration=beat * 16, pos=self.slideLeft, blendType='easeOut'), LerpPosInterval(nodePath=self.rightNodePath, other=self.lockedNodePath, duration=beat * 16, pos=self.slideRight, blendType='easeOut')), HideInterval(self.leftNodePath), HideInterval(self.rightNodePath)))))
|
|
|
|
def enterState4(self):
|
|
FourState.FourState.enterState4(self)
|
|
self.setTrack(None)
|
|
self.leftNodePath.setPos(self.lockedNodePath, self.slideLeft)
|
|
self.rightNodePath.setPos(self.lockedNodePath, self.slideRight)
|
|
self.leftNodePath.hide()
|
|
self.rightNodePath.hide()
|
|
self.lockedNodePath.hide()
|
|
return
|
|
|
|
|
|
class DistributedDoorEntity(DistributedDoorEntityBase.DistributedDoorEntityBase, DistributedEntity.DistributedEntity, BasicEntities.NodePathAttribsProxy, FourState.FourState, VisibilityBlocker.VisibilityBlocker):
|
|
|
|
def __init__(self, cr):
|
|
self.innerDoorsTrack = None
|
|
self.isVisReady = 0
|
|
self.isOuterDoorOpen = 0
|
|
DistributedEntity.DistributedEntity.__init__(self, cr)
|
|
FourState.FourState.__init__(self, self.stateNames, self.stateDurations)
|
|
VisibilityBlocker.VisibilityBlocker.__init__(self)
|
|
self.locks = []
|
|
return
|
|
|
|
def generate(self):
|
|
DistributedEntity.DistributedEntity.generate(self)
|
|
|
|
def announceGenerate(self):
|
|
self.doorNode = hidden.attachNewNode('door-%s' % self.entId)
|
|
DistributedEntity.DistributedEntity.announceGenerate(self)
|
|
BasicEntities.NodePathAttribsProxy.initNodePathAttribs(self)
|
|
self.setup()
|
|
|
|
def disable(self):
|
|
self.takedown()
|
|
self.doorNode.removeNode()
|
|
del self.doorNode
|
|
DistributedEntity.DistributedEntity.disable(self)
|
|
|
|
def delete(self):
|
|
DistributedEntity.DistributedEntity.delete(self)
|
|
|
|
def setup(self):
|
|
self.setupDoor()
|
|
for i in self.locks:
|
|
i.setup()
|
|
|
|
self.accept('exit%s' % (self.getName(),), self.exitTrigger)
|
|
self.acceptAvatar()
|
|
|
|
def takedown(self):
|
|
self.ignoreAll()
|
|
if self.track is not None:
|
|
self.track.finish()
|
|
self.track = None
|
|
if self.innerDoorsTrack is not None:
|
|
self.innerDoorsTrack.finish()
|
|
self.innerDoorsTrack = None
|
|
for i in self.locks:
|
|
i.takedown()
|
|
|
|
self.locks = []
|
|
self.fsm = None
|
|
for i in self.states.keys():
|
|
del self.states[i]
|
|
|
|
self.states = []
|
|
return
|
|
|
|
setUnlock0Event = DistributedDoorEntityBase.stubFunction
|
|
setUnlock1Event = DistributedDoorEntityBase.stubFunction
|
|
setUnlock2Event = DistributedDoorEntityBase.stubFunction
|
|
setUnlock3Event = DistributedDoorEntityBase.stubFunction
|
|
setIsOpenEvent = DistributedDoorEntityBase.stubFunction
|
|
setIsLock0Unlocked = DistributedDoorEntityBase.stubFunction
|
|
setIsLock1Unlocked = DistributedDoorEntityBase.stubFunction
|
|
setIsLock2Unlocked = DistributedDoorEntityBase.stubFunction
|
|
setIsLock3Unlocked = DistributedDoorEntityBase.stubFunction
|
|
setIsOpen = DistributedDoorEntityBase.stubFunction
|
|
setSecondsOpen = DistributedDoorEntityBase.stubFunction
|
|
|
|
def acceptAvatar(self):
|
|
self.accept('enter%s' % (self.getName(),), self.enterTrigger)
|
|
|
|
def rejectInteract(self):
|
|
DistributedEntity.DistributedEntity.rejectInteract(self)
|
|
self.acceptAvatar()
|
|
|
|
def avatarExit(self, avatarId):
|
|
DistributedEntity.DistributedEntity.avatarExit(self, avatarId)
|
|
self.acceptAvatar()
|
|
|
|
def enterTrigger(self, args = None):
|
|
messenger.send('DistributedInteractiveEntity_enterTrigger')
|
|
self.sendUpdate('requestOpen')
|
|
|
|
def exitTrigger(self, args = None):
|
|
messenger.send('DistributedInteractiveEntity_exitTrigger')
|
|
|
|
def okToUnblockVis(self):
|
|
VisibilityBlocker.VisibilityBlocker.okToUnblockVis(self)
|
|
self.isVisReady = 1
|
|
self.openInnerDoors()
|
|
|
|
def changedOnState(self, isOn):
|
|
messenger.send(self.getOutputEventName(), [not isOn])
|
|
|
|
def setLocksState(self, stateBits):
|
|
lock0 = stateBits & 15
|
|
lock1 = (stateBits & 240) >> 4
|
|
lock2 = (stateBits & 3840) >> 8
|
|
if self.isGenerated():
|
|
self.locks[0].setLockState(lock0)
|
|
self.locks[1].setLockState(lock1)
|
|
self.locks[2].setLockState(lock2)
|
|
else:
|
|
self.initialLock0StateIndex = lock0
|
|
self.initialLock1StateIndex = lock1
|
|
self.initialLock2StateIndex = lock2
|
|
|
|
def setDoorState(self, stateIndex, timeStamp):
|
|
self.stateTime = globalClockDelta.localElapsedTime(timeStamp)
|
|
if self.isGenerated():
|
|
if self.stateIndex != stateIndex:
|
|
state = self.states.get(stateIndex)
|
|
if state is not None:
|
|
self.fsm.request(state)
|
|
else:
|
|
self.initialState = stateIndex
|
|
self.initialStateTimestamp = timeStamp
|
|
return
|
|
|
|
def getName(self):
|
|
return 'switch-%s' % str(self.entId)
|
|
|
|
def getNodePath(self):
|
|
if hasattr(self, 'doorNode'):
|
|
return self.doorNode
|
|
return None
|
|
|
|
def setupDoor(self):
|
|
model = loader.loadModel('phase_9/models/cogHQ/CogDoorHandShake')
|
|
if model:
|
|
doorway = model.find('**/Doorway1')
|
|
rootNode = self.doorNode.attachNewNode(self.getName() + '-root')
|
|
rootNode.setPos(self.pos)
|
|
rootNode.setHpr(self.hpr)
|
|
rootNode.setScale(self.scale)
|
|
rootNode.setColor(self.color)
|
|
change = rootNode.attachNewNode('changePos')
|
|
doorway.reparentTo(change)
|
|
self.node = rootNode
|
|
self.node.show()
|
|
self.locks.append(DistributedDoorEntityLock(self,
|
|
0,
|
|
doorway.find('**/Slide_One_Closed'),
|
|
doorway.find('**/Slide_One_Left_Open'),
|
|
doorway.find('**/Slide_One_Right_Open'),
|
|
self.initialLock0StateIndex))
|
|
self.locks.append(DistributedDoorEntityLock(self,
|
|
1,
|
|
doorway.find('**/Slide_Two_Closed'),
|
|
doorway.find('**/Slide_Two_Left_Open'),
|
|
doorway.find('**/Slide_Two_Right_Open'),
|
|
self.initialLock1StateIndex))
|
|
self.locks.append(DistributedDoorEntityLock(self,
|
|
2,
|
|
doorway.find('**/Slide_Three_Closed'),
|
|
doorway.find('**/Slide_Three_Left_Open'),
|
|
doorway.find('**/Slide_Three_Right_Open'),
|
|
self.initialLock2StateIndex))
|
|
|
|
del self.initialLock0StateIndex
|
|
del self.initialLock1StateIndex
|
|
del self.initialLock2StateIndex
|
|
|
|
door = doorway.find('doortop')
|
|
if door.isEmpty():
|
|
print 'doortop hack'
|
|
door = doorway.attachNewNode('doortop')
|
|
doorway.find('doortop1').reparentTo(door)
|
|
doorway.find('doortop2').reparentTo(door)
|
|
|
|
rootNode = self.doorNode.attachNewNode(self.getName() + '-topDoor')
|
|
rootNode.setPos(self.pos)
|
|
rootNode.setHpr(self.hpr)
|
|
rootNode.setScale(self.scale)
|
|
rootNode.setColor(self.color)
|
|
change = rootNode.attachNewNode('changePos')
|
|
door.reparentTo(change)
|
|
self.doorTop = rootNode
|
|
self.doorTop.show()
|
|
|
|
rootNode = self.doorTop.getParent().attachNewNode(self.getName() + '-leftDoor')
|
|
change = rootNode.attachNewNode('change')
|
|
door = doorway.find('**/doorLeft')
|
|
door = door.reparentTo(change)
|
|
self.doorLeft = rootNode
|
|
self.doorLeft.show()
|
|
change.setPos(self.pos)
|
|
change.setHpr(self.hpr)
|
|
change.setScale(self.scale)
|
|
change.setColor(self.color)
|
|
|
|
door = doorway.find('doorbottom')
|
|
if door.isEmpty():
|
|
print 'doorbottom hack'
|
|
door = doorway.attachNewNode('doorbottom')
|
|
doorway.find('doorbottom1').reparentTo(door)
|
|
doorway.find('doorbottom2').reparentTo(door)
|
|
|
|
change = render.attachNewNode('changePos')
|
|
door.reparentTo(change)
|
|
rootNode = self.doorNode.attachNewNode(self.getName() + '-bottomDoor')
|
|
rootNode.setPos(self.pos)
|
|
rootNode.setHpr(self.hpr)
|
|
rootNode.setScale(self.scale)
|
|
rootNode.setColor(self.color)
|
|
change.reparentTo(rootNode)
|
|
self.doorBottom = rootNode
|
|
self.doorBottom.show()
|
|
|
|
rootNode = self.doorTop.getParent().attachNewNode(self.getName() + '-rightDoor')
|
|
change = rootNode.attachNewNode('change')
|
|
door = doorway.find('**/doorRight')
|
|
door = door.reparentTo(change)
|
|
self.doorRight = rootNode
|
|
self.doorRight.show()
|
|
change.setPos(self.pos)
|
|
change.setHpr(self.hpr)
|
|
change.setScale(self.scale)
|
|
change.setColor(self.color)
|
|
|
|
collision = self.doorLeft.find('**/doorLeft_collision1')
|
|
collision.setName(self.getName())
|
|
collision = self.doorLeft.find('**/doorLeft_collision2')
|
|
collision.setName(self.getName())
|
|
collision = self.doorRight.find('**/doorRight_collision1')
|
|
collision.setName(self.getName())
|
|
collision = self.doorRight.find('**/doorRight_collision2')
|
|
collision.setName(self.getName())
|
|
collision = self.doorLeft.find('**/doorLeft_innerCollision')
|
|
collision.setName(self.getName())
|
|
self.leftInnerCollision = collision
|
|
collision = self.doorRight.find('**/doorRight_innerCollision')
|
|
collision.setName(self.getName())
|
|
self.rightInnerCollision = collision
|
|
|
|
if 1:
|
|
pass
|
|
else:
|
|
radius = 8.0
|
|
cSphere = CollisionSphere(0.0, 0.0, 0.0, radius)
|
|
cSphere.setTangible(0)
|
|
cSphereNode = CollisionNode(self.getName())
|
|
cSphereNode.addSolid(cSphere)
|
|
cSphereNode.setFromCollideMask(BitMask32.allOff())
|
|
cSphereNode.setIntoCollideMask(ToontownGlobals.WallBitmask)
|
|
self.cSphereNodePath = self.node.attachNewNode(cSphereNode)
|
|
|
|
if 1:
|
|
self.node.flattenMedium()
|
|
self.doorTop.flattenMedium()
|
|
self.doorBottom.flattenMedium()
|
|
self.doorLeft.flattenMedium()
|
|
self.doorRight.flattenMedium()
|
|
|
|
self.setDoorState(self.initialState, self.initialStateTimestamp)
|
|
del self.initialState
|
|
del self.initialStateTimestamp
|
|
|
|
def setInnerDoorsTrack(self, track):
|
|
if self.innerDoorsTrack is not None:
|
|
self.innerDoorsTrack.pause()
|
|
self.innerDoorsTrack = None
|
|
if track is not None:
|
|
track.start(0.0)
|
|
self.innerDoorsTrack = track
|
|
return
|
|
|
|
def openInnerDoors(self):
|
|
if not self.level.complexVis() or self.isOuterDoorOpen and (not self.isVisBlocker or self.isVisReady):
|
|
duration = self.duration
|
|
slideSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_sliding.ogg')
|
|
finalSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_final.ogg')
|
|
moveDistance = 8.0
|
|
self.setInnerDoorsTrack(Sequence(Func(self.leftInnerCollision.unstash), Func(self.rightInnerCollision.unstash), Parallel(SoundInterval(slideSfx, node=self.node, duration=duration * 0.4, volume=0.8), LerpPosInterval(nodePath=self.doorLeft, duration=duration * 0.4, pos=Vec3(-moveDistance, 0.0, 0.0), blendType='easeOut'), LerpPosInterval(nodePath=self.doorRight, duration=duration * 0.4, pos=Vec3(moveDistance, 0.0, 0.0), blendType='easeOut'), Sequence(Wait(duration * 0.375), SoundInterval(finalSfx, node=self.node, duration=1.0, volume=0.8))), Func(self.doorLeft.stash), Func(self.doorRight.stash)))
|
|
|
|
def closeInnerDoors(self):
|
|
duration = self.duration
|
|
slideSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_sliding.ogg')
|
|
finalSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_final.ogg')
|
|
moveDistance = 8.0
|
|
self.setInnerDoorsTrack(Sequence(Func(self.doorLeft.unstash), Func(self.doorRight.unstash), Parallel(SoundInterval(slideSfx, node=self.node, duration=duration * 0.4, volume=0.8), LerpPosInterval(nodePath=self.doorLeft, duration=duration * 0.4, pos=Vec3(0.0), blendType='easeIn'), LerpPosInterval(nodePath=self.doorRight, duration=duration * 0.4, pos=Vec3(0.0), blendType='easeIn'), Sequence(Wait(duration * 0.375), SoundInterval(finalSfx, node=self.node, duration=1.0, volume=0.8))), Func(self.leftInnerCollision.stash), Func(self.rightInnerCollision.stash)))
|
|
|
|
def setisOuterDoorOpen(self, isOpen):
|
|
self.isOuterDoorOpen = isOpen
|
|
|
|
def enterState1(self):
|
|
FourState.FourState.enterState1(self)
|
|
self.isOuterDoorOpen = 0
|
|
if self.isVisBlocker:
|
|
if not self.isVisReady:
|
|
self.requestUnblockVis()
|
|
else:
|
|
self.okToUnblockVis()
|
|
duration = self.duration
|
|
slideSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_sliding.ogg')
|
|
finalSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_final.ogg')
|
|
moveDistance = 8.0
|
|
self.setTrack(Sequence(Wait(duration * 0.1), Parallel(SoundInterval(slideSfx, node=self.node, duration=duration * 0.4, volume=0.8), LerpPosInterval(nodePath=self.doorTop, duration=duration * 0.4, pos=Vec3(0.0, 0.0, moveDistance), blendType='easeOut'), LerpPosInterval(nodePath=self.doorBottom, duration=duration * 0.4, pos=Vec3(0.0, 0.0, -moveDistance), blendType='easeOut'), Sequence(Wait(duration * 0.375), SoundInterval(finalSfx, node=self.node, duration=1.0, volume=0.8))), Func(self.doorTop.stash), Func(self.doorBottom.stash), Func(self.setisOuterDoorOpen, 1), Func(self.openInnerDoors)))
|
|
|
|
def enterState2(self):
|
|
FourState.FourState.enterState2(self)
|
|
self.isOuterDoorOpen = 1
|
|
self.setTrack(None)
|
|
moveDistance = 7.5
|
|
(self.doorTop.setPos(Vec3(0.0, 0.0, moveDistance)),)
|
|
(self.doorBottom.setPos(Vec3(0.0, 0.0, -moveDistance)),)
|
|
self.doorTop.stash()
|
|
self.doorBottom.stash()
|
|
if not self.isVisBlocker or not self.isWaitingForUnblockVis():
|
|
self.setInnerDoorsTrack(None)
|
|
self.doorLeft.setPos(Vec3(-moveDistance, 0.0, 0.0))
|
|
self.doorRight.setPos(Vec3(moveDistance, 0.0, 0.0))
|
|
self.doorLeft.stash()
|
|
self.doorRight.stash()
|
|
return
|
|
|
|
def exitState2(self):
|
|
FourState.FourState.exitState2(self)
|
|
self.cancelUnblockVis()
|
|
|
|
def enterState3(self):
|
|
FourState.FourState.enterState3(self)
|
|
duration = self.duration
|
|
slideSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_sliding.ogg')
|
|
finalSfx = base.loadSfx('phase_9/audio/sfx/CHQ_FACT_door_open_final.ogg')
|
|
self.setTrack(Sequence(Wait(duration * 0.1),
|
|
Func(self.closeInnerDoors),
|
|
Wait(duration * 0.4),
|
|
Func(self.doorTop.unstash),
|
|
Func(self.doorBottom.unstash),
|
|
Parallel(SoundInterval(slideSfx, node=self.node, duration=duration*0.4, volume=0.8),
|
|
LerpPosInterval(nodePath=self.doorTop, duration=duration*0.4, pos=Vec3(0.0), blendType='easeIn'),
|
|
LerpPosInterval(nodePath=self.doorBottom, duration=duration*0.4, pos=Vec3(0.0), blendType='easeIn'),
|
|
Sequence(Wait(duration*0.375),
|
|
SoundInterval(finalSfx, node=self.node, duration=duration*0.4, volume=0.8))),
|
|
Func(self.setisOuterDoorOpen, 0)))
|
|
|
|
def enterState4(self):
|
|
FourState.FourState.enterState4(self)
|
|
self.setisOuterDoorOpen(0)
|
|
self.isVisReady = 0
|
|
self.setTrack(None)
|
|
self.doorTop.unstash()
|
|
self.doorBottom.unstash()
|
|
self.doorTop.setPos(Vec3(0.0))
|
|
self.doorBottom.setPos(Vec3(0.0))
|
|
self.setInnerDoorsTrack(None)
|
|
self.leftInnerCollision.stash()
|
|
self.rightInnerCollision.stash()
|
|
self.doorLeft.unstash()
|
|
self.doorRight.unstash()
|
|
self.doorLeft.setPos(Vec3(0.0))
|
|
self.doorRight.setPos(Vec3(0.0))
|