historical/toontown-classic.git/toontown/parties/DistributedPartyTeamActivity.py
2024-01-16 11:20:27 -06:00

378 lines
14 KiB
Python

from direct.distributed.ClockDelta import globalClockDelta
from toontown.toonbase import TTLocalizer
from toontown.parties import PartyGlobals
from toontown.parties.DistributedPartyActivity import DistributedPartyActivity
from toontown.parties.activityFSMs import TeamActivityFSM
from toontown.parties.TeamActivityGui import TeamActivityGui
class DistributedPartyTeamActivity(DistributedPartyActivity):
notify = directNotify.newCategory('DistributedPartyTeamActivity')
def __init__(self, cr, activityId, startDelay = PartyGlobals.TeamActivityStartDelay, balanceTeams = False):
DistributedPartyActivity.__init__(self, cr, activityId, PartyGlobals.ActivityTypes.GuestInitiated, wantRewardGui=True)
self.notify.debug('__init__')
self.toonIds = ([], [])
self.isLocalToonPlaying = False
self.localToonTeam = None
self.advantage = 1.0
self.waitToStartTimestamp = None
self._maxPlayersPerTeam = 0
self._minPlayersPerTeam = 0
self._duration = 0
self._startDelay = base.config.GetFloat('party-team-activity-start-delay', startDelay)
self._willBalanceTeams = False # balanceTeams
self._currentStatus = ''
return
def load(self):
DistributedPartyActivity.load(self)
self.teamActivityGui = TeamActivityGui(self)
self.activityFSM = TeamActivityFSM(self)
def unload(self):
DistributedPartyActivity.unload(self)
del self.activityFSM
self.teamActivityGui.unload()
del self.teamActivityGui
if hasattr(self, 'toonIds'):
del self.toonIds
del self.isLocalToonPlaying
del self.localToonTeam
del self.advantage
del self.waitToStartTimestamp
def handleToonShifted(self, toonId):
self.notify.error('handleToonShifted( toonId=%d ) must be overriden by child class.' % toonId)
def handleToonSwitchedTeams(self, toonId):
if toonId == base.localAvatar.doId and self._canSwitchTeams:
if self.isState('WaitForEnough') or self.isState('WaitToStart'):
self.teamActivityGui.enableExitButton()
self.teamActivityGui.enableSwitchButton()
def handleToonDisabled(self, toonId):
self.notify.error('handleToonDisabled( toonId=%d ) must be overriden by child class.' % toonId)
def setPlayersPerTeam(self, min, max):
self._minPlayersPerTeam = min
self._maxPlayersPerTeam = max
def setDuration(self, duration):
self._duration = duration
def setCanSwitchTeams(self, canSwitchTeams):
self._canSwitchTeams = canSwitchTeams
def d_toonJoinRequest(self, team):
if self.isLocalToonInActivity():
return
if self.activityFSM.state in ['WaitForEnough', 'WaitToStart'] and self._localToonRequestStatus is None:
base.cr.playGame.getPlace().fsm.request('activity')
self.localToonJoining()
self.sendUpdate('toonJoinRequest', [team])
return
def d_toonExitRequest(self):
toonId = base.localAvatar.doId
team = self.getTeam(toonId)
if team is not None:
if self._localToonRequestStatus is None:
self.localToonExiting()
self.sendUpdate('toonExitRequest', [team])
else:
self.notify.warning('Not sending exitRequest as localToon has no team.')
return
def joinRequestDenied(self, reason):
DistributedPartyActivity.joinRequestDenied(self, reason)
self.notify.debug('joinRequestDenied')
if reason == PartyGlobals.DenialReasons.Full:
self.showMessage(TTLocalizer.PartyTeamActivityTeamFull)
elif reason == PartyGlobals.DenialReasons.Default:
self.showMessage(TTLocalizer.PartyTeamActivityJoinDenied % self.getTitle())
def exitRequestDenied(self, reason):
DistributedPartyActivity.exitRequestDenied(self, reason)
if reason == PartyGlobals.DenialReasons.Default:
self.showMessage(TTLocalizer.PartyTeamActivityExitDenied % self.getTitle())
if self.isLocalToonPlaying and (self.isState('WaitToStart') or self.isState('WaitForEnough')):
self.teamActivityGui.enableExitButton()
if self._canSwitchTeams:
self.teamActivityGui.enableSwitchButton()
def d_toonSwitchTeamRequest(self):
if not self._canSwitchTeams:
return
self.sendUpdate('toonSwitchTeamRequest')
def switchTeamRequestDenied(self, reason):
self.notify.debug('switchTeamRequestDenied')
if reason == PartyGlobals.DenialReasons.Full:
self.showMessage(TTLocalizer.PartyTeamActivityTeamFull, endState='activity')
elif reason == PartyGlobals.DenialReasons.Default:
self.showMessage(TTLocalizer.PartyTeamActivitySwitchDenied, endState='activity')
if self.isLocalToonPlaying and (self.isState('WaitToStart') or self.isState('WaitForEnough')) and self._canSwitchTeams:
self.teamActivityGui.enableSwitchButton()
def setToonsPlaying(self, leftTeamToonIds, rightTeamToonIds):
newToonIds = [leftTeamToonIds, rightTeamToonIds]
exitedToons, joinedToons, shifters, switchers = self.getToonsPlayingChanges(self.toonIds, newToonIds)
if base.localAvatar.doId in exitedToons:
self.localToonExiting()
self._processExitedToons(exitedToons)
self.setToonIds([leftTeamToonIds, rightTeamToonIds])
self._processJoinedToons(joinedToons)
for toonId in shifters:
self.handleToonShifted(toonId)
if self._canSwitchTeams:
for toonId in switchers:
self.handleToonSwitchedTeams(toonId)
if self.isState('WaitForEnough'):
self._updateWaitForEnoughStatus()
def _updateWaitForEnoughStatus(self):
amount = self.getNumToonsNeededToStart()
if self._willBalanceTeams:
text = TTLocalizer.PartyTeamActivityForMoreWithBalance
else:
text = TTLocalizer.PartyTeamActivityForMore
if amount > 1:
plural = TTLocalizer.PartyTeamActivityForMorePlural
else:
plural = ''
self.setStatus(text % (amount, plural))
def setState(self, newState, timestamp, data):
DistributedPartyActivity.setState(self, newState, timestamp)
if newState == 'WaitToStart':
self.activityFSM.request(newState, timestamp)
elif newState == 'Conclusion':
self.activityFSM.request(newState, data)
else:
self.activityFSM.request(newState)
def d_toonReady(self):
self.sendUpdate('toonReady')
def setAdvantage(self, advantage):
self.advantage = advantage
def handleToonJoined(self, toonId):
if toonId == base.localAvatar.doId:
self.isLocalToonPlaying = True
self.localToonTeam = self.getTeam(base.localAvatar.doId)
self.teamActivityGui.load()
self.teamActivityGui.enableExitButton()
if self._canSwitchTeams:
self.teamActivityGui.enableSwitchButton()
if self.activityFSM.state == 'WaitToStart':
self.showWaitToStartCountdown()
else:
self.showStatus()
def handleToonExited(self, toonId):
if toonId == base.localAvatar.doId:
self.hideStatus()
self.teamActivityGui.disableExitButton()
if self._canSwitchTeams:
self.teamActivityGui.disableSwitchButton()
if self.activityFSM.state == 'WaitToStart':
self.hideWaitToStartCountdown()
self.teamActivityGui.unload()
self.isLocalToonPlaying = False
self.localToonTeam = None
return
def handleRulesDone(self):
self.notify.debug('handleRulesDone')
self.d_toonReady()
self.activityFSM.request('WaitForServer')
def handleGameTimerExpired(self):
pass
def getToonsPlayingChanges(self, oldToonIds, newToonIds):
oldLeftTeam = oldToonIds[0]
oldRightTeam = oldToonIds[1]
newLeftTeam = newToonIds[0]
newRightTeam = newToonIds[1]
oldToons = set(oldLeftTeam + oldRightTeam)
newToons = set(newLeftTeam + newRightTeam)
exitedToons = oldToons.difference(newToons)
joinedToons = newToons.difference(oldToons)
shifters = []
if self._canSwitchTeams:
switchers = list(set(oldLeftTeam) & set(newRightTeam)) + list(set(oldRightTeam) & set(newLeftTeam))
else:
switchers = []
for i in range(len(PartyGlobals.TeamActivityTeams)):
persistentToons = set(oldToonIds[i]) & set(newToonIds[i])
for toonId in persistentToons:
if oldToonIds[i].index(toonId) != newToonIds[i].index(toonId):
shifters.append(toonId)
return (list(exitedToons),
list(joinedToons),
shifters,
switchers)
def getMaxPlayersPerTeam(self):
return self._maxPlayersPerTeam
def getMinPlayersPerTeam(self):
return self._minPlayersPerTeam
def getNumToonsNeededToStart(self):
if self._willBalanceTeams:
return abs(self._minPlayersPerTeam * 2 - self.getNumToonsPlaying())
else:
return self._minPlayersPerTeam
def getToonIdsAsList(self):
return self.toonIds[0] + self.toonIds[1]
def getNumToonsPlaying(self):
return len(self.toonIds[0]) + len(self.toonIds[1])
def getNumToonsInTeam(self, team):
return len(self.toonIds[team])
def getTeam(self, toonId):
for i in range(len(PartyGlobals.TeamActivityTeams)):
if self.toonIds[i].count(toonId) > 0:
return i
else:
return None
return None
def getIndex(self, toonId, team):
if self.toonIds[team].count(toonId) > 0:
return self.toonIds[team].index(toonId)
else:
return None
return None
def _joinLeftTeam(self, collEntry):
if self.isLocalToonInActivity():
return
self.d_toonJoinRequest(PartyGlobals.TeamActivityTeams.LeftTeam)
def _joinRightTeam(self, collEntry):
if self.isLocalToonInActivity():
return
self.d_toonJoinRequest(PartyGlobals.TeamActivityTeams.RightTeam)
def showWaitToStartCountdown(self):
if self.waitToStartTimestamp is None:
self.notify.warning('showWaitToStartCountdown was called when self.waitToStartTimestamp was None')
return
self.teamActivityGui.showWaitToStartCountdown(self._startDelay, self.waitToStartTimestamp, almostDoneCallback=self._onCountdownAlmostDone)
self.showStatus()
self.teamActivityGui.enableExitButton()
return
def _onCountdownAlmostDone(self):
if self._canSwitchTeams:
self.teamActivityGui.disableSwitchButton()
def hideWaitToStartCountdown(self):
self.teamActivityGui.hideWaitToStartCountdown()
self.teamActivityGui.disableExitButton()
self.hideStatus()
def setStatus(self, text):
self._currentStatus = text
if self.isLocalToonPlaying:
self.showStatus()
def showStatus(self):
if self.teamActivityGui is not None:
self.teamActivityGui.showStatus(self._currentStatus)
return
def hideStatus(self):
if self.teamActivityGui is not None:
self.teamActivityGui.hideStatus()
return
def toonsCanSwitchTeams(self):
return self._canSwitchTeams
def isState(self, state):
return hasattr(self, 'activityFSM') and self.activityFSM.getCurrentOrNextState() == state
def startWaitForEnough(self):
self.notify.debug('startWaitForEnough')
self.advantage = 1.0
self._updateWaitForEnoughStatus()
if self.isLocalToonPlaying:
self.teamActivityGui.enableExitButton()
if self._canSwitchTeams:
self.teamActivityGui.enableSwitchButton()
def finishWaitForEnough(self):
self.notify.debug('finishWaitForEnough')
def startWaitToStart(self, waitStartTimestamp):
self.notify.debug('startWaitToStart')
self.waitToStartTimestamp = globalClockDelta.networkToLocalTime(waitStartTimestamp)
self._updateWaitForEnoughStatus()
self.setStatus(TTLocalizer.PartyTeamActivityWaitingToStart)
if self.isLocalToonPlaying:
self.showWaitToStartCountdown()
def finishWaitToStart(self):
self.notify.debug('finishWaitToStart')
if self.isLocalToonPlaying:
self.hideWaitToStartCountdown()
if self._canSwitchTeams:
self.teamActivityGui.disableSwitchButton()
self.waitToStartTimestamp = None
return
def startRules(self):
self.notify.debug('startRules')
if self.isLocalToonPlaying:
DistributedPartyActivity.startRules(self)
def finishRules(self):
self.notify.debug('finishRules')
if self.isLocalToonPlaying:
DistributedPartyActivity.finishRules(self)
if self.activityFSM.getCurrentOrNextState() == 'WaitForEnough':
DistributedPartyActivity.finishRules(self)
def startWaitForServer(self):
self.notify.debug('startWaitForServer')
self.setStatus(TTLocalizer.PartyTeamActivityWaitingForOtherPlayers)
def finishWaitForServer(self):
self.notify.debug('finishWaitForServer')
if self.isLocalToonPlaying:
self.hideStatus()
def startActive(self):
self.notify.debug('startActive')
if self.isLocalToonPlaying:
self.hideStatus()
self.teamActivityGui.showTimer(self._duration)
def finishActive(self):
self.notify.debug('finishActive')
if self.isLocalToonPlaying:
self.teamActivityGui.hideTimer()
self.hideStatus()
def startConclusion(self, data):
self.notify.debug('startConclusion')
self.setStatus('')
if self.isLocalToonPlaying:
self.localToonExiting()
def finishConclusion(self):
self.notify.debug('finishConclusion')
if self.isLocalToonPlaying:
self.hideStatus()