Starsector API
Loading...
Searching...
No Matches
StealthMinefield.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.hullmods;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Random;
6
7import org.lwjgl.util.vector.Vector2f;
8
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.combat.BaseHullMod;
11import com.fs.starfarer.api.combat.CombatEngineAPI;
12import com.fs.starfarer.api.combat.CombatEntityAPI;
13import com.fs.starfarer.api.combat.MissileAPI;
14import com.fs.starfarer.api.combat.ShipAPI;
15import com.fs.starfarer.api.combat.WeaponAPI.WeaponType;
16import com.fs.starfarer.api.util.IntervalUtil;
17import com.fs.starfarer.api.util.Misc;
18import com.fs.starfarer.api.util.WeightedRandomPicker;
19
20public class StealthMinefield extends BaseHullMod {
21
22 public static String MINEFIELD_DATA_KEY = "minefield_data_key";
23 public static class IncomingMine {
24 Vector2f mineLoc;
25 float delay;
26 ShipAPI target;
27 }
28 public static class MinefieldData {
29 ShipAPI source;
30 IntervalUtil tracker = new IntervalUtil(0.5f, 1.5f);
31 List<IncomingMine> incoming = new ArrayList<IncomingMine>();
32 }
33
34
35 @Override
36 public void advanceInCombat(ShipAPI ship, float amount) {
37 super.advanceInCombat(ship, amount);
38
39 //if (true) return;
40
41 CombatEngineAPI engine = Global.getCombatEngine();
42
43 MinefieldData data = (MinefieldData) engine.getCustomData().get(MINEFIELD_DATA_KEY);
44 if (data == null) {
45 data = new MinefieldData();
46 data.source = ship;
47 engine.getCustomData().put(MINEFIELD_DATA_KEY, data);
48 }
49
50 if (data.source != ship) return;
51 if (!ship.isAlive()) return;
52
53
54 for (IncomingMine inc : new ArrayList<IncomingMine>(data.incoming)) {
55 inc.delay -= amount;
56 if (inc.delay <= 0) {
57 spawnMine(ship, inc.mineLoc, inc.target);
58 data.incoming.remove(inc);
59 }
60 }
61
62 data.tracker.advance(amount);
63 if (!data.tracker.intervalElapsed()) return;
64
65 WeightedRandomPicker<IncomingMine> picker = new WeightedRandomPicker<IncomingMine>();
66
67 for (ShipAPI enemy : engine.getShips()) {
68 if (enemy == ship) continue;
69 if (enemy.isHulk()) continue;
70 if (enemy.getOwner() == ship.getOwner()) continue;
71 if (enemy.isFighter()) continue;
72 if (enemy.isDrone()) continue;
73 if (enemy.isStation()) continue;
74 if (enemy.isStationModule()) continue;
75 if (enemy.getTravelDrive() != null && enemy.getTravelDrive().isActive()) continue;
76
77 if ((float) Math.random() > 0.25f) continue;
78
79 Vector2f mineLoc = Misc.getPointAtRadius(enemy.getLocation(),
80 enemy.getCollisionRadius() + 400f + 200f * (float) Math.random());
81 float minOk = 400f + enemy.getCollisionRadius();
82 if (!isAreaClear(mineLoc, minOk)) continue;
83
84 IncomingMine inc = new IncomingMine();
85 inc.delay = (float) Math.random() * 1.5f;
86 inc.target = enemy;
87 inc.mineLoc = mineLoc;
88
89 picker.add(inc);
90 }
91
92 int numToSpawn = Math.max(1, Math.min(new Random().nextInt(6) + 5, picker.getItems().size()));
93
94 for (int i = 0; i < numToSpawn && !picker.isEmpty(); i++) {
95 IncomingMine inc = picker.pickAndRemove();
96 data.incoming.add(inc);
97 }
98
99 }
100
101
102 public void spawnMine(ShipAPI source, Vector2f mineLoc, ShipAPI target) {
103 float mineDir = Misc.getAngleInDegrees(mineLoc, target.getLocation());
104 CombatEngineAPI engine = Global.getCombatEngine();
105 Vector2f currLoc = Misc.getPointAtRadius(mineLoc, 50f + (float) Math.random() * 50f);
106 MissileAPI mine = (MissileAPI) engine.spawnProjectile(source, null,
107 getWeaponId(),
108 currLoc,
109 mineDir, null);
110 if (source != null) {
111 Global.getCombatEngine().applyDamageModifiersToSpawnedProjectileWithNullWeapon(
112 source, WeaponType.MISSILE, false, mine.getDamage());
113// float extraDamageMult = source.getMutableStats().getMissileWeaponDamageMult().getModifiedValue();
114// mine.getDamage().setMultiplier(mine.getDamage().getMultiplier() * extraDamageMult);
115 }
116
117 mine.setFlightTime((float) Math.random());
118 mine.fadeOutThenIn(1f);
119
120 Global.getSoundPlayer().playSound("mine_spawn", 1f, 1f, mine.getLocation(), mine.getVelocity());
121 }
122
123 protected String getWeaponId() {
124 return "minelayer2";
125 }
126
127 public boolean isAreaClear(Vector2f loc, float range) {
128 CombatEngineAPI engine = Global.getCombatEngine();
129 for (ShipAPI other : engine.getShips()) {
130 if (other.isFighter()) continue;
131 if (other.isDrone()) continue;
132
133 float dist = Misc.getDistance(loc, other.getLocation());
134 if (dist < range) {
135 return false;
136 }
137 }
138
139 for (CombatEntityAPI other : Global.getCombatEngine().getAsteroids()) {
140 float dist = Misc.getDistance(loc, other.getLocation());
141 if (dist < other.getCollisionRadius() + 100f) {
142 return false;
143 }
144 }
145
146 return true;
147 }
148
149}
150
151
152
153
static SoundPlayerAPI getSoundPlayer()
Definition Global.java:43
static CombatEngineAPI getCombatEngine()
Definition Global.java:63
void spawnMine(ShipAPI source, Vector2f mineLoc, ShipAPI target)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)