oldschool-toontown/toontown/cogdominium/DistCogdoCraneGame.py

212 lines
8.3 KiB
Python

from panda3d.core import *
from panda3d.physics import *
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.task.Task import Task
from otp.level import LevelConstants
from otp.otpbase import OTPGlobals
from toontown.cogdominium.DistCogdoLevelGame import DistCogdoLevelGame
from toontown.cogdominium import CogdoCraneGameConsts as GameConsts
from toontown.cogdominium.CogdoCraneGameBase import CogdoCraneGameBase
from toontown.toonbase import ToontownTimer
from toontown.toonbase import TTLocalizer as TTL
from toontown.toonbase import ToontownGlobals
class DistCogdoCraneGame(CogdoCraneGameBase, DistCogdoLevelGame):
notify = directNotify.newCategory('DistCogdoCraneGame')
def __init__(self, cr):
DistCogdoLevelGame.__init__(self, cr)
self.cranes = {}
self.moneyBags = {}
def getTitle(self):
return TTL.CogdoCraneGameTitle
def getInstructions(self):
return TTL.CogdoCraneGameInstructions
def announceGenerate(self):
DistCogdoLevelGame.announceGenerate(self)
self.timer = ToontownTimer.ToontownTimer()
self.timer.stash()
if __dev__:
self._durationChangedEvent = self.uniqueName('durationChanged')
def disable(self):
self.timer.destroy()
self.timer = None
DistCogdoLevelGame.disable(self)
return
def enterLoaded(self):
DistCogdoLevelGame.enterLoaded(self)
self.lightning = loader.loadModel('phase_10/models/cogHQ/CBLightning.bam')
self.magnet = loader.loadModel('phase_10/models/cogHQ/CBMagnet.bam')
self.craneArm = loader.loadModel('phase_10/models/cogHQ/CBCraneArm.bam')
self.controls = loader.loadModel('phase_10/models/cogHQ/CBCraneControls.bam')
self.stick = loader.loadModel('phase_10/models/cogHQ/CBCraneStick.bam')
self.cableTex = self.craneArm.findTexture('MagnetControl')
self.moneyBag = loader.loadModel('phase_10/models/cashbotHQ/MoneyBag')
self.geomRoot = NodePath('geom')
self.sceneRoot = self.geomRoot.attachNewNode('sceneRoot')
self.sceneRoot.setPos(35.84, -115.46, 6.46)
self.physicsMgr = PhysicsManager()
integrator = LinearEulerIntegrator()
self.physicsMgr.attachLinearIntegrator(integrator)
fn = ForceNode('gravity')
self.fnp = self.geomRoot.attachNewNode(fn)
gravity = LinearVectorForce(0, 0, GameConsts.Settings.Gravity.get())
fn.addForce(gravity)
self.physicsMgr.addLinearForce(gravity)
self._gravityForce = gravity
self._gravityForceNode = fn
def getSceneRoot(self):
return self.sceneRoot
def privGotSpec(self, levelSpec):
DistCogdoLevelGame.privGotSpec(self, levelSpec)
levelMgr = self.getEntity(LevelConstants.LevelMgrEntId)
self.endVault = levelMgr.geom
self.endVault.reparentTo(self.geomRoot)
self.endVault.findAllMatches('**/MagnetArms').detach()
self.endVault.findAllMatches('**/Safes').detach()
self.endVault.findAllMatches('**/MagnetControlsAll').detach()
cn = self.endVault.find('**/wallsCollision').node()
cn.setIntoCollideMask(OTPGlobals.WallBitmask | ToontownGlobals.PieBitmask | BitMask32.lowerOn(3) << 21)
walls = self.endVault.find('**/RollUpFrameCillison')
walls.detachNode()
self.evWalls = self.replaceCollisionPolysWithPlanes(walls)
self.evWalls.reparentTo(self.endVault)
self.evWalls.stash()
floor = self.endVault.find('**/EndVaultFloorCollision')
floor.detachNode()
self.evFloor = self.replaceCollisionPolysWithPlanes(floor)
self.evFloor.reparentTo(self.endVault)
self.evFloor.setName('floor')
plane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, -50)))
planeNode = CollisionNode('dropPlane')
planeNode.addSolid(plane)
planeNode.setCollideMask(ToontownGlobals.PieBitmask)
self.geomRoot.attachNewNode(planeNode)
def replaceCollisionPolysWithPlanes(self, model):
newCollisionNode = CollisionNode('collisions')
newCollideMask = BitMask32(0)
planes = []
collList = model.findAllMatches('**/+CollisionNode')
if not collList:
collList = [model]
for cnp in collList:
cn = cnp.node()
if not isinstance(cn, CollisionNode):
self.notify.warning('Not a collision node: %s' % repr(cnp))
break
newCollideMask = newCollideMask | cn.getIntoCollideMask()
for i in range(cn.getNumSolids()):
solid = cn.getSolid(i)
if isinstance(solid, CollisionPolygon):
plane = Plane(solid.getPlane())
planes.append(plane)
else:
self.notify.warning('Unexpected collision solid: %s' % repr(solid))
newCollisionNode.addSolid(plane)
newCollisionNode.setIntoCollideMask(newCollideMask)
threshold = 0.1
planes.sort(lambda p1, p2: p1.compareTo(p2, threshold))
lastPlane = None
for plane in planes:
if lastPlane == None or plane.compareTo(lastPlane, threshold) != 0:
cp = CollisionPlane(plane)
newCollisionNode.addSolid(cp)
lastPlane = plane
return NodePath(newCollisionNode)
def exitLoaded(self):
self.fnp.removeNode()
self.physicsMgr.clearLinearForces()
self.geomRoot.removeNode()
self._gravityForce = None
self._gravityForceNode = None
DistCogdoLevelGame.exitLoaded(self)
return
def toCraneMode(self):
if self.cr:
place = self.cr.playGame.getPlace()
if place and hasattr(place, 'fsm'):
place.setState('crane')
def enterVisible(self):
DistCogdoLevelGame.enterVisible(self)
self.geomRoot.reparentTo(render)
def placeEntranceElev(self, elev):
elev.setPos(-10.63, -113.64, 6.03)
elev.setHpr(90, 0, 0)
def enterGame(self):
DistCogdoLevelGame.enterGame(self)
self._physicsTask = taskMgr.add(self._doPhysics, self.uniqueName('physics'), priority=25)
self.evWalls.stash()
self._startTimer()
if __dev__:
self.accept(self._durationChangedEvent, self._startTimer)
def _startTimer(self):
timeLeft = GameConsts.Settings.GameDuration.get() - self.getCurrentGameTime()
self.timer.posInTopRightCorner()
self.timer.setTime(timeLeft)
self.timer.countdown(timeLeft, self.timerExpired)
self.timer.unstash()
def _doPhysics(self, task):
dt = globalClock.getDt()
self.physicsMgr.doPhysics(dt)
return Task.cont
def exitGame(self):
if __dev__:
self.ignore(self._durationChangedEvent)
DistCogdoLevelGame.exitGame(self)
self._physicsTask.remove()
def enterFinish(self):
DistCogdoLevelGame.enterFinish(self)
timeLeft = 10 - (globalClock.getRealTime() - self.getFinishTime())
self.timer.setTime(timeLeft)
self.timer.countdown(timeLeft, self.timerExpired)
self.timer.unstash()
def timerExpired(self):
pass
if __dev__:
def _handleGameDurationChanged(self, gameDuration):
messenger.send(self._durationChangedEvent)
def _handleGravityChanged(self, gravity):
self.physicsMgr.removeLinearForce(self._gravityForce)
self._gravityForceNode.removeForce(self._gravityForce)
self._gravityForce = LinearVectorForce(0, 0, gravity)
self.physicsMgr.addLinearForce(self._gravityForce)
self._gravityForceNode.addForce(self._gravityForce)
def _handleEmptyFrictionCoefChanged(self, coef):
for crane in self.cranes.values():
crane._handleEmptyFrictionCoefChanged(coef)
def _handleRopeLinkMassChanged(self, mass):
for crane in self.cranes.values():
crane._handleRopeLinkMassChanged(mass)
def _handleMagnetMassChanged(self, mass):
for crane in self.cranes.values():
crane._handleMagnetMassChanged(mass)
def _handleMoneyBagGrabHeightChanged(self, height):
for moneyBag in self.moneyBags.values():
moneyBag._handleMoneyBagGrabHeightChanged(height)