def __init__(self, toon, mg): self.mg = mg self.toon = toon self.splat = Actor(GagGlobals.SPLAT_MDL, {'chan': GagGlobals.SPLAT_CHAN}) self.splat.setScale(0.5) self.splat.setColor( VBase4(250.0 / 255.0, 241.0 / 255.0, 24.0 / 255.0, 1.0)) self.splat.setBillboardPointEye() self.gc = WholeCreamPie() self.gc.build() self.gag = self.gc.getGag() self.toon.play('toss', fromFrame=60, toFrame=85) self.gag.reparentTo(self.toon.find('**/def_joint_right_hold')) throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.toon) throwPath.setScale(render, 1) throwPath.setPos(0, 150, -90) throwPath.setHpr(90, -90, 90) self.gag.wrtReparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.track = ProjectileInterval( self.gag, startPos=self.toon.find('**/def_joint_right_hold').getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() taskMgr.doMethodLater(3, self.__handleThrowTrackDone, 'handleThrowTrackDoneDGP-' + str(hash(self)))
def release(self): throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) if not self.gag: self.build() self.entity = self.gag self.gag = None self.entity.wrtReparentTo(render) self.entity.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval(self.entity, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() if self.isLocal(): self.startTimeout() self.buildCollisions() self.avatar.acceptOnce('gagSensor-into', self.onCollision) self.reset() TrapGag.release(self)
def throw(self, p): self.isAirborne = True self.owner.avatar.play('pie', partName='torso', fromFrame=60) base.playSfx(self.owner.throwSound, node=self.owner.avatar) start = NodePath('StartPath') start.reparentTo(self.owner.avatar) start.setScale(render, 1) start.setPos(0, 0, 0) start.setP(p) end = NodePath('ThrowPath') end.reparentTo(start) end.setScale(render, 1) end.setPos(0, 160, -90) end.setHpr(90, -90, 90) self.wrtReparentTo(render) self.setScale(1.0) self.throwIval = ProjectileInterval( self, startPos=self.owner.avatar.find('**/def_joint_right_hold').getPos( render), endPos=end.getPos(render), gravityMult=0.9, duration=3) self.throwIval.start() if self.owner.avId == base.localAvatar.doId: self.accept('snowball-coll-' + str(id(self)) + '-into', self.__handleSnowballCollision) start.removeNode() del start end.removeNode() del end
def gagRelease(self, task): gagRange = NodePath('Gag Range') gagRange.reparentTo(self.localAvatar.find('**/joint_nameTag')) gagRange.setPos(0, 75, 0) gagRange.setHpr(90, -90, 90) if self.gag == None: gagRange.removeNode() base.taskMgr.doMethodLater(0.1, self.enableThrowing, 'Enable Gag Throw') return else: if self.height > 1: grav = 0.7 + self.height / 10 else: grav = 0.7 if self.height > 5.2: base.taskMgr.add(self.enableThrowing, 'Enable Gag Throw') return self.gag.reparentTo(render) self.gag.setHpr(gagRange.getHpr(render)) self.gagMgr.getGagByName(self.currentGag).addCollision(self.gag) handJoint = self.localAvatar.find('**/def_joint_right_hold') startPos = Vec3(handJoint.getPos(render).getX(), handJoint.getPos(render).getY(), handJoint.getPos(render).getZ() + 0.8) self.projectile = ProjectileInterval(self.gag, startPos=startPos, endPos=gagRange.getPos(render), duration=1, gravityMult=grav) self.projectile.start() SoundBank.getSound('pie_throw').play() base.taskMgr.doMethodLater(0.8, self.enableThrowing, 'Enable Gag Throw') base.taskMgr.doMethodLater(2, self.destroyGag, 'Destroy Gag', extraArgs = [self.gag, self.projectile], appendTask = True) base.accept('delete-up', self.null) base.accept('p-up', self.null) self.throwingPie = False return Task.done
def startBallPlayback(self, power, angle, sequenceNum): flyBall = self.ballModel.copyTo(NodePath()) flyBall.setScale(1.0) flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath()) flyBallBubble.reparentTo(flyBall) flyBall.setTag('pieSequence', str(sequenceNum)) flyBall.setTag('throwerId', str(self.avId)) t = power / 100.0 t = 1.0 - t dist = 300 - 200 * t time = 1.5 + 0.5 * t proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time) relVel = proj.startVel def getVelocity(root=self.root, relVel=relVel): return render.getRelativeVector(root, relVel) fly = Sequence( Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel=getVelocity, duration=3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, 'removed collider'), Func(self.flyBallFinishedFlying, sequenceNum)) flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node=self.root), name='flyWithSound') self.notify.debug('starting flyball track') flyWithSound.start() self.flyBallTracks[sequenceNum] = flyWithSound
def throw(self): if not self.gag and not self.isLocal(): self.setHandJoint() self.build() if self.gag and self.getLocation(): self.startEntity() elif self.gag and self.trapMode == 1: throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) self.gag.setScale(self.gag.getScale(render)) self.gag.reparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval( self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() self.buildProjCollisions() self.reset() self.avatar.acceptOnce('projSensor-into', self.onProjCollision)
def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval=Sequence()): ToontownBattleGlobals = ToontownBattleGlobals import toontown.toonbase BattleProps = BattleProps import toontown.battle pie = toon.getPieModel() pie.setScale(0.90000000000000002) 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 = 100 - 70 * t time = 1 + 0.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.59999999999999998 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), Parallel( ActorInterval( toon, 'throw', startFrame=48, partName='torso'), animPie), Func(toon.loop, 'neutral'))), (16.0 / 24.0, Func(pie.detachNode))) fly = Track( (14.0 / 24.0, SoundInterval(sound, node=toon)), (16.0 / 24.0, Sequence( Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52000000000000002, 0.96999999999999997, 2.2400000000000002, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode)))) return (toss, fly, flyPie)
def startBallPlayback(self, power, angle, sequenceNum): """Start the ball flying in the air.""" assert self.notify.debugStateCall(self) # duplicate our current ball model flyBall = self.ballModel.copyTo(NodePath()) flyBall.setScale(1.0) flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath()) flyBallBubble.reparentTo(flyBall) flyBall.setTag('pieSequence', str(sequenceNum)) flyBall.setTag('throwerId', str(self.avId)) # First, create a ProjectileInterval to compute the relative # velocity. t = power / 100.0 # make the ball travel farther, the longer you press the bar t = 1.0 - t # Distance ranges from 300 - 100 ft, time ranges from 1.5 - 2 s. dist = 300 - 200 * t time = 1.5 + 0.5 * t proj = ProjectileInterval( None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time, ) relVel = proj.startVel def getVelocity(root=self.root, relVel=relVel): return render.getRelativeVector(root, relVel) fly = Sequence( #Func(self.ballModel.hide), Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel=getVelocity, duration=3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, "removed collider"), Func(self.flyBallFinishedFlying, sequenceNum)) flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node=self.root), name='flyWithSound') self.notify.debug('starting flyball track') flyWithSound.start() self.flyBallTracks[sequenceNum] = flyWithSound pass
def announceGenerate(self): DistributedElevatorExt.DistributedElevatorExt.announceGenerate(self) angle = self.startingHpr[0] angle -= 90 radAngle = deg2Rad(angle) unitVec = Vec3(math.cos(radAngle), math.sin(radAngle), 0) unitVec *= 11.25 self.endPos = self.startingPos + unitVec self.endPos.setZ(0.5) dist = Vec3(self.endPos - self.enteringPos).length() wheelAngle = dist / (6.72 * math.pi) * 360 self.kartEnterAnimateInterval = Parallel( LerpHprInterval( self.wheels[0], 5.0, Vec3(self.wheels[0].getH(), wheelAngle, self.wheels[0].getR())), LerpHprInterval( self.wheels[1], 5.0, Vec3(self.wheels[1].getH(), wheelAngle, self.wheels[1].getR())), LerpHprInterval( self.wheels[2], 5.0, Vec3(self.wheels[2].getH(), wheelAngle, self.wheels[2].getR())), LerpHprInterval( self.wheels[3], 5.0, Vec3(self.wheels[3].getH(), wheelAngle, self.wheels[3].getR())), name='SwagKartAnimate') trolleyExitTrack1 = Parallel( Sequence( Wait(1.25), Func(self.mole.doMolePop, 0, 0.75, 5, 0.75, MoleFieldBase.HILL_MOLE)), Sequence( LerpPosInterval(self.golfKart, 2.5, self.endPos), Func(self.mole.setHillType, MoleFieldBase.HILL_WHACKED), Func(self.soundBomb.play), Func(self.soundBomb2.play), Func(self.soundUp.play), Parallel( ProjectileInterval(self.golfKart, startPos=self.endPos, endPos=self.flyToPos, duration=2, gravityMult=2.5), self.golfKart.hprInterval( 2, (self.golfKart.getH(), self.golfKart.getP() + 720, 0)))), self.kartEnterAnimateInterval, name='SwagKartExitTrack') self.trolleyExitTrack = Sequence(trolleyExitTrack1) self.trolleyEnterTrack = Sequence( Func(self.golfKart.setP, 0), LerpPosInterval(self.golfKart, 5.0, self.startingPos, startPos=self.enteringPos)) self.closeDoors = Sequence(self.trolleyExitTrack, Func(self.onDoorCloseFinish)) self.openDoors = Sequence(self.trolleyEnterTrack)
def __getItemRecoveredInterval(self, package, avatar): # Generates the item recovered item. Requires the avatar that dug. x, y, z = avatar.getPos(self) return Sequence( ShowInterval(package), ParallelEndTogether( # Move the package up LerpPosInterval(package, duration=PACKAGE_MOVE_UP_TIME, pos=(0.0, 0.0, PACKAGE_MAX_HEIGHT), startPos=(0.0, 0.0, -1), blendType='easeOut'), # Scale and turn the package. LerpHprScaleInterval(package, duration=PACKAGE_MOVE_UP_TIME, hpr=(360.0, 0.0, 0.0), scale=(1.0, 1.0, 1.0), blendType='easeInOut')), # We have to fix the H or the package won't go to the avatar correctly. Func(package.headsUp, avatar), ParallelEndTogether( ProjectileInterval(package, duration=PACKAGE_JUMP_TO_AVATAR_TIME, startPos=(0.0, 0.0, PACKAGE_MAX_HEIGHT), endPos=(x, y, z)), LerpColorScaleInterval(package, duration=PACKAGE_JUMP_TO_AVATAR_TIME, colorScale=NO_COLOR, blendType='easeOut')), SoundInterval(self.itemRecoveredSfx, node=avatar, duration=3.0))
def createOneToonupIval(self, foodNode): """Create and return a toonup Interval for this node. This does not include the initial wait for the toonup to appear """ toonupIndex = self.foodNodes.index(foodNode) waitTimeForOne = self.distBetweenFoodNodes / self.ToonupBeltSpeed waitTime = waitTimeForOne * toonupIndex self.toonupWaitTimes.append(waitTime) totalTimeToTraverseBelt = self.beltLength / self.ToonupBeltSpeed startPosY = -(self.beltLength / 2.0) endPosY = (self.beltLength / 2.0) retval = Sequence( Func(self.loadToonup, toonupIndex), LerpPosInterval(foodNode, duration=totalTimeToTraverseBelt, startPos=Point3(0, startPosY, self.beltHeight), pos=Point3(0, endPosY, self.beltHeight)), ProjectileInterval(foodNode, startPos=Point3(0, endPosY, self.beltHeight), startVel=Point3(0, self.BeltSpeed, 0), endZ=0), Func(self.removeToonup, toonupIndex), ) return retval
def attackTarget(self, task): if(self.hp > 0): if(self.target != None): cog = self.target.getPythonTag('Cog') if(cog.getHealth() > 0): self.gagProp.hide() gag = copy.copy(self.gagProp) gag.reparentTo(render) gag.setPos(self.gagProp.getPos(render)) gag.setHpr(self.gagProp.getHpr(render)) endPos = self.target.find('**/Head').getPos(render) self.projectile = ProjectileInterval(gag, startPos=gag.getPos(render), endPos=endPos, gravityMult=1, duration=1) gag.show() self.projectile.start() self.fireSound.play() self.whizzSound.play() render.getPythonTag('WorldCollisions').addGagCollision(gag) self.target = None self.firing = False base.taskMgr.doMethodLater(2, self.removeGag, 'Remove Gag', extraArgs = [gag, self.projectile], appendTask = True) base.taskMgr.doMethodLater(2, self.resetCannon, 'Reset Cannon') self.cannon.find('**/cannon').setHpr(0, 0, 0) self.setSupply(self.getSupply() - 1) else: self.target = None self.firing = False base.taskMgr.doMethodLater(2, self.resetCannon, 'Reset Cannon') self.cannon.find('**/cannon').setHpr(0, 0, 0) return Task.done
def createDinerMoveIval(self, suit, destPos, chairInfo): dur = suit.getDuration('landing') fr = suit.getFrameRate('landing') landingDur = dur totalDur = 7.3 animTimeInAir = totalDur - dur flyingDur = animTimeInAir impactLength = dur - animTimeInAir tableIndex = chairInfo[0] chairIndex = chairInfo[1] table = self.bossCog.tables[tableIndex] chairLocator = table.chairLocators[chairIndex] chairPos = chairLocator.getPos(self) chairHpr = chairLocator.getHpr(self) suit.setPos(chairPos) table.setDinerStatus(chairIndex, table.HIDDEN) suit.setHpr(chairHpr) wayPoint = (chairPos + destPos) / 2.0 wayPoint.setZ(wayPoint.getZ() + 20) moveIval = Sequence(Func(suit.headsUp, self), Func(suit.pose, 'landing', 0), ProjectileInterval(suit, duration=flyingDur, startPos=chairPos, endPos=destPos, gravityMult=0.25), ActorInterval(suit, 'landing')) if suit.prop == None: suit.prop = BattleProps.globalPropPool.getProp('propeller') propDur = suit.prop.getDuration('propeller') lastSpinFrame = 8 fr = suit.prop.getFrameRate('propeller') spinTime = lastSpinFrame / fr openTime = (lastSpinFrame + 1) / fr suit.attachPropeller() propTrack = Parallel(SoundInterval(suit.propInSound, duration=flyingDur, node=suit), Sequence(ActorInterval(suit.prop, 'propeller', constrainedLoop=1, duration=flyingDur + 1, startTime=0.0, endTime=spinTime), ActorInterval(suit.prop, 'propeller', duration=landingDur, startTime=openTime), Func(suit.detachPropeller))) result = Parallel(moveIval, propTrack) return result
def makeToonGrabInterval(self, toon): toon.pose('leverNeutral', 0) toon.update() rightHandPos = toon.rightHand.getPos(toon) self.toonPitcherPosition = Point3(self.handPos[0] - rightHandPos[0], self.handPos[1] - rightHandPos[1], 0) destZScale = rightHandPos[2] / self.handPos[2] grabIval = Sequence( Func(toon.wrtReparentTo, self.waterPitcherNode), Func(toon.loop, 'neutral'), Parallel( ActorInterval(toon, 'jump'), Sequence( Wait(0.43), Parallel( ProjectileInterval(toon, duration=0.9, startPos=toon.getPos( self.waterPitcherNode), endPos=self.toonPitcherPosition), LerpHprInterval(toon, 0.9, Point3(0, 0, 0)), LerpScaleInterval(self.waterPitcherModel, 0.9, Point3(1, 1, destZScale))))), Func(toon.setPos, self.toonPitcherPosition), Func(toon.loop, 'leverNeutral')) return grabIval
def getToonJumpTrack( av, destNode ): # using a local func allows the ProjectileInterval to # calculate this pos at run-time def getJumpDest(av = av, node = destNode): dest = node.getPos(av.getParent()) dest += Vec3(*self.JumpOutOffsets[seatIndex]) return dest def getJumpHpr(av = av, node = destNode): hpr = node.getHpr(av.getParent()) hpr.setX( hpr.getX() + 180) angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX()) hpr.setX(angle) return hpr toonJumpTrack = Parallel( ActorInterval( av, 'jump' ), Sequence( Wait( 0.1), #43 ), Parallel( #LerpHprInterval( av, # hpr = getJumpHpr, # duration = .9 ), ProjectileInterval( av, endPos = getJumpDest, duration = .9 ) ) ) ) return toonJumpTrack
def makeToonReleaseInterval(self, toon): temp1 = self.waterPitcherNode.attachNewNode('temp1') temp1.setPos(self.toonPitcherPosition) temp2 = self.waterPitcherNode.attachNewNode('temp2') temp2.setPos(0, -10, -self.waterPitcherNode.getZ()) startPos = temp1.getPos(render) endPos = temp2.getPos(render) temp1.removeNode() temp2.removeNode() def getSlideToPos(toon=toon): return render.getRelativePoint(toon, Point3(0, -10, 0)) if self.gotHitByBoss: self.notify.debug('creating zap interval instead') grabIval = Sequence( Func(toon.loop, 'neutral'), Func(toon.wrtReparentTo, render), Parallel(ActorInterval(toon, 'slip-backward'), toon.posInterval(0.5, getSlideToPos, fluid=1))) else: grabIval = Sequence( Func(toon.loop, 'neutral'), Func(toon.wrtReparentTo, render), Parallel( ActorInterval(toon, 'jump'), Sequence( Wait(0.43), ProjectileInterval(toon, duration=0.9, startPos=startPos, endPos=endPos)))) return grabIval
def enterBossFlying(self, startIndex, endIndex, ts = 0.0): duration = 3.5 startPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[startIndex] endPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[endIndex] startPos = CIGlobals.SuitSpawnPoints[self.getHood()][startPoint] endPos = CIGlobals.SuitSpawnPoints[self.getHood()][endPoint] if self.moveIval: self.moveIval.finish() self.moveIval = None self.animIval = Sequence( Func(self.animFSM.request, 'flyaway', [ts]), Wait(1.0), Func(self.animFSM.request, 'flydown', [ts]) ) self.moveIval = Sequence( Wait(0.5), Func(self.headsUp, endPos), ProjectileInterval( self, startPos = startPos, endPos = endPos, gravityMult = 0.25, duration = duration ) ) self.moveIval.start(ts) self.animIval.start(ts)
def releaseProj(task): if(cog.getHealth() > 0): attackRange = ent.find('**/joint_nameTag').attachNewNode("Attack Range") attackRange.setPos(0, 50, -5) self.projectile.setBillboardPointEye() wc = render.getPythonTag('WorldCollisions') wc.addAttackCollision(self.projectile) self.projectile.reparentTo(render) projTrack = ProjectileInterval(self.projectile, endPos = Point3(attackRange.getPos(render)), startPos = (handJoint.getPos(render)), gravityMult = 0.7, duration = 1) projTrack.start() if(self.throwSound != None): SoundBank.getSound(self.throwSound).play() ent.play('neutral') Sequence( Wait(2), Func(destroy, range) ) return Task.done
def attackTarget(self, task): if (self.hp > 0): if (self.target != None): cog = self.target.getPythonTag('Cog') if (cog.getHealth() > 0): self.gagProp.hide() gag = copy.copy(self.gagProp) gag.reparentTo(render) gag.setPos(self.gagProp.getPos(render)) gag.setHpr(self.gagProp.getHpr(render)) endPos = self.target.find('**/Head').getPos(render) self.projectile = ProjectileInterval( gag, startPos=gag.getPos(render), endPos=endPos, gravityMult=1, duration=1) gag.show() self.projectile.start() self.fireSound.play() self.whizzSound.play() render.getPythonTag('WorldCollisions').addGagCollision(gag) self.target = None self.firing = False base.taskMgr.doMethodLater( 2, self.removeGag, 'Remove Gag', extraArgs=[gag, self.projectile], appendTask=True) base.taskMgr.doMethodLater(2, self.resetCannon, 'Reset Cannon') self.cannon.find('**/cannon').setHpr(0, 0, 0) self.setSupply(self.getSupply() - 1) else: self.target = None self.firing = False base.taskMgr.doMethodLater(2, self.resetCannon, 'Reset Cannon') self.cannon.find('**/cannon').setHpr(0, 0, 0) return Task.done
def releaseProj(task): if (cog.getHealth() > 0): attackRange = ent.find( '**/joint_nameTag').attachNewNode("Attack Range") attackRange.setPos(0, 50, -5) self.projectile.setBillboardPointEye() wc = render.getPythonTag('WorldCollisions') wc.addAttackCollision(self.projectile) self.projectile.reparentTo(render) projTrack = ProjectileInterval( self.projectile, endPos=Point3(attackRange.getPos(render)), startPos=(handJoint.getPos(render)), gravityMult=0.7, duration=1) projTrack.start() if (self.throwSound != None): SoundBank.getSound(self.throwSound).play() ent.play('neutral') Sequence(Wait(2), Func(destroy, range)) return Task.done
def __init__(self, collideEventName, parent, pie, endPos, gravityMult, duration, local, turretClass): self.turret = turretClass self.collideEventName = collideEventName self.pieNp = NodePath('pieNP') self.pieNp.reparentTo(parent) self.pieNp.setScale(render, 1) self.pieNp.setPos(endPos) self.pieNp.setHpr(90, -90, 90) self.pie = pie if local: self.pieCollisions() self.pie.setScale(self.pie.getScale(render)) self.pie.setPos(self.pie.getPos(render)) self.pie.reparentTo(render) self.pie.setHpr(self.pieNp.getHpr(render)) self.trajectory = ProjectileInterval(self.pie, startPos=self.pie.getPos(render), endPos=self.pieNp.getPos(render), gravityMult=gravityMult, duration=duration, name='projectilePieTraj' + str(id(self))) self.trajectory.setDoneEvent(self.trajectory.getName()) self.acceptOnce(self.trajectory.getDoneEvent(), self.handleTrajDone) self.trajectory.start() sfx = base.localAvatar.audio3d.loadSfx( "phase_4/audio/sfx/MG_cannon_fire_alt.mp3") base.localAvatar.audio3d.attachSoundToObject(sfx, parent) base.playSfx(sfx) if local: self.acceptOnce('projectilePieSensor' + str(id(self)) + '-into', self.handleCollision)
def getToonJumpTrack(av, seatIndex): # using a local func allows the ProjectileInterval to # calculate this pos at run-time def getJumpDest(av=av, node=self.golfKart): dest = Point3(0, 0, 0) if hasattr(self, 'golfKart') and self.golfKart: dest = Vec3(self.golfKart.getPos(av.getParent())) seatNode = self.golfKart.find("**/seat" + str(seatIndex + 1)) dest += seatNode.getPos(self.golfKart) dna = av.getStyle() dest -= hipOffset if (seatIndex < 2): dest.setY(dest.getY() + 2 * hipOffset.getY()) dest.setZ(dest.getZ() + 0.1) else: self.notify.warning( 'getJumpDestinvalid golfKart, returning (0,0,0)') return dest def getJumpHpr(av=av, node=self.golfKart): hpr = Point3(0, 0, 0) if hasattr(self, 'golfKart') and self.golfKart: hpr = self.golfKart.getHpr(av.getParent()) if (seatIndex < 2): hpr.setX(hpr.getX() + 180) else: hpr.setX(hpr.getX()) angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX()) hpr.setX(angle) else: self.notify.warning( 'getJumpHpr invalid golfKart, returning (0,0,0)') return hpr toonJumpTrack = Parallel( ActorInterval(av, 'jump'), Sequence( Wait(0.43), Parallel( LerpHprInterval(av, hpr=getJumpHpr, duration=.9), ProjectileInterval(av, endPos=getJumpDest, duration=.9), ), ), ) return toonJumpTrack
def serveFood(self, food, chairIndex): self.removeFoodModel(chairIndex) serviceLoc = self.serviceLocs.get(chairIndex) if not food or food.isEmpty(): foodModel = loader.loadModel('phase_12/models/bossbotHQ/canoffood') foodModel.setScale(ToontownGlobals.BossbotFoodModelScale) foodModel.reparentTo(serviceLoc) else: food.wrtReparentTo(serviceLoc) tray = food.find('**/tray') if not tray.isEmpty(): tray.hide() ivalDuration = 1.5 foodMoveIval = Parallel(SoundInterval(self.serveFoodSfx, node=food), ProjectileInterval(food, duration=ivalDuration, startPos=food.getPos(serviceLoc), endPos=serviceLoc.getPos(serviceLoc)), LerpHprInterval(food, ivalDuration, Point3(0, -360, 0))) intervalName = 'serveFood-%d-%d' % (self.index, chairIndex) foodMoveIval.start() self.activeIntervals[intervalName] = foodMoveIval
def getThrowInterval(self, gag, x, y, z, h, p, r): toon = self.toon flyGag = self.createThrowGag(gag) throwSoundIval = self._throwSfx if throwSoundIval.isPlaying(): throwSoundIval.finish() throwSoundIval.node = toon toonThrowIval1 = ActorInterval(toon, 'throw', startFrame=Globals.ThrowStartFrame, endFrame=Globals.ThrowEndFrame, playRate=Globals.ThrowPlayRate, partName='torso') toss = Track( (0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(gag.reparentTo, toon.rightHand), Func(gag.setPosHpr, 0, 0, 0, 0, 0, 0), toonThrowIval1)), (toonThrowIval1.getDuration(), Parallel( Func(gag.detachNode), Sequence( ActorInterval(toon, 'throw', startFrame=Globals.ThrowEndFrame + 1, playRate=Globals.ThrowPlayRate, partName='torso'), Func( self.completeThrow))))) def getEndPos(toon=toon): return render.getRelativePoint(toon, Point3(0, Globals.ThrowDistance, 0)) fly = Track( (0, throwSoundIval), (toonThrowIval1.getDuration(), Sequence( Func(flyGag.reparentTo, render), Func(flyGag.setPosHpr, toon, 0.52000000000000002, 0.96999999999999997, 2.2400000000000002, 0, -45, 0), ProjectileInterval( flyGag, endPos=getEndPos, duration=Globals.ThrowDuration), Func(flyGag.detachNode)))) return (toss, fly, flyGag)
def release(self): TrapGag.release(self) throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) if not self.gag: self.build() self.gag.wrtReparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval(self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() if base.localAvatar == self.avatar: self.buildCollisions() self.avatar.acceptOnce('gagSensor-into', self.onCollision) self.reset()
def createOneToonupIval(self, foodNode): toonupIndex = self.foodNodes.index(foodNode) waitTimeForOne = self.distBetweenFoodNodes / self.ToonupBeltSpeed waitTime = waitTimeForOne * toonupIndex self.toonupWaitTimes.append(waitTime) totalTimeToTraverseBelt = self.beltLength / self.ToonupBeltSpeed startPosY = -(self.beltLength / 2.0) endPosY = self.beltLength / 2.0 retval = Sequence( Func(self.loadToonup, toonupIndex), LerpPosInterval(foodNode, duration=totalTimeToTraverseBelt, startPos=Point3(0, startPosY, self.beltHeight), pos=Point3(0, endPosY, self.beltHeight)), ProjectileInterval(foodNode, startPos=Point3(0, endPosY, self.beltHeight), startVel=Point3(0, self.BeltSpeed, 0), endZ=0), Func(self.removeToonup, toonupIndex)) return retval
def getToonJumpTrack(av, destNode): def getJumpDest(av=av, node=destNode): dest = node.getPos(av.getParent()) dest += Vec3(*self.JumpOutOffsets[seatIndex]) return dest def getJumpHpr(av=av, node=destNode): hpr = node.getHpr(av.getParent()) hpr.setX(hpr.getX() + 180) angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX()) hpr.setX(angle) return hpr toonJumpTrack = Parallel( ActorInterval(av, 'jump'), Sequence( Wait(0.1), Parallel( ProjectileInterval(av, endPos=getJumpDest, duration=0.9)))) return toonJumpTrack
def throw(self): if not self.gag and not self.isLocal(): self.setHandJoint() self.build() if self.gag and self.getLocation(): self.startEntity() elif self.gag and self.trapMode == 1: throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) self.gag.setScale(self.gag.getScale(render)) self.gag.reparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval(self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() self.buildProjCollisions() self.reset() self.avatar.acceptOnce('projSensor-into', self.onProjCollision) if self.isLocal(): base.localAvatar.enablePieKeys()
def startProjInterval(self, startX, startY, startZ, endX, endY, endZ, duration, gravityMult, ts=0): if isinstance(ts, int) and ts != 0: ts = globalClockDelta.localElapsedTime(ts) self.disableRay() self.stopMoveInterval() startPos = Point3(startX, startY, startZ) endPos = Point3(endX, endY, endZ) oldHpr = self.getHpr(render) self.headsUp(endPos) newHpr = self.getHpr(render) self.setHpr(oldHpr) self.moveIval = Parallel( LerpHprInterval(self, duration=0.5, hpr=newHpr, startHpr=oldHpr, blendType='easeInOut'), Sequence(Func(self.animFSM.request, 'flyAway', [ts]), Wait(3.5), Func(self.animFSM.request, 'flyDown', [1.0])), Sequence( Wait(2.0), Func(self.headsUp, endPos), ProjectileInterval(self, startPos=startPos, endPos=endPos, gravityMult=gravityMult, duration=duration))) self.moveIval.start(ts)
class Snowball(NodePath, DirectObject): notify = directNotify.newCategory('Snowball') def __init__(self, mg, index): self.mg = mg self.index = index self.model = None self.collNP = None self.isAirborne = False self.owner = None self.throwIval = None self.impactSound = base.loadSfx('phase_4/audio/sfx/snowball_hit.ogg') NodePath.__init__(self, 'snowball') return def load(self): self.model = loader.loadModel('phase_5/models/props/snowball.bam') self.model.reparentTo(self) base.audio3d.attachSoundToObject(self.impactSound, self) sphere = CollisionSphere(0, 0, 0, 0.35) sphere.setTangible(0) node = CollisionNode('snowball-coll-' + str(id(self))) node.addSolid(sphere) node.setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask) self.collNP = self.attachNewNode(node) self.collNP.setCollideMask(BitMask32(0)) self.collNP.setZ(0.35) event = CollisionHandlerEvent() event.set_in_pattern('%fn-into') event.set_out_pattern('%fn-out') base.cTrav.add_collider(self.collNP, event) def setOwner(self, owner): self.owner = owner def getOwner(self): return self.owner def hasOwner(self): return self.owner is not None def b_throw(self): p = camera.getP(render) self.d_throw(p) self.throw(p) def d_throw(self, p): self.mg.sendUpdate('throw', [self.index, p]) def throw(self, p): self.isAirborne = True self.owner.avatar.play('pie', partName='torso', fromFrame=60) base.playSfx(self.owner.throwSound, node=self.owner.avatar) start = NodePath('StartPath') start.reparentTo(self.owner.avatar) start.setScale(render, 1) start.setPos(0, 0, 0) start.setP(p) end = NodePath('ThrowPath') end.reparentTo(start) end.setScale(render, 1) end.setPos(0, 160, -90) end.setHpr(90, -90, 90) self.wrtReparentTo(render) self.setScale(1.0) self.throwIval = ProjectileInterval( self, startPos=self.owner.avatar.find('**/def_joint_right_hold').getPos( render), endPos=end.getPos(render), gravityMult=0.9, duration=3) self.throwIval.start() if self.owner.avId == base.localAvatar.doId: self.accept('snowball-coll-' + str(id(self)) + '-into', self.__handleSnowballCollision) start.removeNode() del start end.removeNode() del end def pauseThrowIval(self): if self.owner: if self.owner.throwSound: self.owner.throwSound.stop() if self.throwIval: self.throwIval.pause() self.throwIval = None return def handleHitWallOrPlayer(self): self.pauseThrowIval() self.reparentTo(render) self.setPos(self.mg.SnowballData[self.index]) self.setHpr(0, 0, 0) self.isAirborne = False self.owner = None return def handleHitGround(self): self.pauseThrowIval() self.reparentTo(render) self.setZ(0.5) self.setHpr(0, 0, 0) self.isAirborne = False self.owner = None return def __handleSnowballCollision(self, entry): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() name = intoNP.getName() if 'barrier' in name: return self.ignore('snowball-coll-' + str(id(self)) + '-into') self.pauseThrowIval() if self.owner.avId == base.localAvatar.doId: self.mg.firstPerson.mySnowball = None self.mg.firstPerson.hasSnowball = False self.isAirborne = False self.owner = None base.playSfx(self.impactSound, node=self, volume=1.5) if 'wall' in name or 'fence' in name: self.mg.sendUpdate('snowballHitWall', [self.index]) self.handleHitWallOrPlayer() else: if 'floor' in name or 'ground' in name or name == 'team_divider': self.mg.sendUpdate('snowballHitGround', [self.index]) self.handleHitGround() else: for av in self.mg.remoteAvatars: if av.avatar.getKey() == avNP.getKey(): self.handleHitWallOrPlayer() friendly = int(av.team == self.mg.team) if friendly: av.unFreeze() else: av.freeze() self.mg.sendUpdate('snowballHitPlayer', [av.avId, self.mg.team, self.index]) return def b_pickup(self): self.d_pickup(self.mg.cr.localAvId) self.pickup(self.mg.getMyRemoteAvatar()) def d_pickup(self, avId): self.mg.sendUpdate('snowballPickup', [self.index, avId]) def pickup(self, remoteAv): self.setPosHpr(0, 0, 0, 0, 0, 0) self.reparentTo(remoteAv.avatar.find('**/def_joint_right_hold')) self.owner = remoteAv self.isAirborne = False def removeNode(self): self.pauseThrowIval() if self.model: self.model.removeNode() self.model = None if self.collNP: self.collNP.removeNode() self.collNP = None self.isAirborne = None self.owner = None self.mg = None NodePath.removeNode(self) return
class ActivateTrapGag(TrapGag, LocationGag): def __init__(self, name, model, damage, hitSfx, collRadius, mode = 0, anim = None, autoRelease = True, activateSfx = None): TrapGag.__init__(self, name, model, damage, hitSfx, anim, doesAutoRelease=autoRelease) LocationGag.__init__(self, 10, 50, shadowScale=0.25) self.trapMode = mode self.entities = [] self.lifeTime = 120 self.minSafeDistance = 5 self.collRadius = collRadius self.activateSfx = None if game.process == 'client': if activateSfx: self.activateSfx = base.audio3d.loadSfx(activateSfx) return def __clearEntity(self, entity, task): if entity: self.__doDustClear(entity) return Task.done def __doDustClear(self, entity): dustTrack = Sequence() dust = self.buildDust() dust.setBillboardPointEye() dust.setScale(Point3(0.1, 0.9, 1)) dust.setPos(entity.getPos(render)) entity.removeNode() self.removeEntity(entity) dustTrack.append(Func(dust.reparentTo, render)) dustTrack.append(ActorInterval(dust, 'chan')) dustTrack.append(Func(dust.cleanup)) dustTrack.start() def buildProjCollisions(self): gagSph = CollisionSphere(0, 0, 0, 1) gagSph.setTangible(0) gagNode = CollisionNode('projSensor') gagNode.addSolid(gagSph) gagNP = self.gag.attach_new_node(gagNode) gagNP.setScale(0.75, 0.8, 0.75) gagNP.setPos(0.0, 0.1, 0.5) gagNP.setCollideMask(BitMask32.bit(0)) gagNP.node().setFromCollideMask(CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.set_in_pattern('%fn-into') event.set_out_pattern('%fn-out') base.cTrav.addCollider(gagNP, event) def buildCollisions(self): TrapGag.buildCollisions(self) gagSph = CollisionSphere(0, 0, 0, self.collRadius) gagSph.setTangible(0) gagNode = CollisionNode('gagSensor') gagNode.addSolid(gagSph) gagNP = self.gag.attachNewNode(gagNode) gagNP.setScale(0.75, 0.8, 0.75) gagNP.setPos(0.0, 0.1, 0.5) gagNP.setCollideMask(BitMask32.bit(0)) gagNP.node().setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.set_in_pattern('%fn-into') event.set_out_pattern('%fn-out') base.cTrav.addCollider(gagNP, event) if self.isLocal(): self.avatar.accept('gagSensor-into', self.onCollision) def damageSuit(self, suit): if self.isLocal(): self.avatar.sendUpdate('suitHitByPie', [suit.doId, self.getID()]) def onActivate(self, entity, suit): self.removeEntity(entity) def onProjCollision(self, entry): x, y, z = self.gag.getPos(render) self.avatar.sendUpdate('setGagPos', [self.getID(), x, y, z]) self.avatar.b_gagRelease(self.getID()) def onCollision(self, entry): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() if self.avatar.doId == base.localAvatar.doId: for key in base.cr.doId2do.keys(): obj = base.cr.doId2do[key] if obj.__class__.__name__ == 'DistributedSuit': if obj.getKey() == avNP.getKey(): if obj.getHealth() > 0: index = self.getEntityIndex(entry.getFromNodePath().getParent()) if not index == None: self.avatar.b_trapActivate(self.getID(), self.avatar.doId, index, obj.doId) return def buildDust(self): dust = Actor('phase_5/models/props/dust-mod.bam', {'chan': 'phase_5/models/props/dust-chan.bam'}) objBin = 110 for cloudNum in range(1, 12): cloudName = '**/cloud' + str(cloudNum) cloud = dust.find(cloudName) cloud.setBin('fixed', objBin) objBin -= 10 return dust def getSplicedLerpAnimsTrack(self, av, animName, origDuration, newDuration, startTime = 0, fps = 30): track = Sequence() addition = 0 numIvals = int(origDuration * fps) timeInterval = newDuration / numIvals animInterval = origDuration / numIvals for _ in range(0, numIvals): track.append(Wait(timeInterval)) track.append(ActorInterval(av, animName, startTime=startTime + addition, duration=animInterval)) addition += animInterval return track def start(self): TrapGag.startTrap(self) if self.trapMode == 0: LocationGag.start(self, self.avatar) elif self.trapMode == 1: if not self.gag: self.build() self.setHandJoint() self.gag.reparentTo(self.handJoint) self.avatar.play('toss', fromFrame=22) def startEntity(self): if self.getLocation(): x, y, z = self.getLocation() self.gag.setPos(x, y, z - 0.45) if not self.gag: self.build() self.gag.setScale(GagGlobals.PNT3NEAR0) self.gag.reparentTo(render) LerpScaleInterval(self.gag, 1.2, Point3(1.7, 1.7, 1.7)).start() track = Sequence(Wait(0.7)) if self.isSafeLocation(self.gag): self.entities.append(self.gag) suits = [] for obj in base.cr.doId2do.values(): if obj.__class__.__name__ == 'DistributedSuit': if obj.getPlace() == base.localAvatar.zoneId: suits.append(obj) nearestCog = self.getClosestObject(self.gag, suits) suits = [] if nearestCog and nearestCog.getDistance(self.gag) <= self.minSafeDistance: self.onActivate(self.gag, nearestCog) else: track.append(SoundInterval(self.hitSfx, duration=0.5, node=self.avatar)) base.taskMgr.doMethodLater(self.lifeTime, self.__clearEntity, 'Clear Entity', extraArgs=[self.gag], appendTask=True) self.gag = None else: self.cleanupGag() for ent in [self.gag, self.getClosestObject(self.gag, self.entities)]: if ent: self.__doDustClear(ent) track.append(Func(self.completeTrap)) track.start() return def throw(self): if not self.gag and not self.isLocal(): self.setHandJoint() self.build() if self.gag and self.getLocation(): self.startEntity() elif self.gag and self.trapMode == 1: throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) self.gag.setScale(self.gag.getScale(render)) self.gag.reparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval(self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() self.buildProjCollisions() self.reset() self.avatar.acceptOnce('projSensor-into', self.onProjCollision) if self.isLocal(): base.localAvatar.enablePieKeys() def completeTrap(self): LocationGag.complete(self) self.reset() if self.isLocal(): base.localAvatar.enablePieKeys() def release(self): TrapGag.release(self) if self.trapMode == 0: LocationGag.release(self) self.build() self.buildCollisions() actorTrack = LocationGag.getActorTrack(self) if actorTrack: LocationGag.getSoundTrack(self).start() if self.isLocal(): actorTrack.append(Func(self.avatar.b_gagThrow, self.getID())) actorTrack.start() elif self.trapMode == 1: self.startEntity() def setEndPos(self, x, y, z): LocationGag.setDropLoc(self, x, y, z + 0.25) def getClosestObject(self, entity, objects): distances = [] entities = {} for ent in objects: entities.update({ent: ent.getDistance(entity) / 100}) for dist in entities.values(): distances.append(dist) distances.sort() for ent in entities.keys(): if ent.getDistance(entity) / 100 == distances[0]: entities = {} distances = [] return ent def isSafeLocation(self, entity): for ent in self.entities: distance = ent.getDistance(entity) / 100 if distance < self.minSafeDistance: return False return True def getEntityIndex(self, entity): for i in range(len(self.entities)): ent = self.entities[i] if ent == entity: return i def removeEntity(self, entity): if entity in self.entities: self.entities.remove(entity) def getEntities(self): return self.entities def equip(self): TrapGag.equip(self) def unEquip(self): TrapGag.unEquip(self) LocationGag.cleanupLocationSeeker(self)
def finish(self): ProjectileInterval.finish(self) self.__stopPitchTask()
def pause(self): ProjectileInterval.pause(self) self.__stopPitchTask()
def loop(self, startT=0.0, endT=-1.0, playRate=1.0): ProjectileInterval.loop(self, startT, endT, playRate) self.__startPitchTask()
class ActivateTrapGag(TrapGag, LocationGag): collRadius = 1.0 trapMode = 0 autoRelease = True activateSfxPath = None def __init__(self): TrapGag.__init__(self) LocationGag.__init__(self, 10, 50, shadowScale=0.25) # trapMode is the mode the trap gag is on. 0) Trapdoor/Quicksand and 1) Banana Peel, marbles, etc. # This keeps track of the entities we drop. self.entities = [] # This is the length (in seconds) of how long an entity exists. self.lifeTime = 120 # This is the minimum distance an entity has to be from another. self.minSafeDistance = 5 # collRadius is the radius of the CollisionSphere that detects suits. # This is the sound effect called when a trap is tripped. self.activateSfx = None self.entityTrack = None if metadata.PROCESS == 'client': if self.activateSfxPath: self.activateSfx = base.audio3d.loadSfx(self.activateSfxPath) def __clearEntity(self, entity, task): if entity: self.__doDustClear(entity) return task.done def __doDustClear(self, entity): dustTrack = Sequence() dust = self.buildDust() dust.setBillboardPointEye() dust.setScale(Point3(0.1, 0.9, 1)) dust.setPos(entity.getPos(render)) entity.removeNode() self.removeEntity(entity) dustTrack.append(Func(dust.reparentTo, render)) dustTrack.append(ActorInterval(dust, 'chan')) dustTrack.append(Func(dust.cleanup)) dustTrack.start() def buildProjCollisions(self): gagSph = CollisionSphere(0, 0, 0, 1) gagSph.setTangible(0) gagNode = CollisionNode('projSensor') gagNode.addSolid(gagSph) gagNP = self.gag.attach_new_node(gagNode) gagNP.setScale(0.75, 0.8, 0.75) gagNP.setPos(0.0, 0.1, 0.5) gagNP.setCollideMask(BitMask32.bit(0)) gagNP.node().setFromCollideMask(CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.set_in_pattern("%fn-into") event.set_out_pattern("%fn-out") base.cTrav.addCollider(gagNP, event) def buildCollisions(self): TrapGag.buildCollisions(self) gagSph = CollisionSphere(0, 0, 0, self.collRadius) gagSph.setTangible(0) gagNode = CollisionNode('gagSensor') gagNode.addSolid(gagSph) gagNP = self.gag.attachNewNode(gagNode) gagNP.setScale(0.75, 0.8, 0.75) gagNP.setPos(0.0, 0.1, 0.5) gagNP.setCollideMask(BitMask32.bit(0)) gagNP.node().setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.set_in_pattern("%fn-into") event.set_out_pattern("%fn-out") base.cTrav.addCollider(gagNP, event) if self.isLocal(): self.avatar.accept('gagSensor-into', self.onCollision) def damageSuit(self, suit): if self.isLocal(): suit.sendUpdate('hitByGag', [self.getID()]) def onActivate(self, entity, suit): self.removeEntity(entity) def onProjCollision(self, entry): if not self.gag: self.build() x, y, z = self.gag.getPos(render) self.avatar.sendUpdate('setGagPos', [self.getID(), x, y, z]) self.avatar.b_gagRelease(self.getID()) def onCollision(self, entry): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() if self.avatar.doId == base.localAvatar.doId: for key in base.cr.doId2do.keys(): obj = base.cr.doId2do[key] if obj.__class__.__name__ in CIGlobals.SuitClasses: if obj.getKey() == avNP.getKey(): if obj.getHealth() > 0: index = self.getEntityIndex( entry.getFromNodePath().getParent()) if not index is None: self.avatar.b_trapActivate( self.getID(), self.avatar.doId, index, obj.doId) def buildDust(self): dust = Actor('phase_5/models/props/dust-mod.bam', {'chan': 'phase_5/models/props/dust-chan.bam'}) objBin = 110 for cloudNum in range(1, 12): cloudName = '**/cloud' + str(cloudNum) cloud = dust.find(cloudName) cloud.setBin('fixed', objBin) objBin -= 10 return dust def getSplicedLerpAnimsTrack(self, av, animName, origDuration, newDuration, startTime=0, fps=30): track = Sequence() addition = 0 numIvals = int(origDuration * fps) timeInterval = newDuration / numIvals animInterval = origDuration / numIvals for _ in range(0, numIvals): track.append(Wait(timeInterval)) track.append( ActorInterval(av, animName, startTime=startTime + addition, duration=animInterval)) addition += animInterval return track def start(self): TrapGag.startTrap(self) # Let's start the location seeker if we're using a trapdoor or quicksand gag. if self.trapMode == 0: LocationGag.start(self, self.avatar) elif self.trapMode == 1: if not self.gag: self.build() self.setHandJoint() self.gag.reparentTo(self.handJoint) self.avatar.play('toss', fromFrame=22) def startEntity(self): if self.entityTrack: self.entityTrack.pause() self.entityTrack = None if self.getLocation(): x, y, z = self.getLocation() self.gag.setPos(x, y, z - 0.45) if not self.gag: self.build() # Let's let DistributedBattleZone know about this, if we can. lifeTime = self.lifeTime clearTaskName = self.gag.getName() + '-Clear' if base.localAvatarReachable() and hasattr( base.localAvatar, 'myBattle') and base.localAvatar.myBattle != None: base.localAvatar.myBattle.addDebris(self.gag, self.avatar.doId) else: lifeTime = 1.0 self.gag.setScale(GagGlobals.PNT3NEAR0) self.gag.reparentTo(render) LerpScaleInterval(self.gag, 1.2, Point3(1.7, 1.7, 1.7)).start() track = Sequence(Wait(0.7)) if self.isSafeLocation(self.gag): self.entities.append(self.gag) # Let's suck the closest suit into our trap. suits = [] for obj in base.cr.doId2do.values(): if obj.__class__.__name__ == "DistributedSuit": if obj.getPlace() == base.localAvatar.zoneId: suits.append(obj) nearestCog = self.getClosestObject(self.gag, suits) suits = [] if nearestCog and nearestCog.getDistance( self.gag) <= self.minSafeDistance: self.onActivate(self.gag, nearestCog) else: track.append( SoundInterval(self.hitSfx, duration=0.5, node=self.gag)) base.taskMgr.doMethodLater(lifeTime, self.__clearEntity, clearTaskName, extraArgs=[self.gag], appendTask=True) self.gag = None else: # We're too close to another trap, let's clear them out. self.cleanupGag() for ent in [ self.gag, self.getClosestObject(self.gag, self.entities) ]: if ent: self.__doDustClear(ent) track.append(Func(self.completeTrap)) track.start() self.entityTrack = track def throw(self): if not self.gag and not self.isLocal(): self.setHandJoint() self.build() if self.gag and self.getLocation(): self.startEntity() elif self.gag and self.trapMode == 1: throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) self.gag.setScale(self.gag.getScale(render)) self.gag.reparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval( self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() self.buildProjCollisions() self.reset() self.avatar.acceptOnce('projSensor-into', self.onProjCollision) def completeTrap(self): LocationGag.complete(self) self.reset() def release(self): TrapGag.release(self) # Let's release the location seeker if we're using a trapdoor or quicksand. if self.trapMode == 0: LocationGag.release(self) self.build() self.buildCollisions() actorTrack = LocationGag.getActorTrack(self) if actorTrack: LocationGag.getSoundTrack(self).start() if self.isLocal(): actorTrack.append( Func(self.avatar.b_gagThrow, self.getID())) actorTrack.start() elif self.trapMode == 1: self.startEntity() def setEndPos(self, x, y, z): LocationGag.setDropLoc(self, x, y, z + 0.25) def getClosestObject(self, entity, objects): distances = [] entities = {} for ent in objects: entities.update({ent: (ent.getDistance(entity) / 100)}) for dist in entities.values(): distances.append(dist) distances.sort() for ent in entities.keys(): if (ent.getDistance(entity) / 100) == distances[0]: entities = {} distances = [] return ent def isSafeLocation(self, entity): for ent in self.entities: distance = (ent.getDistance(entity) / 100) if distance < self.minSafeDistance: return False return True def getEntityIndex(self, entity): for i in range(len(self.entities)): ent = self.entities[i] if ent == entity: return i def removeEntity(self, entity): if entity in self.entities: self.entities.remove(entity) if base.localAvatarReachable() and hasattr(base.localAvatar, 'myBattle') \ and base.localAvatar.myBattle != None: base.localAvatar.myBattle.removeDebris(entity) def getEntities(self): return self.entities def equip(self): TrapGag.equip(self) def unEquip(self): TrapGag.unEquip(self) LocationGag.cleanupLocationSeeker(self)
def loop(self, startT = 0.0, endT = -1.0, playRate = 1.0): ProjectileInterval.loop(self, startT, endT, playRate) self.__startPitchTask()
class TossTrapGag(TrapGag): def __init__(self, name, model, damage, hitSfx, idleSfx = None, particlesFx = None, anim = None, wantParticles = True): TrapGag.__init__(self, name, model, damage, hitSfx, anim) self.wantParticles = wantParticles self.particles = None self.particlesFx = particlesFx self.idleSfx = None if game.process == 'client': if idleSfx: self.idleSfx = base.audio3d.loadSfx(idleSfx) return def startTrap(self): TrapGag.startTrap(self) if not self.gag: self.build() self.setHandJoint() self.gag.reparentTo(self.handJoint) self.avatar.play('toss', fromFrame=22) def build(self): TrapGag.build(self) self.buildParticles() self.setHandJoint() def buildParticles(self): self.cleanupParticles() if hasattr(self, 'wantParticles') and hasattr(self, 'particlesFx'): if self.wantParticles and self.particlesFx: self.particles = ParticleEffect() self.particles.loadConfig(self.particlesFx) def buildCollisions(self): TrapGag.buildCollisions(self) gagSph = CollisionSphere(0, 0, 0, 1) gagSph.setTangible(0) gagNode = CollisionNode('gagSensor') gagNode.addSolid(gagSph) gagNP = self.gag.attachNewNode(gagNode) gagNP.setScale(0.75, 0.8, 0.75) gagNP.setPos(0.0, 0.1, 0.5) gagNP.setCollideMask(BitMask32.bit(0)) gagNP.node().setFromCollideMask(CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.setInPattern('%fn-into') event.setOutPattern('%fn-out') base.cTrav.addCollider(gagNP, event) def onCollision(self, entry): TrapGag.onCollision(self, entry) gag = self.gag if not gag: gag = self.entity x, y, z = gag.getPos(render) self.avatar.sendUpdate('setGagPos', [self.getID(), x, y, z]) def release(self): TrapGag.release(self) throwPath = NodePath('ThrowPath') throwPath.reparentTo(self.avatar) throwPath.setScale(render, 1) throwPath.setPos(0, 160, -120) throwPath.setHpr(0, 90, 0) if not self.gag: self.build() self.gag.wrtReparentTo(render) self.gag.setHpr(throwPath.getHpr(render)) self.setHandJoint() self.track = ProjectileInterval(self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3) self.track.start() if base.localAvatar == self.avatar: self.buildCollisions() self.avatar.acceptOnce('gagSensor-into', self.onCollision) self.reset() def delete(self): TrapGag.delete(self) self.cleanupParticles() def unEquip(self): TrapGag.unEquip(self) self.cleanupParticles() def cleanupParticles(self): if self.particles: self.particles.cleanup() self.particles = None return
class GagCannon(DirectObject): def __init__(self, gag = None, supply = def_supply, health = 20, fireSpeed = 2, searchTime = 4): self.gag = None self.maxSupply = supply self.supply = 0 self.maxHp = health self.hp = health self.fireSpeed = fireSpeed self.searchTime = searchTime self.maxDistance = 100 self.target = None self.cannon = None self.gagMgr = None self.firing = False self.gagProp = None self.fireSound = SoundBank.getSound('cannon_fire') self.adjustSound = SoundBank.getSound('cannon_adjust') self.whizzSound = SoundBank.getSound('cannon_whizz') def generate(self): self.cannon = loader.loadModel("phase_4/models/minigames/toon_cannon.bam") base.taskMgr.doMethodLater(self.searchTime, self.lookAround, 'Look Around') base.taskMgr.doMethodLater(self.searchTime, self.searchForTarget, 'Search For Target') self.adjustSound.setVolume(0.2) self.adjustSound.setLoop(True) return self.cannon def addGagProp(self): self.gagMgr = render.getPythonTag('GagManager') self.gagProp = self.gagMgr.getGagByName(self.gag).generate() self.gagProp.setName("Turrent_Prop") self.gagProp.reparentTo(self.cannon.find('**/cannon')) self.gagProp.setPos(0, 5.3, 0) self.gagProp.setHpr(0, 270, 0) def removeGagProp(self): if(self.gagProp != None): self.gagProp.removeNode() def lookAround(self, task): if(self.target == None): self.adjustSound.play() cannon = self.cannon.find('**/cannon') def reset(task): if(self.target == None): cannon.hprInterval(2, Vec3(0, 0, 0)).start() Sequence( Wait(2), Func(self.adjustSound.stop) ).start() base.taskMgr.doMethodLater(self.searchTime, self.lookAround, 'Look Around') return Task.done def lookOtherWay(task): if(self.target == None): cannon.hprInterval(4, Vec3(-40, 0, 0)).start() base.taskMgr.doMethodLater(4, reset, 'Reset H') return Task.done cannon.hprInterval(2, Vec3(40, 0, 0)).start() base.taskMgr.doMethodLater(2, lookOtherWay, 'Look Other Way') return Task.done def attemptSupplyRefill(self, task): if(self.supply <= round(float(self.maxSupply) * 0.4)): barrels = render.find('**/Barrels').getChildren() for barrel in barrels: if(self.cannon.getDistance(barrel) <= 25): stats = barrel.getPythonTag('Stats') if(stats.getSupply() > 0): neededSupply = self.maxSupply - self.supply barrelSupply = stats.getSupply() if(barrelSupply >= neededSupply): self.supply += (barrelSupply - neededSupply) stats.setSupply(barrelSupply - neededSupply) else: self.supply += barrelSupply stats.setSupply(0) self.gag = stats.getGag() self.addGagProp() return Task.done def searchForTarget(self, task): if not self.firing and self.target == None: cogs = render.find('**/Cogs').getChildren() distances = [] for cog in cogs: distance = self.cannon.getDistance(cog) if(distance <= self.maxDistance): distances.append(distance) if(len(distances) > 0): distances.sort() checkDistanceIndex = 0 for cog in cogs: distance = self.cannon.getDistance(cog) if(distance == distances[checkDistanceIndex]): if(self.supply > 0): #if(self.isTargetReachable(cog)): self.setTarget(cog) self.cannon.find('**/cannon').lookAt(self.target, 0, 0, 5) self.cannon.find('**/cannon').setP(self.cannon.find('**/cannon').getP() + 1.5) base.taskMgr.doMethodLater(self.fireSpeed, self.attackTarget, 'Attack Target') break #else: #if(checkDistanceIndex + 1 < len(distances)): #checkDistanceIndex += 1 #else: #checkDistanceIndex = 0 else: base.taskMgr.doMethodLater(self.fireSpeed, self.attemptSupplyRefill, 'Attempt Supply Refill') return Task.cont def isTargetReachable(self, target): rayFrom = self.gagProp.getPos() rayTo = target.find('**/Head').getPos(render) world = BulletWorld() result = world.rayTestClosest(rayFrom, rayTo).getNode() if(result != None): print result.getName() if(result.getName() == 'Head'): return True return False def resetCannon(self, task): if not self.gagProp.isEmpty(): self.gagProp.show() base.taskMgr.add(self.lookAround, 'Look Around') return Task.done def attackTarget(self, task): if(self.hp > 0): if(self.target != None): cog = self.target.getPythonTag('Cog') if(cog.getHealth() > 0): self.gagProp.hide() gag = copy.copy(self.gagProp) gag.reparentTo(render) gag.setPos(self.gagProp.getPos(render)) gag.setHpr(self.gagProp.getHpr(render)) endPos = self.target.find('**/Head').getPos(render) self.projectile = ProjectileInterval(gag, startPos=gag.getPos(render), endPos=endPos, gravityMult=1, duration=1) gag.show() self.projectile.start() self.fireSound.play() self.whizzSound.play() render.getPythonTag('WorldCollisions').addGagCollision(gag) self.target = None self.firing = False base.taskMgr.doMethodLater(2, self.removeGag, 'Remove Gag', extraArgs = [gag, self.projectile], appendTask = True) base.taskMgr.doMethodLater(2, self.resetCannon, 'Reset Cannon') self.cannon.find('**/cannon').setHpr(0, 0, 0) self.setSupply(self.getSupply() - 1) else: self.target = None self.firing = False base.taskMgr.doMethodLater(2, self.resetCannon, 'Reset Cannon') self.cannon.find('**/cannon').setHpr(0, 0, 0) return Task.done def removeGag(self, gag, trajectory, task): trajectory.finish() gag.removeNode() return Task.done def setTarget(self, target = None): self.target = target def getTarget(self): return self.target def setMaxHealth(self, maxHp): self.maxHp = maxHp def getMaxHealth(self): return self.maxHp def setHealth(self, hp): self.hp = hp def getHealth(self): return self.hp def setSupply(self, supply): self.supply = supply if(self.supply == 0): self.gag = None self.removeGagProp() def getMaxSupply(self): return self.maxSupply def getSupply(self): return self.supply def getFireSpeed(self): return self.fireSpeed def getSearchTime(self): return self.searchTime