fix some broken minigames

This commit is contained in:
Open Toontown 2023-04-29 22:20:11 -04:00
parent 72c6316f6e
commit 03c45eedb0
3 changed files with 437 additions and 307 deletions

View file

@ -1,23 +1,28 @@
from direct.directnotify import DirectNotifyGlobal
from panda3d.core import *
from toontown.toonbase.ToonBaseGlobal import *
from .DistributedMinigame import *
from direct.distributed.ClockDelta import *
from direct.interval.IntervalGlobal import *
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import ToontownTimer
from panda3d.core import Point3, Quat, rad2Deg, Vec3
from panda3d.otp import Nametag, NametagFloat3d
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.fsm.ClassicFSM import ClassicFSM
from direct.fsm.State import State
from direct.gui.DirectGui import DGG, DirectButton, DirectFrame, DirectLabel
from direct.interval.IntervalGlobal import Parallel, Sequence, SoundInterval, Wait
from direct.task.Task import Task
from . import Trajectory
import math
from toontown.toon import ToonHead
from toontown.effects import Splash
from toontown.effects import DustCloud
from . import CannonGameGlobals
from direct.gui.DirectGui import *
from panda3d.core import *
from direct.task.TaskManagerGlobal import taskMgr
from toontown.effects.DustCloud import DustCloud
from toontown.effects.Splash import Splash
from toontown.minigame import CannonGameGlobals
from toontown.minigame import MinigameGlobals
from toontown.minigame.DistributedMinigame import DistributedMinigame
from toontown.minigame.Trajectory import Trajectory
from toontown.toon.ToonHead import ToonHead
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.toonbase.ToonBaseGlobal import base
from toontown.toonbase.ToontownTimer import ToontownTimer
import math
LAND_TIME = 2
WORLD_SCALE = 2.0
GROUND_SCALE = 1.4 * WORLD_SCALE
@ -40,8 +45,9 @@ TOWER_X_RANGE = int(TOWER_Y_RANGE / 2.0)
INITIAL_VELOCITY = 94.0
WHISTLE_SPEED = INITIAL_VELOCITY * 0.55
class DistributedCannonGame(DistributedMinigame):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMinigame')
notify = directNotify.newCategory('DistributedCannonGame')
font = ToontownGlobals.getToonFont()
LOCAL_CANNON_MOVE_TASK = 'localCannonMoveTask'
REWARD_COUNTDOWN_TASK = 'cannonGameRewardCountdown'
@ -58,11 +64,11 @@ class DistributedCannonGame(DistributedMinigame):
def __init__(self, cr):
DistributedMinigame.__init__(self, cr)
self.gameFSM = ClassicFSM.ClassicFSM('DistributedCannonGame', [State.State('off', self.enterOff, self.exitOff, ['aim']),
State.State('aim', self.enterAim, self.exitAim, ['shoot', 'waitForToonsToLand', 'cleanup']),
State.State('shoot', self.enterShoot, self.exitShoot, ['aim', 'waitForToonsToLand', 'cleanup']),
State.State('waitForToonsToLand', self.enterWaitForToonsToLand, self.exitWaitForToonsToLand, ['cleanup']),
State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
self.gameFSM = ClassicFSM('DistributedCannonGame', [State('off', self.enterOff, self.exitOff, ['aim']),
State('aim', self.enterAim, self.exitAim, ['shoot', 'waitForToonsToLand', 'cleanup']),
State('shoot', self.enterShoot, self.exitShoot, ['aim', 'waitForToonsToLand', 'cleanup']),
State('waitForToonsToLand', self.enterWaitForToonsToLand, self.exitWaitForToonsToLand, ['cleanup']),
State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
self.addChildGameFSM(self.gameFSM)
self.cannonLocationDict = {}
self.cannonPositionDict = {}
@ -92,12 +98,12 @@ class DistributedCannonGame(DistributedMinigame):
def load(self):
self.notify.debug('load')
DistributedMinigame.load(self)
self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
self.ground = loader.loadModel('phase_4/models/minigames/toon_cannon_gameground')
self.tower = loader.loadModel('phase_4/models/minigames/toon_cannon_water_tower')
self.cannon = loader.loadModel('phase_4/models/minigames/toon_cannon')
self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow')
self.hill = loader.loadModel('phase_4/models/minigames/cannon_hill')
self.sky = base.loader.loadModel('phase_3.5/models/props/TT_sky')
self.ground = base.loader.loadModel('phase_4/models/minigames/toon_cannon_gameground')
self.tower = base.loader.loadModel('phase_4/models/minigames/toon_cannon_water_tower')
self.cannon = base.loader.loadModel('phase_4/models/minigames/toon_cannon')
self.dropShadow = base.loader.loadModel('phase_3/models/props/drop_shadow')
self.hill = base.loader.loadModel('phase_4/models/minigames/cannon_hill')
self.sky.setScale(WORLD_SCALE)
self.ground.setScale(GROUND_SCALE)
self.cannon.setScale(CANNON_SCALE)
@ -105,12 +111,12 @@ class DistributedCannonGame(DistributedMinigame):
self.ground.setColor(0.85, 0.85, 0.85, 1.0)
self.hill.setScale(1, 1, CANNON_Z / 20.0)
self.dropShadow.setBin('fixed', 0, 1)
self.splash = Splash.Splash(render)
self.dustCloud = DustCloud.DustCloud(render)
purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui')
self.splash = Splash(base.render)
self.dustCloud = DustCloud(base.render)
purchaseModels = base.loader.loadModel('phase_4/models/gui/purchase_gui')
self.jarImage = purchaseModels.find('**/Jar')
self.jarImage.reparentTo(hidden)
self.rewardPanel = DirectLabel(parent=hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage)
self.jarImage.reparentTo(base.hidden)
self.rewardPanel = DirectLabel(parent=base.hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text='', text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0, -.13), text_font=ToontownGlobals.getSignFont(), image=self.jarImage)
self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel, relief=None, pos=(0, 0, 0.06), scale=0.08, text=TTLocalizer.CannonGameReward, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1))
self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_cannon_game.ogg')
self.sndCannonMove = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_adjust.ogg')
@ -122,7 +128,7 @@ class DistributedCannonGame(DistributedMinigame):
self.sndWin = base.loader.loadSfx('phase_4/audio/sfx/MG_win.ogg')
self.sndRewardTick = base.loader.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg')
guiModel = 'phase_4/models/gui/cannon_game_gui'
cannonGui = loader.loadModel(guiModel)
cannonGui = base.loader.loadModel(guiModel)
self.aimPad = DirectFrame(image=cannonGui.find('**/CannonFire_PAD'), relief=None, pos=(0.7, 0, -0.553333), scale=0.8)
cannonGui.removeNode()
self.aimPad.hide()
@ -141,14 +147,13 @@ class DistributedCannonGame(DistributedMinigame):
bindButton(self.downButton, self.__downPressed, self.__downReleased)
bindButton(self.leftButton, self.__leftPressed, self.__leftReleased)
bindButton(self.rightButton, self.__rightPressed, self.__rightReleased)
self.timer = ToontownTimer.ToontownTimer()
self.timer = ToontownTimer()
self.timer.posInTopRightCorner()
self.timer.hide()
self.DEBUG_TOWER_RANGE = 0
self.DEBUG_CANNON_FAR_LEFT = 0
self.DEBUG_TOWER_NEAR = 1
self.DEBUG_TOWER_FAR_LEFT = 1
return
def unload(self):
self.notify.debug('unload')
@ -199,6 +204,7 @@ class DistributedCannonGame(DistributedMinigame):
av.loop('neutral')
av.setPlayRate(1.0, 'run')
av.nametag.removeNametag(head.tag)
head.delete()
del self.toonHeadDict
@ -227,19 +233,19 @@ class DistributedCannonGame(DistributedMinigame):
DistributedMinigame.onstage(self)
self.__createCannons()
for avId in self.avIdList:
self.cannonDict[avId][0].reparentTo(render)
self.cannonDict[avId][0].reparentTo(base.render)
self.towerPos = self.getTowerPosition()
self.tower.setPos(self.towerPos)
self.tower.reparentTo(render)
self.sky.reparentTo(render)
self.ground.reparentTo(render)
self.tower.reparentTo(base.render)
self.sky.reparentTo(base.render)
self.ground.reparentTo(base.render)
self.hill.setPosHpr(0, CANNON_Y + 2.33, 0, 0, 0, 0)
self.hill.reparentTo(render)
self.splash.reparentTo(render)
self.dustCloud.reparentTo(render)
self.hill.reparentTo(base.render)
self.splash.reparentTo(base.render)
self.dustCloud.reparentTo(base.render)
self.__createToonModels(self.localAvId)
camera.reparentTo(render)
base.camera.reparentTo(base.render)
self.__oldCamFar = base.camLens.getFar()
base.camLens.setFar(FAR_PLANE_DIST)
self.__startIntro()
@ -248,27 +254,28 @@ class DistributedCannonGame(DistributedMinigame):
def offstage(self):
self.notify.debug('offstage')
self.sky.reparentTo(hidden)
self.ground.reparentTo(hidden)
self.hill.reparentTo(hidden)
self.tower.reparentTo(hidden)
self.sky.reparentTo(base.hidden)
self.ground.reparentTo(base.hidden)
self.hill.reparentTo(base.hidden)
self.tower.reparentTo(base.hidden)
for avId in self.avIdList:
self.cannonDict[avId][0].reparentTo(hidden)
self.cannonDict[avId][0].reparentTo(base.hidden)
if avId in self.dropShadowDict:
self.dropShadowDict[avId].reparentTo(hidden)
self.dropShadowDict[avId].reparentTo(base.hidden)
av = self.getAvatar(avId)
if av:
av.dropShadow.show()
av.resetLOD()
self.splash.reparentTo(hidden)
self.splash.reparentTo(base.hidden)
self.splash.stop()
self.dustCloud.reparentTo(hidden)
self.dustCloud.reparentTo(base.hidden)
self.dustCloud.stop()
self.__stopIntro()
base.camLens.setFar(self.__oldCamFar)
self.timer.reparentTo(hidden)
self.rewardPanel.reparentTo(hidden)
self.timer.reparentTo(base.hidden)
self.rewardPanel.reparentTo(base.hidden)
DistributedMinigame.offstage(self)
def getTowerPosition(self):
@ -282,6 +289,7 @@ class DistributedCannonGame(DistributedMinigame):
y = yMax
else:
y = self.randomNumGen.randint(yMin, yMax)
xRange = TOWER_X_RANGE
if self.DEBUG_TOWER_RANGE:
if self.DEBUG_TOWER_FAR_LEFT:
@ -290,6 +298,7 @@ class DistributedCannonGame(DistributedMinigame):
x = xRange
else:
x = self.randomNumGen.randint(0, xRange)
x = x - int(xRange / 2.0)
if base.wantMinigameDifficulty:
diff = self.getDifficulty()
@ -297,6 +306,7 @@ class DistributedCannonGame(DistributedMinigame):
x *= scale
yCenter = (yMin + yMax) / 2.0
y = (y - yCenter) * scale + yCenter
x = float(x) * (float(y) / float(yRange))
y = y - int(yRange / 2.0)
self.notify.debug('getTowerPosition: ' + str(x) + ', ' + str(y))
@ -304,7 +314,7 @@ class DistributedCannonGame(DistributedMinigame):
def __createCannons(self):
for avId in self.avIdList:
cannon = self.cannon.copyTo(hidden)
cannon = self.cannon.copyTo(base.hidden)
barrel = cannon.find('**/cannon')
self.cannonDict[avId] = [cannon, barrel]
@ -317,6 +327,7 @@ class DistributedCannonGame(DistributedMinigame):
self.cannonLocationDict[avId] = Point3(0 * CANNON_X_SPACING - (4 - 1) * CANNON_X_SPACING / 2, CANNON_Y, CANNON_Z)
else:
self.cannonLocationDict[avId] = Point3(3 * CANNON_X_SPACING - (4 - 1) * CANNON_X_SPACING / 2, CANNON_Y, CANNON_Z)
self.cannonPositionDict[avId] = [0, CannonGameGlobals.CANNON_ANGLE_MIN]
self.cannonDict[avId][0].setPos(self.cannonLocationDict[avId])
self.__updateCannonPosition(avId)
@ -324,9 +335,11 @@ class DistributedCannonGame(DistributedMinigame):
def setGameReady(self):
if not self.hasLocalToon:
return
self.notify.debug('setGameReady')
if DistributedMinigame.setGameReady(self):
return
for avId in self.avIdList:
if avId != self.localAvId:
self.__createToonModels(avId)
@ -335,13 +348,13 @@ class DistributedCannonGame(DistributedMinigame):
toon = self.getAvatar(avId)
self.toonScaleDict[avId] = toon.getScale()
toon.useLOD(1000)
toonParent = render.attachNewNode('toonOriginChange')
toonParent = base.render.attachNewNode('toonOriginChange')
toon.reparentTo(toonParent)
toon.setPosHpr(0, 0, -(toon.getHeight() / 2.0), 0, 0, 0)
self.toonModelDict[avId] = toonParent
head = ToonHead.ToonHead()
head = ToonHead()
head.setupHead(self.getAvatar(avId).style)
head.reparentTo(hidden)
head.reparentTo(base.hidden)
self.toonHeadDict[avId] = head
toon = self.getAvatar(avId)
tag = NametagFloat3d()
@ -354,11 +367,12 @@ class DistributedCannonGame(DistributedMinigame):
head.tag = tag
self.__loadToonInCannon(avId)
self.getAvatar(avId).dropShadow.hide()
self.dropShadowDict[avId] = self.dropShadow.copyTo(hidden)
self.dropShadowDict[avId] = self.dropShadow.copyTo(base.hidden)
def setGameStart(self, timestamp):
if not self.hasLocalToon:
return
self.notify.debug('setGameStart')
DistributedMinigame.setGameStart(self, timestamp)
self.__stopIntro()
@ -366,13 +380,13 @@ class DistributedCannonGame(DistributedMinigame):
if not base.config.GetBool('endless-cannon-game', 0):
self.timer.show()
self.timer.countdown(CannonGameGlobals.GameTime, self.__gameTimerExpired)
self.rewardPanel.reparentTo(aspect2d)
self.rewardPanel.reparentTo(base.aspect2d)
self.scoreMult = MinigameGlobals.getScoreMult(self.cr.playGame.hood.id)
self.__startRewardCountdown()
self.airborneToons = 0
self.clockStopTime = None
self.gameFSM.request('aim')
return
def __gameTimerExpired(self):
self.notify.debug('game timer expired')
@ -384,8 +398,10 @@ class DistributedCannonGame(DistributedMinigame):
def updateCannonPosition(self, avId, zRot, angle):
if not self.hasLocalToon:
return
if not self.__playing():
return
if avId != self.localAvId:
self.cannonPositionDict[avId] = [zRot, angle]
self.__updateCannonPosition(avId)
@ -393,8 +409,10 @@ class DistributedCannonGame(DistributedMinigame):
def setCannonWillFire(self, avId, fireTime, zRot, angle):
if not self.hasLocalToon:
return
if not self.__playing():
return
self.notify.debug('setCannonWillFire: ' + str(avId) + ': zRot=' + str(zRot) + ', angle=' + str(angle) + ', time=' + str(fireTime))
self.cannonPositionDict[avId][0] = zRot
self.cannonPositionDict[avId][1] = angle
@ -407,6 +425,7 @@ class DistributedCannonGame(DistributedMinigame):
fireTask = Task.sequence(Task.pause(timeToWait), task)
else:
fireTask = task
fireTask = task
taskMgr.add(fireTask, 'fireCannon' + str(avId))
self.airborneToons += 1
@ -414,10 +433,10 @@ class DistributedCannonGame(DistributedMinigame):
def announceToonWillLandInWater(self, avId, landTime):
if not self.hasLocalToon:
return
self.notify.debug('announceToonWillLandInWater: ' + str(avId) + ': time=' + str(landTime))
if self.clockStopTime == None:
self.clockStopTime = landTime
return
def enterOff(self):
self.notify.debug('enterOff')
@ -444,6 +463,7 @@ class DistributedCannonGame(DistributedMinigame):
def __somebodyWon(self, avId):
if avId == self.localAvId:
base.playSfx(self.sndWin)
self.__killRewardCountdown()
self.timer.stop()
self.gameFSM.request('waitForToonsToLand')
@ -463,6 +483,7 @@ class DistributedCannonGame(DistributedMinigame):
if hasattr(self, 'jarIval'):
self.jarIval.finish()
del self.jarIval
for avId in self.avIdList:
taskMgr.remove('fireCannon' + str(avId))
taskMgr.remove('flyingToon' + str(avId))
@ -607,27 +628,34 @@ class DistributedCannonGame(DistributedMinigame):
rotVel = 0
if self.leftPressed:
rotVel += CannonGameGlobals.CANNON_ROTATION_VEL
if self.rightPressed:
rotVel -= CannonGameGlobals.CANNON_ROTATION_VEL
pos[0] += rotVel * globalClock.getDt()
pos[0] += rotVel * base.clock.getDt()
if pos[0] < CannonGameGlobals.CANNON_ROTATION_MIN:
pos[0] = CannonGameGlobals.CANNON_ROTATION_MIN
elif pos[0] > CannonGameGlobals.CANNON_ROTATION_MAX:
pos[0] = CannonGameGlobals.CANNON_ROTATION_MAX
angVel = 0
if self.upPressed:
angVel += CannonGameGlobals.CANNON_ANGLE_VEL
if self.downPressed:
angVel -= CannonGameGlobals.CANNON_ANGLE_VEL
pos[1] += angVel * globalClock.getDt()
pos[1] += angVel * base.clock.getDt()
if pos[1] < CannonGameGlobals.CANNON_ANGLE_MIN:
pos[1] = CannonGameGlobals.CANNON_ANGLE_MIN
elif pos[1] > CannonGameGlobals.CANNON_ANGLE_MAX:
pos[1] = CannonGameGlobals.CANNON_ANGLE_MAX
if oldRot != pos[0] or oldAng != pos[1]:
if self.cannonMoving == 0:
self.cannonMoving = 1
base.playSfx(self.sndCannonMove, looping=1)
self.__updateCannonPosition(self.localAvId)
if task.time - task.lastPositionBroadcastTime > CANNON_MOVE_UPDATE_FREQ:
task.lastPositionBroadcastTime = task.time
@ -636,7 +664,8 @@ class DistributedCannonGame(DistributedMinigame):
self.cannonMoving = 0
self.sndCannonMove.stop()
self.__broadcastLocalCannonPosition()
return Task.cont
return task.cont
def __broadcastLocalCannonPosition(self):
self.sendUpdate('setCannonPosition', [self.cannonPositionDict[self.localAvId][0], self.cannonPositionDict[self.localAvId][1]])
@ -649,8 +678,8 @@ class DistributedCannonGame(DistributedMinigame):
return Point3(self.cannonLocationDict[self.localAvId][0], CANNON_Y - 25.0, CANNON_Z + 7)
def __putCameraBehindCannon(self):
camera.setPos(self.__getCameraPositionBehindCannon())
camera.setHpr(0, 0, 0)
base.camera.setPos(self.__getCameraPositionBehindCannon())
base.camera.setHpr(0, 0, 0)
def __loadToonInCannon(self, avId):
self.toonModelDict[avId].detachNode()
@ -660,7 +689,7 @@ class DistributedCannonGame(DistributedMinigame):
head.reparentTo(self.cannonDict[avId][1])
head.setPosHpr(0, 6, 0, 0, -45, 0)
sc = self.toonScaleDict[avId]
head.setScale(render, sc[0], sc[1], sc[2])
head.setScale(base.render, sc[0], sc[1], sc[2])
def __toRadians(self, angle):
return angle * 2.0 * math.pi / 360.0
@ -670,10 +699,10 @@ class DistributedCannonGame(DistributedMinigame):
def __calcFlightResults(self, avId, launchTime):
head = self.toonHeadDict[avId]
startPos = head.getPos(render)
startHpr = head.getHpr(render)
hpr = self.cannonDict[avId][1].getHpr(render)
towerPos = self.tower.getPos(render)
startPos = head.getPos(base.render)
startHpr = head.getHpr(base.render)
hpr = self.cannonDict[avId][1].getHpr(base.render)
towerPos = self.tower.getPos(base.render)
rotation = self.__toRadians(hpr[0])
angle = self.__toRadians(hpr[1])
horizVel = INITIAL_VELOCITY * math.cos(angle)
@ -681,7 +710,7 @@ class DistributedCannonGame(DistributedMinigame):
yVel = horizVel * math.cos(rotation)
zVel = INITIAL_VELOCITY * math.sin(angle)
startVel = Vec3(xVel, yVel, zVel)
trajectory = Trajectory.Trajectory(launchTime, startPos, startVel)
trajectory = Trajectory(launchTime, startPos, startVel)
towerList = [towerPos + Point3(0, 0, BUCKET_HEIGHT), TOWER_RADIUS, TOWER_HEIGHT - BUCKET_HEIGHT]
self.notify.debug('calcFlightResults(%s): rotation(%s), angle(%s), horizVel(%s), xVel(%s), yVel(%s), zVel(%s), startVel(%s), trajectory(%s), towerList(%s)' % (avId,
rotation,
@ -701,7 +730,6 @@ class DistributedCannonGame(DistributedMinigame):
avId = task.avId
self.notify.debug('FIRING CANNON FOR AVATAR ' + str(avId))
startPos, startHpr, startVel, trajectory, timeOfImpact, hitWhat = self.__calcFlightResults(avId, launchTime)
self.notify.debug('start position: ' + str(startPos))
self.notify.debug('start velocity: ' + str(startVel))
self.notify.debug('time of launch: ' + str(launchTime))
@ -713,12 +741,13 @@ class DistributedCannonGame(DistributedMinigame):
self.notify.debug('toon will hit the tower')
else:
self.notify.debug('toon will hit the ground')
head = self.toonHeadDict[avId]
head.stopBlink()
head.stopLookAroundNow()
head.reparentTo(hidden)
head.reparentTo(base.hidden)
av = self.toonModelDict[avId]
av.reparentTo(render)
av.reparentTo(base.render)
av.setPos(startPos)
av.setHpr(startHpr)
avatar = self.getAvatar(avId)
@ -737,7 +766,7 @@ class DistributedCannonGame(DistributedMinigame):
info['hRot'] = self.cannonPositionDict[avId][0]
info['haveWhistled'] = 0
info['maxCamPullback'] = CAMERA_PULLBACK_MIN
info['timeEnterTowerXY'], info['timeExitTowerXY'] = trajectory.calcEnterAndLeaveCylinderXY(self.tower.getPos(render), TOWER_RADIUS)
info['timeEnterTowerXY'], info['timeExitTowerXY'] = trajectory.calcEnterAndLeaveCylinderXY(self.tower.getPos(base.render), TOWER_RADIUS)
shootTask.info = info
flyTask.info = info
seqDoneTask.info = info
@ -746,7 +775,8 @@ class DistributedCannonGame(DistributedMinigame):
if avId == self.localAvId:
if info['hitWhat'] == self.HIT_WATER:
self.sendUpdate('setToonWillLandInWater', [info['timeOfImpact']])
return Task.done
return task.done
def __calcToonImpact(self, trajectory, waterTower):
self.notify.debug('trajectory: %s' % trajectory)
@ -757,10 +787,12 @@ class DistributedCannonGame(DistributedMinigame):
self.notify.debug('t_waterImpact: %s' % t_waterImpact)
if t_waterImpact > 0:
return (t_waterImpact, self.HIT_WATER)
t_towerImpact = trajectory.checkCollisionWithCylinderSides(waterTower[0], waterTower[1], waterTower[2])
self.notify.debug('t_towerImpact: %s' % t_towerImpact)
if t_towerImpact > 0:
return (t_towerImpact, self.HIT_TOWER)
t_groundImpact = trajectory.checkCollisionWithGround()
self.notify.debug('t_groundImpact: %s' % t_groundImpact)
if t_groundImpact >= trajectory.getStartTime():
@ -771,8 +803,8 @@ class DistributedCannonGame(DistributedMinigame):
def __shootTask(self, task):
base.playSfx(self.sndCannonFire)
self.dropShadowDict[task.info['avId']].reparentTo(render)
return Task.done
self.dropShadowDict[task.info['avId']].reparentTo(base.render)
return task.done
def __flyTask(self, task):
curTime = task.time + task.info['launchTime']
@ -780,10 +812,11 @@ class DistributedCannonGame(DistributedMinigame):
pos = task.info['trajectory'].getPos(t)
task.info['toon'].setPos(pos)
shadowPos = Point3(pos)
if t >= task.info['timeEnterTowerXY'] and t <= task.info['timeExitTowerXY'] and pos[2] >= self.tower.getPos(render)[2] + TOWER_HEIGHT:
shadowPos.setZ(self.tower.getPos(render)[2] + TOWER_HEIGHT + SHADOW_Z_OFFSET)
if t >= task.info['timeEnterTowerXY'] and t <= task.info['timeExitTowerXY'] and pos[2] >= self.tower.getPos(base.render)[2] + TOWER_HEIGHT:
shadowPos.setZ(self.tower.getPos(base.render)[2] + TOWER_HEIGHT + SHADOW_Z_OFFSET)
else:
shadowPos.setZ(SHADOW_Z_OFFSET)
self.dropShadowDict[task.info['avId']].setPos(shadowPos)
vel = task.info['trajectory'].getVel(t)
run = math.sqrt(vel[0] * vel[0] + vel[1] * vel[1])
@ -791,7 +824,7 @@ class DistributedCannonGame(DistributedMinigame):
theta = self.__toDegrees(math.atan(rise / run))
task.info['toon'].setHpr(task.info['hRot'], -90 + theta, 0)
if task.info['avId'] == self.localAvId:
lookAt = self.tower.getPos(render)
lookAt = self.tower.getPos(base.render)
lookAt.setZ(lookAt.getZ() - TOWER_HEIGHT / 2.0)
towerPos = Point3(self.towerPos)
towerPos.setZ(TOWER_HEIGHT)
@ -804,26 +837,31 @@ class DistributedCannonGame(DistributedMinigame):
perp.normalize()
if ttVec.dot(perp) > 0.0:
perp = Vec3(-perp[0], -perp[1], -perp[2])
a = 1.0 - toonTowerDist / TOON_TOWER_THRESHOLD
a_2 = a * a
multiplier = -2.0 * a_2 * a + 3 * a_2
lookAt = lookAt + perp * (multiplier * MAX_LOOKAT_OFFSET)
foo = Vec3(pos - lookAt)
foo.normalize()
task.info['maxCamPullback'] = max(task.info['maxCamPullback'], CAMERA_PULLBACK_MIN + multiplier * (CAMERA_PULLBACK_MAX - CAMERA_PULLBACK_MIN))
foo = foo * task.info['maxCamPullback']
camPos = pos + Point3(foo)
camera.setPos(camPos)
camera.lookAt(pos)
base.camera.setPos(camPos)
base.camera.lookAt(pos)
if task.info['haveWhistled'] == 0:
if -vel[2] > WHISTLE_SPEED:
if t < task.info['timeOfImpact'] - 0.5:
task.info['haveWhistled'] = 1
base.playSfx(self.sndWhizz)
if t == task.info['timeOfImpact']:
if task.info['haveWhistled']:
self.sndWhizz.stop()
self.dropShadowDict[task.info['avId']].reparentTo(hidden)
self.dropShadowDict[task.info['avId']].reparentTo(base.hidden)
avatar = self.getAvatar(task.info['avId'])
if task.info['hitWhat'] == self.HIT_WATER:
avatar.loop('neutral')
@ -853,15 +891,17 @@ class DistributedCannonGame(DistributedMinigame):
avatar.pose('slip-forward', 25)
base.playSfx(self.sndHitTower)
elif task.info['hitWhat'] == self.HIT_GROUND:
task.info['toon'].setP(render, -150.0)
task.info['toon'].setP(base.render, -150.0)
self.dustCloud.setPos(task.info['toon'], 0, 0, -2.5)
self.dustCloud.setScale(0.35)
self.dustCloud.play()
base.playSfx(self.sndHitGround)
avatar.setPlayRate(2.0, 'run')
avatar.loop('run')
return Task.done
return Task.cont
return task.done
return task.cont
def __flySequenceDoneTask(self, task):
self.airborneToons -= 1
@ -872,7 +912,8 @@ class DistributedCannonGame(DistributedMinigame):
self.__loadToonInCannon(task.info['avId'])
if task.info['avId'] == self.localAvId:
self.gameFSM.request('aim')
return Task.done
return task.done
def __startRewardCountdown(self):
taskMgr.remove(self.REWARD_COUNTDOWN_TASK)
@ -883,24 +924,29 @@ class DistributedCannonGame(DistributedMinigame):
def __updateRewardCountdown(self, task):
if not hasattr(self, 'rewardPanel'):
return Task.cont
return task.cont
curTime = self.getCurrentGameTime()
if self.clockStopTime is not None:
if self.clockStopTime < curTime:
self.__killRewardCountdown()
curTime = self.clockStopTime
score = int(self.scoreMult * CannonGameGlobals.calcScore(curTime) + 0.5)
if not hasattr(task, 'curScore'):
task.curScore = score
self.rewardPanel['text'] = str(score)
if task.curScore != score:
if hasattr(self, 'jarIval'):
self.jarIval.finish()
s = self.rewardPanel.getScale()
self.jarIval = Parallel(Sequence(self.rewardPanel.scaleInterval(0.15, s * 3.0 / 4.0, blendType='easeOut'), self.rewardPanel.scaleInterval(0.15, s, blendType='easeIn')), SoundInterval(self.sndRewardTick), name='cannonGameRewardJarThrob')
self.jarIval.start()
task.curScore = score
return Task.cont
return task.cont
def __startIntro(self):
self.T_WATER = 1
@ -926,18 +972,19 @@ class DistributedCannonGame(DistributedMinigame):
if self.introCameraSeq:
self.introCameraSeq.finish()
self.introCameraSeq = None
camera.wrtReparentTo(render)
base.camera.wrtReparentTo(base.render)
def __spawnCameraLookAtLerp(self, targetPos, targetLookAt, duration):
oldPos = camera.getPos()
oldHpr = camera.getHpr()
camera.setPos(targetPos)
camera.lookAt(targetLookAt)
oldPos = base.camera.getPos()
oldHpr = base.camera.getHpr()
base.camera.setPos(targetPos)
base.camera.lookAt(targetLookAt)
targetQuat = Quat()
targetQuat.setHpr(camera.getHpr())
camera.setPos(oldPos)
camera.setHpr(oldHpr)
self.introCameraSeq = camera.posQuatInterval(duration, Point3(targetPos), targetQuat, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP)
targetQuat.setHpr(base.camera.getHpr())
base.camera.setPos(oldPos)
base.camera.setHpr(oldHpr)
self.introCameraSeq = base.camera.posQuatInterval(duration, Point3(targetPos), targetQuat, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP)
self.introCameraSeq.start()
def __taskLookInWater(self, task):
@ -949,40 +996,40 @@ class DistributedCannonGame(DistributedMinigame):
vecAwayFromCannons.normalize()
camLoc = Point3(vecAwayFromCannons * 20) + Point3(0, 0, 20)
camLoc = camLoc + task.data['towerWaterCenter']
camera.setPos(camLoc)
camera.lookAt(task.data['towerWaterCenter'])
base.camera.setPos(camLoc)
base.camera.lookAt(task.data['towerWaterCenter'])
task.data['vecAwayFromCannons'] = vecAwayFromCannons
return Task.done
return task.done
def __taskPullBackFromWater(self, task):
camLoc = Point3(task.data['vecAwayFromCannons'] * 40) + Point3(0, 0, 20)
camLoc = camLoc + task.data['towerWaterCenter']
lookAt = task.data['cannonCenter']
self.__spawnCameraLookAtLerp(camLoc, lookAt, self.T_WATER2LONGVIEW)
return Task.done
return task.done
def __flyUpToToon(self, task):
headPos = self.toonHeadDict[self.localAvId].getPos(render)
headPos = self.toonHeadDict[self.localAvId].getPos(base.render)
camLoc = headPos + Point3(0, 5, 0)
lookAt = Point3(headPos)
self.__spawnCameraLookAtLerp(camLoc, lookAt, self.T_LONGVIEW2TOONHEAD)
return Task.done
return task.done
def __flyToBackOfCannon(self, task):
lerpNode = hidden.attachNewNode('CannonGameCameraLerpNode')
lerpNode.reparentTo(render)
lerpNode = base.hidden.attachNewNode('CannonGameCameraLerpNode')
lerpNode.reparentTo(base.render)
lerpNode.setPos(self.cannonLocationDict[self.localAvId] + Point3(0, 1, 0))
relCamPos = camera.getPos(lerpNode)
relCamHpr = camera.getHpr(lerpNode)
relCamPos = base.camera.getPos(lerpNode)
relCamHpr = base.camera.getHpr(lerpNode)
startRotation = lerpNode.getHpr()
endRotation = Point3(-180, 0, 0)
lerpNode.setHpr(endRotation)
camera.setPos(self.__getCameraPositionBehindCannon())
endPos = camera.getPos(lerpNode)
base.camera.setPos(self.__getCameraPositionBehindCannon())
endPos = base.camera.getPos(lerpNode)
lerpNode.setHpr(startRotation)
camera.reparentTo(lerpNode)
camera.setPos(relCamPos)
camera.setHpr(relCamHpr)
self.introCameraSeq = Parallel(lerpNode.hprInterval(self.T_TOONHEAD2CANNONBACK, endRotation, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP), camera.posInterval(self.T_TOONHEAD2CANNONBACK, endPos, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP))
base.camera.reparentTo(lerpNode)
base.camera.setPos(relCamPos)
base.camera.setHpr(relCamHpr)
self.introCameraSeq = Parallel(lerpNode.hprInterval(self.T_TOONHEAD2CANNONBACK, endRotation, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP), base.camera.posInterval(self.T_TOONHEAD2CANNONBACK, endPos, blendType='easeInOut', name=self.INTRO_TASK_NAME_CAMERA_LERP))
self.introCameraSeq.start()
return Task.done
return task.done

View file

@ -1,22 +1,36 @@
from panda3d.core import *
from toontown.toonbase.ToonBaseGlobal import *
from direct.interval.IntervalGlobal import *
from .DistributedMinigame import *
from direct.gui.DirectGui import *
from panda3d.core import *
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from toontown.toonbase import ToontownTimer
from . import PatternGameGlobals
from toontown.toon import ToonHead
from toontown.char import CharDNA
from toontown.char import Char
from . import ArrowKeys
import random
from panda3d.core import Point3, VBase4, Vec3
from panda3d.otp import CFSpeech, NametagGlobals
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.fsm.ClassicFSM import ClassicFSM
from direct.fsm.State import State
from direct.gui.DirectGui import DirectLabel
from direct.interval.IntervalGlobal import (
ActorInterval,
Func,
LerpColorInterval,
LerpHprInterval,
LerpPosInterval,
Parallel,
Sequence,
Wait
)
from toontown.char.Char import Char
from toontown.char.CharDNA import CharDNA
from toontown.minigame import PatternGameGlobals
from toontown.minigame.ArrowKeys import ArrowKeys
from toontown.minigame.DistributedMinigame import DistributedMinigame
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.toonbase.ToonBaseGlobal import base
from toontown.toonbase.ToontownTimer import ToontownTimer
from random import choice
class DistributedPatternGame(DistributedMinigame):
notify = directNotify.newCategory('DistributedPatternGame')
phase4snd = 'phase_4/audio/sfx/'
ButtonSoundNames = (phase4snd + 'm_match_trumpet.ogg',
phase4snd + 'm_match_guitar.ogg',
@ -46,14 +60,14 @@ class DistributedPatternGame(DistributedMinigame):
def __init__(self, cr):
DistributedMinigame.__init__(self, cr)
self.gameFSM = ClassicFSM.ClassicFSM('DistributedPatternGame', [State.State('off', self.enterOff, self.exitOff, ['waitForServerPattern']),
State.State('waitForServerPattern', self.enterWaitForServerPattern, self.exitWaitForServerPattern, ['showServerPattern', 'cleanup']),
State.State('showServerPattern', self.enterShowServerPattern, self.exitShowServerPattern, ['getUserInput', 'playBackPatterns', 'cleanup']),
State.State('getUserInput', self.enterGetUserInput, self.exitGetUserInput, ['waitForPlayerPatterns', 'playBackPatterns', 'cleanup']),
State.State('waitForPlayerPatterns', self.enterWaitForPlayerPatterns, self.exitWaitForPlayerPatterns, ['playBackPatterns', 'cleanup', 'checkGameOver']),
State.State('playBackPatterns', self.enterPlayBackPatterns, self.exitPlayBackPatterns, ['checkGameOver', 'cleanup']),
State.State('checkGameOver', self.enterCheckGameOver, self.exitCheckGameOver, ['waitForServerPattern', 'cleanup']),
State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
self.gameFSM = ClassicFSM('DistributedPatternGame', [State('off', self.enterOff, self.exitOff, ['waitForServerPattern']),
State('waitForServerPattern', self.enterWaitForServerPattern, self.exitWaitForServerPattern, ['showServerPattern', 'cleanup']),
State('showServerPattern', self.enterShowServerPattern, self.exitShowServerPattern, ['getUserInput', 'playBackPatterns', 'cleanup']),
State('getUserInput', self.enterGetUserInput, self.exitGetUserInput, ['waitForPlayerPatterns', 'playBackPatterns', 'cleanup']),
State('waitForPlayerPatterns', self.enterWaitForPlayerPatterns, self.exitWaitForPlayerPatterns, ['playBackPatterns', 'cleanup', 'checkGameOver']),
State('playBackPatterns', self.enterPlayBackPatterns, self.exitPlayBackPatterns, ['checkGameOver', 'cleanup']),
State('checkGameOver', self.enterCheckGameOver, self.exitCheckGameOver, ['waitForServerPattern', 'cleanup']),
State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
self.addChildGameFSM(self.gameFSM)
self.arrowColor = VBase4(1, 0, 0, 1)
self.xColor = VBase4(1, 0, 0, 1)
@ -63,7 +77,6 @@ class DistributedPatternGame(DistributedMinigame):
self.opaq = VBase4(1, 0, 0, 1)
self.normalTextColor = VBase4(0.537, 0.84, 0.33, 1.0)
self.__otherToonIndex = {}
return
def getTitle(self):
return TTLocalizer.PatternGameTitle
@ -78,10 +91,10 @@ class DistributedPatternGame(DistributedMinigame):
def load(self):
self.notify.debug('load')
DistributedMinigame.load(self)
self.timer = ToontownTimer.ToontownTimer()
self.timer = ToontownTimer()
self.timer.posInTopRightCorner()
self.timer.hide()
self.room = loader.loadModel('phase_4/models/minigames/matching_room')
self.room = base.loader.loadModel('phase_4/models/minigames/matching_room')
self.buttonSounds = []
for soundName in self.ButtonSoundNames:
self.buttonSounds.append(base.loader.loadSfx(soundName))
@ -95,18 +108,18 @@ class DistributedPatternGame(DistributedMinigame):
self.roundText = DirectLabel(text=self.strRound % 1, text_fg=self.normalTextColor, frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0.014, 0, -.84), scale=0.12)
self.roundText.hide()
self.waitingText.hide()
matchingGameGui = loader.loadModel('phase_3.5/models/gui/matching_game_gui')
matchingGameGui = base.loader.loadModel('phase_3.5/models/gui/matching_game_gui')
minnieArrow = matchingGameGui.find('**/minnieArrow')
minnieX = matchingGameGui.find('**/minnieX')
minnieCircle = matchingGameGui.find('**/minnieCircle')
self.arrows = [None] * 5
for x in range(0, 5):
self.arrows[x] = minnieArrow.copyTo(hidden)
self.arrows[x] = minnieArrow.copyTo(base.hidden)
self.arrows[x].hide()
self.xs = [None] * 5
for x in range(0, 5):
self.xs[x] = minnieX.copyTo(hidden)
self.xs[x] = minnieX.copyTo(base.hidden)
self.xs[x].hide()
self.statusBalls = []
@ -116,20 +129,20 @@ class DistributedPatternGame(DistributedMinigame):
for x in range(0, 4):
for y in range(0, self.totalMoves):
self.statusBalls[x][y] = minnieCircle.copyTo(hidden)
self.statusBalls[x][y] = minnieCircle.copyTo(base.hidden)
self.statusBalls[x][y].hide()
minnieArrow.removeNode()
minnieX.removeNode()
minnieCircle.removeNode()
matchingGameGui.removeNode()
self.minnie = Char.Char()
self.minnie = Char()
m = self.minnie
dna = CharDNA.CharDNA()
dna = CharDNA()
dna.newChar('mn')
m.setDNA(dna)
m.setName(TTLocalizer.Minnie)
m.reparentTo(hidden)
m.reparentTo(base.hidden)
self.backRowHome = Point3(3, 11, 0)
self.backRowXSpacing = 1.8
self.frontRowHome = Point3(0, 18, 0)
@ -140,12 +153,10 @@ class DistributedPatternGame(DistributedMinigame):
self.animPlayRates = []
animPlayRate = 1.4
animPlayRateMult = 1.06
for i in range(PatternGameGlobals.NUM_ROUNDS):
for _ in range(PatternGameGlobals.NUM_ROUNDS):
self.animPlayRates.append(animPlayRate)
animPlayRate *= animPlayRateMult
return
def unload(self):
self.notify.debug('unload')
DistributedMinigame.unload(self)
@ -201,12 +212,12 @@ class DistributedPatternGame(DistributedMinigame):
DistributedMinigame.onstage(self)
self.arrowDict = {}
self.lt = base.localAvatar
camera.reparentTo(render)
camera.setPosHpr(0.0, -14.59, 10.56, 0.0, -16.39, 0.0)
base.camera.reparentTo(base.render)
base.camera.setPosHpr(0.0, -14.59, 10.56, 0.0, -16.39, 0.0)
base.camLens.setFov(24.66)
NametagGlobals.setGlobalNametagScale(0.6)
self.arrowKeys = ArrowKeys.ArrowKeys()
self.room.reparentTo(render)
self.arrowKeys = ArrowKeys()
self.room.reparentTo(base.render)
self.room.setPosHpr(0.0, 18.39, -ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0)
self.room.setScale(1)
for anim in self.minnieAnimNames:
@ -226,7 +237,7 @@ class DistributedPatternGame(DistributedMinigame):
self.toonAnimSpeedMult[anim] = float(self.__numPingPongFrames(numFrames)) / float(self.stdNumDanceStepPingPongFrames)
lt = self.lt
lt.reparentTo(render)
lt.reparentTo(base.render)
lt.useLOD(1000)
lt.setPos(-3.5, 11, 0.0)
lt.setScale(1)
@ -246,11 +257,12 @@ class DistributedPatternGame(DistributedMinigame):
else:
self.arrowDict['lt'][k].setScale(4, 4, 4)
self.arrowDict['lt'][k].setColor(self.xColor)
self.arrowDict['lt'][k].setPos(0, 0, 1)
self.formatStatusBalls(self.arrowDict['lt'][2], jj)
m = self.minnie
m.reparentTo(render)
m.reparentTo(base.render)
m.setPos(-1.6, 20, 0)
m.setScale(1)
self.makeToonLookatCamera(m)
@ -280,13 +292,13 @@ class DistributedPatternGame(DistributedMinigame):
NametagGlobals.setGlobalNametagScale(1.0)
self.arrowKeys.destroy()
del self.arrowKeys
self.room.reparentTo(hidden)
self.room.reparentTo(base.hidden)
self.roundText.hide()
self.minnie.nametag.unmanage(base.marginManager)
self.minnie.stopEarTask()
self.minnie.stop()
self.minnie.stopBlink()
self.minnie.reparentTo(hidden)
self.minnie.reparentTo(base.hidden)
self.lt.setScale(1)
for avId in self.remoteAvIdList:
toon = self.getAvatar(avId)
@ -303,9 +315,11 @@ class DistributedPatternGame(DistributedMinigame):
def setGameReady(self):
if not self.hasLocalToon:
return
self.notify.debug('setGameReady')
if DistributedMinigame.setGameReady(self):
return
for avId in self.remoteAvIdList:
toon = self.getAvatar(avId)
if toon:
@ -321,10 +335,11 @@ class DistributedPatternGame(DistributedMinigame):
else:
self.arrowDict[avId][k].setScale(4, 4, 4)
self.arrowDict[avId][k].setColor(self.xColor)
self.arrowDict[avId][k].setPos(0, 0, 1)
self.formatStatusBalls(self.arrowDict[avId][2], jj)
toon.reparentTo(render)
toon.reparentTo(base.render)
toon.useLOD(1000)
toon.setPos(self.getBackRowPos(avId))
toon.setScale(0.9)
@ -338,16 +353,17 @@ class DistributedPatternGame(DistributedMinigame):
self.waitingText['text'] = self.strPleaseWait
else:
self.waitingText['text'] = self.strWaitingOtherPlayers
self.animTracks = {}
for avId in self.avIdList:
self.animTracks[avId] = None
self.__initGameVars()
return
def setGameStart(self, timestamp):
if not self.hasLocalToon:
return
self.notify.debug('setGameStart')
DistributedMinigame.setGameStart(self, timestamp)
self.gameFSM.request('waitForServerPattern')
@ -360,7 +376,7 @@ class DistributedPatternGame(DistributedMinigame):
return numFrames * 2 - 1
def makeToonLookatCamera(self, toon):
toon.headsUp(camera)
toon.headsUp(base.camera)
def setText(self, t, newtext):
t['text'] = newtext
@ -376,6 +392,7 @@ class DistributedPatternGame(DistributedMinigame):
if startPos:
toon.setPos(startPos)
track.append(Func(toon.setPos, startPos))
for endPos in posList:
toon.headsUp(Point3(endPos))
track.append(Func(toon.setHpr, Point3(toon.getH(), 0, 0)))
@ -387,14 +404,16 @@ class DistributedPatternGame(DistributedMinigame):
if lookAtCam:
saveHpr = toon.getHpr()
toon.headsUp(camera)
toon.headsUp(base.camera)
endHeading = toon.getHpr()[0]
toon.setHpr(saveHpr)
curHeading = toon.getH()
if endHeading - curHeading > 180.0:
endHeading -= 360
elif endHeading - curHeading < -180.0:
endHeading += 360
endHpr = Point3(endHeading, 0, 0)
duration = abs(endHeading - curHeading) / 180.0 * 0.3
track.extend([Func(toon.loop, 'walk'), LerpHprInterval(toon, duration, endHpr), Func(toon.loop, 'neutral')])
@ -456,6 +475,7 @@ class DistributedPatternGame(DistributedMinigame):
ri.append(ActorInterval(actor=self.lt, animName='victory', duration=5.5))
else:
ri.append(Func(self.lt.loop, 'neutral'))
for avId in self.remoteAvIdList:
toon = self.getAvatar(avId)
if toon:
@ -503,18 +523,21 @@ class DistributedPatternGame(DistributedMinigame):
track = Sequence(Func(self.changeArrow, toonID, index), Wait(wait))
else:
track = Sequence(Func(self.changeArrow, toonID, index), Wait(wait), LerpColorInterval(self.arrowDict[toonID][0], d, self.trans, self.opaq))
return track
def getDanceSequenceAnimTrack(self, toon, pattern):
getDanceStepTrack = self.__getToonDanceStepAnimTrack
if toon == self.minnie:
getDanceStepTrack = self.__getMinnieDanceStepAnimTrack
tracks = Sequence()
for direction in pattern:
tracks.append(getDanceStepTrack(toon, direction))
if len(pattern):
tracks.append(Func(toon.loop, 'neutral'))
return tracks
def getDanceSequenceButtonSoundTrack(self, pattern):
@ -558,6 +581,7 @@ class DistributedPatternGame(DistributedMinigame):
def setPattern(self, pattern):
if not self.hasLocalToon:
return
self.notify.debug('setPattern: ' + str(pattern))
self.__serverPattern = pattern
self.gameFSM.request('showServerPattern')
@ -591,6 +615,7 @@ class DistributedPatternGame(DistributedMinigame):
def exitShowServerPattern(self):
if self.showTrack.isPlaying():
self.showTrack.pause()
del self.showTrack
def enterGetUserInput(self):
@ -599,7 +624,7 @@ class DistributedPatternGame(DistributedMinigame):
self.proceedTrack = None
def startTimer(self = self):
self.currentStartTime = globalClock.getFrameTime()
self.currentStartTime = base.clock.getFrameTime()
self.timer.show()
self.timer.countdown(PatternGameGlobals.InputTime, self.__handleInputTimeout)
@ -629,7 +654,6 @@ class DistributedPatternGame(DistributedMinigame):
self.setupTrack = Sequence(Func(self.__setMinnieChat, self.strGo, 0), Func(self.setText, self.roundText, TTLocalizer.PatternGameGo), Func(self.roundText.setScale, 0.3), Func(enableKeys), Func(startTimer), Wait(0.8), Func(self.__clearMinnieChat), Func(self.setText, self.roundText, ' '), Func(self.roundText.setScale, 0.12), Func(self.setTextFG, self.roundText, self.normalTextColor))
self.setupTrack.start()
return
def __handleInputTimeout(self):
self.__doneGettingInput(self.__localPattern)
@ -643,15 +667,18 @@ class DistributedPatternGame(DistributedMinigame):
def remoteButtonPressed(self, avId, index, wrong):
if not self.hasLocalToon:
return
if self.gameFSM.getCurrentState().getName() not in ['getUserInput', 'waitForPlayerPatterns']:
return
if avId != self.localAvId:
if self.animTracks[avId]:
self.animTracks[avId].finish()
av = self.getAvatar(avId)
if wrong:
acts = ['slip-forward', 'slip-backward']
ag = random.choice(acts)
ag = choice(acts)
self.arrowDict[avId][0].hide()
self.animTracks[avId] = Sequence(Func(self.showX, avId), Func(self.colorStatusBall, avId, self.__otherToonIndex[avId], 0), ActorInterval(actor=av, animName=ag, duration=2.35), Func(av.loop, 'neutral'), Func(self.hideX, avId))
else:
@ -659,6 +686,7 @@ class DistributedPatternGame(DistributedMinigame):
arrowTrack = self.getDanceArrowAnimTrack(avId, [index], 1)
potTrack = self.getDanceSequenceAnimTrack(av, [index])
self.animTracks[avId] = Parallel(potTrack, arrowTrack)
self.__otherToonIndex[avId] += 1
self.animTracks[avId].start()
@ -668,13 +696,15 @@ class DistributedPatternGame(DistributedMinigame):
def __buttonPressed(self, index):
if len(self.__localPattern) >= len(self.__serverPattern):
return
if self.animTracks[self.localAvId]:
self.animTracks[self.localAvId].finish()
badd = 0
if index != self.__serverPattern[len(self.__localPattern)]:
badd = 1
acts = ['slip-forward', 'slip-backward']
ag = random.choice(acts)
ag = choice(acts)
self.animTracks[self.localAvId] = Sequence(Func(self.showX, 'lt'), Func(self.colorStatusBall, 'lt', len(self.__localPattern), 0), ActorInterval(actor=self.lt, animName=ag, duration=2.35), Func(self.lt.loop, 'neutral'), Func(self.hideX, 'lt'))
self.arrowDict['lt'][0].hide()
base.playSfx(self.fallSound)
@ -684,6 +714,7 @@ class DistributedPatternGame(DistributedMinigame):
arrowTrack = self.getDanceArrowAnimTrack('lt', [index], 1)
potTrack = self.getDanceSequenceAnimTrack(self.lt, [index])
self.animTracks[self.localAvId] = Parallel(potTrack, arrowTrack)
self.sendUpdate('reportButtonPress', [index, badd])
self.animTracks[self.localAvId].start()
self.__localPattern.append(index)
@ -692,7 +723,7 @@ class DistributedPatternGame(DistributedMinigame):
def __doneGettingInput(self, pattern):
self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS)
self.currentTotalTime = globalClock.getFrameTime() - self.currentStartTime
self.currentTotalTime = base.clock.getFrameTime() - self.currentStartTime
self.proceedTrack = Sequence(Wait(self.getDanceStepDuration()), Func(self.sendUpdate, 'reportPlayerPattern', [pattern, self.currentTotalTime]), Func(self.gameFSM.request, 'waitForPlayerPatterns'))
self.proceedTrack.start()
@ -703,8 +734,10 @@ class DistributedPatternGame(DistributedMinigame):
self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS)
if self.setupTrack and self.setupTrack.isPlaying():
self.setupTrack.pause()
if self.proceedTrack and self.proceedTrack.isPlaying():
self.proceedTrack.pause()
del self.setupTrack
del self.proceedTrack
self.__clearMinnieChat()
@ -715,6 +748,7 @@ class DistributedPatternGame(DistributedMinigame):
def setPlayerPatterns(self, pattern1, pattern2, pattern3, pattern4, fastestAvId):
if not self.hasLocalToon:
return
self.fastestAvId = fastestAvId
self.notify.debug('setPlayerPatterns:' + ' pattern1:' + str(pattern1) + ' pattern2:' + str(pattern2) + ' pattern3:' + str(pattern3) + ' pattern4:' + str(pattern4))
self.playerPatterns = {}
@ -738,6 +772,7 @@ class DistributedPatternGame(DistributedMinigame):
self.roundText['text'] = TTLocalizer.PatternGameFastest
else:
self.roundText['text'] = TTLocalizer.PatternGameFaster
jumpTrack = Sequence(ActorInterval(actor=self.lt, animName='jump', duration=1.7), Func(self.lt.loop, 'neutral'))
elif self.fastestAvId == 0:
if self.round == PatternGameGlobals.NUM_ROUNDS:
@ -745,6 +780,7 @@ class DistributedPatternGame(DistributedMinigame):
else:
self.roundText.setScale(0.1)
self.roundText['text'] = TTLocalizer.PatternGameYouCanDoIt
jumpTrack = Sequence(Wait(0.5), Wait(0.5))
elif self.fastestAvId == 1:
self.roundText.setScale(0.1)
@ -758,7 +794,9 @@ class DistributedPatternGame(DistributedMinigame):
rewardStr = TTLocalizer.PatternGameOtherFastest
else:
rewardStr = TTLocalizer.PatternGameOtherFaster
self.roundText['text'] = av.getName() + rewardStr
success = self.playerPatterns[self.localAvId] == self.__serverPattern
self.hideStatusBalls('lt')
for avId in self.remoteAvIdList:
@ -771,6 +809,7 @@ class DistributedPatternGame(DistributedMinigame):
self.perfectGame = 0
sound = self.incorrectSound
text = self.strWrong
soundTrack = Sequence(Func(base.playSfx, sound), Wait(1.6))
textTrack = Sequence(Wait(0.2), Func(self.__setMinnieChat, text, 0), Wait(1.3), Func(self.__clearMinnieChat))
self.playBackPatternsTrack = Sequence(Parallel(soundTrack, textTrack, jumpTrack), Func(self.gameFSM.request, 'checkGameOver'))
@ -779,6 +818,7 @@ class DistributedPatternGame(DistributedMinigame):
def exitPlayBackPatterns(self):
if self.playBackPatternsTrack.isPlaying():
self.playBackPatternsTrack.pause()
del self.playBackPatternsTrack
def enterCheckGameOver(self):
@ -794,17 +834,19 @@ class DistributedPatternGame(DistributedMinigame):
text = self.strPerfect
sound = self.perfectSound
delay = 2.2
if self.celebrate:
text = TTLocalizer.PatternGameImprov
self.__winTrack = Sequence(Func(self.__setMinnieChat, text, 1), Func(base.playSfx, self.perfectSound), Sequence(self.returnCelebrationIntervals(1)), Sequence(self.returnCelebrationIntervals(0)), Func(self.__clearMinnieChat), Func(self.gameOver))
else:
self.__winTrack = Sequence(Func(self.__setMinnieChat, text, 1), Func(base.playSfx, sound), Wait(delay), Func(self.__clearMinnieChat), Func(self.gameOver))
self.__winTrack.start()
return
def exitCheckGameOver(self):
if self.__winTrack and self.__winTrack.isPlaying():
self.__winTrack.pause()
del self.__winTrack
def enterCleanup(self):

View file

@ -1,30 +1,42 @@
from panda3d.core import *
from toontown.toonbase.ToonBaseGlobal import *
from direct.interval.IntervalGlobal import *
from .DistributedMinigame import *
from direct.gui.DirectGui import *
from panda3d.core import *
from direct.fsm import ClassicFSM, State
from direct.fsm import State
from toontown.toonbase import ToontownTimer
from toontown.toon import ToonHead
from toontown.suit import SuitDNA
from toontown.suit import Suit
from toontown.char import Char
from . import ArrowKeys
import random
from panda3d.core import RopeNode, VBase3
from panda3d.otp import NametagGlobals
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.fsm.ClassicFSM import ClassicFSM
from direct.fsm.State import State
from direct.gui.DirectGui import DGG, DirectLabel
from direct.interval.IntervalGlobal import (
ActorInterval,
Func,
LerpHprInterval,
LerpPosInterval,
LerpPosHprInterval,
Parallel,
Sequence,
Wait
)
from direct.showutil.Rope import Rope
from direct.task.TaskManagerGlobal import taskMgr
from toontown.effects.Ripples import Ripples
from toontown.effects.Splash import Splash
from toontown.minigame import TugOfWarGameGlobals
from toontown.minigame.ArrowKeys import ArrowKeys
from toontown.minigame.DistributedMinigame import DistributedMinigame
from toontown.minigame.MinigamePowerMeter import MinigamePowerMeter
from toontown.suit.Suit import Suit
from toontown.suit.SuitDNA import SuitDNA
from toontown.toonbase import ToontownGlobals
import string
from toontown.toonbase import TTLocalizer
from . import TugOfWarGameGlobals
from direct.showutil import Rope
from toontown.effects import Splash
from toontown.effects import Ripples
from toontown.toonbase import TTLocalizer
from . import MinigamePowerMeter
from direct.task.Task import Task
from toontown.toonbase.ToonBaseGlobal import base
from toontown.toonbase.ToontownTimer import ToontownTimer
import math
class DistributedTugOfWarGame(DistributedMinigame):
notify = directNotify.newCategory('DistributedTugOfWarGame')
bgm = 'phase_4/audio/bgm/MG_tug_o_war.ogg'
toonAnimNames = ['neutral',
'tug-o-war',
@ -46,11 +58,11 @@ class DistributedTugOfWarGame(DistributedMinigame):
def __init__(self, cr):
DistributedMinigame.__init__(self, cr)
self.gameFSM = ClassicFSM.ClassicFSM('DistributedTugOfWarGame', [State.State('off', self.enterOff, self.exitOff, ['waitForGoSignal']),
State.State('waitForGoSignal', self.enterWaitForGoSignal, self.exitWaitForGoSignal, ['tug', 'cleanup']),
State.State('tug', self.enterTug, self.exitTug, ['gameDone', 'cleanup']),
State.State('gameDone', self.enterGameDone, self.exitGameDone, ['cleanup']),
State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
self.gameFSM = ClassicFSM('DistributedTugOfWarGame', [State('off', self.enterOff, self.exitOff, ['waitForGoSignal']),
State('waitForGoSignal', self.enterWaitForGoSignal, self.exitWaitForGoSignal, ['tug', 'cleanup']),
State('tug', self.enterTug, self.exitTug, ['gameDone', 'cleanup']),
State('gameDone', self.enterGameDone, self.exitGameDone, ['cleanup']),
State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
self.addChildGameFSM(self.gameFSM)
self.gameType = TugOfWarGameGlobals.TOON_VS_TOON
self.suit = None
@ -92,13 +104,11 @@ class DistributedTugOfWarGame(DistributedMinigame):
for k in range(4):
self.drinkPositions.append(VBase3(-.2 + 0.2 * k, 16 + 2 * k, 0.0))
self.rng = RandomNumGen.RandomNumGen(1000)
self.introTrack = None
self.showTrack = None
self.setupTrack = None
self.animTracks = {}
self.randomNumGen = None
return
def getTitle(self):
return TTLocalizer.TugOfWarGameTitle
@ -112,40 +122,39 @@ class DistributedTugOfWarGame(DistributedMinigame):
def load(self):
self.notify.debug('load')
DistributedMinigame.load(self)
self.timer = ToontownTimer.ToontownTimer()
self.timer = ToontownTimer()
self.timer.posInTopRightCorner()
self.timer.hide()
self.room = loader.loadModel('phase_4/models/minigames/tug_of_war_dock')
self.room.reparentTo(hidden)
ropeModel = loader.loadModel('phase_4/models/minigames/tug_of_war_rope')
self.room = base.loader.loadModel('phase_4/models/minigames/tug_of_war_dock')
self.room.reparentTo(base.hidden)
ropeModel = base.loader.loadModel('phase_4/models/minigames/tug_of_war_rope')
self.ropeTexture = ropeModel.findTexture('*')
ropeModel.removeNode()
self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow')
self.sky = base.loader.loadModel('phase_3.5/models/props/TT_sky')
self.dropShadow = base.loader.loadModel('phase_3/models/props/drop_shadow')
self.correctSound = base.loader.loadSfx('phase_4/audio/sfx/MG_pos_buzzer.ogg')
self.sndHitWater = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_splash.ogg')
self.whistleSound = base.loader.loadSfx('phase_4/audio/sfx/AA_sound_whistle.ogg')
self.music = base.loader.loadMusic(self.bgm)
self.roundText = DirectLabel(text=' ', text_fg=(0, 1, 0, 1), frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0.014, 0, -.84), scale=0.2)
self.powerMeter = MinigamePowerMeter.MinigamePowerMeter(17)
self.powerMeter.reparentTo(aspect2d)
self.powerMeter = MinigamePowerMeter(17)
self.powerMeter.reparentTo(base.aspect2d)
self.powerMeter.setPos(0, 0, 0.4)
self.powerMeter.setPower(8)
self.powerMeter.setTarget(8)
self.arrows = [None] * 2
for x in range(len(self.arrows)):
self.arrows[x] = loader.loadModel('phase_3/models/props/arrow')
self.arrows[x] = base.loader.loadModel('phase_3/models/props/arrow')
self.arrows[x].reparentTo(self.powerMeter)
self.arrows[x].hide()
self.arrows[x].setScale(0.2 - 0.4 * x, 0.2, 0.2)
self.arrows[x].setPos(0.12 - 0.24 * x, 0, -.26)
self.disableArrow(self.arrows[x])
self.splash = Splash.Splash(render)
self.suitSplash = Splash.Splash(render)
self.ripples = Ripples.Ripples(render)
self.suitRipples = Ripples.Ripples(render)
return
self.splash = Splash(base.render)
self.suitSplash = Splash(base.render)
self.ripples = Ripples(base.render)
self.suitRipples = Ripples(base.render)
def toggleMouseMode(self, param):
self.mouseMode = not self.mouseMode
@ -155,6 +164,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.hilightArrow(self.arrows[1])
else:
self.hilightArrow(self.arrows[0])
self.__spawnMouseSpeedTask()
else:
self.__releaseHandler(0)
@ -183,6 +193,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.powerMeter:
self.powerMeter.destroy()
del self.powerMeter
for x in self.arrows:
if x:
x.removeNode()
@ -197,10 +208,12 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.ripples.stop()
self.ripples.detachNode()
del self.ripples
if self.suitRipples != None:
self.suitRipples.stop()
self.suitRipples.detachNode()
del self.suitRipples
for x in self.avList:
del x
@ -208,6 +221,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
for x in self.tugRopes:
if x != None:
x.detachNode()
del x
del self.tugRopes
@ -235,6 +249,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.suit:
self.suit.delete()
del self.suit
del self.sides
del self.buttons
del self.pullingDict
@ -245,26 +260,24 @@ class DistributedTugOfWarGame(DistributedMinigame):
del self.drinkPositions
del self.offsetDict
del self.keyTTL
del self.rng
return
def onstage(self):
self.notify.debug('onstage')
DistributedMinigame.onstage(self)
self.lt = base.localAvatar
NametagGlobals.setGlobalNametagScale(1)
self.arrowKeys = ArrowKeys.ArrowKeys()
self.room.reparentTo(render)
self.arrowKeys = ArrowKeys()
self.room.reparentTo(base.render)
self.room.setPosHpr(0.0, 18.39, -ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0)
self.room.setScale(0.4)
self.sky.setZ(-5)
self.sky.reparentTo(render)
self.sky.reparentTo(base.render)
self.dropShadow.setColor(0, 0, 0, 0.5)
camera.reparentTo(render)
camera.setPosHpr(-11.4427, 9.03559, 2.80094, -49.104, -0.89, 0)
base.camera.reparentTo(base.render)
base.camera.setPosHpr(-11.4427, 9.03559, 2.80094, -49.104, -0.89, 0)
self.dropShadow.setBin('fixed', 0, 1)
self.splash.reparentTo(render)
self.suitSplash.reparentTo(render)
self.splash.reparentTo(base.render)
self.suitSplash.reparentTo(base.render)
base.playMusic(self.music, looping=1, volume=1)
for x in range(len(self.arrows)):
self.arrows[x].show()
@ -280,20 +293,24 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.introTrack.finish()
del self.introTrack
self.introTrack = None
for track in list(self.animTracks.values()):
if track:
track.finish()
del track
self.animTracks = {}
if self.showTrack:
self.showTrack.finish()
del self.showTrack
self.showTrack = None
if self.setupTrack:
self.setupTrack.finish()
del self.setupTrack
self.setupTrack = None
base.camLens.setFov(ToontownGlobals.DefaultCameraFov)
base.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar)
NametagGlobals.setGlobalNametagScale(1.0)
@ -303,13 +320,14 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.arrowKeys.destroy()
del self.arrowKeys
self.arrowKeys = None
self.room.reparentTo(hidden)
self.sky.reparentTo(hidden)
self.splash.reparentTo(hidden)
self.room.reparentTo(base.hidden)
self.sky.reparentTo(base.hidden)
self.splash.reparentTo(base.hidden)
self.splash.stop()
self.suitSplash.reparentTo(hidden)
self.suitSplash.reparentTo(base.hidden)
self.suitSplash.stop()
self.ripples.reparentTo(hidden)
self.ripples.reparentTo(base.hidden)
self.ripples.stop()
self.hideControls()
self.roundText.hide()
@ -322,42 +340,36 @@ class DistributedTugOfWarGame(DistributedMinigame):
for x in self.tugRopes:
if x != None:
x.reparentTo(hidden)
x.reparentTo(base.hidden)
if self.suit:
self.suit.reparentTo(hidden)
self.suit.reparentTo(base.hidden)
for avId in self.avIdList:
if avId in self.dropShadowDict:
self.dropShadowDict[avId].reparentTo(hidden)
self.dropShadowDict[avId].reparentTo(base.hidden)
if self.suitId in self.dropShadowDict:
self.dropShadowDict[self.suitId].reparentTo(hidden)
return
self.dropShadowDict[self.suitId].reparentTo(base.hidden)
def initCamera(self):
birdseyePosHpr = [1.95461,
18.4891,
38.4646,
1.18185,
-87.5308,
0]
introPosHpr = [None] * 2
introPosHpr[0] = [VBase3(-11.4427, 9.03559, 2.80094), VBase3(-49.104, -0.732374, 0)]
introPosHpr[1] = [VBase3(16.9291, 13.9302, 2.64282), VBase3(66.9685, -6.195, 0)]
gameCamHpr = VBase3(-1.13, 1.042, 0)
gameCamPos = VBase3(0, 1.0838, 2.745)
camera.reparentTo(render)
camera.setPosHpr(introPosHpr[self.sides[self.localAvId]][0], introPosHpr[self.sides[self.localAvId]][1])
base.camera.reparentTo(base.render)
base.camera.setPosHpr(introPosHpr[self.sides[self.localAvId]][0], introPosHpr[self.sides[self.localAvId]][1])
lerpDur = 8
self.introTrack = LerpPosHprInterval(camera, lerpDur, pos=gameCamPos, hpr=gameCamHpr, blendType='easeInOut', name=self.uniqueName('introLerpCameraPos'))
self.introTrack = LerpPosHprInterval(base.camera, lerpDur, pos=gameCamPos, hpr=gameCamHpr, blendType='easeInOut', name=self.uniqueName('introLerpCameraPos'))
self.introTrack.start()
base.camLens.setFov(60 + 2 * self.numPlayers)
base.camLens.setFar(450.0)
return
def sendGameType(self, index, suit):
if not self.hasLocalToon:
return
self.gameType = index
self.suitLevel = suit
if suit == 1:
@ -372,9 +384,11 @@ class DistributedTugOfWarGame(DistributedMinigame):
def setGameReady(self):
if not self.hasLocalToon:
return
self.notify.debug('setGameReady')
if DistributedMinigame.setGameReady(self):
return
self.initToons()
self.createSuits()
self.calculatePositions()
@ -389,7 +403,6 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.showTrack = None
self.setupTrack = None
self.__initGameVars()
return
def hideControls(self):
for x in range(len(self.arrows)):
@ -397,40 +410,39 @@ class DistributedTugOfWarGame(DistributedMinigame):
for rope in self.tugRopes:
if rope != None:
rope.reparentTo(hidden)
rope.reparentTo(base.hidden)
for tex in self.ropeTex:
if tex != None:
for texi in tex:
if texi:
texi.reparentTo(hidden)
texi.reparentTo(base.hidden)
if self.powerMeter != None:
self.powerMeter.unbind(DGG.B1PRESS)
self.powerMeter.unbind(DGG.B1RELEASE)
self.powerMeter.hide()
return
def setUpRopes(self, notTaut):
if self.numPlayers == 1:
suitRightHand = self.suit.getRightHand()
toonRightHand = self.rightHandDict[self.avIdList[0]]
if notTaut:
self.tugRopes[0].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
self.tugRopes[0].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
else:
midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0
self.tugRopes[0].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
elif self.numPlayers == 2:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0,
@ -442,25 +454,25 @@ class DistributedTugOfWarGame(DistributedMinigame):
suitRightHand = self.suit.getRightHand()
toonRightHand = self.rightHandDict[self.avIdList[1]]
if notTaut:
self.tugRopes[1].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
self.tugRopes[1].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
else:
midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0
self.tugRopes[1].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[1].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
self.tugRopes[1].reparentTo(base.render)
else:
if notTaut:
self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (render, (0, 18, -1)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0,
self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (base.render, (0, 18, -1)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0,
0,
0,
1,
@ -473,7 +485,8 @@ class DistributedTugOfWarGame(DistributedMinigame):
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
elif self.numPlayers == 3:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0,
@ -491,26 +504,26 @@ class DistributedTugOfWarGame(DistributedMinigame):
suitRightHand = self.suit.getRightHand()
toonRightHand = self.rightHandDict[self.avIdList[2]]
if notTaut:
self.tugRopes[2].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
self.tugRopes[2].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
else:
midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0
self.tugRopes[2].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[1].reparentTo(render)
self.tugRopes[2].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
self.tugRopes[1].reparentTo(base.render)
self.tugRopes[2].reparentTo(base.render)
else:
if notTaut:
self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0,
self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (base.render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0,
0,
0,
1,
@ -523,14 +536,15 @@ class DistributedTugOfWarGame(DistributedMinigame):
1,
1,
1])
self.tugRopes[0].setup(3, ((self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[0]], (0, 0, 0)), (self.rightHandDict[self.avIdList[1]], (0, 0, 0))), [0,
0,
0,
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[1].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
self.tugRopes[1].reparentTo(base.render)
elif self.numPlayers == 4:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.tugRopes[2].setup(3, ((self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[3]], (0, 0, 0))), [0,
@ -554,24 +568,24 @@ class DistributedTugOfWarGame(DistributedMinigame):
suitRightHand = self.suit.getRightHand()
toonRightHand = self.rightHandDict[self.avIdList[3]]
if notTaut:
self.tugRopes[3].setup(3, ((toonRightHand, (0, 0, 0)), (render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
self.tugRopes[3].setup(3, ((toonRightHand, (0, 0, 0)), (base.render, (0, 18, -1)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
else:
midPt = (suitRightHand.getPos() - toonRightHand.getPos()) / 2.0
self.tugRopes[3].setup(3, ((toonRightHand, (0, 0, 0)), (toonRightHand, (0, 0, 0)), (suitRightHand, (0, 0, 0))), [0,
0,
0,
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[1].reparentTo(render)
self.tugRopes[2].reparentTo(render)
self.tugRopes[3].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
self.tugRopes[1].reparentTo(base.render)
self.tugRopes[2].reparentTo(base.render)
self.tugRopes[3].reparentTo(base.render)
else:
self.tugRopes[2].setup(3, ((self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0)), (self.rightHandDict[self.avIdList[3]], (0, 0, 0))), [0,
0,
@ -586,7 +600,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
1,
1])
if notTaut:
self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0,
self.tugRopes[1].setup(3, ((self.rightHandDict[self.avIdList[1]], (0, 0, 0)), (base.render, (0, 18, -1)), (self.rightHandDict[self.avIdList[2]], (0, 0, 0))), [0,
0,
0,
1,
@ -599,15 +613,16 @@ class DistributedTugOfWarGame(DistributedMinigame):
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[1].reparentTo(render)
self.tugRopes[2].reparentTo(render)
self.tugRopes[0].reparentTo(base.render)
self.tugRopes[1].reparentTo(base.render)
self.tugRopes[2].reparentTo(base.render)
def initToons(self):
for avId in self.avIdList:
toon = self.getAvatar(avId)
if toon:
toon.reparentTo(render)
toon.reparentTo(base.render)
toon.useLOD(1000)
toon.startBlink()
toon.startLookAround()
@ -618,7 +633,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.rightHandDict[avId] = toon.getRightHands()[0]
toon.loop('neutral')
toon.dropShadow.hide()
self.dropShadowDict[avId] = self.dropShadow.copyTo(hidden)
self.dropShadowDict[avId] = self.dropShadow.copyTo(base.hidden)
self.dropShadowDict[avId].reparentTo(toon)
self.dropShadowDict[avId].setScale(0.35)
@ -696,6 +711,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.hprDict[self.avIdList[1]] = hprPositions[0]
self.hprDict[self.avIdList[2]] = hprPositions[1]
self.hprDict[self.avIdList[3]] = hprPositions[1]
for x in self.avIdList:
self.offsetDict[x] = 0
if self.posDict[x][0] < 0:
@ -741,9 +757,11 @@ class DistributedTugOfWarGame(DistributedMinigame):
def setGameStart(self, timestamp):
if not self.hasLocalToon:
return
self.notify.debug('setGameStart')
if not self.__playing():
return
DistributedMinigame.setGameStart(self, timestamp)
self.gameFSM.request('waitForGoSignal')
@ -751,7 +769,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
pass
def makeToonLookatCamera(self, toon):
toon.headsUp(camera)
toon.headsUp(base.camera)
def setText(self, t, newtext):
t['text'] = newtext
@ -788,6 +806,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.notify.debug('exitTug')
if self.suit:
self.suit.loop('neutral')
self.timer.stop()
self.timer.hide()
taskMgr.remove(self.taskName('tug-timeout'))
@ -828,7 +847,8 @@ class DistributedTugOfWarGame(DistributedMinigame):
def __updateKeyPressRateTask(self, task):
if self.gameFSM.getCurrentState().getName() != 'tug':
return Task.done
return task.done
for i in range(len(self.keyTTL)):
self.keyTTL[i] -= 0.1
@ -844,18 +864,20 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.rateMatchAward += 0.3
else:
self.rateMatchAward = 0
self.__spawnUpdateKeyPressRateTask()
return Task.done
return task.done
def __updateTimerTask(self, task):
if self.gameFSM.getCurrentState().getName() != 'tug':
return Task.done
return task.done
self.currentForce = self.computeForce(self.keyRate)
self.sendUpdate('reportCurrentKeyRate', [self.keyRate, self.currentForce])
self.setSpeedGauge()
self.setAnimState(self.localAvId, self.keyRate)
self.__spawnUpdateTimerTask()
return Task.done
return task.done
def __spawnUpdateTimerTask(self):
taskMgr.remove(self.taskName(self.UPDATE_TIMER_TASK))
@ -881,10 +903,12 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.nextRateIndex < len(self.targetRateList):
if self.nextRateIndex == len(self.targetRateList) - 1:
self.allOutMode = 1
self.idealRate = self.targetRateList[self.nextRateIndex][1]
self.idealForce = self.advantage * (4 + 0.4 * self.idealRate)
taskMgr.doMethodLater(self.targetRateList[self.nextRateIndex][0], self.__updateIdealRateTask, self.taskName('targetRateTimer'))
return Task.done
return task.done
def __killUpdateIdealRateTask(self):
taskMgr.remove(self.taskName('targetRateTimer'))
@ -892,14 +916,14 @@ class DistributedTugOfWarGame(DistributedMinigame):
def sendGoSignal(self, index):
if not self.hasLocalToon:
return
self.notify.debug('sendGoSignal')
self.buttons = index
self.setupTrack = None
self.showTrack = None
def startTimer(self = self):
self.currentStartTime = int(globalClock.getFrameTime() * 1000)
time = 10
self.currentStartTime = int(base.clock.getFrameTime() * 1000)
self.timer.show()
self.timer.setTime(TugOfWarGameGlobals.GAME_DURATION)
self.timer.countdown(TugOfWarGameGlobals.GAME_DURATION, self.__gameTimerExpired)
@ -926,13 +950,14 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.introTrack != None:
self.introTrack.finish()
self.introTrack = None
self.setupTrack = Sequence(Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameReady), Wait(1.5), Func(base.playSfx, self.whistleSound), Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameGo), Func(self.roundText.setScale, 0.3), Wait(1.5), Func(startTimer), Func(enableKeys), Func(self.gameFSM.request, 'tug'), Func(self.setText, self.roundText, ' '), Func(self.roundText.setScale, 0.2))
self.setupTrack.start()
return
def sendStopSignal(self, winners, losers, tieers):
if not self.hasLocalToon:
return
self.notify.debug('sendStopSignal')
self.gameFSM.request('gameDone')
self.hideControls()
@ -941,6 +966,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
suitSlipTime = 0
if self.gameFSM.getCurrentState().getName() == 'cleanup' or not self.randomNumGen:
return
if self.suit:
if self.suitId in winners:
newPos = VBase3(2.65, 18, 0.1)
@ -959,6 +985,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
destHpr = startHpr + VBase3(0, 0, -30)
oopsTrack = Sequence(Parallel(Func(self.suit.play, 'flail', None, 26, 38), LerpHprInterval(self.suit, 0.5, destHpr, startHpr=startHpr)), Parallel(Func(self.suit.play, 'slip-forward'), LerpPosInterval(self.suit, duration=1, pos=waterPos), Sequence(Wait(0.55), Func(base.playSfx, self.sndHitWater), Func(self.suitSplash.play), Func(self.ripples.play))))
reactSeq.append(Sequence(Func(self.suit.loop, 'victory'), Wait(2.6), LerpPosInterval(self.suit, duration=2, pos=newPos), oopsTrack, Func(self.suit.loop, 'neutral')))
for avId in self.avIdList:
toon = self.getAvatar(avId)
toon.loop('neutral')
@ -978,6 +1005,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
else:
exitSeq.append(Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameTie))
exitSeq.append(Wait(2.5))
exitSeq.append(Func(self.gameOver))
self.showTrack = Parallel(reactSeq, exitSeq)
for x in list(self.animTracks.values()):
@ -988,27 +1016,31 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.arrowKeys:
self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS)
self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS)
return
def remoteKeyRateUpdate(self, avId, keyRate):
if not self.hasLocalToon:
return
if avId != self.localAvId:
self.setAnimState(avId, keyRate)
def sendSuitPosition(self, suitOffset):
if not self.hasLocalToon:
return
if self.gameFSM.getCurrentState().getName() != 'tug':
return
self.suitOffset = suitOffset
self.moveSuits()
def sendCurrentPosition(self, avIdList, offsetList):
if not self.hasLocalToon:
return
if self.gameFSM.getCurrentState().getName() != 'tug':
return
for i in range(len(avIdList)):
self.offsetDict[avIdList[i]] = offsetList[i]
@ -1017,20 +1049,20 @@ class DistributedTugOfWarGame(DistributedMinigame):
def createSuits(self):
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.suit = Suit.Suit()
self.suit = Suit()
self.origSuitPosHpr = [VBase3(6.0, 18, 0.1), VBase3(120, 0, 0)]
self.suitOffset = 0
d = SuitDNA.SuitDNA()
d = SuitDNA()
d.newSuit(self.suitType)
self.suit.setDNA(d)
self.suit.reparentTo(render)
self.suit.reparentTo(base.render)
self.suit.setPos(self.origSuitPosHpr[0])
self.suit.setHpr(self.origSuitPosHpr[1])
for anim in self.suitAnimNames:
self.suit.pose(anim, 0)
self.suit.pose('tug-o-war', 0)
self.dropShadowDict[self.suitId] = self.dropShadow.copyTo(hidden)
self.dropShadowDict[self.suitId] = self.dropShadow.copyTo(base.hidden)
self.dropShadowDict[self.suitId].reparentTo(self.suit)
self.dropShadowDict[self.suitId].setScale(0.45)
@ -1040,11 +1072,13 @@ class DistributedTugOfWarGame(DistributedMinigame):
toon = self.getAvatar(self.avList[0][0])
if self.avList[0][0] == self.localAvId:
self.advantage = 2.0
toon.applyCheesyEffect(ToontownGlobals.CEBigHead)
elif len(self.avList[1]) == 1:
toon = self.getAvatar(self.avList[1][0])
if self.avList[1][0] == self.localAvId:
self.advantage = 2.0
toon.applyCheesyEffect(ToontownGlobals.CEBigHead)
def setSpeedGauge(self):
@ -1052,12 +1086,14 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.powerMeter.setTarget(self.idealRate)
if not self.allOutMode:
self.powerMeter.updateTooSlowTooFast()
if not self.allOutMode:
index = float(self.currentForce) / self.idealForce
bonus = 0.0
if index > 1:
bonus = max(1, index - 1)
index = 1
color = (0,
0.75 * index + 0.25 * bonus,
0.75 * (1 - index),
@ -1069,10 +1105,12 @@ class DistributedTugOfWarGame(DistributedMinigame):
def setAnimState(self, avId, keyRate):
if self.gameFSM.getCurrentState().getName() != 'tug':
return
toon = self.getAvatar(avId)
if keyRate > 0 and self.pullingDict[avId] == 0:
toon.loop('tug-o-war')
self.pullingDict[avId] = 1
if keyRate <= 0 and self.pullingDict[avId] == 1:
toon.pose('tug-o-war', 3)
toon.startLookAround()
@ -1081,6 +1119,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
def moveSuits(self):
if self.gameType != TugOfWarGameGlobals.TOON_VS_COG:
return
origPos = self.origSuitPosHpr[0]
curPos = self.suit.getPos()
newPos = VBase3(origPos[0] + self.suitOffset, curPos[1], curPos[2])
@ -1088,10 +1127,10 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.animTracks[self.suitId].isPlaying():
self.animTracks[self.suitId].finish()
self.checkIfFallen()
if self.suitId not in self.fallenList:
self.animTracks[self.suitId] = Sequence(LerpPosInterval(self.suit, duration=TugOfWarGameGlobals.SEND_UPDATE, pos=newPos), Func(self.checkIfFallen))
self.animTracks[self.suitId].start()
return
def moveToons(self):
for avId in self.avIdList:
@ -1105,12 +1144,11 @@ class DistributedTugOfWarGame(DistributedMinigame):
if self.animTracks[avId].isPlaying():
self.animTracks[avId].finish()
self.checkIfFallen(avId)
if avId not in self.fallenList:
self.animTracks[avId] = Sequence(LerpPosInterval(toon, duration=TugOfWarGameGlobals.SEND_UPDATE, pos=newPos), Func(self.checkIfFallen, avId))
self.animTracks[avId].start()
return
def checkIfFallen(self, avId = None):
if avId == None:
if self.suitId not in self.fallenList:
@ -1132,7 +1170,6 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.throwInWater(avId)
self.sendUpdate('reportEndOfContest', [losingSide])
return
def throwInWater(self, avId = None):
if avId == None:
@ -1140,7 +1177,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
waterPos = self.drinkPositions.pop()
newPos = VBase3(waterPos[0], waterPos[1], waterPos[2] - self.suit.getHeight() / 1.5)
self.suit.loop('neutral')
self.dropShadowDict[self.suitId].reparentTo(hidden)
self.dropShadowDict[self.suitId].reparentTo(base.hidden)
loser = self.suit
animId = self.suitId
else:
@ -1149,19 +1186,20 @@ class DistributedTugOfWarGame(DistributedMinigame):
waterPos = self.drinkPositions.pop()
newPos = VBase3(waterPos[0], waterPos[1], waterPos[2] - toon.getHeight())
toon.loop('neutral')
self.dropShadowDict[avId].reparentTo(hidden)
self.dropShadowDict[avId].reparentTo(base.hidden)
loser = toon
animId = avId
if self.animTracks[animId] != None:
if self.animTracks[animId].isPlaying():
self.animTracks[animId].finish()
self.splash.setPos(newPos[0], newPos[1], -1.8)
self.splash.setScale(2.5, 2.5, 1)
self.ripples.setPos(newPos[0], newPos[1], -1.7)
self.ripples.setScale(1, 1, 1)
self.animTracks[animId] = Sequence(Parallel(ActorInterval(actor=loser, animName='slip-forward', duration=2.0), LerpPosInterval(loser, duration=2.0, pos=newPos), Sequence(Wait(1.0), Parallel(Func(base.playSfx, self.sndHitWater), Func(self.splash.play), Func(self.ripples.play)))), Func(loser.loop, 'neutral'))
self.animTracks[animId].start()
return
def computeForce(self, keyRate):
F = 0
@ -1170,6 +1208,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
else:
stdDev = 0.25 * self.idealRate
F = self.advantage * (self.rateMatchAward + 4 + 0.4 * self.idealRate) * math.pow(math.e, -math.pow(keyRate - self.idealRate, 2) / (2.0 * math.pow(stdDev, 2)))
return F
def initRopes(self):
@ -1177,8 +1216,9 @@ class DistributedTugOfWarGame(DistributedMinigame):
numRopes = self.numPlayers
else:
numRopes = self.numPlayers - 1
for x in range(0, numRopes):
rope = Rope.Rope(self.uniqueName('TugRope' + str(x)))
rope = Rope(self.uniqueName('TugRope' + str(x)))
if rope.showRope:
rope.ropeNode.setRenderMode(RopeNode.RMBillboard)
rope.ropeNode.setThickness(0.2)
@ -1187,6 +1227,7 @@ class DistributedTugOfWarGame(DistributedMinigame):
rope.ropeNode.setUvDirection(1)
rope.setTransparency(1)
rope.setColor(0.89, 0.89, 0.6, 1)
self.tugRopes.append(rope)
self.setUpRopes(1)
@ -1203,18 +1244,18 @@ class DistributedTugOfWarGame(DistributedMinigame):
for j in range(len(self.ropePts[i])):
self.ropeTex[i][j].setPos(self.ropePts[i][j])
return Task.cont
return task.cont
def __killUpdateRopeTask(self):
taskMgr.remove(self.taskName(self.UPDATE_ROPE_TASK))
def tugTimeoutTask(self, task):
self.gameOver()
return Task.done
return task.done
def waitForGoTimeoutTask(self, task):
self.gameOver()
return Task.done
return task.done
def __spawnMouseSpeedTask(self):
taskMgr.remove(self.taskName('mouseSpeed'))
@ -1227,7 +1268,6 @@ class DistributedTugOfWarGame(DistributedMinigame):
dx = 0.1
if self.mouseMode:
mx = base.mouseWatcherNode.getMouseX()
my = base.mouseWatcherNode.getMouseY()
if self.mouseSide == 0:
if mx > dx:
self.mouseSide = 1
@ -1242,4 +1282,5 @@ class DistributedTugOfWarGame(DistributedMinigame):
self.__pressHandler(1)
elif mx < dx:
self.__releaseHandler(0)
return Task.cont
return task.cont