mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-23 03:35:12 -06:00
697 lines
31 KiB
Python
697 lines
31 KiB
Python
import math
|
|
from pandac.PandaModules import CollisionTube
|
|
from pandac.PandaModules import CollisionNode
|
|
from pandac.PandaModules import Point3
|
|
from pandac.PandaModules import VBase3
|
|
from pandac.PandaModules import RopeNode
|
|
from direct.interval.IntervalGlobal import LerpPosHprInterval
|
|
from direct.interval.IntervalGlobal import LerpPosInterval
|
|
from direct.interval.IntervalGlobal import Wait
|
|
from direct.interval.IntervalGlobal import ActorInterval
|
|
from direct.interval.MetaInterval import Sequence
|
|
from direct.interval.MetaInterval import Parallel
|
|
from direct.interval.FunctionInterval import Func
|
|
from direct.showutil.Rope import Rope
|
|
from direct.showbase.PythonUtil import fitDestAngle2Src
|
|
from direct.fsm.StatePush import StateVar, FunctionCall
|
|
from toontown.toonbase import TTLocalizer
|
|
from toontown.toonbase import ToontownGlobals
|
|
from toontown.effects import Splash
|
|
from toontown.minigame.MinigamePowerMeter import MinigamePowerMeter
|
|
from toontown.minigame.ArrowKeys import ArrowKeys
|
|
import PartyGlobals
|
|
import PartyUtils
|
|
from DistributedPartyTeamActivity import DistributedPartyTeamActivity
|
|
|
|
class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
|
|
notify = directNotify.newCategory('DistributedPartyTugOfWarActivity')
|
|
|
|
def __init__(self, cr):
|
|
DistributedPartyTeamActivity.__init__(self, cr, PartyGlobals.ActivityIds.PartyTugOfWar, startDelay=PartyGlobals.TugOfWarStartDelay)
|
|
self.buttons = [0, 1]
|
|
self.arrowKeys = None
|
|
self.keyTTL = []
|
|
self.idealRate = 0.0
|
|
self.keyRate = 0
|
|
self.allOutMode = False
|
|
self.rateMatchAward = 0.0
|
|
self.toonIdsToStartPositions = {}
|
|
self.toonIdsToIsPullingFlags = {}
|
|
self.toonIdsToRightHands = {}
|
|
self.fallenToons = []
|
|
self.fallenPositions = []
|
|
self.unusedFallenPositionsIndices = [0,
|
|
1,
|
|
2,
|
|
3]
|
|
self.toonIdsToAnimIntervals = {}
|
|
self.tugRopes = []
|
|
return
|
|
|
|
def generate(self):
|
|
DistributedPartyTeamActivity.generate(self)
|
|
self._hopOffFinishedSV = StateVar(True)
|
|
self._rewardFinishedSV = StateVar(True)
|
|
self._isWalkStateReadyFC = FunctionCall(self._testWalkStateReady, self._hopOffFinishedSV, self._rewardFinishedSV)
|
|
|
|
def delete(self):
|
|
self._isWalkStateReadyFC.destroy()
|
|
self._hopOffFinishedSV.destroy()
|
|
self._rewardFinishedSV.destroy()
|
|
DistributedPartyTeamActivity.delete(self)
|
|
|
|
def handleToonJoined(self, toonId):
|
|
DistributedPartyTeamActivity.handleToonJoined(self, toonId)
|
|
self.toonIdsToAnimIntervals[toonId] = None
|
|
if toonId == base.localAvatar.doId:
|
|
base.cr.playGame.getPlace().fsm.request('activity')
|
|
camera.wrtReparentTo(self.root)
|
|
self.cameraMoveIval = LerpPosHprInterval(camera, 1.5, PartyGlobals.TugOfWarCameraPos, PartyGlobals.TugOfWarCameraInitialHpr, other=self.root)
|
|
self.cameraMoveIval.start()
|
|
self.localToonPosIndex = self.getIndex(base.localAvatar.doId, self.localToonTeam)
|
|
self.notify.debug('posIndex: %d' % self.localToonPosIndex)
|
|
toon = self.getAvatar(toonId)
|
|
targetPos = self.dockPositions[self.localToonTeam][self.localToonPosIndex]
|
|
if toon.getZ(self.root) < PartyGlobals.TugOfWarToonPositionZ:
|
|
toon.setZ(self.root, PartyGlobals.TugOfWarToonPositionZ)
|
|
targetH = fitDestAngle2Src(toon.getH(self.root), PartyGlobals.TugOfWarHeadings[self.localToonTeam])
|
|
travelVector = targetPos - toon.getPos(self.root)
|
|
duration = travelVector.length() / 5.0
|
|
if self.toonIdsToAnimIntervals[toonId] is not None:
|
|
self.toonIdsToAnimIntervals[toonId].finish()
|
|
self.toonIdsToAnimIntervals[toonId] = Sequence(Func(toon.startPosHprBroadcast, 0.1), Func(toon.b_setAnimState, 'run'), LerpPosHprInterval(toon, duration, targetPos, VBase3(targetH, 0.0, 0.0), other=self.root), Func(toon.stopPosHprBroadcast), Func(toon.b_setAnimState, 'neutral'))
|
|
self.toonIdsToAnimIntervals[toonId].start()
|
|
return
|
|
|
|
def handleToonExited(self, toonId):
|
|
DistributedPartyTeamActivity.handleToonExited(self, toonId)
|
|
if toonId == base.localAvatar.doId:
|
|
self.cameraMoveIval.pause()
|
|
if toonId not in self.fallenToons:
|
|
if toonId in self.toonIdsToAnimIntervals and self.toonIdsToAnimIntervals[toonId] is not None:
|
|
self.toonIdsToAnimIntervals[toonId].finish()
|
|
toon = self.getAvatar(toonId)
|
|
targetH = fitDestAngle2Src(toon.getH(self.root), 180.0)
|
|
targetPos = self.hopOffPositions[self.getTeam(toonId)][self.getIndex(toonId, self.getTeam(toonId))]
|
|
hopOffAnim = Sequence(Func(toon.startPosHprBroadcast, 0.1), toon.hprInterval(0.2, VBase3(targetH, 0.0, 0.0), other=self.root), Func(toon.b_setAnimState, 'jump', 1.0), Wait(0.4), PartyUtils.arcPosInterval(0.75, toon, targetPos, 5.0, self.root), Func(toon.stopPosHprBroadcast), Func(toon.sendCurrentPosition), Func(self.hopOffFinished, toonId))
|
|
self.toonIdsToAnimIntervals[toonId] = hopOffAnim
|
|
self._hopOffFinishedSV.set(False)
|
|
self.toonIdsToAnimIntervals[toonId].start()
|
|
else:
|
|
self._hopOffFinishedSV.set(True)
|
|
del self.toonIdsToAnimIntervals[toonId]
|
|
return
|
|
|
|
def handleRewardDone(self):
|
|
self._rewardFinishedSV.set(True)
|
|
|
|
def _testWalkStateReady(self, hoppedOff, rewardFinished):
|
|
if hoppedOff and rewardFinished:
|
|
DistributedPartyTeamActivity.handleRewardDone(self)
|
|
|
|
def hopOffFinished(self, toonId):
|
|
if hasattr(self, 'toonIdsToAnimIntervals') and toonId in self.toonIdsToAnimIntervals:
|
|
del self.toonIdsToAnimIntervals[toonId]
|
|
if toonId == base.localAvatar.doId:
|
|
if hasattr(self._hopOffFinishedSV, '_value'):
|
|
self._hopOffFinishedSV.set(True)
|
|
|
|
def handleToonShifted(self, toonId):
|
|
if toonId == base.localAvatar.doId:
|
|
self.localToonPosIndex = self.getIndex(base.localAvatar.doId, self.localToonTeam)
|
|
if self.toonIdsToAnimIntervals[toonId] is not None:
|
|
self.toonIdsToAnimIntervals[toonId].finish()
|
|
toon = self.getAvatar(toonId)
|
|
targetPos = self.dockPositions[self.localToonTeam][self.localToonPosIndex]
|
|
self.toonIdsToAnimIntervals[toonId] = Sequence(Wait(0.6), Func(toon.startPosHprBroadcast, 0.1), Func(toon.b_setAnimState, 'run'), toon.posInterval(0.5, targetPos, other=self.root), Func(toon.stopPosHprBroadcast), Func(toon.b_setAnimState, 'neutral'))
|
|
self.toonIdsToAnimIntervals[toonId].start()
|
|
return
|
|
|
|
def handleToonDisabled(self, toonId):
|
|
if self.toonIdsToAnimIntervals.has_key(toonId):
|
|
if self.toonIdsToAnimIntervals[toonId]:
|
|
if self.toonIdsToAnimIntervals[toonId].isPlaying():
|
|
self.toonIdsToAnimIntervals[toonId].finish()
|
|
else:
|
|
self.notify.debug('self.toonIdsToAnimIntervals[%d] is none' % toonId)
|
|
|
|
def setToonsPlaying(self, leftTeamToonIds, rightTeamToonIds):
|
|
DistributedPartyTeamActivity.setToonsPlaying(self, leftTeamToonIds, rightTeamToonIds)
|
|
self.toonIdsToRightHands.clear()
|
|
for toonId in self.getToonIdsAsList():
|
|
toon = self.getAvatar(toonId)
|
|
if toon:
|
|
self.toonIdsToRightHands[toonId] = toon.getRightHands()[0]
|
|
|
|
def load(self):
|
|
DistributedPartyTeamActivity.load(self)
|
|
self.loadModels()
|
|
self.loadGuiElements()
|
|
self.loadSounds()
|
|
self.loadIntervals()
|
|
self.arrowKeys = ArrowKeys()
|
|
|
|
def loadModels(self):
|
|
self.playArea = loader.loadModel('phase_13/models/parties/partyTugOfWar')
|
|
self.playArea.reparentTo(self.root)
|
|
self.sign.reparentTo(self.playArea.find('**/TugOfWar_sign_locator'))
|
|
self.dockPositions = [[], []]
|
|
for i in range(4):
|
|
self.dockPositions[0].append(Point3(-PartyGlobals.TugOfWarInitialToonPositionsXOffset - PartyGlobals.TugOfWarToonPositionXSeparation * i, 0.0, PartyGlobals.TugOfWarToonPositionZ))
|
|
|
|
for i in range(4):
|
|
self.dockPositions[1].append(Point3(PartyGlobals.TugOfWarInitialToonPositionsXOffset + PartyGlobals.TugOfWarToonPositionXSeparation * i, 0.0, PartyGlobals.TugOfWarToonPositionZ))
|
|
|
|
self.hopOffPositions = [[], []]
|
|
for i in range(1, 5):
|
|
self.hopOffPositions[PartyGlobals.TeamActivityTeams.LeftTeam].append(self.playArea.find('**/leftTeamHopOff%d_locator' % i).getPos())
|
|
self.hopOffPositions[PartyGlobals.TeamActivityTeams.RightTeam].append(self.playArea.find('**/rightTeamHopOff%d_locator' % i).getPos())
|
|
|
|
for i in range(1, 5):
|
|
pos = self.playArea.find('**/fallenToon%d_locator' % i).getPos()
|
|
self.fallenPositions.append(pos)
|
|
|
|
self.joinCollision = []
|
|
self.joinCollisionNodePaths = []
|
|
for i in range(len(PartyGlobals.TeamActivityTeams)):
|
|
collShape = CollisionTube(PartyGlobals.TugOfWarJoinCollisionEndPoints[0], PartyGlobals.TugOfWarJoinCollisionEndPoints[1], PartyGlobals.TugOfWarJoinCollisionRadius)
|
|
collShape.setTangible(True)
|
|
self.joinCollision.append(CollisionNode('TugOfWarJoinCollision%d' % i))
|
|
self.joinCollision[i].addSolid(collShape)
|
|
tubeNp = self.playArea.attachNewNode(self.joinCollision[i])
|
|
tubeNp.node().setCollideMask(ToontownGlobals.WallBitmask)
|
|
self.joinCollisionNodePaths.append(tubeNp)
|
|
self.joinCollisionNodePaths[i].setPos(PartyGlobals.TugOfWarJoinCollisionPositions[i])
|
|
|
|
self.__enableCollisions()
|
|
ropeModel = loader.loadModel('phase_4/models/minigames/tug_of_war_rope')
|
|
self.ropeTexture = ropeModel.findTexture('*')
|
|
ropeModel.removeNode()
|
|
for i in range(PartyGlobals.TugOfWarMaximumPlayersPerTeam * 2 - 1):
|
|
rope = Rope(self.uniqueName('TugRope%d' % i))
|
|
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.0)
|
|
rope.reparentTo(self.root)
|
|
rope.stash()
|
|
self.tugRopes.append(rope)
|
|
|
|
self.splash = Splash.Splash(self.root)
|
|
self.splash.setScale(2.0, 4.0, 1.0)
|
|
pos = self.fallenPositions[0]
|
|
self.splash.setPos(pos[0], pos[1], PartyGlobals.TugOfWarSplashZOffset)
|
|
self.splash.hide()
|
|
|
|
def loadGuiElements(self):
|
|
self.powerMeter = MinigamePowerMeter(PartyGlobals.TugOfWarPowerMeterSize)
|
|
self.powerMeter.reparentTo(aspect2d)
|
|
self.powerMeter.setPos(0.0, 0.0, 0.6)
|
|
self.powerMeter.hide()
|
|
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].setScale(0.2 - 0.4 * x, 0.2, 0.2)
|
|
self.arrows[x].setPos(0.12 - 0.24 * x, 0, -.26)
|
|
|
|
return
|
|
|
|
def loadSounds(self):
|
|
self.splashSound = base.loadSfx('phase_4/audio/sfx/MG_cannon_splash.ogg')
|
|
self.whistleSound = base.loadSfx('phase_4/audio/sfx/AA_sound_whistle.ogg')
|
|
|
|
def loadIntervals(self):
|
|
self.updateIdealRateInterval = Sequence()
|
|
self.updateIdealRateInterval.append(Wait(PartyGlobals.TugOfWarTargetRateList[0][0]))
|
|
for i in range(1, len(PartyGlobals.TugOfWarTargetRateList)):
|
|
duration = PartyGlobals.TugOfWarTargetRateList[i][0]
|
|
idealRate = PartyGlobals.TugOfWarTargetRateList[i][1]
|
|
self.updateIdealRateInterval.append(Func(self.setIdealRate, idealRate))
|
|
if i == len(PartyGlobals.TugOfWarTargetRateList) - 1:
|
|
self.updateIdealRateInterval.append(Func(setattr, self, 'allOutMode', True))
|
|
else:
|
|
self.updateIdealRateInterval.append(Wait(duration))
|
|
|
|
self.updateKeyPressRateInterval = Sequence(Wait(PartyGlobals.TugOfWarKeyPressUpdateRate), Func(self.updateKeyPressRate))
|
|
self.reportToServerInterval = Sequence(Wait(PartyGlobals.TugOfWarKeyPressReportRate), Func(self.reportToServer))
|
|
self.setupInterval = Parallel()
|
|
self.globalSetupInterval = Sequence(Wait(PartyGlobals.TugOfWarReadyDuration + PartyGlobals.TugOfWarGoDuration), Func(self.tightenRopes))
|
|
self.localSetupInterval = Sequence(Func(self.setStatus, TTLocalizer.PartyTugOfWarReady), Func(self.showStatus), Wait(PartyGlobals.TugOfWarReadyDuration), Func(base.playSfx, self.whistleSound), Func(self.setStatus, TTLocalizer.PartyTugOfWarGo), Wait(PartyGlobals.TugOfWarGoDuration), Func(self.enableKeys), Func(self.hideStatus), Func(self.updateIdealRateInterval.start), Func(self.updateKeyPressRateInterval.loop), Func(self.reportToServerInterval.loop))
|
|
self.splashInterval = Sequence(Func(base.playSfx, self.splashSound), Func(self.splash.play))
|
|
|
|
def unload(self):
|
|
DistributedPartyTeamActivity.unload(self)
|
|
self.arrowKeys.destroy()
|
|
self.unloadIntervals()
|
|
self.unloadModels()
|
|
self.unloadGuiElements()
|
|
self.unloadSounds()
|
|
if hasattr(self, 'toonIds'):
|
|
del self.toonIds
|
|
del self.buttons
|
|
del self.arrowKeys
|
|
del self.keyTTL
|
|
del self.idealRate
|
|
del self.keyRate
|
|
del self.allOutMode
|
|
del self.rateMatchAward
|
|
del self.toonIdsToStartPositions
|
|
del self.toonIdsToIsPullingFlags
|
|
del self.toonIdsToRightHands
|
|
del self.fallenToons
|
|
del self.fallenPositions
|
|
del self.unusedFallenPositionsIndices
|
|
self.toonIdsToAnimIntervals.clear()
|
|
del self.toonIdsToAnimIntervals
|
|
|
|
def unloadModels(self):
|
|
self.playArea.removeNode()
|
|
del self.playArea
|
|
del self.dockPositions
|
|
del self.hopOffPositions
|
|
self.__disableCollisions()
|
|
while len(self.joinCollision) > 0:
|
|
collNode = self.joinCollision.pop()
|
|
del collNode
|
|
|
|
while len(self.joinCollisionNodePaths) > 0:
|
|
collNodePath = self.joinCollisionNodePaths.pop()
|
|
collNodePath.removeNode()
|
|
del collNodePath
|
|
|
|
while len(self.tugRopes) > 0:
|
|
rope = self.tugRopes.pop()
|
|
if rope is not None:
|
|
rope.removeNode()
|
|
del rope
|
|
|
|
del self.tugRopes
|
|
self.splash.destroy()
|
|
del self.splash
|
|
return
|
|
|
|
def unloadGuiElements(self):
|
|
for arrow in self.arrows:
|
|
if arrow is not None:
|
|
arrow.removeNode()
|
|
del arrow
|
|
|
|
del self.arrows
|
|
if self.powerMeter is not None:
|
|
self.powerMeter.cleanup()
|
|
del self.powerMeter
|
|
return
|
|
|
|
def unloadSounds(self):
|
|
del self.splashSound
|
|
del self.whistleSound
|
|
|
|
def unloadIntervals(self):
|
|
self.updateIdealRateInterval.pause()
|
|
del self.updateIdealRateInterval
|
|
self.updateKeyPressRateInterval.pause()
|
|
del self.updateKeyPressRateInterval
|
|
self.reportToServerInterval.pause()
|
|
del self.reportToServerInterval
|
|
self.setupInterval.pause()
|
|
del self.setupInterval
|
|
self.globalSetupInterval.pause()
|
|
del self.globalSetupInterval
|
|
self.localSetupInterval.pause()
|
|
del self.localSetupInterval
|
|
self.splashInterval.pause()
|
|
del self.splashInterval
|
|
|
|
def __enableCollisions(self):
|
|
for i in range(len(PartyGlobals.TeamActivityTeams)):
|
|
self.accept('enterTugOfWarJoinCollision%d' % i, getattr(self, '_join%s' % PartyGlobals.TeamActivityTeams.getString(i)))
|
|
|
|
def __disableCollisions(self):
|
|
for i in range(len(PartyGlobals.TeamActivityTeams)):
|
|
self.ignore('enterTugOfWarJoinCollision%d' % i)
|
|
|
|
def startWaitForEnough(self):
|
|
DistributedPartyTeamActivity.startWaitForEnough(self)
|
|
self.__enableCollisions()
|
|
|
|
def finishWaitForEnough(self):
|
|
DistributedPartyTeamActivity.finishWaitForEnough(self)
|
|
self.__disableCollisions()
|
|
|
|
def startWaitToStart(self, waitStartTimestamp):
|
|
DistributedPartyTeamActivity.startWaitToStart(self, waitStartTimestamp)
|
|
self.__enableCollisions()
|
|
|
|
def finishWaitToStart(self):
|
|
DistributedPartyTeamActivity.finishWaitToStart(self)
|
|
self.__disableCollisions()
|
|
|
|
def startRules(self):
|
|
DistributedPartyTeamActivity.startRules(self)
|
|
self.setUpRopes()
|
|
if self.isLocalToonPlaying:
|
|
self.showControls()
|
|
|
|
def finishRules(self):
|
|
DistributedPartyTeamActivity.finishRules(self)
|
|
if self.activityFSM.getCurrentOrNextState() == 'WaitForEnough':
|
|
self.hideRopes()
|
|
self.hideControls()
|
|
|
|
def finishWaitForServer(self):
|
|
DistributedPartyTeamActivity.finishWaitForServer(self)
|
|
if self.activityFSM.getCurrentOrNextState() == 'WaitForEnough':
|
|
self.hideRopes()
|
|
self.hideControls()
|
|
|
|
def startActive(self):
|
|
DistributedPartyTeamActivity.startActive(self)
|
|
self.toonIdsToStartPositions.clear()
|
|
self.toonIdsToIsPullingFlags.clear()
|
|
for toonId in self.getToonIdsAsList():
|
|
self.toonIdsToIsPullingFlags[toonId] = False
|
|
toon = self.getAvatar(toonId)
|
|
if toon:
|
|
self.toonIdsToStartPositions[toonId] = toon.getPos(self.root)
|
|
else:
|
|
self.notify.warning("couldn't find toon %d assigning 0,0,0 to startPos" % toonId)
|
|
self.toonIdsToStartPositions[toonId] = Point3(0, 0, 0)
|
|
|
|
self.unusedFallenPositionsIndices = [0,
|
|
1,
|
|
2,
|
|
3]
|
|
self.setupInterval = Parallel(self.globalSetupInterval)
|
|
if self.isLocalToonPlaying:
|
|
self.keyTTL = []
|
|
self.idealForce = 0.0
|
|
self.keyRate = 0
|
|
self.rateMatchAward = 0.0
|
|
self.allOutMode = False
|
|
self.setIdealRate(PartyGlobals.TugOfWarTargetRateList[0][1])
|
|
self.setupInterval.append(self.localSetupInterval)
|
|
self.setupInterval.start()
|
|
|
|
def finishActive(self):
|
|
DistributedPartyTeamActivity.finishActive(self)
|
|
self.hideControls()
|
|
self.disableKeys()
|
|
self.setupInterval.pause()
|
|
self.reportToServerInterval.pause()
|
|
self.updateKeyPressRateInterval.pause()
|
|
self.updateIdealRateInterval.pause()
|
|
self.hideRopes()
|
|
|
|
def startConclusion(self, losingTeam):
|
|
DistributedPartyTeamActivity.startConclusion(self, losingTeam)
|
|
if self.isLocalToonPlaying:
|
|
self._rewardFinishedSV.set(False)
|
|
if losingTeam == PartyGlobals.TeamActivityNeitherTeam:
|
|
self.setStatus(TTLocalizer.PartyTeamActivityGameTie)
|
|
else:
|
|
self.setStatus(TTLocalizer.PartyTugOfWarGameEnd)
|
|
self.showStatus()
|
|
if losingTeam == PartyGlobals.TeamActivityNeitherTeam:
|
|
for toonId in self.getToonIdsAsList():
|
|
if self.getAvatar(toonId):
|
|
self.getAvatar(toonId).loop('neutral')
|
|
|
|
else:
|
|
for toonId in self.toonIds[losingTeam]:
|
|
if self.getAvatar(toonId):
|
|
self.getAvatar(toonId).loop('neutral')
|
|
|
|
for toonId in self.toonIds[1 - losingTeam]:
|
|
if self.getAvatar(toonId):
|
|
self.getAvatar(toonId).loop('victory')
|
|
|
|
for ival in self.toonIdsToAnimIntervals.values():
|
|
if ival is not None:
|
|
ival.finish()
|
|
|
|
return
|
|
|
|
def finishConclusion(self):
|
|
DistributedPartyTeamActivity.finishConclusion(self)
|
|
self.fallenToons = []
|
|
|
|
def getTitle(self):
|
|
return TTLocalizer.PartyTugOfWarTitle
|
|
|
|
def getInstructions(self):
|
|
return TTLocalizer.TugOfWarInstructions
|
|
|
|
def showControls(self):
|
|
for arrow in self.arrows:
|
|
arrow.setColor(PartyGlobals.TugOfWarDisabledArrowColor)
|
|
|
|
self.powerMeter.setTarget(PartyGlobals.TugOfWarTargetRateList[0][1])
|
|
self.powerMeter.setPower(PartyGlobals.TugOfWarTargetRateList[0][1])
|
|
self.powerMeter.setBarColor((0.0, 1.0, 0.0, 0.5))
|
|
self.powerMeter.clearTooSlowTooFast()
|
|
self.powerMeter.show()
|
|
|
|
def hideControls(self):
|
|
self.powerMeter.hide()
|
|
|
|
def setUpRopes(self):
|
|
self.notify.debug('setUpRopes')
|
|
ropeIndex = 0
|
|
leftToonId = -1
|
|
if self.toonIds[PartyGlobals.TeamActivityTeams.LeftTeam]:
|
|
leftToonId = self.toonIds[PartyGlobals.TeamActivityTeams.LeftTeam][0]
|
|
rightToonId = -1
|
|
if self.toonIds[PartyGlobals.TeamActivityTeams.RightTeam]:
|
|
rightToonId = self.toonIds[PartyGlobals.TeamActivityTeams.RightTeam][0]
|
|
if leftToonId in self.toonIdsToRightHands and rightToonId in self.toonIdsToRightHands:
|
|
self.tugRopes[ropeIndex].setup(3, ((self.toonIdsToRightHands[leftToonId], (0, 0, 0)), (self.root, (0.0, 0.0, 2.5)), (self.toonIdsToRightHands[rightToonId], (0, 0, 0))), [0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1])
|
|
self.tugRopes[ropeIndex].unstash()
|
|
ropeIndex += 1
|
|
teams = [PartyGlobals.TeamActivityTeams.LeftTeam, PartyGlobals.TeamActivityTeams.RightTeam]
|
|
for currTeam in teams:
|
|
numToons = len(self.toonIds[currTeam])
|
|
if numToons > 1:
|
|
for i in range(numToons - 1, 0, -1):
|
|
toon1 = self.toonIds[currTeam][i]
|
|
toon2 = self.toonIds[currTeam][i - 1]
|
|
if not self.toonIdsToRightHands.has_key(toon1):
|
|
self.notify.warning('Toon in tug of war activity but not properly setup: %s' % toon1)
|
|
elif not self.toonIdsToRightHands.has_key(toon2):
|
|
self.notify.warning('Toon in tug of war activity but not properly setup: %s' % toon2)
|
|
else:
|
|
self.notify.debug('Connecting rope between toon %d and toon %d of team %d.' % (i, i - 1, currTeam))
|
|
self.tugRopes[ropeIndex].setup(3, ((self.toonIdsToRightHands[toon1], (0, 0, 0)), (self.toonIdsToRightHands[toon1], (0, 0, 0)), (self.toonIdsToRightHands[toon2], (0, 0, 0))), [0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1])
|
|
self.tugRopes[ropeIndex].unstash()
|
|
ropeIndex += 1
|
|
|
|
def tightenRopes(self):
|
|
self.notify.debug('tightenRopes')
|
|
self.tugRopes[0].setup(3, ((self.toonIdsToRightHands[self.toonIds[PartyGlobals.TeamActivityTeams.LeftTeam][0]], (0, 0, 0)), (self.toonIdsToRightHands[self.toonIds[PartyGlobals.TeamActivityTeams.LeftTeam][0]], (0, 0, 0)), (self.toonIdsToRightHands[self.toonIds[PartyGlobals.TeamActivityTeams.RightTeam][0]], (0, 0, 0))), [0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1])
|
|
|
|
def hideRopes(self):
|
|
self.notify.debug('hideRopes')
|
|
for rope in self.tugRopes:
|
|
rope.stash()
|
|
|
|
def handleGameTimerExpired(self):
|
|
self.disableKeys()
|
|
|
|
def setIdealRate(self, idealRate):
|
|
self.notify.debug('setIdealRate( %d )' % idealRate)
|
|
self.idealRate = idealRate
|
|
self.idealForce = self.advantage * (4 + 0.4 * self.idealRate)
|
|
|
|
def updateKeyPressRate(self):
|
|
for i in range(len(self.keyTTL)):
|
|
self.keyTTL[i] -= PartyGlobals.TugOfWarKeyPressUpdateRate
|
|
|
|
for i in range(len(self.keyTTL)):
|
|
if self.keyTTL[i] <= 0.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.0
|
|
|
|
def reportToServer(self):
|
|
self.currentForce = self.computeForce(self.keyRate)
|
|
self.sendUpdate('reportKeyRateForce', [self.keyRate, self.currentForce])
|
|
self.setSpeedGauge()
|
|
self.setAnimState(base.localAvatar.doId, self.keyRate)
|
|
|
|
def computeForce(self, keyRate):
|
|
F = 0
|
|
if self.allOutMode:
|
|
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 setSpeedGauge(self):
|
|
self.powerMeter.setPower(self.keyRate)
|
|
self.powerMeter.setTarget(self.idealRate)
|
|
if not self.allOutMode:
|
|
self.powerMeter.updateTooSlowTooFast()
|
|
index = float(self.currentForce) / self.idealForce
|
|
bonus = 0.0
|
|
if index > 1.0:
|
|
bonus = max(1.0, index - 1.0)
|
|
index = 1.0
|
|
color = (0,
|
|
0.75 * index + 0.25 * bonus,
|
|
0.75 * (1 - index),
|
|
0.5)
|
|
self.powerMeter.setBarColor(color)
|
|
else:
|
|
self.powerMeter.setBarColor((0.0, 1.0, 0.0, 0.5))
|
|
|
|
def updateToonKeyRate(self, toonId, keyRate):
|
|
if toonId != base.localAvatar.doId:
|
|
self.setAnimState(toonId, keyRate)
|
|
|
|
def setAnimState(self, toonId, keyRate):
|
|
if self.activityFSM.state != 'Active':
|
|
return
|
|
toon = self.getAvatar(toonId)
|
|
if not self.toonIdsToIsPullingFlags.has_key(toonId):
|
|
if self.getTeam(toonId) == None:
|
|
self.notify.warning("setAnimState called with toonId (%d) that wasn't in self.toonIds" % toonId)
|
|
return
|
|
else:
|
|
self.notify.warning('setAnimState called with toonId (%d) that was in self.toonIds but not in self.toonIdsToIsPullingFlags. Adding it.' % toonId)
|
|
self.toonIdsToIsPullingFlags[toonId] = False
|
|
if keyRate > 0 and not self.toonIdsToIsPullingFlags[toonId]:
|
|
if toon:
|
|
toon.loop('tug-o-war')
|
|
else:
|
|
self.notify.warning('toon %d is None, skipping toon.loop(tugowar)' % toonId)
|
|
self.toonIdsToIsPullingFlags[toonId] = True
|
|
if keyRate <= 0 and self.toonIdsToIsPullingFlags[toonId]:
|
|
if toon:
|
|
toon.pose('tug-o-war', 3)
|
|
toon.startLookAround()
|
|
else:
|
|
self.notify.warning('toon %d is None, skipping toon.startLookAround' % toonId)
|
|
self.toonIdsToIsPullingFlags[toonId] = False
|
|
return
|
|
|
|
def enableKeys(self):
|
|
self.notify.debug('enableKeys')
|
|
self.arrowKeys.setPressHandlers([lambda : self.__pressHandler(2),
|
|
lambda : self.__pressHandler(3),
|
|
lambda : self.__pressHandler(1),
|
|
lambda : self.__pressHandler(0)])
|
|
self.arrowKeys.setReleaseHandlers([lambda : self.__releaseHandler(2),
|
|
lambda : self.__releaseHandler(3),
|
|
lambda : self.__releaseHandler(1),
|
|
lambda : self.__releaseHandler(0)])
|
|
for arrow in self.arrows:
|
|
arrow.setColor(PartyGlobals.TugOfWarEnabledArrowColor)
|
|
|
|
def disableKeys(self):
|
|
self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS)
|
|
self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS)
|
|
|
|
def __pressHandler(self, index):
|
|
if index == self.buttons[0]:
|
|
self.arrows[index].setColor(PartyGlobals.TugOfWarHilightedArrowColor)
|
|
self.keyTTL.insert(0, PartyGlobals.TugOfWarKeyPressTimeToLive)
|
|
self.buttons.reverse()
|
|
|
|
def __releaseHandler(self, index):
|
|
if index in self.buttons:
|
|
self.arrows[index].setColor(PartyGlobals.TugOfWarEnabledArrowColor)
|
|
|
|
def updateToonPositions(self, offset):
|
|
if self.activityFSM.state != 'Active':
|
|
return
|
|
if self.isLocalToonPlaying:
|
|
camera.lookAt(self.root, offset, 0.0, PartyGlobals.TugOfWarCameraLookAtHeightOffset)
|
|
for toonId in self.getToonIdsAsList():
|
|
if hasattr(self, 'fallenToons') and toonId not in self.fallenToons:
|
|
toon = self.getAvatar(toonId)
|
|
if toon is not None:
|
|
origPos = self.toonIdsToStartPositions[toonId]
|
|
curPos = toon.getPos(self.root)
|
|
newPos = Point3(origPos[0] + offset, curPos[1], curPos[2])
|
|
if self.toonIdsToAnimIntervals[toonId] != None:
|
|
if self.toonIdsToAnimIntervals[toonId].isPlaying():
|
|
self.toonIdsToAnimIntervals[toonId].finish()
|
|
self.checkIfFallen(toonId)
|
|
if toonId not in self.fallenToons:
|
|
self.toonIdsToAnimIntervals[toonId] = Sequence(LerpPosInterval(toon, duration=PartyGlobals.TugOfWarKeyPressReportRate, pos=newPos, other=self.root), Func(self.checkIfFallen, toonId))
|
|
self.toonIdsToAnimIntervals[toonId].start()
|
|
|
|
return
|
|
|
|
def checkIfFallen(self, toonId):
|
|
if hasattr(self, 'fallenToons') and toonId not in self.fallenToons:
|
|
toon = self.getAvatar(toonId)
|
|
if toon:
|
|
curPos = toon.getPos(self.root)
|
|
team = self.getTeam(toonId)
|
|
if team == PartyGlobals.TeamActivityTeams.LeftTeam and curPos[0] > -2.0 or team == PartyGlobals.TeamActivityTeams.RightTeam and curPos[0] < 2.0:
|
|
losingTeam = self.getTeam(toonId)
|
|
self.throwTeamInWater(losingTeam)
|
|
self.sendUpdate('reportFallIn', [losingTeam])
|
|
|
|
def throwTeamInWater(self, losingTeam):
|
|
self.notify.debug('throwTeamInWater( %s )' % PartyGlobals.TeamActivityTeams.getString(losingTeam))
|
|
splashSet = False
|
|
for toonId in self.toonIds[losingTeam]:
|
|
self.fallenToons.append(toonId)
|
|
toon = self.getAvatar(toonId)
|
|
fallenPosIndex = self.toonIds[losingTeam].index(toonId)
|
|
if fallenPosIndex < 0 or fallenPosIndex >= 4:
|
|
fallenPosIndex = 0
|
|
newPos = self.fallenPositions[fallenPosIndex]
|
|
if self.toonIdsToAnimIntervals.has_key(toonId) and self.toonIdsToAnimIntervals[toonId] is not None:
|
|
if self.toonIdsToAnimIntervals[toonId].isPlaying():
|
|
self.toonIdsToAnimIntervals[toonId].finish()
|
|
if toon:
|
|
parallel = Parallel(ActorInterval(actor=toon, animName='slip-forward', duration=2.0), LerpPosInterval(toon, duration=2.0, pos=newPos, other=self.root))
|
|
else:
|
|
self.notify.warning('toon %d is none, skipping slip-forward' % toonId)
|
|
parallel = Parallel()
|
|
if not splashSet:
|
|
splashSet = True
|
|
parallel.append(self.splashInterval)
|
|
if toon:
|
|
self.toonIdsToAnimIntervals[toonId] = Sequence(parallel, Func(toon.loop, 'neutral'))
|
|
else:
|
|
self.notify.warning('toon %d is none, skipping toon.loop(neutral)' % toonId)
|
|
self.toonIdsToAnimIntervals[toonId] = parallel
|
|
self.toonIdsToAnimIntervals[toonId].start()
|
|
|
|
return
|
|
|
|
def setAdvantage(self, advantage):
|
|
DistributedPartyTeamActivity.setAdvantage(self, advantage)
|
|
if self.isLocalToonPlaying:
|
|
self.setIdealRate(PartyGlobals.TugOfWarTargetRateList[0][1])
|