2019-11-02 17:27:54 -05:00
|
|
|
import math
|
2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import CollisionSphere, CollisionNode, Vec3, Point3, deg2Rad
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.interval.IntervalGlobal import Sequence, Func, Parallel, ActorInterval, Wait, Parallel, LerpHprInterval, ProjectileInterval, LerpPosInterval
|
|
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
|
|
from toontown.building import ElevatorConstants
|
|
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
from toontown.toonbase import TTLocalizer
|
|
|
|
from toontown.safezone import DistributedGolfKart
|
|
|
|
from toontown.building import DistributedElevatorExt
|
|
|
|
from toontown.building import ElevatorConstants
|
|
|
|
from toontown.distributed import DelayDelete
|
|
|
|
from direct.showbase import PythonUtil
|
|
|
|
from toontown.building import BoardingGroupShow
|
|
|
|
|
|
|
|
class DistributedCogKart(DistributedElevatorExt.DistributedElevatorExt):
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCogKart')
|
|
|
|
JumpOutOffsets = ((6.5, -2, -0.025),
|
|
|
|
(-6.5, -2, -0.025),
|
|
|
|
(3.75, 5, -0.025),
|
|
|
|
(-3.75, 5, -0.025))
|
|
|
|
|
|
|
|
def __init__(self, cr):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.__init__(self, cr)
|
|
|
|
self.type = ElevatorConstants.ELEVATOR_COUNTRY_CLUB
|
|
|
|
self.kartModelPath = 'phase_12/models/bossbotHQ/Coggolf_cart3.bam'
|
|
|
|
self.leftDoor = None
|
|
|
|
self.rightDoor = None
|
|
|
|
self.fillSlotTrack = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def generate(self):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.generate(self)
|
|
|
|
self.loader = self.cr.playGame.hood.loader
|
|
|
|
if self.loader:
|
|
|
|
self.notify.debug('Loader has been loaded')
|
|
|
|
self.notify.debug(str(self.loader))
|
|
|
|
else:
|
|
|
|
self.notify.debug('Loader has not been loaded')
|
|
|
|
self.golfKart = render.attachNewNode('golfKartNode')
|
|
|
|
self.kart = loader.loadModel(self.kartModelPath)
|
|
|
|
self.kart.setPos(0, 0, 0)
|
|
|
|
self.kart.setScale(1)
|
|
|
|
self.kart.reparentTo(self.golfKart)
|
|
|
|
self.golfKart.reparentTo(self.loader.geom)
|
|
|
|
self.wheels = self.kart.findAllMatches('**/wheelNode*')
|
|
|
|
self.numWheels = self.wheels.getNumPaths()
|
|
|
|
|
|
|
|
def announceGenerate(self):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.announceGenerate(self)
|
|
|
|
angle = self.startingHpr[0]
|
|
|
|
angle -= 90
|
|
|
|
radAngle = deg2Rad(angle)
|
|
|
|
unitVec = Vec3(math.cos(radAngle), math.sin(radAngle), 0)
|
|
|
|
unitVec *= 45.0
|
|
|
|
self.endPos = self.startingPos + unitVec
|
|
|
|
self.endPos.setZ(0.5)
|
|
|
|
dist = Vec3(self.endPos - self.enteringPos).length()
|
|
|
|
wheelAngle = dist / (4.8 * 1.4 * math.pi) * 360
|
|
|
|
self.kartEnterAnimateInterval = Parallel(LerpHprInterval(self.wheels[0], 5.0, Vec3(self.wheels[0].getH(), wheelAngle, self.wheels[0].getR())), LerpHprInterval(self.wheels[1], 5.0, Vec3(self.wheels[1].getH(), wheelAngle, self.wheels[1].getR())), LerpHprInterval(self.wheels[2], 5.0, Vec3(self.wheels[2].getH(), wheelAngle, self.wheels[2].getR())), LerpHprInterval(self.wheels[3], 5.0, Vec3(self.wheels[3].getH(), wheelAngle, self.wheels[3].getR())), name='CogKartAnimate')
|
|
|
|
trolleyExitTrack1 = Parallel(LerpPosInterval(self.golfKart, 5.0, self.endPos), self.kartEnterAnimateInterval, name='CogKartExitTrack')
|
|
|
|
self.trolleyExitTrack = Sequence(trolleyExitTrack1)
|
|
|
|
self.trolleyEnterTrack = Sequence(LerpPosInterval(self.golfKart, 5.0, self.startingPos, startPos=self.enteringPos))
|
|
|
|
self.closeDoors = Sequence(self.trolleyExitTrack, Func(self.onDoorCloseFinish))
|
|
|
|
self.openDoors = Sequence(self.trolleyEnterTrack)
|
|
|
|
|
|
|
|
def delete(self):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.delete(self)
|
|
|
|
if hasattr(self, 'elevatorFSM'):
|
|
|
|
del self.elevatorFSM
|
|
|
|
|
|
|
|
def setBldgDoId(self, bldgDoId):
|
|
|
|
self.bldg = None
|
|
|
|
self.setupElevatorKart()
|
|
|
|
return
|
|
|
|
|
|
|
|
def setupElevatorKart(self):
|
|
|
|
collisionRadius = ElevatorConstants.ElevatorData[self.type]['collRadius']
|
|
|
|
self.elevatorSphere = CollisionSphere(0, 0, 0, collisionRadius)
|
|
|
|
self.elevatorSphere.setTangible(1)
|
|
|
|
self.elevatorSphereNode = CollisionNode(self.uniqueName('elevatorSphere'))
|
|
|
|
self.elevatorSphereNode.setIntoCollideMask(ToontownGlobals.WallBitmask)
|
|
|
|
self.elevatorSphereNode.addSolid(self.elevatorSphere)
|
|
|
|
self.elevatorSphereNodePath = self.getElevatorModel().attachNewNode(self.elevatorSphereNode)
|
|
|
|
self.elevatorSphereNodePath.hide()
|
|
|
|
self.elevatorSphereNodePath.reparentTo(self.getElevatorModel())
|
|
|
|
self.elevatorSphereNodePath.stash()
|
|
|
|
self.boardedAvIds = {}
|
|
|
|
self.finishSetup()
|
|
|
|
|
|
|
|
def setColor(self, r, g, b):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def getElevatorModel(self):
|
|
|
|
return self.golfKart
|
|
|
|
|
|
|
|
def enterWaitEmpty(self, ts):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.enterWaitEmpty(self, ts)
|
|
|
|
|
|
|
|
def exitWaitEmpty(self):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.exitWaitEmpty(self)
|
|
|
|
|
|
|
|
def forceDoorsOpen(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def forceDoorsClosed(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def setPosHpr(self, x, y, z, h, p, r):
|
|
|
|
self.startingPos = Vec3(x, y, z)
|
|
|
|
self.enteringPos = Vec3(x, y, z - 10)
|
|
|
|
self.startingHpr = Vec3(h, 0, 0)
|
|
|
|
self.golfKart.setPosHpr(x, y, z, h, 0, 0)
|
|
|
|
|
|
|
|
def enterClosing(self, ts):
|
|
|
|
if self.localToonOnBoard:
|
|
|
|
elevator = self.getPlaceElevator()
|
|
|
|
if elevator:
|
|
|
|
elevator.fsm.request('elevatorClosing')
|
|
|
|
self.closeDoors.start(ts)
|
|
|
|
|
|
|
|
def enterClosed(self, ts):
|
|
|
|
self.forceDoorsClosed()
|
|
|
|
self.kartDoorsClosed(self.getZoneId())
|
|
|
|
|
|
|
|
def kartDoorsClosed(self, zoneId):
|
|
|
|
if self.localToonOnBoard:
|
|
|
|
hoodId = ZoneUtil.getHoodId(zoneId)
|
|
|
|
doneStatus = {'loader': 'suitInterior',
|
|
|
|
'where': 'suitInterior',
|
|
|
|
'hoodId': hoodId,
|
|
|
|
'zoneId': zoneId,
|
|
|
|
'shardId': None}
|
|
|
|
elevator = self.elevatorFSM
|
|
|
|
del self.elevatorFSM
|
|
|
|
elevator.signalDone(doneStatus)
|
|
|
|
return
|
|
|
|
|
|
|
|
def setCountryClubInteriorZone(self, zoneId):
|
|
|
|
if self.localToonOnBoard:
|
|
|
|
hoodId = self.cr.playGame.hood.hoodId
|
|
|
|
countryClubId = self.countryClubId
|
|
|
|
if bboard.has('countryClubIdOverride'):
|
|
|
|
countryClubId = bboard.get('countryClubIdOverride')
|
|
|
|
doneStatus = {'loader': 'cogHQLoader',
|
|
|
|
'where': 'countryClubInterior',
|
|
|
|
'how': 'teleportIn',
|
|
|
|
'zoneId': zoneId,
|
|
|
|
'countryClubId': self.countryClubId,
|
|
|
|
'hoodId': hoodId}
|
|
|
|
self.cr.playGame.getPlace().elevator.signalDone(doneStatus)
|
|
|
|
|
|
|
|
def setCountryClubInteriorZoneForce(self, zoneId):
|
|
|
|
place = self.cr.playGame.getPlace()
|
|
|
|
if place:
|
|
|
|
place.fsm.request('elevator', [self, 1])
|
|
|
|
hoodId = self.cr.playGame.hood.hoodId
|
|
|
|
countryClubId = self.countryClubId
|
|
|
|
if bboard.has('countryClubIdOverride'):
|
|
|
|
countryClubId = bboard.get('countryClubIdOverride')
|
|
|
|
doneStatus = {'loader': 'cogHQLoader',
|
|
|
|
'where': 'countryClubInterior',
|
|
|
|
'how': 'teleportIn',
|
|
|
|
'zoneId': zoneId,
|
|
|
|
'countryClubId': self.countryClubId,
|
|
|
|
'hoodId': hoodId}
|
|
|
|
if hasattr(place, 'elevator') and place.elevator:
|
|
|
|
place.elevator.signalDone(doneStatus)
|
|
|
|
else:
|
|
|
|
self.notify.warning("setMintInteriorZoneForce: Couldn't find playGame.getPlace().elevator, zoneId: %s" % zoneId)
|
|
|
|
else:
|
|
|
|
self.notify.warning("setCountryClubInteriorZoneForce: Couldn't find playGame.getPlace(), zoneId: %s" % zoneId)
|
|
|
|
|
|
|
|
def setCountryClubId(self, countryClubId):
|
|
|
|
self.countryClubId = countryClubId
|
|
|
|
|
|
|
|
def getZoneId(self):
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def fillSlot(self, index, avId, wantBoardingShow = 0):
|
|
|
|
self.notify.debug('%s.fillSlot(%s, %s, ... %s)' % (self.doId,
|
|
|
|
index,
|
|
|
|
avId,
|
|
|
|
globalClock.getRealTime()))
|
|
|
|
request = self.toonRequests.get(index)
|
|
|
|
if request:
|
|
|
|
self.cr.relatedObjectMgr.abortRequest(request)
|
|
|
|
del self.toonRequests[index]
|
|
|
|
if avId == 0:
|
|
|
|
pass
|
2019-12-30 00:07:56 -06:00
|
|
|
elif avId not in self.cr.doId2do:
|
2019-11-02 17:27:54 -05:00
|
|
|
func = PythonUtil.Functor(self.gotToon, index, avId)
|
|
|
|
self.toonRequests[index] = self.cr.relatedObjectMgr.requestObjects([avId], allCallback=func)
|
|
|
|
elif not self.isSetup:
|
|
|
|
self.deferredSlots.append((index, avId, wantBoardingShow))
|
|
|
|
else:
|
|
|
|
if avId == base.localAvatar.getDoId():
|
|
|
|
place = base.cr.playGame.getPlace()
|
|
|
|
if not place:
|
|
|
|
return
|
|
|
|
elevator = self.getPlaceElevator()
|
|
|
|
if elevator == None:
|
|
|
|
place.fsm.request('elevator')
|
|
|
|
elevator = self.getPlaceElevator()
|
|
|
|
if not elevator:
|
|
|
|
return
|
|
|
|
self.localToonOnBoard = 1
|
|
|
|
if hasattr(localAvatar, 'boardingParty') and localAvatar.boardingParty:
|
|
|
|
localAvatar.boardingParty.forceCleanupInviteePanel()
|
|
|
|
localAvatar.boardingParty.forceCleanupInviterPanels()
|
|
|
|
if hasattr(base.localAvatar, 'elevatorNotifier'):
|
|
|
|
base.localAvatar.elevatorNotifier.cleanup()
|
|
|
|
cameraTrack = Sequence()
|
|
|
|
cameraTrack.append(Func(elevator.fsm.request, 'boarding', [self.getElevatorModel()]))
|
|
|
|
cameraTrack.append(Func(elevator.fsm.request, 'boarded'))
|
|
|
|
toon = self.cr.doId2do[avId]
|
|
|
|
toon.stopSmooth()
|
|
|
|
toon.wrtReparentTo(self.golfKart)
|
|
|
|
sitStartDuration = toon.getDuration('sit-start')
|
|
|
|
jumpTrack = self.generateToonJumpTrack(toon, index)
|
|
|
|
track = Sequence(jumpTrack, Func(toon.setAnimState, 'Sit', 1.0), Func(self.clearToonTrack, avId), name=toon.uniqueName('fillElevator'), autoPause=1)
|
|
|
|
if wantBoardingShow:
|
|
|
|
boardingTrack, boardingTrackType = self.getBoardingTrack(toon, index, True)
|
|
|
|
track = Sequence(boardingTrack, track)
|
|
|
|
if avId == base.localAvatar.getDoId():
|
|
|
|
cameraWaitTime = 2.5
|
|
|
|
if boardingTrackType == BoardingGroupShow.TRACK_TYPE_RUN:
|
|
|
|
cameraWaitTime = 0.5
|
|
|
|
cameraTrack = Sequence(Wait(cameraWaitTime), cameraTrack)
|
|
|
|
if self.canHideBoardingQuitBtn(avId):
|
|
|
|
track = Sequence(Func(localAvatar.boardingParty.groupPanel.disableQuitButton), track)
|
|
|
|
if avId == base.localAvatar.getDoId():
|
|
|
|
track = Parallel(cameraTrack, track)
|
|
|
|
track.delayDelete = DelayDelete.DelayDelete(toon, 'CogKart.fillSlot')
|
|
|
|
self.storeToonTrack(avId, track)
|
|
|
|
track.start()
|
|
|
|
self.fillSlotTrack = track
|
|
|
|
self.boardedAvIds[avId] = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def generateToonJumpTrack(self, av, seatIndex):
|
|
|
|
av.pose('sit', 47)
|
|
|
|
hipOffset = av.getHipsParts()[2].getPos(av)
|
|
|
|
|
|
|
|
def getToonJumpTrack(av, seatIndex):
|
|
|
|
|
|
|
|
def getJumpDest(av = av, node = self.golfKart):
|
|
|
|
dest = Point3(0, 0, 0)
|
|
|
|
if hasattr(self, 'golfKart') and self.golfKart:
|
|
|
|
dest = Vec3(self.golfKart.getPos(av.getParent()))
|
|
|
|
seatNode = self.golfKart.find('**/seat' + str(seatIndex + 1))
|
|
|
|
dest += seatNode.getPos(self.golfKart)
|
|
|
|
dna = av.getStyle()
|
|
|
|
dest -= hipOffset
|
|
|
|
if seatIndex < 2:
|
|
|
|
dest.setY(dest.getY() + 2 * hipOffset.getY())
|
|
|
|
dest.setZ(dest.getZ() + 0.1)
|
|
|
|
else:
|
|
|
|
self.notify.warning('getJumpDestinvalid golfKart, returning (0,0,0)')
|
|
|
|
return dest
|
|
|
|
|
|
|
|
def getJumpHpr(av = av, node = self.golfKart):
|
|
|
|
hpr = Point3(0, 0, 0)
|
|
|
|
if hasattr(self, 'golfKart') and self.golfKart:
|
|
|
|
hpr = self.golfKart.getHpr(av.getParent())
|
|
|
|
if seatIndex < 2:
|
|
|
|
hpr.setX(hpr.getX() + 180)
|
|
|
|
else:
|
|
|
|
hpr.setX(hpr.getX())
|
|
|
|
angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX())
|
|
|
|
hpr.setX(angle)
|
|
|
|
else:
|
|
|
|
self.notify.warning('getJumpHpr invalid golfKart, returning (0,0,0)')
|
|
|
|
return hpr
|
|
|
|
|
|
|
|
toonJumpTrack = Parallel(ActorInterval(av, 'jump'), Sequence(Wait(0.43), Parallel(LerpHprInterval(av, hpr=getJumpHpr, duration=0.9), ProjectileInterval(av, endPos=getJumpDest, duration=0.9))))
|
|
|
|
return toonJumpTrack
|
|
|
|
|
|
|
|
def getToonSitTrack(av):
|
|
|
|
toonSitTrack = Sequence(ActorInterval(av, 'sit-start'), Func(av.loop, 'sit'))
|
|
|
|
return toonSitTrack
|
|
|
|
|
|
|
|
toonJumpTrack = getToonJumpTrack(av, seatIndex)
|
|
|
|
toonSitTrack = getToonSitTrack(av)
|
|
|
|
jumpTrack = Sequence(Parallel(toonJumpTrack, Sequence(Wait(1), toonSitTrack)))
|
|
|
|
return jumpTrack
|
|
|
|
|
|
|
|
def emptySlot(self, index, avId, bailFlag, timestamp, timeSent = 0):
|
|
|
|
if self.fillSlotTrack:
|
|
|
|
self.fillSlotTrack.finish()
|
|
|
|
self.fillSlotTrack = None
|
|
|
|
if avId == 0:
|
|
|
|
pass
|
|
|
|
elif not self.isSetup:
|
|
|
|
newSlots = []
|
|
|
|
for slot in self.deferredSlots:
|
|
|
|
if slot[0] != index:
|
|
|
|
newSlots.append(slot)
|
|
|
|
|
|
|
|
self.deferredSlots = newSlots
|
2019-12-30 00:07:56 -06:00
|
|
|
elif avId in self.cr.doId2do:
|
2019-11-02 17:27:54 -05:00
|
|
|
if bailFlag == 1 and hasattr(self, 'clockNode'):
|
|
|
|
if timestamp < self.countdownTime and timestamp >= 0:
|
|
|
|
self.countdown(self.countdownTime - timestamp)
|
|
|
|
else:
|
|
|
|
self.countdown(self.countdownTime)
|
|
|
|
toon = self.cr.doId2do[avId]
|
|
|
|
toon.stopSmooth()
|
|
|
|
sitStartDuration = toon.getDuration('sit-start')
|
|
|
|
jumpOutTrack = self.generateToonReverseJumpTrack(toon, index)
|
|
|
|
track = Sequence(jumpOutTrack, Func(self.notifyToonOffElevator, toon), Func(self.clearToonTrack, avId), name=toon.uniqueName('emptyElevator'), autoPause=1)
|
|
|
|
if self.canHideBoardingQuitBtn(avId):
|
|
|
|
track.append(Func(localAvatar.boardingParty.groupPanel.enableQuitButton))
|
|
|
|
track.append(Func(localAvatar.boardingParty.enableGoButton))
|
|
|
|
track.delayDelete = DelayDelete.DelayDelete(toon, 'CogKart.emptySlot')
|
|
|
|
self.storeToonTrack(toon.doId, track)
|
|
|
|
track.start()
|
|
|
|
if avId == base.localAvatar.getDoId():
|
|
|
|
messenger.send('exitElevator')
|
|
|
|
if avId in self.boardedAvIds:
|
|
|
|
del self.boardedAvIds[avId]
|
|
|
|
else:
|
|
|
|
self.notify.warning('toon: ' + str(avId) + " doesn't exist, and" + ' cannot exit the elevator!')
|
|
|
|
return
|
|
|
|
|
|
|
|
def generateToonReverseJumpTrack(self, av, seatIndex):
|
|
|
|
self.notify.debug('av.getH() = %s' % av.getH())
|
|
|
|
|
|
|
|
def getToonJumpTrack(av, destNode):
|
|
|
|
|
|
|
|
def getJumpDest(av = av, node = destNode):
|
|
|
|
dest = node.getPos(av.getParent())
|
|
|
|
dest += Vec3(*self.JumpOutOffsets[seatIndex])
|
|
|
|
return dest
|
|
|
|
|
|
|
|
def getJumpHpr(av = av, node = destNode):
|
|
|
|
hpr = node.getHpr(av.getParent())
|
|
|
|
hpr.setX(hpr.getX() + 180)
|
|
|
|
angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX())
|
|
|
|
hpr.setX(angle)
|
|
|
|
return hpr
|
|
|
|
|
|
|
|
toonJumpTrack = Parallel(ActorInterval(av, 'jump'), Sequence(Wait(0.1), Parallel(ProjectileInterval(av, endPos=getJumpDest, duration=0.9))))
|
|
|
|
return toonJumpTrack
|
|
|
|
|
|
|
|
toonJumpTrack = getToonJumpTrack(av, self.golfKart)
|
|
|
|
jumpTrack = Sequence(toonJumpTrack, Func(av.loop, 'neutral'), Func(av.wrtReparentTo, render))
|
|
|
|
return jumpTrack
|
|
|
|
|
|
|
|
def startCountdownClock(self, countdownTime, ts):
|
|
|
|
DistributedElevatorExt.DistributedElevatorExt.startCountdownClock(self, countdownTime, ts)
|
|
|
|
self.clock.setH(self.clock.getH() + 180)
|
|
|
|
|
|
|
|
def rejectBoard(self, avId, reason = 0):
|
2019-12-30 00:07:56 -06:00
|
|
|
print('rejectBoard %s' % reason)
|
2019-11-02 17:27:54 -05:00
|
|
|
if hasattr(base.localAvatar, 'elevatorNotifier'):
|
|
|
|
if reason == ElevatorConstants.REJECT_SHUFFLE:
|
|
|
|
base.localAvatar.elevatorNotifier.showMe(TTLocalizer.ElevatorHoppedOff)
|
|
|
|
elif reason == ElevatorConstants.REJECT_MINLAFF:
|
|
|
|
base.localAvatar.elevatorNotifier.showMe(TTLocalizer.KartMinLaff % self.minLaff)
|
|
|
|
elif reason == ElevatorConstants.REJECT_PROMOTION:
|
|
|
|
base.localAvatar.elevatorNotifier.showMe(TTLocalizer.BossElevatorRejectMessage)
|
|
|
|
elif reason == ElevatorConstants.REJECT_NOT_YET_AVAILABLE:
|
|
|
|
base.localAvatar.elevatorNotifier.showMe(TTLocalizer.NotYetAvailable)
|
|
|
|
doneStatus = {'where': 'reject'}
|
|
|
|
elevator = self.getPlaceElevator()
|
|
|
|
if elevator:
|
|
|
|
elevator.signalDone(doneStatus)
|
|
|
|
|
|
|
|
def getDestName(self):
|
|
|
|
if self.countryClubId == ToontownGlobals.BossbotCountryClubIntA:
|
|
|
|
return TTLocalizer.ElevatorBossBotCourse0
|
|
|
|
elif self.countryClubId == ToontownGlobals.BossbotCountryClubIntB:
|
|
|
|
return TTLocalizer.ElevatorBossBotCourse1
|
|
|
|
elif self.countryClubId == ToontownGlobals.BossbotCountryClubIntC:
|
|
|
|
return TTLocalizer.ElevatorBossBotCourse2
|