package net.sector.entities.enemies; import java.util.Set; import net.sector.entities.EEntity; import net.sector.entities.Entity; import net.sector.entities.EntityNavigable; import net.sector.entities.IDamageable; import net.sector.entities.orbs.EntityOrbShield; import net.sector.entities.player.EntityPlayerShip; import net.sector.entities.shots.EntityShotBase; import net.sector.level.SuperContext; import net.sector.models.Models; import net.sector.models.PhysModel; import com.porcupine.coord.Coord; import com.porcupine.coord.Vec; /** * Mine entity * * @author Ondřej Hruška (MightyPork) */ public class EntityMine extends EntityNavigable { private double scale = 1; private double healthMax; private static PhysModel shipModel = Models.spaceMine; private static final double mMoveSpeed = 0.00001; @Override public boolean hasGlobalMovement() { return true; } /** * Enemy ship * * @param scale * @param pos */ public EntityMine(double scale, Coord pos) { super(shipModel, mMoveSpeed, scale, pos); setDefaultDriver(); this.rotDir.setTo(0, 1, 0); this.rotAngle.set(rand.nextDouble() * 360); this.collidePriority = 2000; this.lifetime = -1; this.MAX_SPEED = 0.2 * (0.3 / mass); } /** * Enemy ship, scale=1 * * @param pos */ public EntityMine(Coord pos) { super(shipModel, mMoveSpeed, 1, pos); setDefaultDriver(); this.rotDir.setTo(0, 1, 0); this.rotAngle.set(rand.nextDouble() * 360); this.collidePriority = 2000; this.lifetime = -1; this.MAX_SPEED = 0.2 * (0.3 / mass); } private void setDefaultDriver() { setDriver(SuperContext.basicDrivers.getDriver("mine")); } @Override public double getHealthMax() { return healthMax; } @Override public void onImpact(Entity hitBy) { if (hitBy == null) return; boolean dead = false; if (hitBy.getType() == EEntity.SHOT_BAD || hitBy.getType() == EEntity.SHOT_GOOD) { if (rand.nextInt(2) == 0) { dead = true; if (((EntityShotBase) hitBy).scoreCounter != null) { ((EntityShotBase) hitBy).scoreCounter.addScore(scoreValue); } boom(hitBy); } } else { dead = true; boom(hitBy); } if (!hitBy.isDead()) defaultOnImpact(hitBy); if (dead) setDead(); } public void boom(Entity hitBy) { explodeForce(getPos(), 30 * scale, true); double range = 6; double distMultiplier = 7; // to make it fade away faster double damage = 50 * scale; if (hitBy != null) { if (!(hitBy instanceof EntityPlayerShip)) { hitBy.addDamage(this, damage); } else { ((EntityPlayerShip) hitBy).piecesAddDamageSquare(collider, damage, distMultiplier, range); } } Set ents = getScene().getEntitiesInRange(getPos(), range); if (!ents.isEmpty()) { for (Entity e : ents) { if (e == this) continue; if (e.isDead()) continue; if (e instanceof EntityMine) continue; if (e == hitBy) continue; double dist = e.getPos().distTo(getPos()) - e.getRadius() - getRadius(); dist *= distMultiplier; if (dist < 1) dist = 1; if (e.getType() == EEntity.PLAYER) { ((EntityPlayerShip) e).piecesAddDamageSquare(collider, damage, distMultiplier, range); } e.addDamage(this, damage / (dist * dist)); e.getMotion().add_ip(getPos().vecTo(e.getPos()).norm(0.1 / (dist * dist))); } } } @Override public void addDamage(IDamageable source, double points) { super.addDamage(source, points); } @Override public void onDeath() { if (lastDamageSource.getType() == EEntity.SHOT_GOOD && rand.nextInt(4) == 0) { if (scene.playerShip.body.shieldSystem.getLoadRatio() < 1) { scene.add(new EntityOrbShield(getPos(), 400 * (0.6 + rand.nextDouble() * 0.7))); } } } @Override public EEntity getType() { return EEntity.MINE; } @Override public void shootOnce(int gunIndex) {} @Override public Vec getGunShotDir(int gunIndex) { return getMotion(); } }