2015-06-23 18:11:48 -05:00
|
|
|
from panda3d.core import *
|
2015-03-03 16:10:12 -06:00
|
|
|
from toontown.toonbase.ToonBaseGlobal import *
|
|
|
|
from DistributedMinigame import *
|
|
|
|
from direct.interval.IntervalGlobal import *
|
|
|
|
from direct.fsm import ClassicFSM, State
|
|
|
|
from direct.fsm import State
|
2015-05-25 04:31:46 -05:00
|
|
|
from toontown.safezone import Walk, SnowUtil
|
2015-03-03 16:10:12 -06:00
|
|
|
from toontown.toonbase import ToontownTimer
|
|
|
|
from direct.gui import OnscreenText
|
|
|
|
import MinigameAvatarScorePanel
|
|
|
|
from direct.distributed import DistributedSmoothNode
|
|
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
from toontown.toonbase import TTLocalizer
|
|
|
|
from otp.otpbase import OTPGlobals
|
|
|
|
import TagGameGlobals
|
|
|
|
import Trajectory
|
|
|
|
|
|
|
|
class DistributedTagGame(DistributedMinigame):
|
|
|
|
DURATION = TagGameGlobals.DURATION
|
|
|
|
IT_SPEED_INCREASE = 1.3
|
|
|
|
IT_ROT_INCREASE = 1.3
|
|
|
|
|
|
|
|
def __init__(self, cr):
|
|
|
|
DistributedMinigame.__init__(self, cr)
|
|
|
|
self.gameFSM = ClassicFSM.ClassicFSM('DistributedTagGame', [State.State('off', self.enterOff, self.exitOff, ['play']), State.State('play', self.enterPlay, self.exitPlay, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, ['off'])], 'off', 'off')
|
|
|
|
self.addChildGameFSM(self.gameFSM)
|
|
|
|
self.walkStateData = Walk.Walk('walkDone')
|
|
|
|
self.scorePanels = []
|
|
|
|
base.localAvatar.isIt = 0
|
|
|
|
self.modelCount = 4
|
|
|
|
|
|
|
|
def getTitle(self):
|
|
|
|
return TTLocalizer.TagGameTitle
|
|
|
|
|
|
|
|
def getInstructions(self):
|
|
|
|
return TTLocalizer.TagGameInstructions
|
|
|
|
|
|
|
|
def getMaxDuration(self):
|
|
|
|
return self.DURATION
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
self.notify.debug('load')
|
|
|
|
DistributedMinigame.load(self)
|
|
|
|
self.itText = OnscreenText.OnscreenText('itText', fg=(0.95, 0.95, 0.65, 1), scale=0.14, font=ToontownGlobals.getSignFont(), pos=(0.0, -0.8), wordwrap=15, mayChange=1)
|
|
|
|
self.itText.hide()
|
2015-05-25 04:31:46 -05:00
|
|
|
safezoneId = self.getSafezoneId()
|
|
|
|
self.sky = loader.loadModel(TagGameGlobals.getSky(safezoneId))
|
|
|
|
self.ground = loader.loadModel(TagGameGlobals.getGround(safezoneId))
|
2015-03-03 16:10:12 -06:00
|
|
|
self.music = base.loadMusic('phase_4/audio/bgm/MG_toontag.ogg')
|
|
|
|
self.tagSfx = base.loadSfx('phase_4/audio/sfx/MG_Tag_C.ogg')
|
|
|
|
self.itPointer = loader.loadModel('phase_4/models/minigames/bboard-pointer')
|
|
|
|
self.tracks = []
|
2015-05-25 04:31:46 -05:00
|
|
|
self.initialPositions = TagGameGlobals.getDropPoints(safezoneId)
|
2015-03-03 16:10:12 -06:00
|
|
|
self.IT = None
|
2015-05-25 04:31:46 -05:00
|
|
|
|
|
|
|
if TagGameGlobals.isSnowHood(safezoneId):
|
|
|
|
self.snow, self.snowRender = SnowUtil.createSnow(self.ground)
|
|
|
|
|
2015-03-03 16:10:12 -06:00
|
|
|
return
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
self.notify.debug('unload')
|
|
|
|
DistributedMinigame.unload(self)
|
|
|
|
self.ignoreAll()
|
|
|
|
del self.tracks
|
|
|
|
del self.IT
|
|
|
|
self.sky.removeNode()
|
|
|
|
del self.sky
|
|
|
|
self.itPointer.removeNode()
|
|
|
|
del self.itPointer
|
|
|
|
self.ground.removeNode()
|
|
|
|
del self.ground
|
|
|
|
del self.music
|
|
|
|
del self.tagSfx
|
|
|
|
self.itText.cleanup()
|
|
|
|
del self.itText
|
|
|
|
self.removeChildGameFSM(self.gameFSM)
|
|
|
|
del self.gameFSM
|
2015-05-25 04:31:46 -05:00
|
|
|
self.destroySnow()
|
|
|
|
|
|
|
|
def destroySnow(self):
|
|
|
|
if hasattr(self, 'snow'):
|
|
|
|
self.snow.cleanup()
|
|
|
|
self.snowRender.removeNode()
|
|
|
|
del self.snow
|
|
|
|
del self.snowRender
|
2015-03-03 16:10:12 -06:00
|
|
|
|
|
|
|
def onstage(self):
|
|
|
|
self.notify.debug('onstage')
|
|
|
|
DistributedMinigame.onstage(self)
|
|
|
|
self.ground.reparentTo(render)
|
|
|
|
self.sky.reparentTo(render)
|
|
|
|
myPos = self.avIdList.index(self.localAvId)
|
|
|
|
base.localAvatar.setPosHpr(*self.initialPositions[myPos])
|
|
|
|
base.localAvatar.reparentTo(render)
|
|
|
|
base.localAvatar.loop('neutral')
|
|
|
|
camera.reparentTo(render)
|
|
|
|
camera.setPosHpr(0, -24, 16, 0, -30, 0)
|
|
|
|
base.camLens.setFar(450.0)
|
|
|
|
base.transitions.irisIn(0.4)
|
2015-06-26 14:44:51 -05:00
|
|
|
NametagGlobals.setMasterArrowsOn(1)
|
2015-03-03 16:10:12 -06:00
|
|
|
DistributedSmoothNode.activateSmoothing(1, 1)
|
|
|
|
self.IT = None
|
2015-05-25 04:31:46 -05:00
|
|
|
|
|
|
|
if hasattr(self, 'snow'):
|
|
|
|
self.snow.start(camera, self.snowRender)
|
|
|
|
|
2015-03-03 16:10:12 -06:00
|
|
|
return
|
|
|
|
|
|
|
|
def offstage(self):
|
|
|
|
self.notify.debug('offstage')
|
|
|
|
DistributedSmoothNode.activateSmoothing(1, 0)
|
2015-06-26 14:44:51 -05:00
|
|
|
NametagGlobals.setMasterArrowsOn(0)
|
2015-03-03 16:10:12 -06:00
|
|
|
DistributedMinigame.offstage(self)
|
|
|
|
self.sky.reparentTo(hidden)
|
|
|
|
self.ground.reparentTo(hidden)
|
|
|
|
base.camLens.setFar(ToontownGlobals.DefaultCameraFar)
|
|
|
|
self.itText.hide()
|
|
|
|
|
|
|
|
def setGameReady(self):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameReady')
|
|
|
|
if DistributedMinigame.setGameReady(self):
|
|
|
|
return
|
|
|
|
for avId in self.avIdList:
|
|
|
|
self.acceptTagEvent(avId)
|
|
|
|
|
|
|
|
myPos = self.avIdList.index(self.localAvId)
|
|
|
|
for i in xrange(self.numPlayers):
|
|
|
|
avId = self.avIdList[i]
|
|
|
|
avatar = self.getAvatar(avId)
|
|
|
|
if avatar:
|
|
|
|
avatar.startSmooth()
|
|
|
|
|
|
|
|
base.localAvatar.setPosHpr(*self.initialPositions[myPos])
|
|
|
|
base.localAvatar.d_clearSmoothing()
|
|
|
|
base.localAvatar.sendCurrentPosition()
|
|
|
|
base.localAvatar.b_setAnimState('neutral', 1)
|
|
|
|
base.localAvatar.b_setParent(ToontownGlobals.SPRender)
|
|
|
|
|
|
|
|
def setGameStart(self, timestamp):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameStart')
|
|
|
|
DistributedMinigame.setGameStart(self, timestamp)
|
|
|
|
self.gameFSM.request('play')
|
|
|
|
|
|
|
|
def enterOff(self):
|
|
|
|
self.notify.debug('enterOff')
|
|
|
|
|
|
|
|
def exitOff(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterPlay(self):
|
|
|
|
self.notify.debug('enterPlay')
|
|
|
|
for i in xrange(self.numPlayers):
|
|
|
|
avId = self.avIdList[i]
|
|
|
|
avName = self.getAvatarName(avId)
|
|
|
|
scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(avId, avName)
|
|
|
|
scorePanel.setPos(-0.213, 0.0, 0.28 * i + 0.66)
|
|
|
|
scorePanel.reparentTo(base.a2dBottomRight)
|
|
|
|
self.scorePanels.append(scorePanel)
|
|
|
|
|
2015-06-26 02:09:27 -05:00
|
|
|
base.setCellsAvailable(base.rightCells, 0)
|
2015-03-03 16:10:12 -06:00
|
|
|
self.walkStateData.enter()
|
|
|
|
self.walkStateData.fsm.request('walking')
|
|
|
|
if base.localAvatar.isIt:
|
|
|
|
base.mouseInterfaceNode.setForwardSpeed(ToontownGlobals.ToonForwardSpeed * self.IT_SPEED_INCREASE)
|
|
|
|
base.mouseInterfaceNode.setRotateSpeed(ToontownGlobals.ToonRotateSpeed * self.IT_ROT_INCREASE)
|
|
|
|
self.timer = ToontownTimer.ToontownTimer()
|
|
|
|
self.timer.posInTopRightCorner()
|
|
|
|
self.timer.setTime(self.DURATION)
|
|
|
|
self.timer.countdown(self.DURATION, self.timerExpired)
|
|
|
|
base.playMusic(self.music, looping=1, volume=0.9)
|
|
|
|
base.localAvatar.setIdealCameraPos(Point3(0, -24, 8))
|
|
|
|
|
|
|
|
def exitPlay(self):
|
|
|
|
for task in self.tracks:
|
|
|
|
task.finish()
|
|
|
|
|
|
|
|
self.tracks = []
|
|
|
|
for avId in self.avIdList:
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if toon:
|
|
|
|
toon.getGeomNode().clearMat()
|
|
|
|
toon.scale = 1.0
|
|
|
|
toon.rescaleToon()
|
|
|
|
|
|
|
|
self.walkStateData.exit()
|
|
|
|
self.music.stop()
|
|
|
|
self.timer.destroy()
|
|
|
|
del self.timer
|
|
|
|
for panel in self.scorePanels:
|
|
|
|
panel.cleanup()
|
|
|
|
|
|
|
|
self.scorePanels = []
|
2015-06-26 02:09:27 -05:00
|
|
|
base.setCellsAvailable(base.rightCells, 1)
|
2015-03-03 16:10:12 -06:00
|
|
|
base.mouseInterfaceNode.setForwardSpeed(ToontownGlobals.ToonForwardSpeed)
|
|
|
|
base.mouseInterfaceNode.setRotateSpeed(ToontownGlobals.ToonRotateSpeed)
|
|
|
|
self.itPointer.reparentTo(hidden)
|
|
|
|
base.localAvatar.cameraIndex = 0
|
|
|
|
base.localAvatar.setCameraPositionByIndex(0)
|
|
|
|
|
|
|
|
def timerExpired(self):
|
|
|
|
self.notify.debug('local timer expired')
|
|
|
|
self.gameOver()
|
|
|
|
|
|
|
|
def enterCleanup(self):
|
|
|
|
self.notify.debug('enterCleanup')
|
|
|
|
self.gameFSM.request('off')
|
|
|
|
|
|
|
|
def exitCleanup(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def setIt(self, avId):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
if self.gameFSM.getCurrentState().getName() != 'play':
|
|
|
|
self.notify.debug('Ignoring setIt after done playing')
|
|
|
|
return
|
|
|
|
self.itText.show()
|
|
|
|
self.notify.debug(str(avId) + ' is now it')
|
|
|
|
if avId == self.localAvId:
|
|
|
|
self.itText.setText(TTLocalizer.TagGameYouAreIt)
|
|
|
|
base.localAvatar.isIt = 1
|
|
|
|
base.localAvatar.controlManager.setSpeeds(OTPGlobals.ToonForwardSpeed * self.IT_SPEED_INCREASE, OTPGlobals.ToonJumpForce, OTPGlobals.ToonReverseSpeed * self.IT_SPEED_INCREASE, OTPGlobals.ToonRotateSpeed * self.IT_ROT_INCREASE)
|
|
|
|
else:
|
|
|
|
self.itText.setText(TTLocalizer.TagGameSomeoneElseIsIt % self.getAvatarName(avId))
|
|
|
|
base.localAvatar.isIt = 0
|
|
|
|
base.localAvatar.setWalkSpeedNormal()
|
|
|
|
avatar = self.getAvatar(avId)
|
|
|
|
if avatar:
|
|
|
|
self.itPointer.reparentTo(avatar)
|
|
|
|
self.itPointer.setZ(avatar.getHeight())
|
|
|
|
base.playSfx(self.tagSfx)
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
duration = 0.6
|
|
|
|
if not toon:
|
|
|
|
return
|
|
|
|
spinTrack = LerpHprInterval(toon.getGeomNode(), duration, Point3(0, 0, 0), startHpr=Point3(-5.0 * 360.0, 0, 0), blendType='easeOut')
|
|
|
|
growTrack = Parallel()
|
|
|
|
gs = 2.5
|
|
|
|
for hi in xrange(toon.headParts.getNumPaths()):
|
|
|
|
head = toon.headParts[hi]
|
|
|
|
growTrack.append(LerpScaleInterval(head, duration, Point3(gs, gs, gs)))
|
|
|
|
|
|
|
|
def bounceFunc(t, trajectory, node = toon.getGeomNode()):
|
|
|
|
node.setZ(trajectory.calcZ(t))
|
|
|
|
|
|
|
|
def bounceCleanupFunc(node = toon.getGeomNode(), z = toon.getGeomNode().getZ()):
|
|
|
|
node.setZ(z)
|
|
|
|
|
|
|
|
bounceTrack = Sequence()
|
|
|
|
startZ = toon.getGeomNode().getZ()
|
|
|
|
tLen = 0
|
|
|
|
zVel = 30
|
|
|
|
decay = 0.6
|
|
|
|
while tLen < duration:
|
|
|
|
trajectory = Trajectory.Trajectory(0, Point3(0, 0, startZ), Point3(0, 0, zVel), gravMult=5.0)
|
|
|
|
dur = trajectory.calcTimeOfImpactOnPlane(startZ)
|
|
|
|
if dur <= 0:
|
|
|
|
break
|
|
|
|
bounceTrack.append(LerpFunctionInterval(bounceFunc, fromData=0.0, toData=dur, duration=dur, extraArgs=[trajectory]))
|
|
|
|
tLen += dur
|
|
|
|
zVel *= decay
|
|
|
|
|
|
|
|
bounceTrack.append(Func(bounceCleanupFunc))
|
|
|
|
tagTrack = Sequence(Func(toon.animFSM.request, 'off'), Parallel(spinTrack, growTrack, bounceTrack), Func(toon.animFSM.request, 'Happy'))
|
|
|
|
self.tracks.append(tagTrack)
|
|
|
|
tagTrack.start()
|
|
|
|
if self.IT:
|
|
|
|
it = self.getAvatar(self.IT)
|
|
|
|
shrinkTrack = Parallel()
|
|
|
|
for hi in xrange(it.headParts.getNumPaths()):
|
|
|
|
head = it.headParts[hi]
|
|
|
|
scale = ToontownGlobals.toonHeadScales[it.style.getAnimal()]
|
|
|
|
shrinkTrack.append(LerpScaleInterval(head, duration, scale))
|
|
|
|
|
|
|
|
self.tracks.append(shrinkTrack)
|
|
|
|
shrinkTrack.start()
|
|
|
|
self.IT = avId
|
|
|
|
|
|
|
|
def acceptTagEvent(self, avId):
|
|
|
|
self.accept('enterdistAvatarCollNode-' + str(avId), self.sendTagIfIt, [avId])
|
|
|
|
|
|
|
|
def sendTagIfIt(self, avId, collisionEntry):
|
|
|
|
if base.localAvatar.isIt:
|
|
|
|
self.notify.debug('Tagging ' + str(avId))
|
|
|
|
self.sendUpdate('tag', [avId])
|
|
|
|
else:
|
|
|
|
self.notify.debug('Bumped ' + str(avId))
|
|
|
|
|
|
|
|
def setTreasureScore(self, scores):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setTreasureScore: %s' % scores)
|
|
|
|
for i in xrange(len(self.scorePanels)):
|
2015-06-16 12:26:44 -05:00
|
|
|
self.scorePanels[i].setScore(scores[i])
|