oldschool-toontown/toontown/cogdominium/CogdoMazePlayer.py
2019-11-02 18:27:54 -04:00

190 lines
6.7 KiB
Python

from pandac.PandaModules import Point3, NodePath
from direct.fsm.FSM import FSM
from direct.interval.IntervalGlobal import ProjectileInterval, Track, ActorInterval
from direct.interval.IntervalGlobal import Func, Sequence, Parallel
from CogdoMazeGameObjects import CogdoMazeSplattable
import CogdoMazeGameGlobals as Globals
import CogdoUtil
import random
class CogdoMazePlayer(FSM, CogdoMazeSplattable):
notify = directNotify.newCategory('CogdoMazePlayer')
_key = None
GagHitEventName = 'CogdoMazePlayer_GagHit'
RemovedEventName = 'CogdoMazePlayer_Removed'
def __init__(self, id, toon):
FSM.__init__(self, 'CogdoMazePlayer')
CogdoMazeSplattable.__init__(self, toon, '%s-%i' % (Globals.PlayerCollisionName, id), 0.5)
self.id = id
self.toon = toon
self.defaultTransitions = {'Off': ['Ready'],
'Ready': ['Normal', 'Off'],
'Normal': ['Hit', 'Done', 'Off'],
'Hit': ['Normal', 'Done', 'Off'],
'Done': ['Off']}
self.toon.reparentTo(render)
self.gagModel = CogdoUtil.loadMazeModel('waterBalloon')
self.equippedGag = None
self._toonHitSfx = base.cogdoGameAudioMgr.createSfx('toonHit', self.toon)
self._throwSfx = base.cogdoGameAudioMgr.createSfxIval('throw')
self.accept(toon.getDisableEvent(), self.removed)
self.request('Off')
return
def destroy(self):
if self.equippedGag:
self.removeGag()
del self._toonHitSfx
del self._throwSfx
CogdoMazeSplattable.destroy(self)
def enterOff(self):
self.toon.setAnimState('Happy', 1.0)
self.toon.setSpeed(0, 0)
def exitOff(self):
pass
def enterReady(self):
pass
def exitReady(self):
pass
def enterNormal(self):
self.toon.startSmooth()
if self.equippedGag is not None:
self.equippedGag.unstash()
return
def exitNormal(self):
self.toon.stopSmooth()
if self.equippedGag is not None:
self.equippedGag.stash()
return
def enterHit(self, elapsedTime = 0.0):
animationInfo = Globals.ToonAnimationInfo['hit']
self._hitIval = self._getToonAnimationIval(animationInfo[0], duration=animationInfo[1], startFrame=animationInfo[2], nextState='Normal')
self._hitIval.start(elapsedTime)
self._toonHitSfx.play()
def exitHit(self):
self._hitIval.pause()
del self._hitIval
if self.equippedGag is not None:
self.toon.setAnimState('Catching', 1.0)
else:
self.toon.setAnimState('Happy', 1.0)
return
def enterDone(self):
self.toon.setAnimState('off', 1.0)
def filterDone(self, request, args):
if request == 'Done':
return None
else:
return self.defaultFilter(request, args)
return None
def exitDone(self):
pass
def handleGameStart(self):
self.accept(Globals.GagCollisionName + '-into-' + self.gagCollisionName, self.handleGagHit)
def hitByDrop(self):
if self.state == 'Normal':
self.request('Hit')
if self.equippedGag != None:
self.removeGag()
return
def handleGagHit(self, collEntry):
gagNodePath = collEntry.getFromNodePath().getParent()
messenger.send(self.GagHitEventName, [self.toon.doId, gagNodePath])
def hitByGag(self):
self.doSplat()
def equipGag(self):
if self.equippedGag != None:
return
self.toon.setAnimState('Catching')
holdingGag = self.gagModel.copyTo(self.toon.leftHand)
holdingGag.setScale(Globals.GagPickupScale)
color = random.choice(Globals.GagColors)
holdingGag.setColorScale(color)
holdingGag.setZ(-0.2)
holdingGag.setX(self.toon, 0)
holdingGag.setHpr(0, 0, 0)
self.equippedGag = holdingGag
return
def removeGag(self):
if self.equippedGag is None:
return
self.toon.setAnimState('Happy')
self.equippedGag.detachNode()
self.equippedGag = None
return
def createThrowGag(self, gag):
throwGag = gag.copyTo(NodePath('gag'))
return throwGag
def removed(self):
messenger.send(self.RemovedEventName, [self])
def showToonThrowingGag(self, heading, pos):
gag = self.equippedGag
if gag is None:
return
self.removeGag()
tossTrack, flyTrack, object = self.getThrowInterval(gag, pos[0], pos[1], pos[2], heading, 0, 0)
def matchRunningAnim(toon = self.toon):
toon.playingAnim = None
toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed)
return
newTossTrack = Sequence(tossTrack, Func(matchRunningAnim))
throwTrack = Parallel(newTossTrack, flyTrack)
throwTrack.start(0)
return object
def completeThrow(self):
self.toon.loop('neutral')
def getThrowInterval(self, gag, x, y, z, h, p, r):
toon = self.toon
flyGag = self.createThrowGag(gag)
throwSoundIval = self._throwSfx
if throwSoundIval.isPlaying():
throwSoundIval.finish()
throwSoundIval.node = toon
toonThrowIval1 = ActorInterval(toon, 'throw', startFrame=Globals.ThrowStartFrame, endFrame=Globals.ThrowEndFrame, playRate=Globals.ThrowPlayRate, partName='torso')
toss = Track((0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(gag.reparentTo, toon.rightHand), Func(gag.setPosHpr, 0, 0, 0, 0, 0, 0), toonThrowIval1)), (toonThrowIval1.getDuration(), Parallel(Func(gag.detachNode), Sequence(ActorInterval(toon, 'throw', startFrame=Globals.ThrowEndFrame + 1, playRate=Globals.ThrowPlayRate, partName='torso'), Func(self.completeThrow)))))
def getEndPos(toon = toon):
return render.getRelativePoint(toon, Point3(0, Globals.ThrowDistance, 0))
fly = Track((0, throwSoundIval), (toonThrowIval1.getDuration(), Sequence(Func(flyGag.reparentTo, render), Func(flyGag.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), ProjectileInterval(flyGag, endPos=getEndPos, duration=Globals.ThrowDuration), Func(flyGag.detachNode))))
return (toss, fly, flyGag)
def _getToonAnimationIval(self, animName, startFrame = 0, duration = 1, nextState = None):
totalFrames = self.toon.getNumFrames(animName)
frames = totalFrames - 1 - startFrame
frameRate = self.toon.getFrameRate(animName)
newRate = frames / duration
playRate = newRate / frameRate
ival = Sequence(ActorInterval(self.toon, animName, startTime=startFrame / newRate, endTime=totalFrames / newRate, playRate=playRate))
if nextState is not None:
def done():
self.request(nextState)
ival.append(Func(done))
return ival