From 03c45eedb0af7ed2caca00320f19f76e78b5657e Mon Sep 17 00:00:00 2001 From: Open Toontown <57279094+opentoontown@users.noreply.github.com> Date: Sat, 29 Apr 2023 22:20:11 -0400 Subject: [PATCH] fix some broken minigames --- toontown/minigame/DistributedCannonGame.py | 287 +++++++++-------- toontown/minigame/DistributedPatternGame.py | 150 +++++---- toontown/minigame/DistributedTugOfWarGame.py | 307 +++++++++++-------- 3 files changed, 437 insertions(+), 307 deletions(-) diff --git a/toontown/minigame/DistributedCannonGame.py b/toontown/minigame/DistributedCannonGame.py index 8b75fac..8c46021 100644 --- a/toontown/minigame/DistributedCannonGame.py +++ b/toontown/minigame/DistributedCannonGame.py @@ -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 diff --git a/toontown/minigame/DistributedPatternGame.py b/toontown/minigame/DistributedPatternGame.py index 286ea7e..7e7420c 100644 --- a/toontown/minigame/DistributedPatternGame.py +++ b/toontown/minigame/DistributedPatternGame.py @@ -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): diff --git a/toontown/minigame/DistributedTugOfWarGame.py b/toontown/minigame/DistributedTugOfWarGame.py index 7530efe..2dcae83 100644 --- a/toontown/minigame/DistributedTugOfWarGame.py +++ b/toontown/minigame/DistributedTugOfWarGame.py @@ -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