oldschool-toontown/toontown/cogdominium/CogdoMazePlayer.py

191 lines
6.8 KiB
Python
Raw Permalink Normal View History

from panda3d.core import Point3, NodePath
2019-11-02 17:27:54 -05:00
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
from . import CogdoMazeGameGlobals as Globals
from . import CogdoUtil
2019-11-02 17:27:54 -05:00
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