package com.deftwun.zombiecopter.systems; import com.badlogic.ashley.core.Component; import com.badlogic.ashley.core.Engine; import com.badlogic.ashley.core.Entity; import com.badlogic.ashley.core.Family; import com.badlogic.ashley.systems.IteratingSystem; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.physics.box2d.Fixture; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Logger; import com.deftwun.zombiecopter.CollisionBits; import com.deftwun.zombiecopter.App; import com.deftwun.zombiecopter.ComponentMappers; import com.deftwun.zombiecopter.components.BulletComponent; import com.deftwun.zombiecopter.components.ChildComponent; import com.deftwun.zombiecopter.components.HealthComponent; import com.deftwun.zombiecopter.components.LookComponent; import com.deftwun.zombiecopter.components.PhysicsComponent; import com.deftwun.zombiecopter.components.PlayerComponent; import com.deftwun.zombiecopter.components.SpriteComponent; import com.deftwun.zombiecopter.components.TimeToLiveComponent; public class DamageSystem extends IteratingSystem{ private Logger logger = new Logger("DamageSystem", Logger.INFO); private final float deadEntityTimeLimit = 5; @SuppressWarnings("unchecked") public DamageSystem() { super(Family.all(BulletComponent.class).get()); logger.debug("initializing"); } @Override public void addedToEngine(Engine engine) { super.addedToEngine(engine); logger.debug("added to engine"); } @Override public void update(float deltaTime) { super.update(deltaTime); } public void death(Entity entity){ ComponentMappers mappers = App.engine.mappers; PhysicsComponent physics = mappers.physics.get(entity); HealthComponent health = mappers.health.get(entity); if (health.isDead == false){ health.isDead = true; logger.debug("Entity #" + entity.getId() + " has died."); App.engine.systems.particle.addEffect(health.deathEffect, physics.getPosition(), 0); //Item Drop if (!health.drop.equals("") && MathUtils.randomBoolean(health.dropRate)){ logger.debug("Dropping item: " + health.drop); App.engine.factory.build(health.drop, physics.getPosition(), physics.getLinearVelocity()); } //Corpse if (!health.corpse.equals("")){ logger.debug("Creating corpse: " + health.corpse); Entity corpse = App.engine.factory.build(health.corpse,physics.getPosition(), physics.getLinearVelocity()); if (entity == App.engine.systems.player.getPlayer()){ App.engine.systems.player.setPlayer(corpse); } App.engine.removeEntity(entity); } //No corpse?.... Well I guess I'll just wing it and just make the entity basically a corpse until it gets removed (time to live) else{ logger.debug("Entity has no corpse. Will now attempt to disable entity by removing key components."); physics.getPrimaryBody().setFixedRotation(false); //Remove all components except these ones for (Component c : entity.getComponents()){ if (!(c instanceof PhysicsComponent) && !(c instanceof TimeToLiveComponent) && !(c instanceof SpriteComponent) && !(c instanceof HealthComponent) && !(c instanceof PlayerComponent) && !(c instanceof LookComponent)) { entity.remove(c.getClass()); } } //Set Time to live TimeToLiveComponent ttl = mappers.timeToLive.get(entity); if (ttl == null) ttl = App.engine.createComponent(TimeToLiveComponent.class); ttl.time = 0; ttl.timeLimit = deadEntityTimeLimit; entity.add(ttl); logger.debug(" ..countdown to removal (timeToLive) = " + ttl.timeLimit + " seconds."); } } //Intense death (Gibbed) else if (health.value < -health.max / 3){ logger.debug("Entity #" + entity.getId() + " has been gibbed: Intense Death"); App.engine.systems.particle.addEffect(health.gibbedEffect, physics.getPosition(), 0); App.engine.removeEntity(entity); } } public void dealDamage(Entity e, float dmg){ dealDamage(e,dmg,0); } public void dealDamage(Entity target, float dmg, float angle){ dealDamage(null,target,dmg,angle); } public void dealDamage(Entity dealer, Entity target, float dmg, float angle){ HealthComponent h = App.engine.mappers.health.get(target); PhysicsComponent p = App.engine.mappers.physics.get(target); if (h == null) return; if (p != null) App.engine.systems.particle.addEffect(h.damageEffect, p.getPosition(),angle); logger.debug(String.format("%f damage dealt to Entity#%d",dmg,target.getId())); h.value -= dmg; h.isHurt = true; if (h.value <= 0 && !h.isDead){ death(target); if (dealer != null){ logger.debug(String.format("Entity %d has killed Entity %d",dealer.getId(),target.getId())); } } } @Override protected void processEntity(Entity entity, float deltaTime) { PhysicsComponent physics = App.engine.mappers.physics.get(entity); BulletComponent bullet = App.engine.mappers.bullet.get(entity); ChildComponent child = App.engine.mappers.child.get(entity); //Iterate over all touching fixtures, checking to see if they have // health, and deal damage as necessary Array<Fixture> fixturesTouching = App.engine.systems.physics.getFixturesTouching(physics); for (Fixture f : fixturesTouching){ //Should have no effect on sensors if (f.isSensor()) continue; PhysicsComponent p = (PhysicsComponent) f.getBody().getUserData(); if (p == null) continue; Entity dealer = (child == null) ? entity : child.parentEntity; dealDamage(dealer,p.ownerEntity,bullet.damage,physics.getRotation()); } //disable bullet after colliding with anything if (physics.getCollisionNormal() > 0) { physics.setFilter(CollisionBits.Effects,CollisionBits.Mask_Effects); entity.remove(BulletComponent.class); //logger.debug("Entity #" + entity.getId() + ": damage disabled"); } } }