def onCollision(self, contact, frNp, intoNP): print "onCollision:", frNp, "->", intoNP avNP = intoNP.getParent() fromNP = frNp.getParent() if fromNP.isEmpty(): return for obj in base.avatars: if CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey(): obj.handleHitByToon(self.avatar, self.getID(), self.avatar.getDistance(obj)) elif obj.__class__.__name__ == "DistributedPieTurret": if obj.getKey() == avNP.getKey(): if obj.getHealth() < obj.getMaxHealth(): #self.avatar.sendUpdate('toonHitByPie', [obj.doId, self.getID()]) pass self.splatPos = fromNP.getPos(render) self.avatar.sendUpdate('setSplatPos', [ self.getID(), self.splatPos.getX(), self.splatPos.getY(), self.splatPos.getZ() ]) self.handleSplat()
def fireLaser(self): result = PhysicsUtils.rayTestClosestNotMe( self, self.laserVec[0], self.laserVec[1], CIGlobals.WorldGroup | CIGlobals.CharacterGroup, self.getBattleZone().getPhysicsWorld()) traceEnd = self.laserVec[1] if result: traceEnd = result.getHitPos() hitNode = NodePath(result.getNode()) avNP = hitNode.getParent() for obj in base.air.avatars[self.getBattleZone().zoneId]: if (CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey() and self.getBattleZone().getGameRules().canDamage( self, obj, None)): dmgInfo = TakeDamageInfo(self, -1, 10, traceEnd, self.laserVec[0]) obj.takeDamage(dmgInfo) break self.getBattleZone().getTempEnts().makeLaser(self.laserVec[0], traceEnd, Vec4(1, 0, 0, 1), 1.0)
def onProjectileHit(self, contact, collider, intoNP, deleteIt=True): bz = base.air.getBattleZone(collider.zoneId) surface = Surfaces.getSurfaceFromContact(contact, bz) bz.d_emitSound(surface.getBulletImpacts(), contact.getHitPos(), 0.5) avNP = intoNP.getPythonTag("physicsObject") collider.d_impact(contact.getHitPos()) if CIGlobals.isAvatar(avNP): if self.canDamage(avNP): currProj = collider.getPos(render) dmgInfo = TakeDamageInfo( self.avatar, self.getID(), self.calcDamage( (currProj - collider.getInitialPos()).length()), currProj, collider.getInitialPos(), hitNode=intoNP) avNP.takeDamage(dmgInfo) elif self.avatar.getRelationshipTo( avNP) == RELATIONSHIP_FRIEND and self.HealFriends: avNP.heal(self.HealAmount) avNP.handleRule("HealedByFriend") if deleteIt: collider.requestDelete() # Emit a sound at the hit point self.avatar.emitSound(SOUND_COMBAT, contact.getHitPos(), duration=0.25)
def onCollision(self, entity, intoNP): if not entity or entity.isEmpty(): return dropMdl = entity.find('**/DropMdl') soundTrack = entity.getPythonTag(SoundTrackName) avNP = intoNP.getParent() hitCog = False soundTrack.pause() shrinkTrack = Sequence() if self.avatar.doId == base.localAvatar.doId: for obj in base.avatars: if CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey(): dist = (obj.getPos(render).getXy() - entity.getPos(render).getXy()).length() obj.handleHitByToon(self.avatar, self.getID(), dist * 4) doId = 0 if not obj.isDistributed() else obj.doId self.avatar.b_trapActivate(self.getID(), self.avatar.doId, 0, doId) hitCog = True if hitCog: base.audio3d.attachSoundToObject(self.hitSfx, entity) SoundInterval(self.hitSfx, node=entity).start() shrinkTrack.append(Wait(0.5)) else: base.audio3d.attachSoundToObject(self.missSfx, entity) SoundInterval(self.missSfx, node=entity).start() shrinkTrack.append(Wait(0.25)) shrinkTrack.append( LerpScaleInterval(dropMdl, 0.3, Point3(0.01, 0.01, 0.01))) shrinkTrack.append(Func(self.clearEntity, entity)) shrinkTrack.start()
def onProjectileHit(self, contact, collider, intoNP): surface = Surfaces.getSurface(intoNP.getSurfaceProp()) self.avatar.getBattleZone().d_emitSound(surface.getBulletImpacts(), contact.getHitPos(), 0.5) avNP = intoNP.getParent() collider.d_impact(contact.getHitPos()) currProj = collider.getPos(render) dmgInfo = TakeDamageInfo( self.avatar, self.getID(), self.calcDamage((currProj - collider.getInitialPos()).length()), currProj, collider.getInitialPos()) try: # Sometimes the avatar could be deleted unexpectedly. for obj in base.air.avatars[self.avatar.getBattleZone().zoneId]: if (CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey() and self.canDamage(obj)): obj.takeDamage(dmgInfo) break except: pass collider.requestDelete()
def __handleHitSomething_trace(self, hitNode, hitPos, distance, origin, traces=1, impact=True): if impact: surface = Surfaces.getSurface(hitNode.getSurfaceProp()) self.avatar.getBattleZone().d_emitSound(surface.getBulletImpacts(), hitPos, 0.5) avNP = hitNode.getParent() try: # Again, sometimes the avatar can be deleted unexpectedly. for obj in base.air.avatars[self.avatar.getBattleZone().zoneId]: if (CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey() and self.canDamage(obj)): for _ in xrange(traces): dmgInfo = TakeDamageInfo(self.avatar, self.getID(), self.calcDamage(distance), hitPos, origin) obj.takeDamage(dmgInfo) break except: pass
def damageCogsNearby(self, radius = None): if self.avatar.doId != base.localAvatar.doId: return if not radius: radius = self.soundRange suits = [] for obj in base.avatars: if CIGlobals.isAvatar(obj): if obj.getDistance(self.avatar) <= radius: if self.avatar.doId == base.localAvatar.doId: suits.append(obj) def shouldContinue(suit, track): if suit.isDead(): track.finish() for suit in suits: if self.name != GagGlobals.Opera: suit.handleHitByToon(self.avatar, self.getID(), obj.getDistance(self.avatar)) else: breakEffect = CIParticleEffect() breakEffect.loadConfig('phase_5/etc/soundBreak.ptf') breakEffect.setDepthWrite(0) breakEffect.setDepthTest(0) breakEffect.setTwoSided(1) suitTrack = Sequence() if suit.isDead(): return suitTrack.append(Wait(2.5)) delayTime = random.random() suitTrack.append(Wait(delayTime + 2.0)) suitTrack.append(Func(shouldContinue, suit, suitTrack)) suitTrack.append(Func(self.setPosFromOther, breakEffect, suit, Point3(0, 0, 0))) suitTrack.append(SoundInterval(self.hitSfx, node=suit)) suitTrack.append(Func(suit.handleHitByToon, self.avatar, self.getID(), obj.getDistance(self.avatar))) suitTrack.start() suits = None
def _handleShotSomething(self, intoNP, hitPos, distance): avNP = intoNP.getParent() if base.localAvatarReachable() and self.isLocal(): for obj in base.avatars: if CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey(): obj.handleHitByToon(self.avatar, self.getID(), distance) vm = self.getViewModel() fpsCam = self.getFPSCam() track = Sequence() if action == self.actionIdle: track.append(Func(vm.loop, "idle")) elif action == self.actionDraw: track.append(ActorInterval(vm, "draw")) elif action == self.actionPump: track.append(Func(self.pumpSound.play)) track.append(ActorInterval(vm, "pump")) elif action == self.actionFire: camQuat = camera.getQuat(render) pFrom = camera.getPos(render) pTo = pFrom + camQuat.xform(Vec3.forward() * 10000) hitPos = Point3(pTo) result = base.physicsWorld.rayTestClosest(pFrom, pTo, CIGlobals.WorldGroup) if result.hasHit(): node = result.getNode() hitPos = result.getHitPos() distance = (hitPos - pFrom).length() self._handleShotSomething(NodePath(node), hitPos, distance) self.clip -= 1 fpsCam = self.getFPSCam() if base.localAvatar.isFirstPerson(): fpsCam.addViewPunch( Vec3(random.uniform(-2, 2), random.uniform(2, 1), 0)) base.localAvatar.sendUpdate('usedGag', [self.id]) track.append(Func(self.fireSound.play)) track.append(ActorInterval(vm, "fire")) elif action == self.actionDblFire: track.append(Func(self.dblFireSound.play)) track.append(ActorInterval(vm, "altfire")) elif action == self.actionReload: sound = random.choice(self.reloadSounds) track.append(Func(sound.play)) track.append(ActorInterval(vm, "reload2")) elif action == self.actionBeginReload: track.append(ActorInterval(vm, "reload1")) elif action == self.actionEndReload: track.append(ActorInterval(vm, "reload3")) fpsCam.setVMAnimTrack(track)
def b_explode(self): self.explode() self.sendUpdate('explode') for obj in base.avatars: if CIGlobals.isAvatar(obj): dist = obj.getDistance(self) if dist <= GagGlobals.TNT_RANGE: obj.handleHitByToon(base.localAvatar, GagGlobals.gagIdByName[GagGlobals.TNT], dist)
def think(self): elapsed = self.getEntityStateElapsed() state = self.getEntityState() if state == self.StateUp: if self.timeInAir >= 0 and elapsed >= (self.timeInAir + self.startDelay): self.b_setEntityState(self.StateStomp) elif state == self.StateDown: if self.timeOnGround >= 0 and elapsed >= self.timeOnGround: self.b_setEntityState(self.StateRaise) if not self.stomped: self.stomped = True result = self.dispatch.getPhysicsWorld().contactTest( self.floorColl.node()) for contact in result.getContacts(): node = contact.getNode1() if node == self.floorColl.node(): node = contact.getNode0() if node.isOfType(BulletGhostNode.getClassType()): continue avNP = NodePath(node).getParent() for obj in self.air.avatars[self.dispatch.zoneId]: if (CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey() and obj not in self.damaged): if self.damage != -1: obj.takeDamage( TakeDamageInfo(self, damageAmount=self.damage, damageType=DMG_FORCE)) else: obj.takeDamage( TakeDamageInfo( self, damageAmount=obj.getHealth(), damageType=DMG_FORCE)) self.damaged.append(obj) break elif state == self.StateStomp: self.startDelay = 0.0 if elapsed >= self.height / self.stompSpeed: self.b_setEntityState(self.StateDown) elif state == self.StateRaise: if elapsed >= self.height / self.raiseSpeed: self.b_setEntityState(self.StateUp)
def onGearHit(self, contact, collider, intoNP): avNP = intoNP.getParent() currProj = collider.getPos(render) dmgInfo = TakeDamageInfo(self, -1, 10, currProj, collider.getInitialPos()) for obj in base.air.avatars[self.getBattleZone().zoneId]: if (CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey()): obj.takeDamage(dmgInfo) break
def __explodeTask(self, task): self.sendUpdate('explode') for obj in self.air.avatars[self.zoneId]: if CIGlobals.isAvatar(obj) and self.attack.canDamage(obj): dist = obj.getDistance(self) if dist <= GagGlobals.TNT_RANGE: info = TakeDamageInfo(self.avatar, ATTACK_GAG_TNT, self.attack.calcDamage(dist), self.getPos()) obj.takeDamage(info) self.requestDelete() return task.done
def onHit(self, pos, intoNP): BaseProjectile.onHit(self, pos, intoNP) WATER_SPRAY_COLOR = Point4(0.3, 0.7, 0.9, 0.7) CIGlobals.makeSplat(pos, WATER_SPRAY_COLOR, 0.3) if self.local: avNP = intoNP.getParent() for obj in base.avatars: if CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey(): gid = GagGlobals.getIDByName(GagGlobals.WaterGun) obj.handleHitByToon(base.localAvatar, gid, (self.getPos(render) - self.initialPos).length()) self.removeNode()
def __handleHitSomething_trace(self, hitNode, hitPos, hitNormal, distance, origin, contact, traces=1, impact=True): traceDir = (hitPos - origin).normalized() if impact and hasattr(self, 'avatar'): surface = Surfaces.getSurfaceFromContact( contact, self.avatar.getBattleZone()) self.avatar.getBattleZone().d_emitSound(surface.getBulletImpacts(), hitPos, 0.5) decals = surface.getImpactDecals() if len(decals): self.avatar.getBattleZone().getTempEnts().makeDecalTrace( random.choice(decals), 0.3, 0, origin, hitPos + (traceDir * 0.1)) if "metal" in Surfaces.getSurfaceName(surface): for _ in range(traces * random.randint(2, 4)): self.avatar.getBattleZone().getTempEnts( ).makeBulletRicochet(hitPos, traceDir, hitNormal) # Emit a sound at the hit point self.avatar.emitSound(SOUND_COMBAT, contact.getHitPos(), duration=0.25) avNP = hitNode.getPythonTag("physicsObject") # Again, sometimes the avatar can be deleted unexpectedly. if (CIGlobals.isAvatar(avNP) and self.canDamage(avNP)): for _ in range(traces): dmgInfo = TakeDamageInfo(self.avatar, self.getID(), self.calcDamage(distance), hitPos, origin, hitNode=hitNode) avNP.takeDamage(dmgInfo)
def _handleSprayCollision(self, intoNP, hitPos, distance): avNP = intoNP.getParent() if base.localAvatarReachable() and self.isLocal(): for obj in base.avatars: if CIGlobals.isAvatar(obj) and obj.getKey() == avNP.getKey(): obj.handleHitByToon(self.avatar, self.getID(), distance) self.splatPos = hitPos self.splatDist = distance gagPos = hitPos self.handleSplat() self.avatar.sendUpdate( 'setSplatPos', [self.getID(), gagPos.getX(), gagPos.getY(), gagPos.getZ()])
def __explodeTask(self, task): self.sendUpdate('explode') self.avatar.emitSound(SOUND_COMBAT, self.getPos(), volume = 2.0) for obj in self.air.avatars[self.zoneId]: if CIGlobals.isAvatar(obj) and self.attack.canDamage(obj): dist = obj.getDistance(self) if dist <= GagGlobals.TNT_RANGE: dmgPos = obj.getPos(render) + (0, 0, obj.getHeight() / 2.0) dmgForce = (dmgPos - self.getPos(render)).normalized() dmgForce *= 750.0 dmgForce *= max(0, 1 - (dist / GagGlobals.TNT_RANGE)) info = TakeDamageInfo(self.avatar, ATTACK_GAG_TNT, self.attack.calcDamage(dist), damagePos = dmgPos, damageOrigin = self.getPos(), dmgForce = dmgForce) obj.takeDamage(info) self.requestDelete() return task.done