toontown-just-works/toontown/coghq/DistributedMaze.py
2024-07-07 18:08:39 -05:00

235 lines
9.3 KiB
Python

from otp.level.BasicEntities import DistributedNodePathEntity
from panda3d.core import *
from direct.interval.IntervalGlobal import *
from toontown.toonbase.ToontownGlobals import *
import random
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.ClockDelta import globalClockDelta
import DistributedBarrelBase
from otp.level.BasicEntities import DistributedNodePathEntity
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownTimer
from direct.task import Task
from direct.gui.DirectGui import DGG, DirectFrame, DirectLabel
class DistributedMaze(DistributedNodePathEntity):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMaze')
ScheduleTaskName = 'mazeScheduler'
RemoveBlocksDict = {2: ('HedgeBlock_0_1',),
4: (('HedgeBlock_0_1', 'HedgeBlock_1_3', 'HedgeBlock_2_3'), ('HedgeBlock_0_2', 'HedgeBlock_2_3', 'HedgeBlock_1_3'), ('HedgeBlock_0_1', 'HedgeBlock_0_2', 'HedgeBlock_1_3', 'HedgeBlock_2_3'))}
def __init__(self, cr):
DistributedNodePathEntity.__init__(self, cr)
self.numSections = 0
self.GameDuration = 35.0 + self.numSections * 15.0
self.timer = None
self.frame2D = None
self.gameLabel = None
self.gameStarted = 0
self.finished = 0
self.timedOut = 0
self.toonFinishedText = TTLocalizer.toonFinishedHedgeMaze
self.toonEnteredText = TTLocalizer.enterHedgeMaze
return
def announceGenerate(self):
DistributedNodePathEntity.announceGenerate(self)
self.addHints(self.roomHold)
self.loadGui()
def disable(self):
DistributedNodePathEntity.disable(self)
self.unloadGui()
self.cleanupTimer()
self.ignoreAll()
def delete(self):
self.cleanupTimer()
DistributedNodePathEntity.delete(self)
def setRoomDoId(self, roomDoId):
self.roomDoId = roomDoId
room = self.cr.doId2do.get(roomDoId)
if room:
self.gotRoom([room])
else:
self.roomRequest = self.cr.relatedObjectMgr.requestObjects([roomDoId], allCallback=self.gotRoom, timeout=5)
def gotRoom(self, rooms):
self.roomRequest = None
room = rooms[0]
self.roomHold = room
rotations = [0,
0,
90,
90,
180,
180,
270,
270]
self.getRng().shuffle(rotations)
self.numSections = 0
for i in xrange(0, 4):
maze = room.getGeom().find('**/Maze_Inside_%d' % i)
if not maze.isEmpty():
self.numSections += 1
if rotations:
maze.setH(rotations.pop())
self.GameDuration = 35.0 + self.numSections * 15.0
self.removeHedgeBlocks(room)
return
def addHints(self, room):
self.focusPoint = self.attachNewNode('GolfGreenGameFrame')
hintList = room.getGeom().findAllMatches('**/dead*')
for hint in hintList:
self.actSphere = CollisionSphere(0, 0, 0, 7.0)
self.actSphereNode = CollisionNode('mazegame_hint-%s-%s' % (self.level.getLevelId(), self.entId))
self.actSphereNode.addSolid(self.actSphere)
self.actSphereNodePath = hint.attachNewNode(self.actSphereNode)
self.actSphereNode.setCollideMask(WallBitmask)
self.actSphere.setTangible(0)
self.enterEvent = 'enter' + self.actSphereNode.getName()
self.accept(self.enterEvent, self.__handleToonEnterHint)
self.exitEvent = 'exit' + self.actSphereNode.getName()
self.accept(self.exitEvent, self.__handleToonExitHint)
enterance = room.getGeom().find('**/ENTRANCE')
self.enterSphere = CollisionSphere(0, 0, 0, 8.0)
self.enterSphereNode = CollisionNode('mazegame_enter-%s-%s' % (self.level.getLevelId(), self.entId))
self.enterSphereNode.addSolid(self.enterSphere)
self.enterSphereNodePath = enterance.attachNewNode(self.enterSphereNode)
self.enterSphereNode.setCollideMask(WallBitmask)
self.enterSphere.setTangible(0)
self.enteranceEvent = 'enter' + self.enterSphereNode.getName()
self.accept(self.enteranceEvent, self.__handleToonEnterance)
finish = room.getGeom().find('**/finish')
self.finishSphere = CollisionSphere(0, 0, 0, 15.0)
self.finishSphereNode = CollisionNode('mazegame_finish-%s-%s' % (self.level.getLevelId(), self.entId))
self.finishSphereNode.addSolid(self.finishSphere)
self.finishSphereNodePath = finish.attachNewNode(self.finishSphereNode)
self.finishSphereNode.setCollideMask(WallBitmask)
self.finishSphere.setTangible(0)
self.finishEvent = 'enter' + self.finishSphereNode.getName()
self.accept(self.finishEvent, self.__handleToonFinish)
def __handleToonEnterance(self, collEntry):
if not self.gameStarted:
self.notify.debug('sending clientTriggered for %d' % self.doId)
self.sendUpdate('setClientTriggered', [])
self.level.countryClub.showInfoText(self.toonEnteredText)
def __handleToonFinish(self, collEntry):
self.sendUpdate('setFinishedMaze', [])
self.finished = 1
def __handleToonEnterHint(self, collEntry):
camHeight = base.localAvatar.getClampedAvatarHeight()
heightScaleFactor = camHeight * 0.3333333333
defLookAt = Point3(0.0, 1.5, camHeight)
cameraPoint = Point3(0.0, -22.0 * heightScaleFactor, camHeight + 54.0)
base.localAvatar.stopUpdateSmartCamera()
base.localAvatar.startUpdateSmartCamera(push=0)
base.localAvatar.setIdealCameraPos(cameraPoint)
def __handleToonExitHint(self, collEntry):
base.localAvatar.stopUpdateSmartCamera()
base.localAvatar.startUpdateSmartCamera()
base.localAvatar.setCameraPositionByIndex(base.localAvatar.cameraIndex)
self.cameraHold = None
return
def getRng(self):
return random.Random(self.entId * self.doId)
def removeHedgeBlocks(self, room):
if self.numSections in self.RemoveBlocksDict:
blocksToRemove = self.getRng().choice(self.RemoveBlocksDict[self.numSections])
for blockName in blocksToRemove:
block = room.getGeom().find('**/%s' % blockName)
if not block.isEmpty():
block.removeNode()
def setGameStart(self, timestamp):
self.notify.debug('%d setGameStart: Starting game' % self.doId)
self.gameStartTime = globalClockDelta.networkToLocalTime(timestamp)
self.gameStarted = True
curGameTime = self.getCurrentGameTime()
timeLeft = self.GameDuration - curGameTime
self.cleanupTimer()
self.timer = ToontownTimer.ToontownTimer()
self.timer.posBelowTopRightCorner()
self.timer.setTime(timeLeft)
self.timer.countdown(timeLeft, self.timerExpired)
self.startScheduleTask()
self.frame2D.show()
def setGameOver(self):
self.timedOut = 1
if not self.finished:
self.sendUpdate('damageMe', [])
roomNum = self.level.roomNum
club = self.level.countryClub
self.gameOverTrack = Sequence()
self.gameOverTrack.append(localAvatar.getTeleportOutTrack())
self.gameOverTrack.append(Func(localAvatar.setPos, self.finishSphereNodePath.getPos(render)))
self.gameOverTrack.append(Func(localAvatar.play, 'jump'))
self.gameOverTrack.append(Func(self.level.countryClub.camEnterRoom, roomNum))
self.gameOverTrack.start()
self.timerExpired()
def local2GameTime(self, timestamp):
return timestamp - self.gameStartTime
def game2LocalTime(self, timestamp):
return timestamp + self.gameStartTime
def getCurrentGameTime(self):
return self.local2GameTime(globalClock.getFrameTime())
def startScheduleTask(self):
taskMgr.add(self.scheduleTask, self.ScheduleTaskName)
def stopScheduleTask(self):
taskMgr.remove(self.ScheduleTaskName)
def scheduleTask(self, task):
curTime = self.getCurrentGameTime()
def cleanupTimer(self):
if self.timer:
self.timer.stop()
self.timer.destroy()
self.timer = None
return
def timerExpired(self):
self.cleanupTimer()
self.unloadGui()
def loadGui(self):
self.frame2D = DirectFrame(scale=1.0, pos=(0.0, 0, 0.9), relief=DGG.FLAT, parent=aspect2d, frameSize=(-0.3,
0.3,
-0.05,
0.05), frameColor=(0.737, 0.573, 0.345, 0.3))
self.frame2D.hide()
self.gameLabel = DirectLabel(parent=self.frame2D, relief=None, pos=(0, 0, 0), scale=1.0, text=TTLocalizer.mazeLabel, text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text_scale=0.075, text_pos=(0, -0.02))
return
def unloadGui(self):
if self.frame2D:
self.frame2D.destroy()
self.frame2D = None
if self.gameLabel:
self.gameLabel.destroy()
self.gameLabel = None
return
def toonFinished(self, avId, place, lastToon):
toon = base.cr.doId2do.get(avId)
if toon and not self.timedOut:
self.level.countryClub.showInfoText(self.toonFinishedText % (toon.getName(), TTLocalizer.hedgeMazePlaces[place]))
if lastToon:
self.setGameOver()