toontown-just-works/toontown/cogdominium/CogdoMazeGameObjects.py
2024-07-07 18:08:39 -05:00

266 lines
10 KiB
Python

from pandac.PandaModules import CollisionSphere, CollisionTube, CollisionNode
from pandac.PandaModules import NodePath, BitMask32
from pandac.PandaModules import Point3, Point4, WaitInterval, Vec3, Vec4
from direct.interval.IntervalGlobal import LerpScaleInterval, LerpColorScaleInterval, LerpPosInterval, LerpFunc
from direct.interval.IntervalGlobal import Func, Sequence, Parallel
from direct.showbase.DirectObject import DirectObject
from direct.task.Task import Task
from toontown.toonbase import ToontownGlobals
import CogdoMazeGameGlobals as Globals
from CogdoGameExit import CogdoGameExit
import CogdoUtil
import math
import random
class CogdoMazeSplattable:
def __init__(self, object, name, collisionRadius):
self.object = object
self.splat = CogdoUtil.loadMazeModel('splash')
self.splat.setBillboardPointEye()
self.splat.setBin('fixed', 40)
self.splat.setDepthTest(False)
self.splat.setDepthWrite(False)
self.splatTrack = None
self._splatSfxIval = base.cogdoGameAudioMgr.createSfxIval('splat')
self.initGagCollision(name, collisionRadius)
return
def destroy(self):
self.disableGagCollision()
if self._splatSfxIval.isPlaying():
self._splatSfxIval.finish()
del self._splatSfxIval
def initGagCollision(self, name, radius):
self.gagCollisionName = name
collision = CollisionTube(0, 0, 0, 0, 0, 4, radius)
collision.setTangible(1)
self.gagCollNode = CollisionNode(self.gagCollisionName)
self.gagCollNode.setIntoCollideMask(ToontownGlobals.PieBitmask)
self.gagCollNode.addSolid(collision)
self.gagCollNodePath = self.object.attachNewNode(self.gagCollNode)
def disableGagCollision(self):
self.gagCollNodePath.removeNode()
def doSplat(self):
if self.splatTrack and self.splatTrack.isPlaying():
self.splatTrack.finish()
self.splat.reparentTo(render)
self.splat.setPos(self.object, 0, 0, 3.0)
self.splat.setY(self.splat.getY() - 1.0)
self._splatSfxIval.node = self.splat
self.splatTrack = Parallel(self._splatSfxIval, Sequence(Func(self.splat.showThrough), LerpScaleInterval(self.splat, duration=0.5, scale=6, startScale=1, blendType='easeOut'), Func(self.splat.hide)))
self.splatTrack.start()
class CogdoMazeDrop(NodePath, DirectObject):
def __init__(self, game, id, x, y):
NodePath.__init__(self, 'dropNode%s' % id)
self.game = game
self.id = id
self.reparentTo(hidden)
self.setPos(x, y, 0)
shadow = loader.loadModel('phase_3/models/props/square_drop_shadow')
shadow.setZ(0.2)
shadow.setBin('ground', 10)
shadow.setColor(1, 1, 1, 1)
shadow.reparentTo(self)
self.shadow = shadow
drop = CogdoUtil.loadMazeModel('cabinetSmFalling')
roll = random.randint(-15, 15)
drop.setHpr(0, 0, roll)
drop.setZ(Globals.DropHeight)
self.collTube = CollisionTube(0, 0, 0, 0, 0, 4, Globals.DropCollisionRadius)
self.collTube.setTangible(0)
name = Globals.DropCollisionName
self.collNode = CollisionNode(name)
self.collNode.addSolid(self.collTube)
self.collNodePath = drop.attachNewNode(self.collNode)
self.collNodePath.hide()
self.collNodePath.setTag('isFalling', str('True'))
drop.reparentTo(self)
self.drop = drop
self._dropSfx = base.cogdoGameAudioMgr.createSfxIval('drop', volume=0.6)
def disableCollisionDamage(self):
self.collTube.setTangible(1)
self.collTube.setRadius(Globals.DroppedCollisionRadius)
self.collNode.setIntoCollideMask(ToontownGlobals.WallBitmask)
self.collNodePath.setTag('isFalling', str('False'))
def getDropIval(self):
shadow = self.shadow
drop = self.drop
id = self.id
hangTime = Globals.ShadowTime
dropTime = Globals.DropTime
dropHeight = Globals.DropHeight
targetShadowScale = 0.5
targetShadowAlpha = 0.4
shadowScaleIval = LerpScaleInterval(shadow, dropTime, targetShadowScale, startScale=0)
shadowAlphaIval = LerpColorScaleInterval(shadow, hangTime, Point4(1, 1, 1, targetShadowAlpha), startColorScale=Point4(1, 1, 1, 0))
shadowIval = Parallel(shadowScaleIval, shadowAlphaIval)
startPos = Point3(0, 0, dropHeight)
drop.setPos(startPos)
dropIval = LerpPosInterval(drop, dropTime, Point3(0, 0, 0), startPos=startPos, blendType='easeIn')
dropSoundIval = self._dropSfx
dropSoundIval.node = self
self.drop.setTransparency(1)
def _setRandScale(t):
self.drop.setScale(self, 1 - random.random() / 16, 1 - random.random() / 16, 1 - random.random() / 4)
scaleChange = 0.4 + random.random() / 4
dropShakeSeq = Sequence(
LerpScaleInterval(self.drop, 0.25, Vec3(1.0 + scaleChange, 1.0 + scaleChange / 2, 1.0 - scaleChange), blendType='easeInOut'),
LerpScaleInterval(self.drop, 0.25, Vec3(1.0, 1.0, 1.0), blendType='easeInOut'), Func(self.disableCollisionDamage),
LerpScaleInterval(self.drop, 0.2, Vec3(1.0 + scaleChange / 8, 1.0 + scaleChange / 8, 1.0 - scaleChange / 8), blendType='easeInOut'),
LerpScaleInterval(self.drop, 0.2, Vec3(1.0, 1.0, 1.0), blendType='easeInOut'),
LerpScaleInterval(self.drop, 0.15, Vec3(1.0 + scaleChange / 16, 1.0 + scaleChange / 16, 1.0 - scaleChange / 16), blendType='easeInOut'),
LerpScaleInterval(self.drop, 0.15, Vec3(1.0, 1.0, 1.0), blendType='easeInOut'),
LerpScaleInterval(self.drop, 0.1, Vec3(1.0 + scaleChange / 16, 1.0 + scaleChange / 8, 1.0 - scaleChange / 16), blendType='easeInOut'),
LerpColorScaleInterval(self.drop, Globals.DropFadeTime, Vec4(1.0, 1.0, 1.0, 0.0)))
ival = Sequence(
Func(self.reparentTo, render),
Parallel(Sequence(WaitInterval(hangTime), dropIval), shadowIval),
Parallel(Func(self.game.dropHit, self, id), dropSoundIval, dropShakeSeq),
Func(self.game.cleanupDrop, id), name='drop%s' % id)
self.ival = ival
return ival
def destroy(self):
self.ival.pause()
self.ival = None
self._dropSfx.pause()
self._dropSfx = None
self.collTube = None
self.collNode = None
self.collNodePath.removeNode()
self.collNodePath = None
self.removeNode()
return
class CogdoMazeExit(CogdoGameExit, DirectObject):
EnterEventName = 'CogdoMazeDoor_Enter'
def __init__(self):
CogdoGameExit.__init__(self)
self.revealed = False
self._players = []
self._initCollisions()
def _initCollisions(self):
collSphere = CollisionSphere(0, 0, 0, 3.0)
collSphere.setTangible(0)
self.collNode = CollisionNode(self.getName())
self.collNode.addSolid(collSphere)
self.collNP = self.attachNewNode(self.collNode)
def destroy(self):
self.ignoreAll()
CogdoGameExit.destroy(self)
def enable(self):
self.collNode.setFromCollideMask(ToontownGlobals.WallBitmask)
self.accept('enter' + self.getName(), self._handleEnterCollision)
def disable(self):
self.ignore('enter' + self.getName())
self.collNode.setFromCollideMask(BitMask32(0))
def _handleEnterCollision(self, collEntry):
messenger.send(CogdoMazeExit.EnterEventName, [self])
def onstage(self):
self.unstash()
self.enable()
def offstage(self):
self.stash()
self.disable()
def playerEntersDoor(self, player):
if player not in self._players:
self._players.append(player)
self.toonEnters(player.toon)
def getPlayerCount(self):
return len(self._players)
def hasPlayer(self, player):
return player in self._players
class CogdoMazeWaterCooler(NodePath, DirectObject):
UpdateTaskName = 'CogdoMazeWaterCooler_Update'
def __init__(self, serialNum, model):
NodePath.__init__(self, 'CogdoMazeWaterCooler-%i' % serialNum)
self.serialNum = serialNum
self._model = model
self._model.reparentTo(self)
self._model.setPosHpr(0, 0, 0, 0, 0, 0)
self._initCollisions()
self._initArrow()
self._update = None
self.__startUpdateTask()
return
def destroy(self):
self.ignoreAll()
self.__stopUpdateTask()
self.collNodePath.removeNode()
self.removeNode()
def _initCollisions(self):
offset = Globals.WaterCoolerTriggerOffset
self.collSphere = CollisionSphere(offset[0], offset[1], offset[2], Globals.WaterCoolerTriggerRadius)
self.collSphere.setTangible(0)
name = Globals.WaterCoolerCollisionName
self.collNode = CollisionNode(name)
self.collNode.addSolid(self.collSphere)
self.collNodePath = self.attachNewNode(self.collNode)
def _initArrow(self):
matchingGameGui = loader.loadModel('phase_3.5/models/gui/matching_game_gui')
arrow = matchingGameGui.find('**/minnieArrow')
arrow.setScale(Globals.CoolerArrowScale)
arrow.setColor(*Globals.CoolerArrowColor)
arrow.setPos(0, 0, Globals.CoolerArrowZ)
arrow.setHpr(0, 0, 90)
arrow.setBillboardAxis()
self._arrow = NodePath('Arrow')
arrow.reparentTo(self._arrow)
self._arrow.reparentTo(self)
self._arrowTime = 0
self.accept(Globals.WaterCoolerShowEventName, self.showArrow)
self.accept(Globals.WaterCoolerHideEventName, self.hideArrow)
matchingGameGui.removeNode()
def showArrow(self):
self._arrow.unstash()
def hideArrow(self):
self._arrow.stash()
def update(self, dt):
newZ = math.sin(globalClock.getFrameTime() * Globals.CoolerArrowSpeed) * Globals.CoolerArrowBounce
self._arrow.setZ(newZ)
def __startUpdateTask(self):
self.__stopUpdateTask()
self._update = taskMgr.add(self._updateTask, self.UpdateTaskName, 45)
def __stopUpdateTask(self):
if self._update is not None:
taskMgr.remove(self._update)
return
def _updateTask(self, task):
dt = globalClock.getDt()
self.update(dt)
return Task.cont