def explode(self, position, force, damage, damageRadius, sourceEntity = None, damagingEntity = None): """Triggers an explosion animation, which involves applying force to surrounding Entities, and damaging Entities where applicable. sourceEntity is excluded from damage and force, and damagingEntity gets the credit for any damage done. If damagingEntity is None, sourceEntity gets the credit. If both are None, no damage is done. """ particles.add(particles.SparkParticleGroup(position, numParticles = 500, speed = damageRadius * 2.5, lifeTime = 1.0, size = 6.0)) particles.add(particles.ExplosionParticleGroup(position)) for entity in (entity for entity in self.entities.values() if entity != sourceEntity and isinstance(entity, ObjectEntity)): vector = entity.getPosition() - position distance = vector.length() if distance >= damageRadius or distance == 0: continue force2 = force * max(1 - (distance / damageRadius), 0) * entity.radius * 0.5 damage2 = damage * max(1 - (distance / damageRadius), 0) pos = entity.getPosition() vector = pos - position distance = vector.length() vector.normalize() if entity.active: vector = engine.impulseToForce(vector.getX() * force2, vector.getY() * force2, vector.getZ() * force2) pos = entity.getPosition() radius = entity.radius * 0.4 pos += Vec3(uniform(-radius, radius), uniform(-radius, radius), uniform(-radius, radius)) entity.addForceAtPosition(vector, pos) if damage2 > 0: if damagingEntity != None: entity.damage(damagingEntity, damage2, False) # Grenades don't count as ranged damage. elif sourceEntity != None: entity.damage(sourceEntity, damage2, False)
def clientUpdate(self, aiWorld, entityGroup, iterator=None): Gun.clientUpdate(self, aiWorld, entityGroup, iterator) if iterator != None: if net.Boolean.getFrom(iterator): # We're firing self.lastFire = engine.clock.time if self.active: self.chainGunSound.play(entity=self.actor) self.light.add() direction = net2.StandardVec3.getFrom(iterator) if net.Boolean.getFrom(iterator): # Bullet hit something hitPos = net2.StandardVec3.getFrom(iterator) if self.active: origin = self.getPosition() + (direction * random() * 4) pos = hitPos - (direction * random() * 4) self.tracer.draw(origin, pos) if net.Boolean.getFrom(iterator): entityId = net.Uint8.getFrom(iterator) entity = entityGroup.getEntity(entityId) damage = net.Uint16.getFrom(iterator) if entity != None: entity.damage(self.actor, damage) if isinstance(entity, entities.Actor): particles.add( particles.HitRegisterParticleGroup( hitPos - direction, entity.getTeam().color, damage * 2 / self.damage)) else: particles.add( particles.SparkParticleGroup(hitPos)) else: particles.add(particles.SparkParticleGroup(hitPos)) self.ricochetSound.play(position=hitPos) if engine.clock.time - self.lastFire > 0.1: self.light.remove() elif self.active: self.light.setPos(self.getPosition()) self.light.setAttenuation((0, 0, 0.005 + math.pow( (engine.clock.time - self.lastFire), 2) * 8))
def clientUpdate(self, aiWorld, entityGroup, iterator=None): Gun.clientUpdate(self, aiWorld, entityGroup, iterator) if iterator != None: if net.Boolean.getFrom(iterator): # We're firing self.lastFire = engine.clock.time if self.active: self.pistolSound.play(entity=self.actor) self.light.add() direction = net2.StandardVec3.getFrom(iterator) if net.Boolean.getFrom(iterator): # Bullet hit something hitPos = net2.StandardVec3.getFrom(iterator) if self.active: origin = self.getPosition() + (direction * random() * 4) pos = hitPos - (direction * random() * 4) self.tracer.draw(origin, pos) if net.Boolean.getFrom(iterator): entityId = net.Uint8.getFrom(iterator) entity = entityGroup.getEntity(entityId) damage = net.Uint16.getFrom(iterator) pin = False pin = net.Boolean.getFrom( iterator ) # Whether we're pinning the entity against the wall pinPos = net2.HighResVec3.getFrom(iterator) if entity != None: if pin: self.pinSound.play(position=hitPos) if not entity.pinned: entity.pin(hitPos - (direction * entity.radius)) spike = entities.Spike(pinPos, direction) spike.attachTo(entity) entityGroup.addGraphicsObject(spike) entity.damage(self.actor, damage) if isinstance(entity, entities.Actor): particles.add( particles.HitRegisterParticleGroup( hitPos - direction, entity.getTeam().color, damage * 2 / self.damage)) else: particles.add( particles.SparkParticleGroup(hitPos)) else: particles.add(particles.SparkParticleGroup(hitPos)) entityGroup.addGraphicsObject( entities.Spike(hitPos, direction)) self.ricochetSound.play(position=hitPos) if engine.clock.time - self.lastFire > 0.1: self.light.remove() elif self.active: self.light.setPos(self.getPosition()) self.light.setAttenuation((0, 0, 0.005 + math.pow( (engine.clock.time - self.lastFire), 2) * 8))