package net.mostlyoriginal.ns2d.system.active; import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.annotations.Wire; import com.artemis.managers.GroupManager; import com.artemis.systems.VoidEntitySystem; import com.artemis.utils.ImmutableBag; import com.badlogic.gdx.math.MathUtils; import net.mostlyoriginal.ns2d.component.*; import net.mostlyoriginal.ns2d.system.passive.AssetSystem; import net.mostlyoriginal.ns2d.system.render.DialogRenderSystem; import net.mostlyoriginal.ns2d.system.render.UIStopwatchRenderSytem; /** * @author Daan van Yperen */ @Wire public class CombatSystem extends VoidEntitySystem { private ComponentMapper<Health> hm; private ComponentMapper<Buildable> bm; private ComponentMapper<RespawnOnDeath> rm; private ComponentMapper<Payload> pm; private ComponentMapper<Attached> am; private ComponentMapper<Pos> pom; private ComponentMapper<Bounds> bom; private ComponentMapper<Critical> cm; private BuildableSystem buildableSystem; private GroupManager groupManager; private AttachmentSystem attachmentSystem; private ParticleSystem particleSystem; private UIStopwatchRenderSytem uiStopwatchRenderSytem; private AssetSystem assetSystem; private EntitySpawnerSystem entitySpawnerSystem; private int killsPerSecond; private DialogRenderSystem dialogRenderSystem; @Override protected void initialize() { super.initialize(); } public void damage(Entity victim, int damage) { if (hm.has(victim)) { Health health = hm.get(victim); health.damage += damage; if (am.has(victim)) { final Attached attached = am.get(victim); if (attached != null) { attachmentSystem.push(attached, MathUtils.random(360), MathUtils.clamp(damage * 2, 1, 5)); } } // flag critical as recently damaged if (cm.has(victim)) { cm.get(victim).damageAge = 0; } else if (bm.has(victim)) { bm.get(victim).damageAge = 0; } boolean dead = health.damage >= health.health; if ( health.woundParticle != null ) { for ( int i=0, s=MathUtils.random( dead ? 6 : 1, dead ? 10 : 2); s>i; i++ ) { final Pos pos = pom.get(victim); final Bounds bounds = bom.get(victim); particleSystem.setRotation(MathUtils.random(20,160)); particleSystem.spawnParticle((int)(pos.x + bounds.cx()), (int)(pos.y + bounds.cy()), health.woundParticle ); particleSystem.setRotation(0); } } if (dead) { if (cm.has(victim)) { uiStopwatchRenderSytem.gameOver = true; } if (health.deathSfxId!= null) { assetSystem.playSfx(health.deathSfxId[MathUtils.random(0,health.deathSfxId.length-1)],victim); } if (rm.has(victim)) { respawnEntity(victim); return; } victim.edit().remove(Health.class); if (bm.has(victim)) { // unbuild. buildableSystem.destroyBuildable(victim); } else { // kill killsPerSecond++; victim.deleteFromWorld(); } } else { if (health.damageSfxId!= null) { assetSystem.playSfx(health.damageSfxId[MathUtils.random(0,health.damageSfxId.length-1)],victim); } } } } public void respawnEntity(Entity victim) { final RespawnOnDeath respawnOnDeath = rm.get(victim); Health health = hm.get(victim); health.damage = 0; entitySpawnerSystem.giveWeapon(victim, "rifle"); // freeze in place for X seconds. victim.edit().add(new Script() .remove(Health.class) .add(new Frozen()) .wait(2f) .remove(Frozen.class) .add(new Health(10))); // move to spawner. ImmutableBag<Entity> spawners = groupManager.getEntities("spawner"); if (spawners.size() > 0) { Entity spawner = spawners.get(MathUtils.random(0, spawners.size() - 1)); Pos spawnerPos = spawner.getComponent(Pos.class); Pos playerPos = victim.getComponent(Pos.class); playerPos.x = spawnerPos.x - 8; playerPos.y = spawnerPos.y + 6; } } float funnyCooldown; float age; @Override protected void processSystem() { age += world.delta; funnyCooldown -= world.delta; if ( age > 1 ) { age = 0; if ( killsPerSecond > 3) { if ( funnyCooldown <= 0) { funnyCooldown = 30f; dialogRenderSystem.randomSay(DialogRenderSystem.SLOW_KILL_BEAST); } } killsPerSecond = 0; } } }