Tug Of War + Cog-O-War

This commit is contained in:
John 2015-07-27 10:55:40 +03:00
parent 26de40ce8c
commit 3e81a8c468
7 changed files with 372 additions and 79 deletions

View file

@ -20,7 +20,7 @@ class DistributedPartyTeamActivity(DistributedPartyActivity):
self._minPlayersPerTeam = 0 self._minPlayersPerTeam = 0
self._duration = 0 self._duration = 0
self._startDelay = base.config.GetFloat('party-team-activity-start-delay', startDelay) self._startDelay = base.config.GetFloat('party-team-activity-start-delay', startDelay)
self._willBalanceTeams = balanceTeams self._willBalanceTeams = False # balanceTeams
self._currentStatus = '' self._currentStatus = ''
return return
@ -207,7 +207,7 @@ class DistributedPartyTeamActivity(DistributedPartyActivity):
switchers = list(set(oldLeftTeam) & set(newRightTeam)) + list(set(oldRightTeam) & set(newLeftTeam)) switchers = list(set(oldLeftTeam) & set(newRightTeam)) + list(set(oldRightTeam) & set(newLeftTeam))
else: else:
switchers = [] switchers = []
for i in xrange(len(PartyGlobals.TeamActivityTeams)): for i in range(len(PartyGlobals.TeamActivityTeams)):
persistentToons = set(oldToonIds[i]) & set(newToonIds[i]) persistentToons = set(oldToonIds[i]) & set(newToonIds[i])
for toonId in persistentToons: for toonId in persistentToons:
if oldToonIds[i].index(toonId) != newToonIds[i].index(toonId): if oldToonIds[i].index(toonId) != newToonIds[i].index(toonId):
@ -240,7 +240,7 @@ class DistributedPartyTeamActivity(DistributedPartyActivity):
return len(self.toonIds[team]) return len(self.toonIds[team])
def getTeam(self, toonId): def getTeam(self, toonId):
for i in xrange(len(PartyGlobals.TeamActivityTeams)): for i in range(len(PartyGlobals.TeamActivityTeams)):
if self.toonIds[i].count(toonId) > 0: if self.toonIds[i].count(toonId) > 0:
return i return i
else: else:

View file

@ -1,35 +1,216 @@
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
from toontown.parties.DistributedPartyActivityAI import DistributedPartyActivityAI from direct.distributed.ClockDelta import globalClockDelta
from DistributedPartyActivityAI import DistributedPartyActivityAI
from activityFSMs import TeamActivityAIFSM
import PartyGlobals
'''
dclass DistributedPartyTeamActivity : DistributedPartyActivity {
toonJoinRequest(uint8(0-1)) airecv clsend;
toonExitRequest(uint8(0-1)) airecv clsend;
toonSwitchTeamRequest() airecv clsend;
setPlayersPerTeam(uint8, uint8) broadcast required;
setDuration(uint8) broadcast required;
setCanSwitchTeams(bool) broadcast required;
setState(string, int16, uint32) broadcast ram;
setToonsPlaying(uint32 [0-8], uint32 [0-8]) required broadcast ram;
setAdvantage(uint16/100);
switchTeamRequestDenied(uint8);
};
'''
'''self.defaultTransitions = {'WaitForEnough': ['WaitToStart'],
'WaitToStart': ['WaitForEnough', 'WaitClientsReady'],
'WaitClientsReady': ['WaitForEnough', 'Active'],
'Active': ['WaitForEnough', 'Conclusion'],
'Conclusion': ['WaitForEnough']}'''
class DistributedPartyTeamActivityAI(DistributedPartyActivityAI): class DistributedPartyTeamActivityAI(DistributedPartyActivityAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyTeamActivityAI") notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyTeamActivityAI")
forbidTeamChanges = False
startDelay = PartyGlobals.TeamActivityStartDelay
def __init__(self, air, parent, activityTuple):
self.toonIds = ([], [])
self.responses = set()
self.fsm = TeamActivityAIFSM(self)
DistributedPartyActivityAI.__init__(self, air, parent, activityTuple)
def announceGenerate(self):
self.b_setState('WaitForEnough')
DistributedPartyActivityAI.announceGenerate(self)
def toonJoinRequest(self, todo0): def toonJoinRequest(self, team):
pass av = self._getCaller()
if not av:
return
if not self.fsm.state in ('WaitForEnough', 'WaitToStart'):
self.sendUpdateToAvatarId(av.doId, 'joinTeamRequestDenied', [PartyGlobals.DenialReasons.Default])
return
if len(self.toonIds[team]) >= self.getPlayersPerTeam()[1]:
self.sendUpdateToAvatarId(av.doId, 'joinTeamRequestDenied', [PartyGlobals.DenialReasons.Full])
return
if av.doId in self.toonsPlaying:
self.air.writeServerEvent('suspicious', av.doId, 'tried to join party team activity again!')
self.sendUpdateToAvatarId(av.doId, 'joinTeamRequestDenied', [PartyGlobals.DenialReasons.Default])
return
def toonExitRequest(self, todo0): # idgaf if they exit unexpectedly in this case
pass self.toonIds[team].append(av.doId)
DistributedPartyActivityAI.toonJoinRequest(self)
self.__update()
def toonExitRequest(self, team):
av = self._getCaller()
if not av:
return
if not self.fsm.state in ('WaitForEnough', 'WaitToStart'):
self.sendUpdateToAvatarId(av.doId, 'exitRequestDenied', [PartyGlobals.DenialReasons.Default])
return
if not (av.doId in self.toonIds[0] or av.doId in self.toonIds[1]):
self.air.writeServerEvent('suspicious', avId, 'tried to switch DistributedPartyActivityAI team, but not in one')
self.sendUpdateToAvatarId(av.doId, 'exitRequestDenied', [PartyGlobals.DenialReasons.Default])
return
currentTeam = (1, 0)[av.doId in self.toonIds[0]]
self.toonIds[currentTeam].remove(av.doId)
DistributedPartyActivityAI.toonExitRequest(self)
self.__update()
def toonSwitchTeamRequest(self): def toonSwitchTeamRequest(self):
pass av = self._getCaller()
if not av:
return
if not self.getCanSwitchTeams():
self.air.writeServerEvent('suspicious', avId, 'tried to switch DistributedPartyActivityAI team in bad time')
self.sendUpdateToAvatarId(av.doId, 'switchTeamRequestDenied', [PartyGlobals.DenialReasons.Default])
return
if not (av.doId in self.toonIds[0] or av.doId in self.toonIds[1]):
self.air.writeServerEvent('suspicious', avId, 'tried to switch DistributedPartyActivityAI team, but not in one')
self.sendUpdateToAvatarId(av.doId, 'switchTeamRequestDenied', [PartyGlobals.DenialReasons.Default])
return
currentTeam = (1, 0)[av.doId in self.toonIds[0]]
otherTeam = (1, 0)[currentTeam]
if len(self.toonIds[otherTeam]) >= self.getPlayersPerTeam()[1]:
self.sendUpdateToAvatarId(av.doId, 'switchTeamRequestDenied', [PartyGlobals.DenialReasons.Full])
return
self.toonIds[currentTeam].remove(av.doId)
self.toonIds[otherTeam].append(av.doId)
self.__update()
def setPlayersPerTeam(self, todo0, todo1): def getPlayersPerTeam(self):
pass return (PartyGlobals.CogActivityMinPlayersPerTeam,
PartyGlobals.CogActivityMaxPlayersPerTeam)
def __areTeamsCorrect(self):
minPlayers = self.getPlayersPerTeam()[0]
return all(len(self.toonIds[i]) >= minPlayers for i in xrange(2))
def setDuration(self, todo0): def getDuration(self):
pass raise NotImplementedError('getDuration() -- pure virtual')
def setCanSwitchTeams(self, todo0): def getCanSwitchTeams(self):
pass return self.fsm.state in ('Off', 'WaitForEnough', 'WaitToStart') and not self.forbidTeamChanges
def setState(self, todo0, todo1, todo2): def updateToonsPlaying(self):
pass self.sendUpdate('setToonsPlaying', self.getToonsPlaying())
def setToonsPlaying(self, todo0, todo1): def getToonsPlaying(self):
pass return self.toonIds
def setAdvantage(self, todo0): def setAdvantage(self, todo0):
pass pass
def b_setState(self, state, data=0):
self.fsm.request(state, data)
self.d_setState(state, data)
def d_setState(self, state, data=0):
self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime(), data])
def switchTeamRequestDenied(self, todo0): def _getCaller(self):
avId = self.air.getAvatarIdFromSender()
if avId not in self.air.doId2do:
self.air.writeServerEvent('suspicious', avId, 'called some DistributedPartyActivityAI method outside shard')
return None
return self.air.doId2do[avId]
def __update(self):
self.updateToonsPlaying()
if self.fsm.state == 'WaitForEnough':
if self.__areTeamsCorrect():
self.b_setState('WaitToStart')
elif self.fsm.state == 'WaitToStart':
if not self.__areTeamsCorrect():
self.b_setState('WaitForEnough')
def startWaitForEnough(self, data):
pass pass
def finishWaitForEnough(self):
pass
def startWaitToStart(self, data):
def advance(task):
self.fsm.request('WaitClientsReady')
self.d_setState('Rules')
return task.done
taskMgr.doMethodLater(self.startDelay, advance, self.taskName('dostart'))
def finishWaitToStart(self):
taskMgr.remove(self.taskName('dostart'))
def __doStart(self, task = None):
self.b_setState('Active')
if task: return task.done
def startWaitClientsReady(self):
self.responses = set()
taskMgr.doMethodLater(15, self.__doStart, self.taskName('clientready'))
def finishWaitClientsReady(self):
taskMgr.remove(self.taskName('clientready'))
def toonReady(self):
self.responses.add(self.air.getAvatarIdFromSender())
if self.responses == set(self.toonsPlaying):
self.__doStart()
def startActive(self, data):
taskMgr.doMethodLater(self.getDuration(), self.__finish, self.taskName('finish'))
def finishActive(self):
taskMgr.remove(self.taskName('finish'))
def __finish(self, task):
self.calcReward()
self.b_setState('Conclusion')
return task.done
def calcReward(self):
raise NotImplementedError('calcReward() -- pure virtual')
def startConclusion(self, data):
raise NotImplementedError('startConclusion() -- pure virtual')
def finishConclusion(self):
raise NotImplementedError('finishConclusion() -- pure virtual')

View file

@ -128,7 +128,7 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
return return
def handleToonDisabled(self, toonId): def handleToonDisabled(self, toonId):
if toonId in self.toonIdsToAnimIntervals: if self.toonIdsToAnimIntervals.has_key(toonId):
if self.toonIdsToAnimIntervals[toonId]: if self.toonIdsToAnimIntervals[toonId]:
if self.toonIdsToAnimIntervals[toonId].isPlaying(): if self.toonIdsToAnimIntervals[toonId].isPlaying():
self.toonIdsToAnimIntervals[toonId].finish() self.toonIdsToAnimIntervals[toonId].finish()
@ -156,24 +156,24 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
self.playArea.reparentTo(self.root) self.playArea.reparentTo(self.root)
self.sign.reparentTo(self.playArea.find('**/TugOfWar_sign_locator')) self.sign.reparentTo(self.playArea.find('**/TugOfWar_sign_locator'))
self.dockPositions = [[], []] self.dockPositions = [[], []]
for i in xrange(4): for i in range(4):
self.dockPositions[0].append(Point3(-PartyGlobals.TugOfWarInitialToonPositionsXOffset - PartyGlobals.TugOfWarToonPositionXSeparation * i, 0.0, PartyGlobals.TugOfWarToonPositionZ)) self.dockPositions[0].append(Point3(-PartyGlobals.TugOfWarInitialToonPositionsXOffset - PartyGlobals.TugOfWarToonPositionXSeparation * i, 0.0, PartyGlobals.TugOfWarToonPositionZ))
for i in xrange(4): for i in range(4):
self.dockPositions[1].append(Point3(PartyGlobals.TugOfWarInitialToonPositionsXOffset + PartyGlobals.TugOfWarToonPositionXSeparation * i, 0.0, PartyGlobals.TugOfWarToonPositionZ)) self.dockPositions[1].append(Point3(PartyGlobals.TugOfWarInitialToonPositionsXOffset + PartyGlobals.TugOfWarToonPositionXSeparation * i, 0.0, PartyGlobals.TugOfWarToonPositionZ))
self.hopOffPositions = [[], []] self.hopOffPositions = [[], []]
for i in xrange(1, 5): for i in range(1, 5):
self.hopOffPositions[PartyGlobals.TeamActivityTeams.LeftTeam].append(self.playArea.find('**/leftTeamHopOff%d_locator' % i).getPos()) 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()) self.hopOffPositions[PartyGlobals.TeamActivityTeams.RightTeam].append(self.playArea.find('**/rightTeamHopOff%d_locator' % i).getPos())
for i in xrange(1, 5): for i in range(1, 5):
pos = self.playArea.find('**/fallenToon%d_locator' % i).getPos() pos = self.playArea.find('**/fallenToon%d_locator' % i).getPos()
self.fallenPositions.append(pos) self.fallenPositions.append(pos)
self.joinCollision = [] self.joinCollision = []
self.joinCollisionNodePaths = [] self.joinCollisionNodePaths = []
for i in xrange(len(PartyGlobals.TeamActivityTeams)): for i in range(len(PartyGlobals.TeamActivityTeams)):
collShape = CollisionTube(PartyGlobals.TugOfWarJoinCollisionEndPoints[0], PartyGlobals.TugOfWarJoinCollisionEndPoints[1], PartyGlobals.TugOfWarJoinCollisionRadius) collShape = CollisionTube(PartyGlobals.TugOfWarJoinCollisionEndPoints[0], PartyGlobals.TugOfWarJoinCollisionEndPoints[1], PartyGlobals.TugOfWarJoinCollisionRadius)
collShape.setTangible(True) collShape.setTangible(True)
self.joinCollision.append(CollisionNode('TugOfWarJoinCollision%d' % i)) self.joinCollision.append(CollisionNode('TugOfWarJoinCollision%d' % i))
@ -187,7 +187,7 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
ropeModel = loader.loadModel('phase_4/models/minigames/tug_of_war_rope') ropeModel = loader.loadModel('phase_4/models/minigames/tug_of_war_rope')
self.ropeTexture = ropeModel.findTexture('*') self.ropeTexture = ropeModel.findTexture('*')
ropeModel.removeNode() ropeModel.removeNode()
for i in xrange(PartyGlobals.TugOfWarMaximumPlayersPerTeam * 2 - 1): for i in range(PartyGlobals.TugOfWarMaximumPlayersPerTeam * 2 - 1):
rope = Rope(self.uniqueName('TugRope%d' % i)) rope = Rope(self.uniqueName('TugRope%d' % i))
if rope.showRope: if rope.showRope:
rope.ropeNode.setRenderMode(RopeNode.RMBillboard) rope.ropeNode.setRenderMode(RopeNode.RMBillboard)
@ -213,7 +213,7 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
self.powerMeter.setPos(0.0, 0.0, 0.6) self.powerMeter.setPos(0.0, 0.0, 0.6)
self.powerMeter.hide() self.powerMeter.hide()
self.arrows = [None] * 2 self.arrows = [None] * 2
for x in xrange(len(self.arrows)): for x in range(len(self.arrows)):
self.arrows[x] = loader.loadModel('phase_3/models/props/arrow') self.arrows[x] = loader.loadModel('phase_3/models/props/arrow')
self.arrows[x].reparentTo(self.powerMeter) self.arrows[x].reparentTo(self.powerMeter)
self.arrows[x].setScale(0.2 - 0.4 * x, 0.2, 0.2) self.arrows[x].setScale(0.2 - 0.4 * x, 0.2, 0.2)
@ -228,7 +228,7 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
def loadIntervals(self): def loadIntervals(self):
self.updateIdealRateInterval = Sequence() self.updateIdealRateInterval = Sequence()
self.updateIdealRateInterval.append(Wait(PartyGlobals.TugOfWarTargetRateList[0][0])) self.updateIdealRateInterval.append(Wait(PartyGlobals.TugOfWarTargetRateList[0][0]))
for i in xrange(1, len(PartyGlobals.TugOfWarTargetRateList)): for i in range(1, len(PartyGlobals.TugOfWarTargetRateList)):
duration = PartyGlobals.TugOfWarTargetRateList[i][0] duration = PartyGlobals.TugOfWarTargetRateList[i][0]
idealRate = PartyGlobals.TugOfWarTargetRateList[i][1] idealRate = PartyGlobals.TugOfWarTargetRateList[i][1]
self.updateIdealRateInterval.append(Func(self.setIdealRate, idealRate)) self.updateIdealRateInterval.append(Func(self.setIdealRate, idealRate))
@ -328,11 +328,11 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
del self.splashInterval del self.splashInterval
def __enableCollisions(self): def __enableCollisions(self):
for i in xrange(len(PartyGlobals.TeamActivityTeams)): for i in range(len(PartyGlobals.TeamActivityTeams)):
self.accept('enterTugOfWarJoinCollision%d' % i, getattr(self, '_join%s' % PartyGlobals.TeamActivityTeams.getString(i))) self.accept('enterTugOfWarJoinCollision%d' % i, getattr(self, '_join%s' % PartyGlobals.TeamActivityTeams.getString(i)))
def __disableCollisions(self): def __disableCollisions(self):
for i in xrange(len(PartyGlobals.TeamActivityTeams)): for i in range(len(PartyGlobals.TeamActivityTeams)):
self.ignore('enterTugOfWarJoinCollision%d' % i) self.ignore('enterTugOfWarJoinCollision%d' % i)
def startWaitForEnough(self): def startWaitForEnough(self):
@ -481,12 +481,12 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
for currTeam in teams: for currTeam in teams:
numToons = len(self.toonIds[currTeam]) numToons = len(self.toonIds[currTeam])
if numToons > 1: if numToons > 1:
for i in xrange(numToons - 1, 0, -1): for i in range(numToons - 1, 0, -1):
toon1 = self.toonIds[currTeam][i] toon1 = self.toonIds[currTeam][i]
toon2 = self.toonIds[currTeam][i - 1] toon2 = self.toonIds[currTeam][i - 1]
if toon1 not in self.toonIdsToRightHands: if not self.toonIdsToRightHands.has_key(toon1):
self.notify.warning('Toon in tug of war activity but not properly setup: %s' % toon1) self.notify.warning('Toon in tug of war activity but not properly setup: %s' % toon1)
elif toon2 not in self.toonIdsToRightHands: elif not self.toonIdsToRightHands.has_key(toon2):
self.notify.warning('Toon in tug of war activity but not properly setup: %s' % toon2) self.notify.warning('Toon in tug of war activity but not properly setup: %s' % toon2)
else: else:
self.notify.debug('Connecting rope between toon %d and toon %d of team %d.' % (i, i - 1, currTeam)) self.notify.debug('Connecting rope between toon %d and toon %d of team %d.' % (i, i - 1, currTeam))
@ -522,10 +522,10 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
self.idealForce = self.advantage * (4 + 0.4 * self.idealRate) self.idealForce = self.advantage * (4 + 0.4 * self.idealRate)
def updateKeyPressRate(self): def updateKeyPressRate(self):
for i in xrange(len(self.keyTTL)): for i in range(len(self.keyTTL)):
self.keyTTL[i] -= PartyGlobals.TugOfWarKeyPressUpdateRate self.keyTTL[i] -= PartyGlobals.TugOfWarKeyPressUpdateRate
for i in xrange(len(self.keyTTL)): for i in range(len(self.keyTTL)):
if self.keyTTL[i] <= 0.0: if self.keyTTL[i] <= 0.0:
a = self.keyTTL[0:i] a = self.keyTTL[0:i]
del self.keyTTL del self.keyTTL
@ -579,7 +579,7 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
if self.activityFSM.state != 'Active': if self.activityFSM.state != 'Active':
return return
toon = self.getAvatar(toonId) toon = self.getAvatar(toonId)
if toonId not in self.toonIdsToIsPullingFlags: if not self.toonIdsToIsPullingFlags.has_key(toonId):
if self.getTeam(toonId) == None: if self.getTeam(toonId) == None:
self.notify.warning("setAnimState called with toonId (%d) that wasn't in self.toonIds" % toonId) self.notify.warning("setAnimState called with toonId (%d) that wasn't in self.toonIds" % toonId)
return return
@ -671,7 +671,7 @@ class DistributedPartyTugOfWarActivity(DistributedPartyTeamActivity):
if fallenPosIndex < 0 or fallenPosIndex >= 4: if fallenPosIndex < 0 or fallenPosIndex >= 4:
fallenPosIndex = 0 fallenPosIndex = 0
newPos = self.fallenPositions[fallenPosIndex] newPos = self.fallenPositions[fallenPosIndex]
if toonId in self.toonIdsToAnimIntervals and self.toonIdsToAnimIntervals[toonId] is not None: if self.toonIdsToAnimIntervals.has_key(toonId) and self.toonIdsToAnimIntervals[toonId] is not None:
if self.toonIdsToAnimIntervals[toonId].isPlaying(): if self.toonIdsToAnimIntervals[toonId].isPlaying():
self.toonIdsToAnimIntervals[toonId].finish() self.toonIdsToAnimIntervals[toonId].finish()
if toon: if toon:

View file

@ -1,20 +1,133 @@
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
from toontown.parties.DistributedPartyTeamActivityAI import DistributedPartyTeamActivityAI
from DistributedPartyTeamActivityAI import DistributedPartyTeamActivityAI
from toontown.toonbase import TTLocalizer
import PartyGlobals
'''
dclass DistributedPartyTugOfWarActivity : DistributedPartyTeamActivity {
reportKeyRateForce(uint32, int16/100) airecv clsend;
reportFallIn(uint8) airecv clsend;
setToonsPlaying(uint32 [0-4], uint32 [0-4]) required broadcast ram;
updateToonKeyRate(uint32, uint32) broadcast;
updateToonPositions(int16/1000) broadcast;
};
'''
scoreRef = {'tie': (PartyGlobals.TugOfWarTieReward, PartyGlobals.TugOfWarTieReward),
0: (PartyGlobals.TugOfWarWinReward, PartyGlobals.TugOfWarLossReward),
1: (PartyGlobals.TugOfWarLossReward, PartyGlobals.TugOfWarWinReward),
10:(PartyGlobals.TugOfWarFallInWinReward, PartyGlobals.TugOfWarFallInLossReward),
11: (PartyGlobals.TugOfWarFallInLossReward, PartyGlobals.TugOfWarFallInWinReward),
}
class DistributedPartyTugOfWarActivityAI(DistributedPartyTeamActivityAI): class DistributedPartyTugOfWarActivityAI(DistributedPartyTeamActivityAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyTugOfWarActivityAI") notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyTugOfWarActivityAI")
forbidTeamChanges = True
startDelay = PartyGlobals.TugOfWarStartDelay
def getDuration(self):
return PartyGlobals.TugOfWarDuration
def reportKeyRateForce(self, todo0, todo1): def reportKeyRateForce(self, keyRate, force):
pass # Basic sanity check
av = self._getCaller()
if not av:
return
avId = av.doId
if not (avId in self.toonIds[0] or avId in self.toonIds[1]):
self.air.writeServerEvent('suspicious', avId, 'sent DistributedPartyTugOfWarActivityAI.reportKeyRateForce, but not playing')
return
self.forces[avId] = force
self.sendUpdate('updateToonKeyRate', [avId, keyRate])
self.d_updateToonPositions()
def d_updateToonPositions(self):
_getTeamForce = lambda team: sum(self.forces.get(avId, 0) for avId in self.toonIds[team])
f0 = _getTeamForce(0)
f1 = _getTeamForce(1)
fr = f0 + f1
if fr != 0:
delta = (f0 - f1) / fr
self.pos += -delta * PartyGlobals.TugOfWarMovementFactor * 2
def reportFallIn(self, todo0): self.sendUpdate('updateToonPositions', [self.pos])
pass
def reportFallIn(self, losingTeam):
def setToonsPlaying(self, todo0, todo1): if self.fsm.state != 'Active' or self._hasFall:
pass return
def updateToonKeyRate(self, todo0, todo1): # Basic sanity check
pass av = self._getCaller()
if not av:
def updateToonPositions(self, todo0): return
pass
avId = av.doId
if not (avId in self.toonIds[0] or avId in self.toonIds[1]):
self.air.writeServerEvent('suspicious', avId, 'sent DistributedPartyTugOfWarActivityAI.reportFallIn, but not playing')
return
losers = int(self.pos < 0)
if losers != losingTeam:
self.air.writeServerEvent('suspicious', avId, 'called DistributedPartyTugOfWarActivityAI.reportFallIn with incorrect losingTeam')
self._hasFall = 1
def _advance(task):
self.calcReward()
return task.done
taskMgr.doMethodLater(1, _advance, self.taskName('fallIn-advance'))
taskMgr.remove(self.taskName('finish')) # Mitigate races
def calcReward(self):
nobodyWins = abs(self.pos) <= 2
if nobodyWins:
self._winnerTeam = 3
self._teamScores = scoreRef['tie']
else:
self._winnerTeam = int(self.pos < 0)
self._teamScores = scoreRef[self._winnerTeam + self._hasFall * 10]
self.b_setState('Conclusion', self._winnerTeam)
def startActive(self, data):
self.forces = {}
self.pos = 0
self._hasFall = 0
DistributedPartyTeamActivityAI.startActive(self, data)
def startConclusion(self, data):
taskMgr.doMethodLater(1, self.__exitConclusion, self.taskName('exitconc'))
def finishConclusion(self):
taskMgr.remove(self.taskName('exitconc'))
def __exitConclusion(self, task):
def _sendReward(team):
jb = self._teamScores[team]
msg = TTLocalizer.PartyTeamActivityRewardMessage % jb
for avId in self.toonIds[team]:
av = self.air.doId2do.get(avId)
if av:
self.sendUpdateToAvatarId(avId, 'showJellybeanReward', [jb, av.getMoney(), msg])
av.addMoney(jb)
_sendReward(0)
_sendReward(1)
self.toonsPlaying = []
self.toonIds = ([], [])
self.updateToonsPlaying()
self.b_setState('WaitForEnough')
return task.done

View file

@ -263,13 +263,13 @@ class PartyCogActivity(DirectObject):
pos = self._doorStartPos[team] pos = self._doorStartPos[team]
else: else:
pos = (self._doorStartPos[team] + Point3(0, 0, -7.0),) pos = (self._doorStartPos[team] + Point3(0, 0, -7.0),)
ival = self._arenaDoors[team].posInterval(0.75, pos, blendType='easeIn') ival = self._arenaDoors[team].posInterval(0.75, Point3(0, 0, -7.0), blendType='easeIn')
self._arenaDoorIvals[team] = ival self._arenaDoorIvals[team] = ival
ival.start() ival.start()
return return
def openArenaDoorForTeam(self, team): def openArenaDoorForTeam(self, team):
self._playArenaDoorIval(team, opening=True) self._playArenaDoorIval(team, opening=False)
def closeArenaDoorForTeam(self, team): def closeArenaDoorForTeam(self, team):
self._playArenaDoorIval(team, opening=False) self._playArenaDoorIval(team, opening=False)

View file

@ -290,8 +290,8 @@ class PartyEditorGrid:
None, None,
None, None,
None]] None]]
for y in xrange(len(self.grid)): for y in range(len(self.grid)):
for x in xrange(len(self.grid[0])): for x in range(len(self.grid[0])):
if self.grid[y][x]: if self.grid[y][x]:
self.grid[y][x] = PartyEditorGridSquare(self.partyEditor, x, y) self.grid[y][x] = PartyEditorGridSquare(self.partyEditor, x, y)
@ -299,8 +299,8 @@ class PartyEditorGrid:
def getActivitiesOnGrid(self): def getActivitiesOnGrid(self):
activities = [] activities = []
for y in xrange(len(self.grid)): for y in range(len(self.grid)):
for x in xrange(len(self.grid[0])): for x in range(len(self.grid[0])):
if self.grid[y][x] and self.grid[y][x].gridElement: if self.grid[y][x] and self.grid[y][x].gridElement:
if not self.grid[y][x].gridElement.isDecoration: if not self.grid[y][x].gridElement.isDecoration:
activityTuple = self.grid[y][x].gridElement.getActivityTuple(x, y) activityTuple = self.grid[y][x].gridElement.getActivityTuple(x, y)
@ -312,8 +312,8 @@ class PartyEditorGrid:
def getActivitiesElementsOnGrid(self): def getActivitiesElementsOnGrid(self):
activities = [] activities = []
activityElems = [] activityElems = []
for y in xrange(len(self.grid)): for y in range(len(self.grid)):
for x in xrange(len(self.grid[0])): for x in range(len(self.grid[0])):
if self.grid[y][x] and self.grid[y][x].gridElement: if self.grid[y][x] and self.grid[y][x].gridElement:
if not self.grid[y][x].gridElement.isDecoration: if not self.grid[y][x].gridElement.isDecoration:
activityTuple = self.grid[y][x].gridElement.getActivityTuple(x, y) activityTuple = self.grid[y][x].gridElement.getActivityTuple(x, y)
@ -325,8 +325,8 @@ class PartyEditorGrid:
def getDecorationsOnGrid(self): def getDecorationsOnGrid(self):
decorations = [] decorations = []
for y in xrange(len(self.grid)): for y in range(len(self.grid)):
for x in xrange(len(self.grid[0])): for x in range(len(self.grid[0])):
if self.grid[y][x] and self.grid[y][x].gridElement: if self.grid[y][x] and self.grid[y][x].gridElement:
if self.grid[y][x].gridElement.isDecoration: if self.grid[y][x].gridElement.isDecoration:
decorationTuple = self.grid[y][x].gridElement.getDecorationTuple(x, y) decorationTuple = self.grid[y][x].gridElement.getDecorationTuple(x, y)
@ -344,8 +344,8 @@ class PartyEditorGrid:
def checkGridSquareForAvailability(self, gridSquare, size): def checkGridSquareForAvailability(self, gridSquare, size):
xOffsetLow, xOffsetHigh, yOffset = self.getXYOffsets(size) xOffsetLow, xOffsetHigh, yOffset = self.getXYOffsets(size)
for y in xrange(int(gridSquare.y - size[1] / 2), int(gridSquare.y + size[1] / 2) + yOffset): for y in range(int(gridSquare.y - size[1] / 2), int(gridSquare.y + size[1] / 2) + yOffset):
for x in xrange(int(gridSquare.x - size[0] / 2) + xOffsetLow, int(gridSquare.x + size[0] / 2) + xOffsetHigh): for x in range(int(gridSquare.x - size[0] / 2) + xOffsetLow, int(gridSquare.x + size[0] / 2) + xOffsetHigh):
testGridSquare = self.getGridSquare(x, y) testGridSquare = self.getGridSquare(x, y)
if testGridSquare is None: if testGridSquare is None:
return False return False
@ -361,8 +361,8 @@ class PartyEditorGrid:
if self.grid[y][x] is not None: if self.grid[y][x] is not None:
if self.checkGridSquareForAvailability(self.grid[y][x], size): if self.checkGridSquareForAvailability(self.grid[y][x], size):
return self.grid[y][x] return self.grid[y][x]
for y in xrange(PartyGlobals.PartyEditorGridSize[1]): for y in range(PartyGlobals.PartyEditorGridSize[1]):
for x in xrange(PartyGlobals.PartyEditorGridSize[0]): for x in range(PartyGlobals.PartyEditorGridSize[0]):
if self.grid[y][x] is not None: if self.grid[y][x] is not None:
if self.checkGridSquareForAvailability(self.grid[y][x], size): if self.checkGridSquareForAvailability(self.grid[y][x], size):
return self.grid[y][x] return self.grid[y][x]
@ -384,8 +384,8 @@ class PartyEditorGrid:
def registerNewElement(self, gridElement, centerGridSquare, size): def registerNewElement(self, gridElement, centerGridSquare, size):
xOffsetLow, xOffsetHigh, yOffset = self.getXYOffsets(size) xOffsetLow, xOffsetHigh, yOffset = self.getXYOffsets(size)
for y in xrange(int(centerGridSquare.y - size[1] / 2), int(centerGridSquare.y + size[1] / 2) + yOffset): for y in range(int(centerGridSquare.y - size[1] / 2), int(centerGridSquare.y + size[1] / 2) + yOffset):
for x in xrange(int(centerGridSquare.x - size[0] / 2) + xOffsetLow, int(centerGridSquare.x + size[0] / 2) + xOffsetHigh): for x in range(int(centerGridSquare.x - size[0] / 2) + xOffsetLow, int(centerGridSquare.x + size[0] / 2) + xOffsetHigh):
testGridSquare = self.getGridSquare(x, y) testGridSquare = self.getGridSquare(x, y)
if testGridSquare is None: if testGridSquare is None:
return False return False
@ -400,8 +400,8 @@ class PartyEditorGrid:
def removeElement(self, centerGridSquare, size): def removeElement(self, centerGridSquare, size):
xOffsetLow, xOffsetHigh, yOffset = self.getXYOffsets(size) xOffsetLow, xOffsetHigh, yOffset = self.getXYOffsets(size)
for y in xrange(int(centerGridSquare.y - size[1] / 2), int(centerGridSquare.y + size[1] / 2) + yOffset): for y in range(int(centerGridSquare.y - size[1] / 2), int(centerGridSquare.y + size[1] / 2) + yOffset):
for x in xrange(int(centerGridSquare.x - size[0] / 2) + xOffsetLow, int(centerGridSquare.x + size[0] / 2) + xOffsetHigh): for x in range(int(centerGridSquare.x - size[0] / 2) + xOffsetLow, int(centerGridSquare.x + size[0] / 2) + xOffsetHigh):
testGridSquare = self.getGridSquare(x, y) testGridSquare = self.getGridSquare(x, y)
if testGridSquare is None: if testGridSquare is None:
return False return False
@ -414,8 +414,8 @@ class PartyEditorGrid:
def destroy(self): def destroy(self):
self.partyEditor = None self.partyEditor = None
for y in xrange(len(self.grid)): for y in range(len(self.grid)):
for x in xrange(len(self.grid[0])): for x in range(len(self.grid[0])):
if self.grid[y][x]: if self.grid[y][x]:
self.grid[y][x].destroy() self.grid[y][x].destroy()

View file

@ -72,11 +72,11 @@ class PartyEditorListElement(DirectButton):
self.bind(DirectGuiGlobals.B1RELEASE, self.released) self.bind(DirectGuiGlobals.B1RELEASE, self.released)
self.partyEditorGridElements = [] self.partyEditorGridElements = []
if self.isDecoration: if self.isDecoration:
for i in xrange(PartyGlobals.DecorationInformationDict[self.id]['limitPerParty']): for i in range(PartyGlobals.DecorationInformationDict[self.id]['limitPerParty']):
self.partyEditorGridElements.append(PartyEditorGridElement(self.partyEditor, self.id, self.isDecoration, self.checkSoldOutAndAffordability)) self.partyEditorGridElements.append(PartyEditorGridElement(self.partyEditor, self.id, self.isDecoration, self.checkSoldOutAndAffordability))
else: else:
for i in xrange(PartyGlobals.ActivityInformationDict[self.id]['limitPerParty']): for i in range(PartyGlobals.ActivityInformationDict[self.id]['limitPerParty']):
self.partyEditorGridElements.append(PartyEditorGridElement(self.partyEditor, self.id, self.isDecoration, self.checkSoldOutAndAffordability)) self.partyEditorGridElements.append(PartyEditorGridElement(self.partyEditor, self.id, self.isDecoration, self.checkSoldOutAndAffordability))
self.activeGridElementIndex = -1 self.activeGridElementIndex = -1
@ -130,14 +130,13 @@ class PartyEditorListElement(DirectButton):
else: else:
self.setTooExpensive(False) self.setTooExpensive(False)
tooExpensive = False tooExpensive = False
for i in xrange(len(self.partyEditorGridElements)): for i in range(len(self.partyEditorGridElements)):
if not self.partyEditorGridElements[i].overValidSquare: if not self.partyEditorGridElements[i].overValidSquare:
if not tooExpensive: if not tooExpensive:
self.setSoldOut(False) self.setSoldOut(False)
return return
self.setSoldOut(True) self.setSoldOut(True)
return
def setTooExpensive(self, value): def setTooExpensive(self, value):
self.partyEditor.partyPlanner.elementBuyButton['text'] = TTLocalizer.PartyPlannerBuy self.partyEditor.partyPlanner.elementBuyButton['text'] = TTLocalizer.PartyPlannerBuy
@ -165,14 +164,14 @@ class PartyEditorListElement(DirectButton):
def clicked(self, mouseEvent): def clicked(self, mouseEvent):
PartyEditorListElement.notify.debug("Element %s's icon was clicked" % self.name) PartyEditorListElement.notify.debug("Element %s's icon was clicked" % self.name)
self.partyEditor.listElementClicked() self.partyEditor.listElementClicked()
for i in xrange(len(self.partyEditorGridElements)): for i in range(len(self.partyEditorGridElements)):
if not self.partyEditorGridElements[i].overValidSquare: if not self.partyEditorGridElements[i].overValidSquare:
self.partyEditorGridElements[i].attach(mouseEvent) self.partyEditorGridElements[i].attach(mouseEvent)
self.activeGridElementIndex = i self.activeGridElementIndex = i
return return
def buyButtonClicked(self, desiredXY = None): def buyButtonClicked(self, desiredXY = None):
for i in xrange(len(self.partyEditorGridElements)): for i in range(len(self.partyEditorGridElements)):
if not self.partyEditorGridElements[i].overValidSquare: if not self.partyEditorGridElements[i].overValidSquare:
if self.partyEditorGridElements[i].placeInPartyGrounds(desiredXY): if self.partyEditorGridElements[i].placeInPartyGrounds(desiredXY):
self.activeGridElementIndex = i self.activeGridElementIndex = i