def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval = Sequence()): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.5) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame=48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.mp3') t = power / 100.0 dist = lerp(PartyGlobals.CogActivityPieMinDist, PartyGlobals.CogActivityPieMaxDist, t) time = lerp(1.0, 1.5, t) proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(toon = toon, relVel = relVel): return render.getRelativeVector(toon, relVel) * 0.6 def __safeSetAnimState(toon = toon, state = 'Happy'): if toon and hasattr(toon, 'animFSM'): toon.setAnimState('Happy') else: self.notify.warning('The toon is being destroyed. No attribute animState.') toss = Track((0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), animPie, Parallel(ActorInterval(toon, 'throw', startFrame=48, playRate=1.5, partName='torso'), animPie), Func(__safeSetAnimState, toon, 'Happy'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track((14.0 / 24.0, SoundInterval(sound, node=toon, cutOff=PartyGlobals.PARTY_COG_CUTOFF)), (16.0 / 24.0, Sequence(Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return (toss, fly, flyPie)
def driftMood(self, dt = None, curMood = None): now = globalClock.getFrameTime() if not hasattr(self, 'lastDriftTime'): self.lastDriftTime = now if dt is None: dt = now - self.lastDriftTime self.lastDriftTime = now if dt <= 0.0: return if curMood is None: curMood = self def doDrift(curValue, timeToMedian, dt = float(dt)): newValue = curValue + dt / (timeToMedian * 7200) return min(max(newValue, 0.0), 1.0) self.boredom = doDrift(curMood.boredom, self.tBoredom) self.loneliness = doDrift(curMood.loneliness, self.tLoneliness) self.sadness = doDrift(curMood.sadness, self.tSadness) self.fatigue = doDrift(curMood.fatigue, self.tFatigue) self.hunger = doDrift(curMood.hunger, self.tHunger) self.confusion = doDrift(curMood.confusion, self.tConfusion) self.excitement = doDrift(curMood.excitement, self.tExcitement) self.surprise = doDrift(curMood.surprise, self.tSurprise) self.affection = doDrift(curMood.affection, self.tAffection) abuse = average(curMood.hunger, curMood.hunger, curMood.hunger, curMood.boredom, curMood.loneliness) tipPoint = 0.6 if abuse < tipPoint: tAnger = lerp(self.tAngerDec, -PetMood.LONGTIME, abuse / tipPoint) else: tAnger = lerp(PetMood.LONGTIME, self.tAngerInc, (abuse - tipPoint) / (1.0 - tipPoint)) self.anger = doDrift(curMood.anger, tAnger) self.announceChange() return
def calcDifficultyConstants(self, difficulty, numPlayers): ToonSpeedRange = [16.0, 25.0] self.ToonSpeed = lerp(ToonSpeedRange[0], ToonSpeedRange[1], difficulty) self.SuitSpeed = self.ToonSpeed / 2.0 self.SuitPeriodRange = [lerp(5.0, 3.0, self.getDifficulty()), lerp(15.0, 8.0, self.getDifficulty())] def scaledDimensions(widthHeight, scale): w, h = widthHeight return [math.sqrt(scale * w * w), math.sqrt(scale * h * h)] BaseStageDimensions = [20, 15] areaScales = [1.0, 1.0, 3.0 / 2, 4.0 / 2] self.StageAreaScale = areaScales[numPlayers - 1] self.StageLinearScale = math.sqrt(self.StageAreaScale) self.notify.debug("StageLinearScale: %s" % self.StageLinearScale) self.StageDimensions = scaledDimensions(BaseStageDimensions, self.StageAreaScale) self.notify.debug("StageDimensions: %s" % self.StageDimensions) self.StageHalfWidth = self.StageDimensions[0] / 2.0 self.StageHalfHeight = self.StageDimensions[1] / 2.0 MOHs = [24] * 2 + [26, 28] self.MinOffscreenHeight = MOHs[self.getNumPlayers() - 1] distance = math.sqrt( self.StageDimensions[0] * self.StageDimensions[0] + self.StageDimensions[1] * self.StageDimensions[1] ) distance /= self.StageLinearScale if self.DropPlacerType == PathDropPlacer: distance /= 1.5 ToonRunDuration = distance / self.ToonSpeed offScreenOnScreenRatio = 1.0 fraction = 1.0 / 3 * 0.85 self.BaselineOnscreenDropDuration = ToonRunDuration / (fraction * (1.0 + offScreenOnScreenRatio)) self.notify.debug("BaselineOnscreenDropDuration=%s" % self.BaselineOnscreenDropDuration) self.OffscreenTime = offScreenOnScreenRatio * self.BaselineOnscreenDropDuration self.notify.debug("OffscreenTime=%s" % self.OffscreenTime) self.BaselineDropDuration = self.BaselineOnscreenDropDuration + self.OffscreenTime self.MaxDropDuration = self.BaselineDropDuration self.DropPeriod = self.BaselineDropDuration / 2.0 scaledNumPlayers = (numPlayers - 1.0) * 0.75 + 1.0 self.DropPeriod /= scaledNumPlayers typeProbs = {"fruit": 3, "anvil": 1} probSum = reduce(lambda x, y: x + y, typeProbs.values()) for key in typeProbs.keys(): typeProbs[key] = float(typeProbs[key]) / probSum scheduler = DropScheduler( CatchGameGlobals.GameDuration, self.FirstDropDelay, self.DropPeriod, self.MaxDropDuration, self.FasterDropDelay, self.FasterDropPeriodMult, ) self.totalDrops = 0 while not scheduler.doneDropping(): scheduler.stepT() self.totalDrops += 1 self.numFruits = int(self.totalDrops * typeProbs["fruit"]) self.numAnvils = int(self.totalDrops - self.numFruits)
def _handleDidTrick(self, trickId): DistributedPetAI.notify.debug('_handleDidTrick: %s' % trickId) if trickId == PetTricks.Tricks.BALK: return aptitude = self.getTrickAptitude(trickId) self.setTrickAptitude(trickId, aptitude + PetTricks.AptitudeIncrementDidTrick) self.addToMood('fatigue', lerp(PetTricks.MaxTrickFatigue, PetTricks.MinTrickFatigue, aptitude))
def update(self, pet): if not pet: return for trickId in PetTricks.TrickId2scIds.keys(): trickText = TTLocalizer.PetTrickStrings[trickId] if trickId < len(pet.trickAptitudes): aptitude = pet.trickAptitudes[trickId] bar = self.bars.get(trickId) label = self.bars.get(trickId) if aptitude != 0: healRange = PetTricks.TrickHeals[trickId] hp = lerp(healRange[0], healRange[1], aptitude) if hp == healRange[1]: hp = healRange[1] length = 1 barColor = (0.7, 0.8, 0.5, 1) else: hp, length = divmod(hp, 1) barColor = (0.9, 1, 0.7, 1) if not label: self.labels[trickId] = DirectLabel(parent=self, relief=None, pos=(0, 0, 0.43 - trickId * 0.155), scale=0.7, text=trickText, text_scale=TTLocalizer.PDPtrickText, text_fg=(0.05, 0.14, 0.4, 1), text_align=TextNode.ALeft, text_pos=(-1.4, -0.05)) else: label['text'] = trickText if not bar: self.bars[trickId] = DirectWaitBar(parent=self, pos=(0, 0, 0.43 - trickId * 0.155), relief=DGG.SUNKEN, frameSize=(-0.5, 0.9, -0.1, 0.1), borderWidth=(0.025, 0.025), scale=0.7, frameColor=(0.4, 0.6, 0.4, 1), barColor=barColor, range=1.0 + FUDGE_FACTOR, value=length + FUDGE_FACTOR, text=str(int(hp)) + ' ' + TTLocalizer.Laff, text_scale=TTLocalizer.PDPlaff, text_fg=(0.05, 0.14, 0.4, 1), text_align=TextNode.ALeft, text_pos=TTLocalizer.PDPlaffPos) else: bar['value'] = length + FUDGE_FACTOR bar['text'] = (str(int(hp)) + ' ' + TTLocalizer.Laff,) return
def calcDrift(baseT, trait, fasterDriftIsBetter = False): value = trait.percentile if not trait.higherIsBetter: value = 1.0 - value if fasterDriftIsBetter: if value < 0.5: factor = lerp(2.0, 1.0, value * 2.0) else: rebased = (value - 0.5) * 2.0 factor = lerp(1.0, 0.1, rebased * rebased) elif value < 0.5: factor = lerp(0.75, 1.0, value * 2.0) else: rebased = (value - 0.5) * 2.0 factor = lerp(1.0, 28.0, rebased * rebased) return baseT * factor
def updatePriorities(self): if len(self.goals) == 0: return if self.primaryGoal is None: highestPriority = -99999.0 candidates = [] else: highestPriority = self.primaryGoal.getPriority() candidates = [self.primaryGoal] decayDur = PetConstants.PrimaryGoalDecayDur priFactor = PetConstants.PrimaryGoalScale elapsed = min(decayDur, globalClock.getFrameTime() - self.primaryStartT) highestPriority *= lerp(priFactor, 1.0, elapsed / decayDur) for goal in self.goals: thisPri = goal.getPriority() if thisPri >= highestPriority: if thisPri > highestPriority: highestPriority = thisPri candidates = [goal] else: candidates.append(goal) newPrimary = random.choice(candidates) if self.primaryGoal != newPrimary: self.pet.notify.debug('new goal: %s, priority=%s' % (newPrimary.__class__.__name__, highestPriority)) self._setPrimaryGoal(newPrimary) return
def startSuitWalkTask(self): ival = Parallel(name='catchGameMetaSuitWalk') rng = RandomNumGen(self.randomNumGen) delay = 0.0 while delay < CatchGameGlobals.GameDuration: delay += lerp(self.SuitPeriodRange[0], self.SuitPeriodRange[0], rng.random()) walkIval = Sequence(name='catchGameSuitWalk') walkIval.append(Wait(delay)) def pickY(self = self, rng = rng): return lerp(-self.StageHalfHeight, self.StageHalfHeight, rng.random()) m = [2.5, 2.5, 2.3, 2.1][self.getNumPlayers() - 1] startPos = Point3(-(self.StageHalfWidth * m), pickY(), 0) stopPos = Point3(self.StageHalfWidth * m, pickY(), 0) if rng.choice([0, 1]): startPos, stopPos = stopPos, startPos walkIval.append(self.getSuitWalkIval(startPos, stopPos, rng)) ival.append(walkIval) ival.start() self.suitWalkIval = ival
def move(self, task = None): print "START WALKING" if self.isEmpty(): try: self.air.writeServerEvent('Late Pet Move Call', self.doId, ' ') except: pass taskMgr.remove(task.name) return Task.done if not self.isLockMoverEnabled(): pass #self.mover.move() #self.mover.processImpulses() #self.mover.integrate() numNearby = len(self.brain.nearbyAvs) - 1 minNearby = 5 if numNearby > minNearby: delay = 0.08 * (numNearby - minNearby) self.setPosHprBroadcastPeriod(PetConstants.PosBroadcastPeriod + lerp(delay * 0.75, delay, random.random())) maxDist = 1000 if abs(self.getX()) > maxDist or abs(self.getY()) > maxDist: DistributedPetAI.notify.warning('deleting pet %s before he wanders off too far' % self.doId) self._outOfBounds = True self.stopPosHprBroadcast() self.requestDelete() return Task.done if __dev__: self.pscMoveResc.start() taskMgr.doMethodLater(simbase.petMovePeriod, self.move, self.getMoveTaskName()) if __dev__: self.pscMoveResc.stop() return Task.done
def _handleDidTrick(self, trickId): DistributedPetProxyAI.notify.debug("_handleDidTrick: %s" % trickId) if trickId == PetTricks.Tricks.BALK: return aptitude = self.getTrickAptitude(trickId) self.setTrickAptitude(trickId, aptitude + PetTricks.AptitudeIncrementDidTrick) self.addToMood("fatigue", lerp(PetTricks.MaxTrickFatigue, PetTricks.MinTrickFatigue, aptitude)) self.d_setDominantMood(self.mood.getDominantMood())
def finish(avatar = avatar, trickId = trickId, self = self): if hasattr(self.pet, 'brain'): healRange = PetTricks.TrickHeals[trickId] aptitude = self.pet.getTrickAptitude(trickId) healAmt = int(lerp(healRange[0], healRange[1], aptitude)) if healAmt: for avId, av in self.pet._getFullNearbyToonDict().items(): if isinstance(av, DistributedToonAI.DistributedToonAI): av.toonUp(healAmt) self.pet._handleDidTrick(trickId) if not self.pet.isLockedDown(): self.pet.unlockPet() messenger.send(self.getTrickDoneEvent())
def _willDoTrick(self, trickId): if self.isContented(): minApt = PetTricks.MinActualTrickAptitude maxApt = PetTricks.MaxActualTrickAptitude else: minApt = PetTricks.NonHappyMinActualTrickAptitude maxApt = PetTricks.NonHappyMaxActualTrickAptitude randVal = random.random() cutoff = lerp(minApt, maxApt, self.getTrickAptitude(trickId)) if self.mood.isComponentActive('fatigue'): cutoff *= 0.5 cutoff *= PetTricks.TrickAccuracies[trickId] DistributedPetAI.notify.debug('_willDoTrick: %s / %s' % (randVal, cutoff)) return randVal < cutoff
def finish(avatar = avatar, trickId = trickId, self = self): if hasattr(self.pet, 'brain'): healRange = PetTricks.TrickHeals[trickId] aptitude = self.pet.getTrickAptitude(trickId) healAmt = int(lerp(healRange[0], healRange[1], aptitude)) if healAmt: for avId in self.pet.brain.getAvIdsLookingAtUs(): av = self.pet.air.doId2do.get(avId) if av: if isinstance(av, DistributedToonAI.DistributedToonAI): av.toonUp(healAmt) self.pet._handleDidTrick(trickId) if not self.pet.isLockedDown(): self.pet.unlockPet() messenger.send(self.getTrickDoneEvent())
def move(self, task=None): if self.isEmpty(): self.air.writeServerEvent("Late Pet Move Call", self.doId, " ") taskMgr.remove(task.name) return Task.done numNearby = len(self.brain.nearbyAvs) - 1 minNearby = 5 if numNearby > minNearby: delay = 0.08 * (numNearby - minNearby) self.setPosHprBroadcastPeriod(PetConstants.PosBroadcastPeriod + lerp(delay * 0.75, delay, random.random())) maxDist = 1000 if abs(self.getX()) > maxDist or abs(self.getY()) > maxDist: DistributedPetAI.notify.warning("deleting pet %s before he wanders off too far" % self.doId) self._outOfBounds = True self.stopPosHprBroadcast() self.requestDelete() return Task.done taskMgr.doMethodLater(simbase.petMovePeriod, self.move, self.getMoveTaskName()) return Task.done
def zoom(t): self.mapConfig.camSlider['value'] = lerp( self.camY[0], self.camY[1], t)
def driftMood(self, dt=None, curMood=None): # Pass in a dt to simulate mood over a specific amount of time. # If dt not passed in, simulates based on time elapsed since last call. # Typical call pattern: # driftMood(timeSinceLastSeen) # driftMood() # driftMood() # ... # # If you want to calculate mood drift using another PetMood as the # starting point, pass it in as curMood. This is the recommended # method for simulating mood on the client, where the results are # not being stored in the database: # driftMood(timeSinceLastSeen(), lastMood) # ... # driftMood(timeSinceLastSeen(), lastMood) # ... # driftMood(timeSinceLastSeen(), lastMood) # # The resulting mood will match the mood calculated by the AI # (using the first method, above) when the pet comes into existence # TODO: add variation to this. Over long dt's, add in a sine wave, # some random noise, etc. #print("dt is %s" % dt) now = globalClock.getFrameTime() if not hasattr(self, 'lastDriftTime'): self.lastDriftTime = now if dt is None: dt = now - self.lastDriftTime self.lastDriftTime = now if dt <= 0.: return if __debug__: try: dt *= simbase.petMoodTimescale except: pass if curMood is None: curMood = self # linear motion, for now def doDrift(curValue, timeToMedian, dt=float(dt)): # mood = mood + secs/((hrs/2*(mood/2))*(secs/hr)) """ use this to make sure that the numbers are even moving print curValue - (curValue + dt/(timeToMedian*7200)) """ newValue = curValue + dt / (timeToMedian * 7200) #3600)#60*60) return clampScalar(newValue, 0., 1.) self.boredom = doDrift(curMood.boredom, self.tBoredom) # these are currently never used #self.restlessness = doDrift(curMood.restlessness, self.tRestlessness) #self.playfulness = doDrift(curMood.playfulness, self.tPlayfulness) self.loneliness = doDrift(curMood.loneliness, self.tLoneliness) self.sadness = doDrift(curMood.sadness, self.tSadness) self.fatigue = doDrift(curMood.fatigue, self.tFatigue) self.hunger = doDrift(curMood.hunger, self.tHunger) self.confusion = doDrift(curMood.confusion, self.tConfusion) self.excitement = doDrift(curMood.excitement, self.tExcitement) self.surprise = doDrift(curMood.surprise, self.tSurprise) self.affection = doDrift(curMood.affection, self.tAffection) # for the sake of long-haul calculations, do the feedback calcs # after the simple independent calcs abuse = average(curMood.hunger, curMood.hunger, curMood.hunger, curMood.boredom, curMood.loneliness) tipPoint = .6 if abuse < tipPoint: tAnger = lerp(self.tAngerDec, -PetMood.LONGTIME, abuse / tipPoint) else: tAnger = lerp(PetMood.LONGTIME, self.tAngerInc, (abuse - tipPoint) / (1. - tipPoint)) self.anger = doDrift(curMood.anger, tAnger) self.announceChange()
def setZoom(self, zoom): self._zoom = clampScalar(0.0, 0.75, zoom) self.buffer.camera.setY(lerp(self.camY[0], self.camY[1], self._zoom)) self.mapBall._setTiltLimit(lerp(self.tiltLimit[0], self.tiltLimit[1], self._zoom)) self.mapBall.updateTextZoom(self._zoom)
def lerpDownAnimWeight(self, t, animSpanId, finalVal = 0.0): self.setDownAnimWeight(lerp(self.savedDownAnimWeight, finalVal, t), animSpanId)
def lerpUpAnimWeight(self, t, animSpanId, finalVal = 1.0): self.setUpAnimWeight(lerp(self.savedUpAnimWeight, finalVal, t), animSpanId)
def pickY(self=self, rng=rng): return lerp(-self.StageHalfHeight, self.StageHalfHeight, rng.random())
def pickY(self = self, rng = rng): return lerp(-self.StageHalfHeight, self.StageHalfHeight, rng.random())
def zoom(t): self.mapConfig.camSlider['value'] = lerp(self.camY[0], self.camY[1], t)
def lerpDownAnimWeight(self, t, animSpanId, finalVal=0.0): self.setDownAnimWeight(lerp(self.savedDownAnimWeight, finalVal, t), animSpanId)
def setRelZ(t): self.av.getGeomNode().setZ(lerp(0, avFlyHeight, t))
def calcDifficultyConstants(self, difficulty, numPlayers): ToonSpeedRange = [16.0, 25.0] self.ToonSpeed = lerp(ToonSpeedRange[0], ToonSpeedRange[1], difficulty) self.SuitSpeed = self.ToonSpeed / 2.0 self.SuitPeriodRange = [ lerp(5.0, 3.0, self.getDifficulty()), lerp(15.0, 8.0, self.getDifficulty()) ] def scaledDimensions(widthHeight, scale): w, h = widthHeight return [math.sqrt(scale * w * w), math.sqrt(scale * h * h)] BaseStageDimensions = [20, 15] areaScales = [1.0, 1.0, 3.0 / 2, 4.0 / 2] self.StageAreaScale = areaScales[numPlayers - 1] self.StageLinearScale = math.sqrt(self.StageAreaScale) self.notify.debug('StageLinearScale: %s' % self.StageLinearScale) self.StageDimensions = scaledDimensions(BaseStageDimensions, self.StageAreaScale) self.notify.debug('StageDimensions: %s' % self.StageDimensions) self.StageHalfWidth = self.StageDimensions[0] / 2.0 self.StageHalfHeight = self.StageDimensions[1] / 2.0 MOHs = [24] * 2 + [26, 28] self.MinOffscreenHeight = MOHs[self.getNumPlayers() - 1] distance = math.sqrt(self.StageDimensions[0] * self.StageDimensions[0] + self.StageDimensions[1] * self.StageDimensions[1]) distance /= self.StageLinearScale if self.DropPlacerType == PathDropPlacer: distance /= 1.5 ToonRunDuration = distance / self.ToonSpeed offScreenOnScreenRatio = 1.0 fraction = 1.0 / 3 * 0.85 self.BaselineOnscreenDropDuration = ToonRunDuration / ( fraction * (1.0 + offScreenOnScreenRatio)) self.notify.debug('BaselineOnscreenDropDuration=%s' % self.BaselineOnscreenDropDuration) self.OffscreenTime = offScreenOnScreenRatio * self.BaselineOnscreenDropDuration self.notify.debug('OffscreenTime=%s' % self.OffscreenTime) self.BaselineDropDuration = self.BaselineOnscreenDropDuration + self.OffscreenTime self.MaxDropDuration = self.BaselineDropDuration self.DropPeriod = self.BaselineDropDuration / 2.0 scaledNumPlayers = (numPlayers - 1.0) * 0.75 + 1.0 self.DropPeriod /= scaledNumPlayers typeProbs = {'fruit': 3, 'anvil': 1} probSum = reduce(lambda x, y: x + y, typeProbs.values()) for key in typeProbs.keys(): typeProbs[key] = float(typeProbs[key]) / probSum scheduler = DropScheduler(CatchGameGlobals.GameDuration, self.FirstDropDelay, self.DropPeriod, self.MaxDropDuration, self.FasterDropDelay, self.FasterDropPeriodMult) self.totalDrops = 0 while not scheduler.doneDropping(): scheduler.stepT() self.totalDrops += 1 self.numFruits = int(self.totalDrops * typeProbs['fruit']) self.numAnvils = int(self.totalDrops - self.numFruits)
def adjustShadowScale(t, self=self): modelY = self.model.getY() maxHeight = 10 a = min(-modelY / maxHeight, 1.0) self.shadow.setScale(lerp(1, 0.2, a)) self.shadow.setAlphaScale(lerp(1, 0.2, a))
def lerpMood(self, component, factor): curVal = self.mood.getComponent(component) if factor < 0: self.setMoodComponent(component, lerp(curVal, 0.0, -factor)) else: self.setMoodComponent(component, lerp(curVal, 1.0, factor))
def setZoom(self, zoom): self._zoom = clampScalar(0.0, 0.75, zoom) self.buffer.camera.setY(lerp(self.camY[0], self.camY[1], self._zoom)) self.mapBall._setTiltLimit( lerp(self.tiltLimit[0], self.tiltLimit[1], self._zoom)) self.mapBall.updateTextZoom(self._zoom)
def lerpUpAnimWeight(self, t, animSpanId, finalVal=1.0): self.setUpAnimWeight(lerp(self.savedUpAnimWeight, finalVal, t), animSpanId)
def getDropIval(self, x, y, dropObjName, num): objType = Name2DropObjectType[dropObjName] dropNode = hidden.attachNewNode('catchDropNode%s' % num) dropNode.setPos(x, y, 0) shadow = self.dropShadow.copyTo(dropNode) shadow.setZ(0.2) shadow.setColor(1, 1, 1, 1) object = self.getObjModel(dropObjName) object.reparentTo(dropNode) if dropObjName in ['watermelon', 'anvil']: objH = object.getH() absDelta = {'watermelon': 12, 'anvil': 15}[dropObjName] delta = (self.randomNumGen.random() * 2.0 - 1.0) * absDelta newH = objH + delta else: newH = self.randomNumGen.random() * 360.0 object.setH(newH) sphereName = 'FallObj%s' % num radius = self.ObjRadius if objType.good: radius *= lerp(1.0, 1.3, self.getDifficulty()) collSphere = CollisionSphere(0, 0, 0, radius) collSphere.setTangible(0) collNode = CollisionNode(sphereName) collNode.setCollideMask(ToontownGlobals.CatchGameBitmask) collNode.addSolid(collSphere) collNodePath = object.attachNewNode(collNode) collNodePath.hide() if self.ShowObjSpheres: collNodePath.show() catchEventName = 'ltCatch' + sphereName def eatCollEntry(forward, collEntry): forward() self.accept(catchEventName, Functor(eatCollEntry, Functor(self.__handleCatch, num))) def cleanup(self=self, dropNode=dropNode, num=num, event=catchEventName): self.ignore(event) dropNode.removeNode() duration = objType.fallDuration onscreenDuration = objType.onscreenDuration dropHeight = self.MinOffscreenHeight targetShadowScale = 0.3 if self.TrickShadows: intermedScale = targetShadowScale * (self.OffscreenTime / self.BaselineDropDuration) shadowScaleIval = Sequence( LerpScaleInterval(shadow, self.OffscreenTime, intermedScale, startScale=0)) shadowScaleIval.append( LerpScaleInterval(shadow, duration - self.OffscreenTime, targetShadowScale, startScale=intermedScale)) else: shadowScaleIval = LerpScaleInterval(shadow, duration, targetShadowScale, startScale=0) targetShadowAlpha = 0.4 shadowAlphaIval = LerpColorScaleInterval( shadow, self.OffscreenTime, Point4(1, 1, 1, targetShadowAlpha), startColorScale=Point4(1, 1, 1, 0)) shadowIval = Parallel(shadowScaleIval, shadowAlphaIval) if self.UseGravity: def setObjPos(t, objType=objType, object=object): z = objType.trajectory.calcZ(t) object.setZ(z) setObjPos(0) dropIval = LerpFunctionInterval(setObjPos, fromData=0, toData=onscreenDuration, duration=onscreenDuration) else: startPos = Point3(0, 0, self.MinOffscreenHeight) object.setPos(startPos) dropIval = LerpPosInterval(object, onscreenDuration, Point3(0, 0, 0), startPos=startPos, blendType='easeIn') ival = Sequence(Func(Functor(dropNode.reparentTo, render)), Parallel( Sequence(WaitInterval(self.OffscreenTime), dropIval), shadowIval), Func(cleanup), name='drop%s' % num) landSound = None if objType == Name2DropObjectType['anvil']: landSound = self.sndAnvilLand if landSound: ival.append(SoundInterval(landSound)) return ival
def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval=Sequence()): from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.5) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame=48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.ogg') t = power / 100.0 dist = lerp(PartyGlobals.CogActivityPieMinDist, PartyGlobals.CogActivityPieMaxDist, t) time = lerp(1.0, 1.5, t) proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(toon=toon, relVel=relVel): return render.getRelativeVector(toon, relVel) * 0.6 def __safeSetAnimState(toon=toon, state='Happy'): if toon and hasattr(toon, 'animFSM'): toon.setAnimState('Happy') else: self.notify.warning( 'The toon is being destroyed. No attribute animState.') toss = Track((0, Sequence( Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), animPie, Parallel( ActorInterval(toon, 'throw', startFrame=48, playRate=1.5, partName='torso'), animPie), Func(__safeSetAnimState, toon, 'Happy'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track( (14.0 / 24.0, SoundInterval( sound, node=toon, cutOff=PartyGlobals.PARTY_COG_CUTOFF)), (16.0 / 24.0, Sequence( Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return (toss, fly, flyPie)
def getTossPieInterval( self, toon, x, y, z, h, p, r, power, beginFlyIval=Sequence()): """Adapted from toon.py to suit our needs. Returns (toss, pie, flyPie), where toss is an interval to animate the toon tossing a pie, pie is the interval to animate the pie flying through the air, and pieModel is the model that flies. This is used in the final BossBattle sequence of CogHQ when we all throw pies directly at the boss cog. """ from toontown.toonbase import ToontownBattleGlobals from toontown.battle import BattleProps pie = toon.getPieModel() pie.setScale(0.5) flyPie = pie.copyTo(NodePath('a')) pieName = ToontownBattleGlobals.pieNames[toon.pieType] pieType = BattleProps.globalPropPool.getPropType(pieName) animPie = Sequence() if pieType == 'actor': animPie = ActorInterval(pie, pieName, startFrame = 48) sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.mp3') # First, create a ProjectileInterval to compute the relative # velocity. assert 0 <= power <= 100, "invalid pie throw power %s" % power t = power / 100.0 # Distance ranges from CogActivityPieMinDist to CogActivityPieMaxDist ft, time ranges from 1 to 1.5 s. dist = lerp(PartyGlobals.CogActivityPieMinDist, PartyGlobals.CogActivityPieMaxDist, t) time = lerp(1.0, 1.5, t) proj = ProjectileInterval( None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time ) relVel = proj.startVel def getVelocity(toon = toon, relVel = relVel): return render.getRelativeVector(toon, relVel) * 0.6 toss = Track( (0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), animPie, Parallel( ActorInterval( toon, 'throw', startFrame=48, #duration=0.25, #self.throwPieLimitTime, playRate=1.5, partName='torso' ), animPie ), Func(toon.setAnimState, 'Happy'), )), (16./24., Func(pie.detachNode))) fly = Track( (14./24., SoundInterval(sound, node = toon, cutOff=PartyGlobals.PARTY_COG_CUTOFF)), (16./24., Sequence(Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel = getVelocity , duration = 6), #LerpPosInterval(flyPie, duration = 3, Point3(0.52,50,2.24)), Func(flyPie.detachNode), )), ) return (toss, fly, flyPie)
def getDropIval(self, x, y, dropObjName, num): objType = Name2DropObjectType[dropObjName] dropNode = hidden.attachNewNode("catchDropNode%s" % num) dropNode.setPos(x, y, 0) shadow = self.dropShadow.copyTo(dropNode) shadow.setZ(0.2) shadow.setColor(1, 1, 1, 1) object = self.getObjModel(dropObjName) object.reparentTo(dropNode) if dropObjName in ["watermelon", "anvil"]: objH = object.getH() absDelta = {"watermelon": 12, "anvil": 15}[dropObjName] delta = (self.randomNumGen.random() * 2.0 - 1.0) * absDelta newH = objH + delta else: newH = self.randomNumGen.random() * 360.0 object.setH(newH) sphereName = "FallObj%s" % num radius = self.ObjRadius if objType.good: radius *= lerp(1.0, 1.3, self.getDifficulty()) collSphere = CollisionSphere(0, 0, 0, radius) collSphere.setTangible(0) collNode = CollisionNode(sphereName) collNode.setCollideMask(ToontownGlobals.CatchGameBitmask) collNode.addSolid(collSphere) collNodePath = object.attachNewNode(collNode) collNodePath.hide() if self.ShowObjSpheres: collNodePath.show() catchEventName = "ltCatch" + sphereName def eatCollEntry(forward, collEntry): forward() self.accept(catchEventName, Functor(eatCollEntry, Functor(self.__handleCatch, num))) def cleanup(self=self, dropNode=dropNode, num=num, event=catchEventName): self.ignore(event) dropNode.removeNode() duration = objType.fallDuration onscreenDuration = objType.onscreenDuration dropHeight = self.MinOffscreenHeight targetShadowScale = 0.3 if self.TrickShadows: intermedScale = targetShadowScale * (self.OffscreenTime / self.BaselineDropDuration) shadowScaleIval = Sequence(LerpScaleInterval(shadow, self.OffscreenTime, intermedScale, startScale=0)) shadowScaleIval.append( LerpScaleInterval(shadow, duration - self.OffscreenTime, targetShadowScale, startScale=intermedScale) ) else: shadowScaleIval = LerpScaleInterval(shadow, duration, targetShadowScale, startScale=0) targetShadowAlpha = 0.4 shadowAlphaIval = LerpColorScaleInterval( shadow, self.OffscreenTime, Point4(1, 1, 1, targetShadowAlpha), startColorScale=Point4(1, 1, 1, 0) ) shadowIval = Parallel(shadowScaleIval, shadowAlphaIval) if self.UseGravity: def setObjPos(t, objType=objType, object=object): z = objType.trajectory.calcZ(t) object.setZ(z) setObjPos(0) dropIval = LerpFunctionInterval(setObjPos, fromData=0, toData=onscreenDuration, duration=onscreenDuration) else: startPos = Point3(0, 0, self.MinOffscreenHeight) object.setPos(startPos) dropIval = LerpPosInterval(object, onscreenDuration, Point3(0, 0, 0), startPos=startPos, blendType="easeIn") ival = Sequence( Func(Functor(dropNode.reparentTo, render)), Parallel(Sequence(WaitInterval(self.OffscreenTime), dropIval), shadowIval), Func(cleanup), name="drop%s" % num, ) landSound = None if objType == Name2DropObjectType["anvil"]: landSound = self.sndAnvilLand if landSound: ival.append(SoundInterval(landSound)) return ival
def getDropIval(self, x, y, dropObjName, generation, num): objType = PartyGlobals.Name2DropObjectType[dropObjName] id = (generation, num) dropNode = hidden.attachNewNode('catchDropNode%s' % (id,)) dropNode.setPos(x, y, 0) shadow = self.dropShadow.copyTo(dropNode) shadow.setZ(PartyGlobals.CatchDropShadowHeight) shadow.setColor(1, 1, 1, 1) object = self.getObjModel(dropObjName) object.reparentTo(hidden) if dropObjName in ['watermelon', 'anvil']: objH = object.getH() absDelta = {'watermelon': 12, 'anvil': 15}[dropObjName] delta = (self.randomNumGen.random() * 2.0 - 1.0) * absDelta newH = objH + delta else: newH = self.randomNumGen.random() * 360.0 object.setH(newH) sphereName = 'FallObj%s' % (id,) radius = self.ObjRadius if objType.good: radius *= lerp(1.0, 1.3, 0.5) collSphere = CollisionSphere(0, 0, 0, radius) collSphere.setTangible(0) collNode = CollisionNode(sphereName) collNode.setCollideMask(PartyGlobals.CatchActivityBitmask) collNode.addSolid(collSphere) collNodePath = object.attachNewNode(collNode) collNodePath.hide() if self.ShowObjSpheres: collNodePath.show() catchEventName = 'ltCatch' + sphereName def eatCollEntry(forward, collEntry): forward() self.accept(catchEventName, Functor(eatCollEntry, Functor(self.__handleCatch, id[0], id[1]))) def cleanup(self = self, dropNode = dropNode, id = id, event = catchEventName): self.ignore(event) dropNode.removeNode() duration = objType.fallDuration onscreenDuration = objType.onscreenDuration targetShadowScale = 0.3 if self.trickShadows: intermedScale = targetShadowScale * (self.OffscreenTime / self.BaselineDropDuration) shadowScaleIval = Sequence(LerpScaleInterval(shadow, self.OffscreenTime, intermedScale, startScale=0)) shadowScaleIval.append(LerpScaleInterval(shadow, duration - self.OffscreenTime, targetShadowScale, startScale=intermedScale)) else: shadowScaleIval = LerpScaleInterval(shadow, duration, targetShadowScale, startScale=0) targetShadowAlpha = 0.4 shadowAlphaIval = LerpColorScaleInterval(shadow, self.OffscreenTime, Point4(1, 1, 1, targetShadowAlpha), startColorScale=Point4(1, 1, 1, 0)) shadowIval = Parallel(shadowScaleIval, shadowAlphaIval) if self.useGravity: def setObjPos(t, objType = objType, object = object): z = objType.trajectory.calcZ(t) object.setZ(z) setObjPos(0) dropIval = LerpFunctionInterval(setObjPos, fromData=0, toData=onscreenDuration, duration=onscreenDuration) else: startPos = Point3(0, 0, self.MinOffscreenHeight) object.setPos(startPos) dropIval = LerpPosInterval(object, onscreenDuration, Point3(0, 0, 0), startPos=startPos, blendType='easeIn') ival = Sequence(Func(Functor(dropNode.reparentTo, self.root)), Parallel(Sequence(WaitInterval(self.OffscreenTime), Func(Functor(object.reparentTo, dropNode)), dropIval), shadowIval), Func(cleanup), name='drop%s' % (id,)) if objType == PartyGlobals.Name2DropObjectType['anvil']: ival.append(Func(self.playAnvil)) return ival
def printPeriodTable(name, numSuitList, fasterSuits, tTransFunc=None): str = '%s = {\n' % name # cycle through the safezones and calculate the # corresponding suit speeds for zone in MinigameGlobals.SafeZones: str += '%s%s : {' % (' '*4, zone) difficulty = MinigameGlobals.getDifficulty(zone) minSpeed = lerp(self.MinSuitSpeedRange[0], self.MinSuitSpeedRange[1], difficulty) maxSpeed = lerp(self.MaxSuitSpeedRange[0], self.MaxSuitSpeedRange[1], difficulty) # all the 'slower' suits will be slower than this speed, # all the 'faster' suits will be faster. midSpeed = (minSpeed + maxSpeed) / 2. # cycle through the suit counts (how many suits # will be in play) for numSuits in numSuitList: # there must be an even number of suits assert not numSuits % 2 speeds = [] for i in range(numSuits//2): if fasterSuits: i += numSuits//2 t = i / float(numSuits-1) # map t into 0..1 if fasterSuits: t -= .5 t *= 2. # apply any time transformation function if tTransFunc != None: t = tTransFunc(t) if fasterSuits: speed = lerp(midSpeed, maxSpeed, t) else: speed = lerp(minSpeed, midSpeed, t) speeds.append(speed) # calculate the corresponding suit periods def calcUpdatePeriod(speed): # result in tics # SUIT_TIC_FREQ: tics/sec # CELL_WIDTH: feet # speed: feet/sec # tics = ((tics/sec) * feet) / (feet/sec) return int((float(MazeGameGlobals.SUIT_TIC_FREQ) * \ float(MazeData.CELL_WIDTH)) / speed) periods = list(map(calcUpdatePeriod, speeds)) filler = "" if numSuits < 10: filler = " " str += '%s%s : %s,\n%s%s' % (numSuits, filler, periods, ' '*4, ' '*8) str += '},\n' str += '%s}' % (' '*4) print(str)