oldschool-toontown/toontown/minigame/DistributedTugOfWarGame.py
2020-01-14 14:28:52 -05:00

1245 lines
49 KiB
Python

from pandac.PandaModules import *
from toontown.toonbase.ToonBaseGlobal import *
from direct.interval.IntervalGlobal import *
from .DistributedMinigame import *
from direct.gui.DirectGui import *
from pandac.PandaModules 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 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
class DistributedTugOfWarGame(DistributedMinigame):
bgm = 'phase_4/audio/bgm/MG_tug_o_war.ogg'
toonAnimNames = ['neutral',
'tug-o-war',
'slip-forward',
'slip-backward',
'victory',
'sad-neutral']
suitAnimNames = ['neutral',
'tug-o-war',
'slip-forward',
'slip-backward',
'flail',
'victory']
UPDATE_TIMER_TASK = 'TugOfWarGameUpdateTimerTask'
UPDATE_KEY_PRESS_RATE_TASK = 'TugOfWarGameUpdateKeyPressRateTask'
UPDATE_ROPE_TASK = 'TugOfWarGameUpdateRopeTask'
H_TO_L = 0
L_TO_H = 1
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.addChildGameFSM(self.gameFSM)
self.gameType = TugOfWarGameGlobals.TOON_VS_TOON
self.suit = None
self.suitId = 666
self.suitType = 'f'
self.suitLevel = 1
self.sides = {}
self.avList = [[], []]
self.buttons = [0, 1]
self.mouseMode = 0
self.mouseSide = 0
self.fallenList = []
self.handycap = 2.0
self.advantage = 1.0
self.tugRopes = []
self.ropePts = []
self.ropeTex = []
self.rightHandDict = {}
self.posDict = {}
self.hprDict = {}
self.offsetDict = {}
self.pullingDict = {}
self.dropShadowDict = {}
self.arrowKeys = None
self.keyTTL = []
self.idealRate = 2.0
self.idealForce = 0.0
self.keyRate = 0
self.allOutMode = 0
self.rateMatchAward = 0
self.targetRateList = [[8, 6],
[5, 7],
[6, 8],
[6, 10],
[7, 11],
[8, 12]]
self.nextRateIndex = 0
self.drinkPositions = []
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
def getInstructions(self):
return TTLocalizer.TugOfWarInstructions
def getMaxDuration(self):
return TugOfWarGameGlobals.GAME_DURATION
def load(self):
self.notify.debug('load')
DistributedMinigame.load(self)
self.timer = ToontownTimer.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.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.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.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].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
def toggleMouseMode(self, param):
self.mouseMode = not self.mouseMode
if self.mouseMode:
mpos = param.getMouse()
if mpos[0] < 0:
self.hilightArrow(self.arrows[1])
else:
self.hilightArrow(self.arrows[0])
self.__spawnMouseSpeedTask()
else:
self.__releaseHandler(0)
self.__releaseHandler(1)
self.__killMouseSpeedTask()
def unload(self):
self.notify.debug('unload')
DistributedMinigame.unload(self)
del self.lt
self.timer.destroy()
del self.timer
self.room.removeNode()
del self.room
self.sky.removeNode()
del self.sky
del self.dropShadowDict
self.dropShadow.removeNode()
del self.dropShadow
del self.correctSound
del self.sndHitWater
del self.whistleSound
del self.music
self.roundText.destroy()
del self.roundText
if self.powerMeter:
self.powerMeter.destroy()
del self.powerMeter
for x in self.arrows:
if x:
x.removeNode()
del x
del self.arrows
self.splash.destroy()
del self.splash
self.suitSplash.destroy()
del self.suitSplash
if self.ripples != None:
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
del self.avList
for x in self.tugRopes:
if x != None:
x.detachNode()
del x
del self.tugRopes
for x in self.ropePts:
if x:
for t in x:
del t
del x
del self.ropePts
for x in self.ropeTex:
if x:
for t in x:
t.destroy()
del t
del x
del self.ropeTex
del self.posDict
del self.hprDict
self.removeChildGameFSM(self.gameFSM)
del self.gameFSM
if self.suit:
self.suit.delete()
del self.suit
del self.sides
del self.buttons
del self.pullingDict
del self.rightHandDict
for x in self.drinkPositions:
del x
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.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.dropShadow.setColor(0, 0, 0, 0.5)
camera.reparentTo(render)
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)
base.playMusic(self.music, looping=1, volume=1)
for x in range(len(self.arrows)):
self.arrows[x].show()
for avId in self.avIdList:
self.pullingDict[avId] = 0
def offstage(self):
self.notify.debug('offstage')
DistributedMinigame.offstage(self)
self.music.stop()
if self.introTrack:
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)
if self.arrowKeys:
self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS)
self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS)
self.arrowKeys.destroy()
del self.arrowKeys
self.arrowKeys = None
self.room.reparentTo(hidden)
self.sky.reparentTo(hidden)
self.splash.reparentTo(hidden)
self.splash.stop()
self.suitSplash.reparentTo(hidden)
self.suitSplash.stop()
self.ripples.reparentTo(hidden)
self.ripples.stop()
self.hideControls()
self.roundText.hide()
for avId in self.avIdList:
av = self.getAvatar(avId)
if av:
av.loop('neutral')
av.resetLOD()
av.dropShadow.show()
for x in self.tugRopes:
if x != None:
x.reparentTo(hidden)
if self.suit:
self.suit.reparentTo(hidden)
for avId in self.avIdList:
if avId in self.dropShadowDict:
self.dropShadowDict[avId].reparentTo(hidden)
if self.suitId in self.dropShadowDict:
self.dropShadowDict[self.suitId].reparentTo(hidden)
return
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])
lerpDur = 8
self.introTrack = LerpPosHprInterval(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:
self.suitType = 'pp'
elif suit == 2:
self.suitType = 'dt'
elif suit == 3:
self.suitType = 'gh'
elif suit == 4:
self.suitType = 'cr'
def setGameReady(self):
if not self.hasLocalToon:
return
self.notify.debug('setGameReady')
if DistributedMinigame.setGameReady(self):
return
self.initToons()
self.createSuits()
self.calculatePositions()
self.initHandycaps()
self.initRopes()
self.initCamera()
self.animTracks = {}
for avId in self.avIdList:
self.animTracks[avId] = None
self.animTracks[self.suitId] = None
self.showTrack = None
self.setupTrack = None
self.__initGameVars()
return
def hideControls(self):
for x in range(len(self.arrows)):
self.arrows[x].hide()
for rope in self.tugRopes:
if rope != None:
rope.reparentTo(hidden)
for tex in self.ropeTex:
if tex != None:
for texi in tex:
if texi:
texi.reparentTo(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,
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)
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,
0,
0,
1,
1,
1])
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,
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)
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,
0,
0,
1,
1,
1])
else:
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)
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,
0,
0,
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])
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,
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)
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,
0,
0,
1,
1,
1])
else:
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,
0,
0,
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)
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,
0,
0,
1,
1,
1])
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,
0,
0,
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])
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,
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)
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,
0,
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])
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,
0,
0,
1,
1,
1])
else:
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,
0,
0,
1,
1,
1])
self.tugRopes[0].reparentTo(render)
self.tugRopes[1].reparentTo(render)
self.tugRopes[2].reparentTo(render)
def initToons(self):
for avId in self.avIdList:
toon = self.getAvatar(avId)
if toon:
toon.reparentTo(render)
toon.useLOD(1000)
toon.startBlink()
toon.startLookAround()
for anim in self.toonAnimNames:
toon.pose(anim, 0)
toon.pose('tug-o-war', 3)
self.rightHandDict[avId] = toon.getRightHands()[0]
toon.loop('neutral')
toon.dropShadow.hide()
self.dropShadowDict[avId] = self.dropShadow.copyTo(hidden)
self.dropShadowDict[avId].reparentTo(toon)
self.dropShadowDict[avId].setScale(0.35)
def calculatePositions(self):
hprPositions = [VBase3(240, 0, 0), VBase3(120, 0, 0)]
dockPositions = []
for k in range(5):
dockPositions.append(VBase3(-9.0 + 1.5 * k, 18, 0.1))
for k in range(5):
dockPositions.append(VBase3(3 + 1.5 * k, 18, 0.1))
self.sendUpdate('sendNewAvIdList', [self.avIdList])
if self.numPlayers == 1:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.posDict[self.suitId] = dockPositions[7]
self.posDict[self.avIdList[0]] = dockPositions[2]
self.hprDict[self.avIdList[0]] = hprPositions[0]
else:
self.notify.warning("can't play toon vs. toon with one player")
elif self.numPlayers == 2:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.arrangeByHeight(self.avIdList, self.H_TO_L, 0, 1)
self.posDict[self.suitId] = dockPositions[7]
self.posDict[self.avIdList[0]] = dockPositions[1]
self.posDict[self.avIdList[1]] = dockPositions[2]
self.hprDict[self.avIdList[0]] = hprPositions[0]
self.hprDict[self.avIdList[1]] = hprPositions[0]
else:
self.randomNumGen.shuffle(self.avIdList)
self.posDict[self.avIdList[0]] = dockPositions[2]
self.posDict[self.avIdList[1]] = dockPositions[7]
self.hprDict[self.avIdList[0]] = hprPositions[0]
self.hprDict[self.avIdList[1]] = hprPositions[1]
elif self.numPlayers == 3:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.arrangeByHeight(self.avIdList, self.H_TO_L, 0, 2)
self.posDict[self.suitId] = dockPositions[7]
self.posDict[self.avIdList[0]] = dockPositions[0]
self.posDict[self.avIdList[1]] = dockPositions[1]
self.posDict[self.avIdList[2]] = dockPositions[2]
self.hprDict[self.avIdList[0]] = hprPositions[0]
self.hprDict[self.avIdList[1]] = hprPositions[0]
self.hprDict[self.avIdList[2]] = hprPositions[0]
else:
self.randomNumGen.shuffle(self.avIdList)
self.arrangeByHeight(self.avIdList, self.H_TO_L, 0, 1)
self.posDict[self.avIdList[0]] = dockPositions[1]
self.posDict[self.avIdList[1]] = dockPositions[2]
self.posDict[self.avIdList[2]] = dockPositions[7]
self.hprDict[self.avIdList[0]] = hprPositions[0]
self.hprDict[self.avIdList[1]] = hprPositions[0]
self.hprDict[self.avIdList[2]] = hprPositions[1]
elif self.numPlayers == 4:
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.arrangeByHeight(self.avIdList, self.H_TO_L, 0, 3)
self.posDict[self.suitId] = dockPositions[6]
self.posDict[self.avIdList[0]] = dockPositions[0]
self.posDict[self.avIdList[1]] = dockPositions[1]
self.posDict[self.avIdList[2]] = dockPositions[2]
self.posDict[self.avIdList[3]] = dockPositions[3]
self.hprDict[self.avIdList[0]] = hprPositions[0]
self.hprDict[self.avIdList[1]] = hprPositions[0]
self.hprDict[self.avIdList[2]] = hprPositions[0]
self.hprDict[self.avIdList[3]] = hprPositions[0]
else:
self.randomNumGen.shuffle(self.avIdList)
self.arrangeByHeight(self.avIdList, self.H_TO_L, 0, 1)
self.arrangeByHeight(self.avIdList, self.L_TO_H, 2, 3)
self.posDict[self.avIdList[0]] = dockPositions[1]
self.posDict[self.avIdList[1]] = dockPositions[2]
self.posDict[self.avIdList[2]] = dockPositions[7]
self.posDict[self.avIdList[3]] = dockPositions[8]
self.hprDict[self.avIdList[0]] = hprPositions[0]
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:
self.sides[x] = 0
self.avList[0].append(x)
else:
self.sides[x] = 1
self.avList[1].append(x)
for avId in self.avIdList:
toon = self.getAvatar(avId)
toon.setPos(self.posDict[avId])
toon.setHpr(self.hprDict[avId])
def arrangeByHeight(self, avIdList, order, iStart, iFin):
for i in range(iStart, iFin + 1):
for j in range(i + 1, iFin + 1):
if order == self.H_TO_L and self.rightHandDict[avIdList[i]].getZ() < self.rightHandDict[avIdList[j]].getZ() or order == self.L_TO_H and self.rightHandDict[avIdList[i]].getZ() > self.rightHandDict[avIdList[j]].getZ():
temp = avIdList[i]
avIdList[i] = avIdList[j]
avIdList[j] = temp
def disableArrow(self, a):
a.setColor(1, 0, 0, 0.3)
def enableArrow(self, a):
a.setColor(1, 0, 0, 1)
def hilightArrow(self, a):
a.setColor(1, 0.7, 0, 1)
def unhilightArrow(self, a):
self.enableArrow(a)
def handleDisabledAvatar(self, avId):
self.notify.debug('handleDisabledAvatar')
self.notify.debug('avatar ' + str(avId) + ' disabled')
DistributedMinigame.handleDisabledAvatar(self, avId)
def __playing(self):
return self.gameFSM.getCurrentState() != self.gameFSM.getFinalState()
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')
def __initGameVars(self):
pass
def makeToonLookatCamera(self, toon):
toon.headsUp(camera)
def setText(self, t, newtext):
t['text'] = newtext
def setTextFG(self, t, fg):
t['text_fg'] = fg
def enterOff(self):
self.notify.debug('enterOff')
def exitOff(self):
pass
def enterWaitForGoSignal(self):
self.notify.debug('enterWaitForGoSignal')
self.powerMeter.show()
self.sendUpdate('reportPlayerReady', [self.sides[self.localAvId]])
self.roundText.show()
taskMgr.doMethodLater(TugOfWarGameGlobals.WAIT_FOR_GO_TIMEOUT, self.waitForGoTimeoutTask, self.taskName('wait-for-go-timeout'))
def exitWaitForGoSignal(self):
taskMgr.remove(self.taskName('wait-for-go-timeout'))
def enterTug(self):
self.notify.debug('enterTug')
self.__spawnUpdateIdealRateTask()
self.__spawnUpdateTimerTask()
self.__spawnUpdateKeyPressRateTask()
taskMgr.doMethodLater(TugOfWarGameGlobals.TUG_TIMEOUT, self.tugTimeoutTask, self.taskName('tug-timeout'))
if self.suit:
self.suit.loop('tug-o-war')
def exitTug(self):
self.notify.debug('exitTug')
if self.suit:
self.suit.loop('neutral')
self.timer.stop()
self.timer.hide()
taskMgr.remove(self.taskName('tug-timeout'))
def enterGameDone(self):
pass
def exitGameDone(self):
pass
def enterCleanup(self):
self.notify.debug('enterCleanup')
self.__killUpdateIdealRateTask()
self.__killUpdateTimerTask()
self.__killUpdateKeyPressRateTask()
self.__killUpdateRopeTask()
def exitCleanup(self):
pass
def __gameTimerExpired(self):
self.notify.debug('game timer expired')
if self.arrowKeys:
self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS)
self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS)
def __pressHandler(self, index):
self.notify.debug('pressHandler')
if index == self.buttons[0]:
self.hilightArrow(self.arrows[index])
self.keyTTL.insert(0, 1.0)
self.buttons.reverse()
def __releaseHandler(self, index):
self.notify.debug('releaseHandler')
if index in self.buttons:
self.unhilightArrow(self.arrows[index])
def __updateKeyPressRateTask(self, task):
if self.gameFSM.getCurrentState().getName() != 'tug':
return Task.done
for i in range(len(self.keyTTL)):
self.keyTTL[i] -= 0.1
for i in range(len(self.keyTTL)):
if self.keyTTL[i] <= 0:
a = self.keyTTL[0:i]
del self.keyTTL
self.keyTTL = a
break
self.keyRate = len(self.keyTTL)
if self.keyRate == self.idealRate or self.keyRate == self.idealRate + 1:
self.rateMatchAward += 0.3
else:
self.rateMatchAward = 0
self.__spawnUpdateKeyPressRateTask()
return Task.done
def __updateTimerTask(self, task):
if self.gameFSM.getCurrentState().getName() != 'tug':
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
def __spawnUpdateTimerTask(self):
taskMgr.remove(self.taskName(self.UPDATE_TIMER_TASK))
taskMgr.doMethodLater(TugOfWarGameGlobals.SEND_UPDATE, self.__updateTimerTask, self.taskName(self.UPDATE_TIMER_TASK))
def __killUpdateTimerTask(self):
taskMgr.remove(self.taskName(self.UPDATE_TIMER_TASK))
def __spawnUpdateKeyPressRateTask(self):
taskMgr.remove(self.taskName(self.UPDATE_KEY_PRESS_RATE_TASK))
taskMgr.doMethodLater(0.1, self.__updateKeyPressRateTask, self.taskName(self.UPDATE_KEY_PRESS_RATE_TASK))
def __killUpdateKeyPressRateTask(self):
taskMgr.remove(self.taskName(self.UPDATE_KEY_PRESS_RATE_TASK))
def __spawnUpdateIdealRateTask(self):
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'))
def __updateIdealRateTask(self, task):
self.nextRateIndex = self.nextRateIndex + 1
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
def __killUpdateIdealRateTask(self):
taskMgr.remove(self.taskName('targetRateTimer'))
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.timer.show()
self.timer.setTime(TugOfWarGameGlobals.GAME_DURATION)
self.timer.countdown(TugOfWarGameGlobals.GAME_DURATION, self.__gameTimerExpired)
def enableKeys(self = self):
def keyPress(self, index):
self.__pressHandler(index)
def keyRelease(self, index):
self.__releaseHandler(index)
self.arrowKeys.setPressHandlers([lambda self = self, keyPress = keyPress: keyPress(self, 2),
lambda self = self, keyPress = keyPress: keyPress(self, 3),
lambda self = self, keyPress = keyPress: keyPress(self, 1),
lambda self = self, keyPress = keyPress: keyPress(self, 0)])
self.arrowKeys.setReleaseHandlers([lambda self = self, keyRelease = keyRelease: keyRelease(self, 2),
lambda self = self, keyRelease = keyRelease: keyRelease(self, 3),
lambda self = self, keyRelease = keyRelease: keyRelease(self, 1),
lambda self = self, keyRelease = keyRelease: keyRelease(self, 0)])
for x in index:
self.enableArrow(self.arrows[x])
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()
reactSeq = Sequence()
exitSeq = Sequence()
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)
randInt = self.randomNumGen.randrange(0, 10)
oopsTrack = Wait(0)
if randInt < 3:
suitSlipTime = 2.2
waterPos = VBase3(0, 16, -5)
newPos -= VBase3(0.4, 0, 0)
self.suitSplash.stop()
self.suitSplash.setPos(waterPos[0], waterPos[1], -1.8)
self.suitSplash.setScale(3.5, 3.5, 1)
self.suitRipples.setPos(waterPos[0], waterPos[1], -1.7)
self.suitRipples.setScale(1, 1, 1)
startHpr = self.suit.getHpr()
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')
if avId in winners:
reactSeq.append(Func(toon.loop, 'victory'))
elif avId in losers:
reactSeq.append(Func(toon.loop, 'neutral'))
else:
reactSeq.append(Func(toon.loop, 'neutral'))
if self.localAvId in winners:
exitSeq.append(Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameEnd))
exitSeq.append(Wait(5.0))
elif self.localAvId in losers:
exitSeq.append(Func(self.setText, self.roundText, TTLocalizer.TugOfWarGameEnd))
exitSeq.append(Wait(4.8 + suitSlipTime))
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()):
if x != None:
x.finish()
self.showTrack.start()
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]
self.moveToons()
self.setUpRopes(0)
def createSuits(self):
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
self.suit = Suit.Suit()
self.origSuitPosHpr = [VBase3(6.0, 18, 0.1), VBase3(120, 0, 0)]
self.suitOffset = 0
d = SuitDNA.SuitDNA()
d.newSuit(self.suitType)
self.suit.setDNA(d)
self.suit.reparentTo(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].reparentTo(self.suit)
self.dropShadowDict[self.suitId].setScale(0.45)
def initHandycaps(self):
if self.numPlayers == 3 and self.gameType == TugOfWarGameGlobals.TOON_VS_TOON:
if len(self.avList[0]) == 1:
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):
self.powerMeter.setPower(self.keyRate)
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),
0.5)
self.powerMeter.setBarColor(color)
else:
self.powerMeter.setBarColor((0, 1, 0, 0.5))
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()
self.pullingDict[avId] = 0
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])
if self.animTracks[self.suitId] != None:
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:
if avId not in self.fallenList:
toon = self.getAvatar(avId)
if toon:
origPos = self.posDict[avId]
curPos = toon.getPos()
newPos = VBase3(origPos[0] + self.offsetDict[avId] / self.handycap, curPos[1], curPos[2])
if self.animTracks[avId] != None:
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:
curPos = self.suit.getPos()
if curPos[0] < 0 and curPos[0] > -2 or curPos[0] > 0 and curPos[0] < 2:
self.hideControls()
self.throwInWater()
losingSide = 1
self.sendUpdate('reportEndOfContest', [losingSide])
elif avId not in self.fallenList:
toon = self.getAvatar(avId)
if toon:
curPos = toon.getPos()
if curPos[0] < 0 and curPos[0] > -2 or curPos[0] > 0 and curPos[0] < 2:
self.hideControls()
losingSide = self.sides[avId]
for avId in self.avIdList:
if self.sides[avId] == losingSide:
self.throwInWater(avId)
self.sendUpdate('reportEndOfContest', [losingSide])
return
def throwInWater(self, avId = None):
if avId == None:
self.fallenList.append(self.suitId)
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)
loser = self.suit
animId = self.suitId
else:
self.fallenList.append(avId)
toon = self.getAvatar(avId)
waterPos = self.drinkPositions.pop()
newPos = VBase3(waterPos[0], waterPos[1], waterPos[2] - toon.getHeight())
toon.loop('neutral')
self.dropShadowDict[avId].reparentTo(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
if self.allOutMode == 1:
F = 0.75 * keyRate
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):
if self.gameType == TugOfWarGameGlobals.TOON_VS_COG:
numRopes = self.numPlayers
else:
numRopes = self.numPlayers - 1
for x in range(0, numRopes):
rope = Rope.Rope(self.uniqueName('TugRope' + str(x)))
if rope.showRope:
rope.ropeNode.setRenderMode(RopeNode.RMBillboard)
rope.ropeNode.setThickness(0.2)
rope.setTexture(self.ropeTexture)
rope.ropeNode.setUvMode(RopeNode.UVDistance)
rope.ropeNode.setUvDirection(1)
rope.setTransparency(1)
rope.setColor(0.89, 0.89, 0.6, 1)
self.tugRopes.append(rope)
self.setUpRopes(1)
def __spawnUpdateRopeTask(self):
taskMgr.remove(self.taskName(self.UPDATE_ROPE_TASK))
taskMgr.add(self.__updateRopeTask, self.taskName(self.UPDATE_ROPE_TASK))
def __updateRopeTask(self, task):
if self.tugRopes != None:
for i in range(len(self.tugRopes)):
if self.tugRopes[i] != None:
self.ropePts[i] = self.tugRopes[i].getPoints(len(self.ropeTex[i]))
for j in range(len(self.ropePts[i])):
self.ropeTex[i][j].setPos(self.ropePts[i][j])
return Task.cont
def __killUpdateRopeTask(self):
taskMgr.remove(self.taskName(self.UPDATE_ROPE_TASK))
def tugTimeoutTask(self, task):
self.gameOver()
return Task.done
def waitForGoTimeoutTask(self, task):
self.gameOver()
return Task.done
def __spawnMouseSpeedTask(self):
taskMgr.remove(self.taskName('mouseSpeed'))
taskMgr.add(self.__mouseSpeedTask, self.taskName('mouseSpeed'))
def __killMouseSpeedTask(self):
taskMgr.remove(self.taskName('mouseSpeed'))
def __mouseSpeedTask(self, task):
dx = 0.1
if self.mouseMode:
mx = base.mouseWatcherNode.getMouseX()
my = base.mouseWatcherNode.getMouseY()
if self.mouseSide == 0:
if mx > dx:
self.mouseSide = 1
self.__releaseHandler(1)
self.__pressHandler(0)
elif mx > -dx:
self.__releaseHandler(1)
elif self.mouseSide == 1:
if mx < -dx:
self.mouseSide = 0
self.__releaseHandler(0)
self.__pressHandler(1)
elif mx < dx:
self.__releaseHandler(0)
return Task.cont