import math from direct.directnotify import DirectNotifyGlobal from toontown.minigame.DropScheduler import ThreePhaseDropScheduler from toontown.parties import PartyGlobals from functools import reduce class DistributedPartyCatchActivityBase: notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPartyCatchActivityBase') FallRateCap_Players = 20 def calcDifficultyConstants(self, numPlayers): self.FirstDropDelay = 0.0 self.NormalDropDelay = int(1.0 / 12 * PartyGlobals.CatchActivityDuration) self.FasterDropDelay = int(9.0 / 12 * PartyGlobals.CatchActivityDuration) DistributedPartyCatchActivityBase.notify.debug('will start dropping fast after %s seconds' % self.FasterDropDelay) self.SlowerDropPeriodMult = 1.5 self.FasterDropPeriodMult = 1.0 / 3 self.ToonSpeed = 16.0 def scaledDimensions(widthHeight, scale): w, h = widthHeight return [math.sqrt(scale * w * w), math.sqrt(scale * h * h)] BaseStageDimensions = [36, 36] self.StageAreaScale = 1.0 self.StageLinearScale = math.sqrt(self.StageAreaScale) DistributedPartyCatchActivityBase.notify.debug('StageLinearScale: %s' % self.StageLinearScale) self.StageDimensions = scaledDimensions(BaseStageDimensions, self.StageAreaScale) DistributedPartyCatchActivityBase.notify.debug('StageDimensions: %s' % self.StageDimensions) self.StageHalfWidth = self.StageDimensions[0] / 2.0 self.StageHalfHeight = self.StageDimensions[1] / 2.0 self.MinOffscreenHeight = 30 distance = math.sqrt(self.StageDimensions[0] * self.StageDimensions[0] + self.StageDimensions[1] * self.StageDimensions[1]) distance /= self.StageLinearScale ToonRunDuration = distance / self.ToonSpeed offScreenOnScreenRatio = 1.0 fraction = 1.0 / 3 * 0.85 self.BaselineOnscreenDropDuration = ToonRunDuration / (fraction * (1.0 + offScreenOnScreenRatio)) DistributedPartyCatchActivityBase.notify.debug('BaselineOnscreenDropDuration=%s' % self.BaselineOnscreenDropDuration) self.OffscreenTime = offScreenOnScreenRatio * self.BaselineOnscreenDropDuration DistributedPartyCatchActivityBase.notify.debug('OffscreenTime=%s' % self.OffscreenTime) self.BaselineDropDuration = self.BaselineOnscreenDropDuration + self.OffscreenTime self.MaxDropDuration = self.BaselineDropDuration self.DropPeriod = self.BaselineDropDuration / 3.0 scaledNumPlayers = (min(numPlayers, self.FallRateCap_Players) - 1.0) * 0.85 + 1.0 self.DropPeriod /= scaledNumPlayers typeProbs = {'fruit': 3, 'anvil': 1} probSum = reduce(lambda x, y: x + y, list(typeProbs.values())) for key in list(typeProbs.keys()): typeProbs[key] = float(typeProbs[key]) / probSum scheduler = ThreePhaseDropScheduler(PartyGlobals.CatchActivityDuration, self.FirstDropDelay, self.DropPeriod, self.MaxDropDuration, self.SlowerDropPeriodMult, self.NormalDropDelay, self.FasterDropDelay, self.FasterDropPeriodMult) self.totalDrops = 0 while not scheduler.doneDropping(continuous=True): scheduler.stepT() self.totalDrops += 1 self.numFruits = int(self.totalDrops * typeProbs['fruit']) self.numAnvils = int(self.totalDrops - self.numFruits) self.generationDuration = scheduler.getDuration()