oldschool-toontown/toontown/coghq/DistributedMaze.py
2019-12-30 01:07:56 -05:00

235 lines
9.3 KiB
Python

from otp.level.BasicEntities import DistributedNodePathEntity
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
from toontown.toonbase.ToontownGlobals import *
import random
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.ClockDelta import globalClockDelta
from . 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 range(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()