Poodletooth-iLand/toontown/parties/DistributedPartyTugOfWarActivityAI.py

133 lines
4.7 KiB
Python

from direct.directnotify import DirectNotifyGlobal
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):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyTugOfWarActivityAI")
forbidTeamChanges = True
startDelay = PartyGlobals.TugOfWarStartDelay
def getDuration(self):
return PartyGlobals.TugOfWarDuration
def reportKeyRateForce(self, keyRate, force):
# 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
self.sendUpdate('updateToonPositions', [self.pos])
def reportFallIn(self, losingTeam):
if self.fsm.state != 'Active' or self._hasFall:
return
# 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.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