2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import *
|
2019-11-02 17:27:54 -05:00
|
|
|
from toontown.toonbase.ToonBaseGlobal import *
|
|
|
|
from direct.interval.IntervalGlobal import *
|
2019-12-30 00:07:56 -06:00
|
|
|
from .DistributedMinigame import *
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.gui.DirectGui import *
|
2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import *
|
2019-11-02 17:27:54 -05:00
|
|
|
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
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import ArrowKeys
|
2019-11-02 17:27:54 -05:00
|
|
|
import random
|
|
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
import string
|
|
|
|
from toontown.toonbase import TTLocalizer
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import TugOfWarGameGlobals
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.showutil import Rope
|
|
|
|
from toontown.effects import Splash
|
|
|
|
from toontown.effects import Ripples
|
|
|
|
from toontown.toonbase import TTLocalizer
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import MinigamePowerMeter
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.task.Task import Task
|
|
|
|
|
|
|
|
class DistributedTugOfWarGame(DistributedMinigame):
|
2020-01-14 13:28:52 -06:00
|
|
|
bgm = 'phase_4/audio/bgm/MG_tug_o_war.ogg'
|
2019-11-02 17:27:54 -05:00
|
|
|
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')
|
2020-01-14 13:28:52 -06:00
|
|
|
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')
|
2019-11-23 16:18:49 -06:00
|
|
|
self.music = base.loader.loadMusic(self.bgm)
|
2019-11-02 17:27:54 -05:00
|
|
|
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
|
2019-12-30 00:07:56 -06:00
|
|
|
for track in list(self.animTracks.values()):
|
2019-11-02 17:27:54 -05:00
|
|
|
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:
|
2019-12-30 00:07:56 -06:00
|
|
|
if avId in self.dropShadowDict:
|
2019-11-02 17:27:54 -05:00
|
|
|
self.dropShadowDict[avId].reparentTo(hidden)
|
|
|
|
|
2019-12-30 00:07:56 -06:00
|
|
|
if self.suitId in self.dropShadowDict:
|
2019-11-02 17:27:54 -05:00
|
|
|
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)
|
2019-12-30 00:07:56 -06:00
|
|
|
for x in list(self.animTracks.values()):
|
2019-11-02 17:27:54 -05:00
|
|
|
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
|