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 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 start(self, startT=0.0, endT=-1.0, playRate=1.0): ProjectileInterval.start(self, startT, endT, playRate) self.__startPitchTask()
def start(self, startT = 0.0, endT = -1.0, playRate = 1.0): ProjectileInterval.start(self, startT, endT, playRate) self.__startPitchTask()
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 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
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)
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 self.timeout = 5.0 if game.process == 'client': if idleSfx: self.idleSfx = base.audio3d.loadSfx(idleSfx) 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.entity.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) self.avatar.acceptOnce('gagSensor-into', self.onCollision) def onCollision(self, entry): TrapGag.onCollision(self, entry) x, y, z = self.entity.getPos(render) base.localAvatar.sendUpdate('setGagPos', [self.getID(), x, y, z]) 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 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
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)
class Snowball(NodePath, DirectObject): """Represents a useable snowball in Winter Dodgeball minigame (client)""" notify = directNotify.newCategory("Snowball") def __init__(self, mg, index): # The minigame self.mg = mg self.index = index # The snowball geometry self.model = None self.collNP = None self.shadow = None # Has the snowball been thrown and is it currently in the air? self.isAirborne = False # The RemoteDodgeballAvatar that is currently holding this snowball. self.owner = None self.throwIval = None self.impactSound = base.loadSfx('phase_4/audio/sfx/snowball_hit.ogg') NodePath.__init__(self, "snowball") def load(self): self.model = loader.loadModel("phase_5/models/props/snowball.bam") self.model.reparentTo(self) self.shadow = CIGlobals.makeDropShadow(0.1) self.shadow.reparentTo(self) base.audio3d.attachSoundToObject(self.impactSound, self) # Setup collisions 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.show() 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): """ Sets the owner of this snowball. owner - A DodgeballRemoteAvatar instance """ self.owner = owner def getOwner(self): return self.owner def hasOwner(self): """Returns whether or not this snowball has an owner.""" 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): if not self.owner or not CIGlobals.isNodePathOk(self.owner.avatar): return self.isAirborne = True self.owner.avatar.play('pie', partName='torso', fromFrame=62) 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, -35) 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=2) 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 def handleHitWallOrPlayer(self): self.pauseThrowIval() CIGlobals.makeSplat(self.getPos(render), (1, 1, 1, 1), 0.25) self.reparentTo(render) self.setPos(self.mg.SnowballData[self.index]) self.setHpr(0, 0, 0) self.shadow.show() self.isAirborne = False self.owner = None def handleHitGround(self): self.pauseThrowIval() self.reparentTo(render) self.setZ(0) self.setHpr(0, 0, 0) self.shadow.show() self.isAirborne = False self.owner = None def resetSnowball(self): self.mg.sendUpdate('snowballHitWall', [self.index]) self.handleHitWallOrPlayer() def __handleSnowballCollision(self, entry): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() name = intoNP.getName() if 'barrier' in name: # Don't react to hitting a team barrier. return else: 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: # We hit a wall. Go back to our center position. self.resetSnowball() elif 'floor' in name or 'ground' in name or name == 'team_divider': # We hit the floor. Stay on the ground. self.mg.sendUpdate('snowballHitGround', [self.index]) self.handleHitGround() else: for av in self.mg.remoteAvatars: if av.avatar.getKey() == avNP.getKey(): # We hit this toon! 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]) 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 self.shadow.hide() def removeNode(self): self.pauseThrowIval() if self.model: self.model.removeNode() self.model = None if self.collNP: self.collNP.removeNode() self.collNP = None if self.shadow: self.shadow.removeNode() self.shadow = None self.isAirborne = None self.owner = None self.mg = None NodePath.removeNode(self)
class DeliveryGamePie(DirectObject): 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 splat(self): self.mg.pies.remove(self) self.track.pause() self.splat.play('chan') self.splat.reparentTo(render) self.splat.setPos(self.gag.getPos(render)) self.gag.reparentTo(hidden) taskMgr.doMethodLater(0.5, self.delSplat, 'Delete Splat' + str(hash(self))) def delSplat(self, task): self.splat.reparentTo(hidden) self.cleanup() def __handleThrowTrackDone(self, task): self.cleanup() return task.done def cleanup(self): if hasattr(self, 'cleanedUp'): return self.cleanedUp = 1 del self.mg del self.toon self.gc.cleanupGag() del self.gc self.gag.removeNode() del self.gag del self.track self.splat.cleanup() del self.splat taskMgr.remove('handleThrowTrackDoneDGP-' + str(hash(self))) taskMgr.remove('Delete Splat' + str(hash(self))) def __handlePieCollision(self, entry): self.splat() self.mg.sendUpdate('pieSplat', [self.mg.pies.index(self)]) intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() fromNP = entry.getFromNodePath().getParent() if fromNP.isEmpty(): return for key in base.cr.doId2do.keys(): obj = base.cr.doId2do[key] if obj.__class__.__name__ == "DistributedDeliveryGameSuit": if obj.getKey() == avNP.getKey(): self.mg.sendUpdate('hitSuitWithPie', [obj.doId])
class ProjectilePie(DirectObject): 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 pieCollisions(self): pss = CollisionSphere(0, 0, 0, 1) psnode = CollisionNode('projectilePieSensor' + str(id(self))) psnode.add_solid(pss) self.psnp = self.pie.attach_new_node(psnode) self.psnp.set_collide_mask(BitMask32(0)) self.psnp.node().set_from_collide_mask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask) event = CollisionHandlerEvent() event.set_in_pattern("%fn-into") event.set_out_pattern("%fn-out") base.cTrav.add_collider(self.psnp, event) def handleCollision(self, entry): messenger.send(self.collideEventName, [entry, self]) def handleTrajDone(self): self.cleanup() def cleanup(self): self.ignore(self.trajectory.getDoneEvent()) self.trajectory.finish() del self.trajectory if self.turret.piesInFlight: self.turret.piesInFlight.remove(self) self.ignore('projectilePieSensor' + str(id(self)) + '-into') del self.collideEventName if hasattr(self, 'psnp'): self.psnp.removeNode() del self.psnp self.pie.removeNode() del self.pie del self.pieNp del self.turret
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
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 Player(DirectObject): keyMap = {'left': 0, 'right': 0, 'forward': 0, 'backward': 0, 'control': 0} movingJumping = False movingNeutral = False movingForward = False movingRotation = False movingBackward = False movementEnabled = True throwingPie = False canThrowPie = True currentGag = None gagMgr = None hit = False data = {} hp = 15 maxHp = 15 jellybeans = 0 def __init__(self, avatar): self.data = avatar.getData() self.localAvatar = avatar.getAvatar() self.gag = None self.setupToon() self.walkSound = SoundBank.getSound('toon_walk') self.runSound = SoundBank.getSound('toon_run') self.laffMeter = LaffMeter(self) self.laffMeter.setPos(-1.18, 0, -0.84) self.laffMeter.start() self.localAvatar.setPythonTag('Avatar', self) self.gagMgr = GagManager() render.setPythonTag('GagManager', self.gagMgr) from doomsday.shop.GagCannon import GagCannon from doomsday.shop.GagBarrel import GagBarrel gagCannon = GagCannon().generate() gagCannon.reparentTo(render) gagCannon.setPos(43.36, -0.82, 4.03) gagCannon.setH(89.47) #gagCannon2 = GagCannon().generate() #gagCannon2.reparentTo(render) #gagCannon2.setPos(-60.18, -9.06, 1.23) #gagCannon2.setH(93.90) barrel = GagBarrel('Wedding Cake').generate() barrel.setPos(43.36, 6.71, 4.03) barrel.setH(89.47) barrel = GagBarrel('Wedding Cake').generate() barrel.setPos(-57.20, -5.61, 1.23) barrel.setH(91.19) return def getData(self): return self.data def playMovementSound(self, sound): sound.setVolume(0.8) sound.setLoop(True) sound.play() def setHealth(self, paramHealth): self.hp = paramHealth self.laffMeter.adjustFace(self.hp, self.maxHp, quietly=0) def setJellybeans(self, amt): self.jellybeans = amt def getJellybeans(self): return self.jellybeans def teleportIn(self): portal_chan = loader.loadModel('phase_3.5/models/props/portal-chan.bam') portal = Actor(loader.loadModel('phase_3.5/models/props/portal-mod.bam'), {'chan' : portal_chan}) portal.setScale(1.3) portal.setBin('fixed', 40) portal.setDepthWrite(False) portal.setDepthTest(False) portal.reparentTo(self.localAvatar.find('**/joint_nameTag')) portal.setPos(0, -2, -0.05) portal.setHpr(0, 0, 0) portal.play('chan', fromFrame=60) def setMovement(self, flag): self.movementEnabled = flag if(flag is False): self.movingJumping = False self.movingBackward = False self.movingForward = False self.movingNeutral = False self.movingRotation = False #base.taskMgr.remove('controlManager') self.keyMap = { 'left': 0, 'right': 0, 'forward': 0, 'backward': 0, 'control': 0} self.walkControls.setWalkSpeed(0, 0, 0, 0) else: base.taskMgr.add(self.handleMovement, 'controlManager') self.walkControls.enableAvatarControls() base.localAvatar.physControls = self.walkControls def setHit(self, flag): self.hit = flag def isHit(self): return self.hit def getHealth(self): return self.hp def getAvatar(self): return self.localAvatar def setupCamera(self): base.camera.reparentTo(self.localAvatar) base.camera.setPos(0, -13.2375, 3.2375) def getAirborneHeight(self): return 3.2624999999999997 def setWatchKey(self, key, input, keyMapName): def watchKey(active = True): if active == True: inputState.set(input, True) self.keyMap[keyMapName] = 1 else: inputState.set(input, False) self.keyMap[keyMapName] = 0 if(self.movementEnabled): base.accept(key, watchKey, [True]) base.accept(key + '-up', watchKey, [False]) def handleMovement(self, task): if self.keyMap['control'] == 1: if self.keyMap['forward'] or self.keyMap['backward'] or self.keyMap['left'] or self.keyMap['right'] and self.throwingPie == False: if self.movingJumping == False: if self.localAvatar.physControls.isAirborne: self.setMovementAnimation('running-jump-idle') elif self.keyMap['forward']: if self.movingForward == False: self.setMovementAnimation('run') elif self.keyMap['backward']: if self.movingBackward == False: self.setMovementAnimation('walk', playRate=-1.0) elif self.keyMap['left'] or self.keyMap['right']: if self.movingRotation == False: self.setMovementAnimation('walk') elif not self.localAvatar.physControls.isAirborne: if self.keyMap['forward']: if self.movingForward == False: self.setMovementAnimation('run') elif self.keyMap['backward']: if self.movingBackward == False: self.setMovementAnimation('walk', playRate=-1.0) elif self.keyMap['left'] or self.keyMap['right']: if self.movingRotation == False: self.setMovementAnimation('walk') elif self.movingJumping == False: if self.localAvatar.physControls.isAirborne: self.setMovementAnimation('jump-idle') elif self.movingNeutral == False: self.setMovementAnimation('neutral') elif not self.localAvatar.physControls.isAirborne: if self.movingNeutral == False: self.setMovementAnimation('neutral') elif self.keyMap['forward'] == 1: if self.movingForward == False: if not self.localAvatar.physControls.isAirborne: self.setMovementAnimation('run') elif self.keyMap['backward'] == 1: if self.movingBackward == False: if not self.localAvatar.physControls.isAirborne: self.setMovementAnimation('walk', playRate=-1.0) elif self.keyMap['left'] or self.keyMap['right']: if self.movingRotation == False: if not self.localAvatar.physControls.isAirborne: self.setMovementAnimation('walk') elif not self.localAvatar.physControls.isAirborne: if self.movingNeutral == False and self.throwingPie == False: self.setMovementAnimation('neutral') return Task.cont def setMovementAnimation(self, loopName, playRate = 1.0): if 'jump' in loopName: self.movingJumping = True self.movingForward = False self.movingNeutral = False self.movingRotation = False self.movingBackward = False self.walkSound.stop() self.runSound.stop() elif loopName == 'run': self.movingJumping = False self.movingForward = True self.movingNeutral = False self.movingRotation = False self.movingBackward = False self.walkSound.stop() self.playMovementSound(self.runSound) elif loopName == 'walk': self.movingJumping = False self.movingForward = False self.movingNeutral = False if playRate == -1.0: self.movingBackward = True self.movingRotation = False else: self.movingBackward = False self.movingRotation = True self.runSound.stop() self.playMovementSound(self.walkSound) elif loopName == 'neutral': self.movingJumping = False self.movingForward = False self.movingNeutral = True self.movingRotation = False self.movingBackward = False self.runSound.stop() self.walkSound.stop() elif loopName == 'pie-throw' or loopName == 'pie-throw-2': self.throwingPie = True self.movingJumping = False self.movingForward = False self.movingNeutral = False self.movingRotation = False self.movingBackward = False self.runSound.stop() self.walkSound.stop() if loopName == 'pie-throw': ActorInterval(self.localAvatar, 'pie-throw', playRate=playRate, startFrame=0, endFrame=45).loop() elif loopName == 'pie-throw-2': ActorInterval(self.localAvatar, 'pie-throw', playRate=playRate, startFrame=45, endFrame=90).loop() else: ActorInterval(self.localAvatar, loopName, playRate=playRate).loop() def calculateHeight(self, task): self.height = task.time * 1.75 if task.time >= 4: self.height = 5 return Task.done return Task.cont def gagStart(self): if self.throwingPie == False and self.canThrowPie == True: base.accept('delete', self.null) self.canThrowPie = False gagMgr = render.getPythonTag('GagManager') self.gag = copy.copy(gagMgr.getGagByName(self.currentGag).generate()) self.gag.reparentTo(self.localAvatar.find('**/def_joint_right_hold')) self.setMovementAnimation('pie-throw') base.taskMgr.add(self.calculateHeight, 'Calculate Height') return def gagThrow(self): if self.throwingPie: self.setMovementAnimation('pie-throw-2') taskMgr.doMethodLater(0.75, self.gagRelease, 'gag release') else: self.throwingPie = False base.taskMgr.remove('Calculate Height') 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 destroyGag(self, gag, trajectory, task): trajectory.finish() gag.removeNode() return Task.done def null(self): pass def enableThrowing(self, task): self.canThrowPie = True self.setMovementAnimation('neutral') base.accept('delete', self.gagStart) base.accept('delete-up', self.gagThrow) base.accept('p', self.gagStart) base.accept('p-up', self.gagThrow) return Task.done def removeGag(self, task): if self.gag != None: self.gag.removeNode() self.gag = None return Task.done def setupPhysics(self): base.accept('delete', self.gagStart) base.accept('delete-up', self.gagThrow) base.accept('p', self.gagStart) base.accept('p-up', self.gagThrow) self.setWatchKey('arrow_up', 'forward', 'forward') self.setWatchKey('w', 'forward', 'forward') self.setWatchKey('control-arrow_up', 'forward', 'forward') self.setWatchKey('control-w_up', 'forward', 'forward') self.setWatchKey('alt-arrow_up', 'forward', 'forward') self.setWatchKey('alt-w_up', 'forward', 'forward') self.setWatchKey('shift-arrow_up', 'forward', 'forward') self.setWatchKey('shift-w_up', 'forward', 'forward') self.setWatchKey('arrow_down', 'reverse', 'backward') self.setWatchKey('s', 'reverse', 'backward') self.setWatchKey('control-arrow_down', 'reverse', 'backward') self.setWatchKey('control-s', 'reverse', 'backward') self.setWatchKey('alt-arrow_down', 'reverse', 'backward') self.setWatchKey('alt-s', 'reverse', 'backward') self.setWatchKey('shift-arrow_down', 'reverse', 'backward') self.setWatchKey('shift-s', 'reverse', 'backward') self.setWatchKey('arrow_left', 'turnLeft', 'left') self.setWatchKey('a', 'turnLeft', 'left') self.setWatchKey('control-arrow_left', 'turnLeft', 'left') self.setWatchKey('control-a', 'turnLeft', 'left') self.setWatchKey('alt-arrow_left', 'turnLeft', 'left') self.setWatchKey('alt-a', 'turnLeft', 'left') self.setWatchKey('shift-arrow_left', 'turnLeft', 'left') self.setWatchKey('shift-a', 'turnLeft', 'left') self.setWatchKey('arrow_right', 'turnRight', 'right') self.setWatchKey('d', 'turnRight', 'right') self.setWatchKey('control-arrow_right', 'turnRight', 'right') self.setWatchKey('control-d', 'turnRight', 'right') self.setWatchKey('alt-arrow_right', 'turnRight', 'right') self.setWatchKey('alt-d', 'turnRight', 'right') self.setWatchKey('shift-arrow_right', 'turnRight', 'right') self.setWatchKey('shift-d', 'turnRight', 'right') self.setWatchKey('control', 'jump', 'control') base.taskMgr.add(self.handleMovement, 'controlManager') def setupToon(self): self.localAvatar.setName('Toon') self.localAvatar.setPythonTag('Avatar', self) geom = self.localAvatar.getGeomNode() geom.getChild(0).setSx(0.730000019073) geom.getChild(0).setSz(0.730000019073) base.localAvatar = self.localAvatar wallBitmask = BitMask32(1) floorBitmask = BitMask32(2) base.cTrav = CollisionTraverser() walkControls = GravityWalker(legacyLifter=True) walkControls.setWallBitMask(wallBitmask) walkControls.setFloorBitMask(floorBitmask) walkControls.setWalkSpeed(8.0, 20.0, 4.0, 20.0) walkControls.initializeCollisions(base.cTrav, self.localAvatar, floorOffset=0.025, reach=4.0) walkControls.setAirborneHeightFunc(self.getAirborneHeight) walkControls.enableAvatarControls() self.walkControls = walkControls self.localAvatar.physControls = walkControls self.localAvatar.physControls.placeOnFloor() self.setupPhysics() Hud(self) self.setupCamera() render.getPythonTag('WorldCollisions').addToonCollision() def setCurrentGag(self, gagName): self.currentGag = gagName def getCurrentGag(self): return self.currentGag def updateLaffMeter(self): self.laffMeter.adjustFace(self.hp, self.maxHp, quietly = 0)
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 self.entityTrack = 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(): 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 == 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) else: if 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() 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.gag)) 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() self.entityTrack = track return def throw(self): if not self.gag and not self.isLocal(): self.setHandJoint() self.build() if self.gag and self.getLocation(): self.startEntity() else: if 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) 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() else: if 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)