2019-11-02 17:27:54 -05:00
|
|
|
import math
|
|
|
|
from direct.showbase.PythonUtil import bound, lerp
|
|
|
|
from direct.task.Task import Task
|
|
|
|
from direct.interval.MetaInterval import Sequence, Parallel
|
|
|
|
from direct.interval.FunctionInterval import Func, Wait
|
|
|
|
from direct.interval.SoundInterval import SoundInterval
|
|
|
|
from direct.interval.LerpInterval import LerpScaleInterval, LerpFunc
|
|
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
|
|
from pandac.PandaModules import NodePath, Point3, VBase3
|
|
|
|
from toontown.minigame.OrthoDrive import OrthoDrive
|
|
|
|
from toontown.minigame.OrthoWalk import OrthoWalk
|
|
|
|
from toontown.battle.BattleProps import globalPropPool
|
|
|
|
from toontown.battle.BattleSounds import globalBattleSoundCache
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import PartyGlobals
|
|
|
|
from .PartyCogActivityInput import PartyCogActivityInput
|
|
|
|
from .PartyCogActivityGui import PartyCogActivityGui
|
|
|
|
from .PartyCogUtils import CameraManager
|
|
|
|
from .PartyCogUtils import StrafingControl
|
2019-11-02 17:27:54 -05:00
|
|
|
UPDATE_TASK_NAME = 'PartyCogActivityLocalPlayer_UpdateTask'
|
|
|
|
THROW_PIE_LIMIT_TIME = 0.2
|
|
|
|
|
|
|
|
class PartyCogActivityPlayer:
|
|
|
|
toon = None
|
|
|
|
position = None
|
|
|
|
team = None
|
|
|
|
score = 0
|
|
|
|
enabled = False
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('PartyCogActivityPlayer')
|
|
|
|
|
|
|
|
def __init__(self, activity, toon, position, team):
|
|
|
|
self.activity = activity
|
|
|
|
self.position = position
|
|
|
|
self.toon = toon
|
|
|
|
self.team = team
|
|
|
|
self.netTimeSentToStartByHit = 0
|
|
|
|
self.kaboomTrack = None
|
|
|
|
self.locator = None
|
|
|
|
self.teamSpot = self.activity.getIndex(self.toon.doId, self.team)
|
|
|
|
splatName = 'splat-creampie'
|
|
|
|
self.splat = globalPropPool.getProp(splatName)
|
|
|
|
self.splat.setBillboardPointEye()
|
|
|
|
self.splatType = globalPropPool.getPropType(splatName)
|
|
|
|
self.pieHitSound = globalBattleSoundCache.getSound('AA_wholepie_only.mp3')
|
|
|
|
return
|
|
|
|
|
|
|
|
def destroy(self):
|
|
|
|
self.cleanUpIvals()
|
|
|
|
self.toon = None
|
|
|
|
self.locator = None
|
|
|
|
self.position = None
|
|
|
|
self.pieHitSound = None
|
|
|
|
self.splat = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def cleanUpIvals(self):
|
|
|
|
if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
|
|
|
|
self.kaboomTrack.finish()
|
|
|
|
self.kaboomTrack = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def faceForward(self):
|
|
|
|
self.toon.setH(0)
|
|
|
|
|
|
|
|
def setToonStartPosition(self, position):
|
|
|
|
self.position = position
|
|
|
|
|
|
|
|
def updateToonPosition(self):
|
|
|
|
self.toon.setPos(self.activity.root, self.position)
|
|
|
|
self.toon.setH(self.locator, 0.0)
|
|
|
|
|
|
|
|
def setTeam(self, team):
|
|
|
|
self.team = team
|
|
|
|
self.locator = self.activity.view.teamLocators[self.team]
|
|
|
|
self.teamSpot = self.activity.getIndex(self.toon.doId, self.team)
|
|
|
|
|
|
|
|
def entersActivity(self):
|
|
|
|
self.locator = self.activity.view.teamLocators[self.team]
|
|
|
|
|
|
|
|
def exitsActivity(self):
|
|
|
|
offset = 0
|
|
|
|
if self.teamSpot:
|
|
|
|
offset = 4.0 * self.teamSpot
|
|
|
|
self.toon.wrtReparentTo(render)
|
|
|
|
self.toon.setPos(self.locator, offset, -35.0, 0.0)
|
|
|
|
self.toon.setH(self.activity.root, 0.0)
|
|
|
|
self.locator = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def enable(self):
|
|
|
|
if self.enabled:
|
|
|
|
return
|
|
|
|
self.toon.wrtReparentTo(self.locator)
|
|
|
|
self.enabled = True
|
|
|
|
|
|
|
|
def disable(self):
|
|
|
|
if not self.enabled:
|
|
|
|
return
|
|
|
|
self.toon.wrtReparentTo(render)
|
|
|
|
self.enabled = False
|
|
|
|
self.cleanUpIvals()
|
|
|
|
|
|
|
|
def hitBody(self):
|
|
|
|
points = PartyGlobals.CogActivityHitPoints
|
|
|
|
self.score += points
|
|
|
|
return points
|
|
|
|
|
|
|
|
def hitHead(self):
|
|
|
|
points = PartyGlobals.CogActivityHitPointsForHead
|
|
|
|
self.score += points
|
|
|
|
return points
|
|
|
|
|
|
|
|
def resetScore(self):
|
|
|
|
self.score = 0
|
|
|
|
|
|
|
|
def respondToPieHit(self, timestamp, pos):
|
|
|
|
if self.netTimeSentToStartByHit < timestamp:
|
|
|
|
self.__showSplat(pos)
|
|
|
|
if self.netTimeSentToStartByHit < timestamp:
|
|
|
|
self.netTimeSentToStartByHit = timestamp
|
|
|
|
else:
|
|
|
|
self.activity.notify.debug('PartyCogPlayer respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit)
|
|
|
|
|
|
|
|
def __showSplat(self, position):
|
|
|
|
if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
|
|
|
|
self.kaboomTrack.finish()
|
|
|
|
if not self.pieHitSound:
|
|
|
|
self.notify.warning('Trying to play hit sound on destroyed player')
|
|
|
|
return
|
|
|
|
splatName = 'splat-creampie'
|
|
|
|
self.splat = globalPropPool.getProp(splatName)
|
|
|
|
self.splat.setBillboardPointEye()
|
|
|
|
self.splat.reparentTo(render)
|
|
|
|
self.splat.setPos(self.toon, position)
|
|
|
|
self.splat.setY(self.toon, bound(self.splat.getY(), self.toon.getHeight() / 2.0, position.getY()))
|
|
|
|
self.splat.setAlphaScale(1.0)
|
|
|
|
targetscale = 0.75
|
|
|
|
|
|
|
|
def setSplatAlpha(amount):
|
|
|
|
self.splat.setAlphaScale(amount)
|
|
|
|
|
|
|
|
self.kaboomTrack = Parallel(SoundInterval(self.pieHitSound, node=self.toon, volume=1.0, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence(Func(self.splat.showThrough), Parallel(Sequence(LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType='easeOut'), Wait(0.175)), Sequence(Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType='easeOut'))), Func(self.splat.cleanup), Func(self.splat.removeNode)))
|
|
|
|
self.kaboomTrack.start()
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
class PartyCogActivityLocalPlayer(PartyCogActivityPlayer):
|
|
|
|
|
|
|
|
def __init__(self, activity, position, team, exitActivityCallback = None):
|
|
|
|
PartyCogActivityPlayer.__init__(self, activity, base.localAvatar, position, team)
|
|
|
|
self.input = PartyCogActivityInput(exitActivityCallback)
|
|
|
|
self.gui = PartyCogActivityGui()
|
|
|
|
self.throwPiePrevTime = 0
|
|
|
|
self.lastMoved = 0
|
|
|
|
if base.localAvatar:
|
|
|
|
self.prevPos = base.localAvatar.getPos()
|
|
|
|
self.cameraManager = None
|
|
|
|
self.control = None
|
|
|
|
self.consecutiveShortThrows = 0
|
|
|
|
return
|
|
|
|
|
|
|
|
def destroy(self):
|
|
|
|
if self.enabled:
|
|
|
|
self.disable()
|
|
|
|
if self.cameraManager is not None:
|
|
|
|
self.cameraManager.setEnabled(False)
|
|
|
|
self.cameraManager.destroy()
|
|
|
|
del self.cameraManager
|
|
|
|
del self.gui
|
|
|
|
del self.input
|
|
|
|
if self.control is not None:
|
|
|
|
self.control.destroy()
|
|
|
|
del self.control
|
|
|
|
PartyCogActivityPlayer.destroy(self)
|
|
|
|
return
|
|
|
|
|
|
|
|
def _initOrthoWalk(self):
|
|
|
|
orthoDrive = OrthoDrive(9.778, customCollisionCallback=self.activity.view.checkOrthoDriveCollision)
|
|
|
|
self.orthoWalk = OrthoWalk(orthoDrive, broadcast=True)
|
|
|
|
|
|
|
|
def _destroyOrthoWalk(self):
|
|
|
|
self.orthoWalk.stop()
|
|
|
|
self.orthoWalk.destroy()
|
|
|
|
del self.orthoWalk
|
|
|
|
|
|
|
|
def getPieThrowingPower(self, time):
|
|
|
|
elapsed = max(time - self.input.throwPiePressedStartTime, 0.0)
|
|
|
|
w = 1.0 / PartyGlobals.CogActivityPowerMeterTime * 2.0 * math.pi
|
|
|
|
power = int(round(-math.cos(w * elapsed) * 50.0 + 50.0))
|
|
|
|
return power
|
|
|
|
|
|
|
|
def isShortThrow(self, time):
|
|
|
|
elapsed = max(time - self.input.throwPiePressedStartTime, 0.0)
|
|
|
|
return elapsed <= PartyGlobals.CogActivityShortThrowTime
|
|
|
|
|
|
|
|
def checkForThrowSpam(self, time):
|
|
|
|
if self.isShortThrow(time):
|
|
|
|
self.consecutiveShortThrows += 1
|
|
|
|
else:
|
|
|
|
self.consecutiveShortThrows = 0
|
|
|
|
return self.consecutiveShortThrows >= PartyGlobals.CogActivityShortThrowSpam
|
|
|
|
|
|
|
|
def _startUpdateTask(self):
|
|
|
|
task = Task(self._updateTask)
|
|
|
|
task.lastPositionBroadcastTime = 0.0
|
|
|
|
self.throwPiePrevTime = 0
|
|
|
|
taskMgr.add(task, UPDATE_TASK_NAME)
|
|
|
|
|
|
|
|
def _stopUpdateTask(self):
|
|
|
|
taskMgr.remove(UPDATE_TASK_NAME)
|
|
|
|
|
|
|
|
def _updateTask(self, task):
|
|
|
|
self._update()
|
|
|
|
if base.localAvatar.getPos() != self.prevPos:
|
|
|
|
self.prevPos = base.localAvatar.getPos()
|
|
|
|
self.lastMoved = self.activity.getCurrentActivityTime()
|
|
|
|
if max(self.activity.getCurrentActivityTime() - self.lastMoved, 0) > PartyGlobals.ToonMoveIdleThreshold:
|
|
|
|
self.gui.showMoveControls()
|
|
|
|
if max(self.activity.getCurrentActivityTime() - self.throwPiePrevTime, 0) > PartyGlobals.ToonAttackIdleThreshold:
|
|
|
|
self.gui.showAttackControls()
|
|
|
|
if self.input.throwPieWasReleased:
|
|
|
|
if self.checkForThrowSpam(globalClock.getFrameTime()):
|
|
|
|
self.gui.showSpamWarning()
|
|
|
|
self.input.throwPieWasReleased = False
|
|
|
|
self.throwPie(self.getPieThrowingPower(globalClock.getFrameTime()))
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def throwPie(self, piePower):
|
|
|
|
if not self.activity.isState('Active'):
|
|
|
|
return
|
|
|
|
if self.activity.getCurrentActivityTime() - self.throwPiePrevTime > THROW_PIE_LIMIT_TIME:
|
|
|
|
self.throwPiePrevTime = self.activity.getCurrentActivityTime()
|
|
|
|
self.activity.b_pieThrow(self.toon, piePower)
|
|
|
|
|
|
|
|
def _update(self):
|
|
|
|
self.control.update()
|
|
|
|
|
|
|
|
def getLookat(self, whosLooking, refNode = None):
|
|
|
|
if refNode is None:
|
|
|
|
refNode = render
|
|
|
|
dist = 5.0
|
|
|
|
oldParent = self.tempNP.getParent()
|
|
|
|
self.tempNP.reparentTo(whosLooking)
|
|
|
|
self.tempNP.setPos(0.0, dist, 0.0)
|
|
|
|
pos = self.tempNP.getPos(refNode)
|
|
|
|
self.tempNP.reparentTo(oldParent)
|
|
|
|
return pos
|
|
|
|
|
|
|
|
def entersActivity(self):
|
|
|
|
base.cr.playGame.getPlace().setState('activity')
|
|
|
|
PartyCogActivityPlayer.entersActivity(self)
|
|
|
|
self.gui.disableToontownHUD()
|
|
|
|
self.cameraManager = CameraManager(camera)
|
|
|
|
self.tempNP = NodePath('temp')
|
|
|
|
self.lookAtMyTeam()
|
|
|
|
self.control = StrafingControl(self)
|
|
|
|
|
|
|
|
def exitsActivity(self):
|
|
|
|
PartyCogActivityPlayer.exitsActivity(self)
|
|
|
|
self.gui.enableToontownHUD()
|
|
|
|
self.cameraManager.setEnabled(False)
|
|
|
|
self.tempNP.removeNode()
|
|
|
|
self.tempNP = None
|
|
|
|
if not aspect2d.find('**/JellybeanRewardGui*'):
|
|
|
|
base.cr.playGame.getPlace().setState('walk')
|
|
|
|
else:
|
|
|
|
self.toon.startPosHprBroadcast()
|
|
|
|
return
|
|
|
|
|
|
|
|
def getRunToStartPositionIval(self):
|
|
|
|
targetH = self.locator.getH()
|
|
|
|
travelVec = self.position - self.toon.getPos(self.activity.root)
|
|
|
|
duration = travelVec.length() / 9.778
|
|
|
|
startH = 0.0
|
|
|
|
if travelVec.getY() < 0.0:
|
|
|
|
startH = 180.0
|
|
|
|
return Sequence(Func(self.toon.startPosHprBroadcast, 0.1), Func(self.toon.b_setAnimState, 'run'), Parallel(self.toon.hprInterval(0.5, VBase3(startH, 0.0, 0.0), other=self.activity.root), self.toon.posInterval(duration, self.position, other=self.activity.root)), Func(self.toon.b_setAnimState, 'neutral'), self.toon.hprInterval(0.25, VBase3(targetH, 0.0, 0.0), other=self.activity.root), Func(self.toon.stopPosHprBroadcast))
|
|
|
|
|
|
|
|
def enable(self):
|
|
|
|
if self.enabled:
|
|
|
|
return
|
|
|
|
PartyCogActivityPlayer.enable(self)
|
|
|
|
self.toon.b_setAnimState('Happy')
|
|
|
|
self._initOrthoWalk()
|
|
|
|
self.orthoWalk.start()
|
|
|
|
self.orthoWalking = True
|
|
|
|
self.input.enable()
|
|
|
|
self.gui.disableToontownHUD()
|
|
|
|
self.gui.load()
|
|
|
|
self.gui.setScore(0)
|
|
|
|
self.gui.showScore()
|
|
|
|
self.gui.setTeam(self.team)
|
|
|
|
self.gui.startTrackingCogs(self.activity.view.cogManager.cogs)
|
|
|
|
self.control.enable()
|
|
|
|
self._startUpdateTask()
|
|
|
|
|
|
|
|
def disable(self):
|
|
|
|
if not self.enabled:
|
|
|
|
return
|
|
|
|
self._stopUpdateTask()
|
|
|
|
self.toon.b_setAnimState('neutral')
|
|
|
|
PartyCogActivityPlayer.disable(self)
|
|
|
|
self.orthoWalking = False
|
|
|
|
self.orthoWalk.stop()
|
|
|
|
self._destroyOrthoWalk()
|
|
|
|
self.input.disable()
|
|
|
|
self._aimMode = False
|
|
|
|
self.cameraManager.setEnabled(False)
|
|
|
|
self.gui.hide()
|
|
|
|
self.gui.stopTrackingCogs()
|
|
|
|
self.gui.unload()
|
|
|
|
|
|
|
|
def updateScore(self):
|
|
|
|
self.gui.setScore(self.score)
|
|
|
|
|
|
|
|
def b_updateToonPosition(self):
|
|
|
|
self.updateToonPosition()
|
|
|
|
self.d_updateToonPosition()
|
|
|
|
|
|
|
|
def d_updateToonPosition(self):
|
|
|
|
self.toon.d_setPos(self.toon.getX(), self.toon.getY(), self.toon.getZ())
|
|
|
|
self.toon.d_setH(self.toon.getH())
|
|
|
|
|
|
|
|
def lookAtArena(self):
|
|
|
|
self.cameraManager.setEnabled(True)
|
|
|
|
self.cameraManager.setTargetPos(self.activity.view.arena.find('**/conclusionCamPos_locator').getPos(render))
|
|
|
|
self.cameraManager.setTargetLookAtPos(self.activity.view.arena.find('**/conclusionCamAim_locator').getPos(render))
|
|
|
|
|
|
|
|
def lookAtMyTeam(self):
|
|
|
|
activityView = self.activity.view
|
|
|
|
arena = activityView.arena
|
|
|
|
pos = activityView.teamCamPosLocators[self.team].getPos()
|
|
|
|
aim = activityView.teamCamAimLocators[self.team].getPos()
|
|
|
|
camera.wrtReparentTo(arena)
|
|
|
|
self.cameraManager.setPos(camera.getPos(render))
|
|
|
|
self.tempNP.reparentTo(arena)
|
|
|
|
self.tempNP.setPos(arena, pos)
|
|
|
|
self.cameraManager.setTargetPos(self.tempNP.getPos(render))
|
|
|
|
self.cameraManager.setLookAtPos(self.getLookat(camera))
|
|
|
|
self.tempNP.reparentTo(arena)
|
|
|
|
self.tempNP.setPos(arena, aim)
|
|
|
|
self.cameraManager.setTargetLookAtPos(self.tempNP.getPos(render))
|
|
|
|
self.cameraManager.setEnabled(True)
|
|
|
|
camera.setP(0.0)
|
|
|
|
camera.setR(0.0)
|