286 lines
11 KiB
Python
286 lines
11 KiB
Python
|
from pandac.PandaModules import *
|
||
|
from toontown.toonbase.ToonBaseGlobal import *
|
||
|
from DistributedMinigame import *
|
||
|
from direct.interval.IntervalGlobal import *
|
||
|
from direct.fsm import ClassicFSM, State
|
||
|
from direct.fsm import State
|
||
|
from toontown.safezone import Walk
|
||
|
from toontown.toonbase import ToontownTimer
|
||
|
from direct.gui import OnscreenText
|
||
|
import MinigameAvatarScorePanel
|
||
|
from direct.distributed import DistributedSmoothNode
|
||
|
import random
|
||
|
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 = []
|
||
|
self.initialPositions = ((0, 10, 0, 180, 0, 0),
|
||
|
(10, 0, 0, 90, 0, 0),
|
||
|
(0, -10, 0, 0, 0, 0),
|
||
|
(-10, 0, 0, -90, 0, 0))
|
||
|
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()
|
||
|
self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
|
||
|
self.ground = loader.loadModel('phase_4/models/minigames/tag_arena')
|
||
|
self.music = base.loadMusic('phase_4/audio/bgm/MG_toontag.mid')
|
||
|
self.tagSfx = base.loadSfx('phase_4/audio/sfx/MG_Tag_C.mp3')
|
||
|
self.itPointer = loader.loadModel('phase_4/models/minigames/bboard-pointer')
|
||
|
self.tracks = []
|
||
|
self.IT = None
|
||
|
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
|
||
|
|
||
|
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)
|
||
|
NametagGlobals.setMasterArrowsOn(1)
|
||
|
DistributedSmoothNode.activateSmoothing(1, 1)
|
||
|
self.IT = None
|
||
|
return
|
||
|
|
||
|
def offstage(self):
|
||
|
self.notify.debug('offstage')
|
||
|
DistributedSmoothNode.activateSmoothing(1, 0)
|
||
|
NametagGlobals.setMasterArrowsOn(0)
|
||
|
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 range(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 range(self.numPlayers):
|
||
|
avId = self.avIdList[i]
|
||
|
avName = self.getAvatarName(avId)
|
||
|
scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(avId, avName)
|
||
|
scorePanel.setPos(1.12, 0.0, 0.28 * i - 0.34)
|
||
|
self.scorePanels.append(scorePanel)
|
||
|
|
||
|
base.setCellsAvailable(base.rightCells, 0)
|
||
|
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 = []
|
||
|
base.setCellsAvailable(base.rightCells, 1)
|
||
|
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 range(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 range(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 range(len(self.scorePanels)):
|
||
|
self.scorePanels[i].setScore(scores[i])
|