diff --git a/CHANGELOG.md b/CHANGELOG.md index e694ccd..bb2e738 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ ## 0.0.7 (not yet released) -* Systems that are threatened by a neighboring hostile force are now overlaid with orange cross-hatching instead of yellow cross-hatching. Yellow cross-hatching is now used exclusively for systems at risk of collapse due to insufficient garrison. +* Several improvements have been made to the tactical overlay: -* The bright yellow cross-hatching used to indicate systems at risk of immediate collapse is now applied more consistently and accurately. Previously, some systems could be shaded with faded yellow cross-hatching even though they were at risk of immediate collapse, but now dim yellow cross-hatching is only applied to systems at risk of collapse due to a chain reaction. + * Systems that are threatened by a neighboring hostile force are now overlaid with orange hatching instead of yellow hatching. Yellow hatching is now used exclusively for systems at risk of collapse due to insufficient garrison. + + * The bright yellow hatching used to indicate systems at risk of immediate collapse is now applied more consistently and accurately. Previously, some systems could be shaded with faded yellow hatching even though they were at risk of immediate collapse, but now dim yellow hatching is only applied to systems at risk of collapse due to a chain reaction. + + * Fleet movements out of systems that are at risk of being stellar bombed no longer count towards the worst-case garrison calculation and therefore will not eliminate yellow or red hatching on their destination system. With this change, the absence of any hatching on a system provides a true guarantee that the system will not be lost. * While placing a terraforming project, resources that are currently in surplus are colored green in the production panel, and systems that only provide a single unit of that resource (and provide no other resources) are highlighted green on the map. diff --git a/docs/tactical-overlay.md b/docs/tactical-overlay.md index d49c063..70eba38 100644 --- a/docs/tactical-overlay.md +++ b/docs/tactical-overlay.md @@ -43,3 +43,5 @@ One important property that follows from the above is that there is almost alway ### The tactical overlay and stellar bombs Because stellar bombs prevent all fleet movements out of the target system for a turn, deploying a stellar bomb can affect the tactical overlay. Most significantly, if a system you control is only bordered by one hostile system, deploying a stellar bomb on that system will eliminate the **orange** hatching on the adjacent system! This is in fact the *only* way to remove such hatching, so although it may be counterintuitive, the most valuable way to use a stellar bomb may be defensive rather than offensive. + +Note, however, that this ability cuts both ways: fleet movements out of any system at risk of being stellar bombed may be canceled. Therefore, such fleet movements do not count towards the worst-case garrison calculation and will not eliminate hatching on their destination system. This can be somewhat counterintuitive, but erring on the side of caution ensures that the absence of any hatching on a system is a true guarantee that the system will not be lost. diff --git a/src/main/java/funorb/shatteredplans/client/game/TacticalAnalysis.java b/src/main/java/funorb/shatteredplans/client/game/TacticalAnalysis.java index 6abf5b9..2970f6c 100644 --- a/src/main/java/funorb/shatteredplans/client/game/TacticalAnalysis.java +++ b/src/main/java/funorb/shatteredplans/client/game/TacticalAnalysis.java @@ -24,6 +24,12 @@ public final class TacticalAnalysis { */ private final boolean[] systemThreatened; + /** + * {@code true} for systems that could be the target of a stellar bomb on + * this turn. + */ + private final boolean[] systemBombable; + /** * {@code true} for systems that the local player is guaranteed to own * after this turn. Implies {@link #systemCanOwn}. @@ -80,6 +86,7 @@ public final class TacticalAnalysis { public TacticalAnalysis(final int systemCount) { this.systemThreatened = new boolean[systemCount]; + this.systemBombable = new boolean[systemCount]; this.systemCanOwn = new boolean[systemCount]; this.systemWillOwn = new boolean[systemCount]; this.guaranteedCollapseWave = new int[systemCount]; @@ -128,11 +135,17 @@ public final class TacticalAnalysis { this.minGarrisonAtTurnEnd[system.index] = 0; } + this.systemBombable[system.index] = Arrays.stream(system.neighbors) + .anyMatch(neighbor -> neighbor.owner != null + && system.owner != neighbor.owner + && (system.owner == null || !neighbor.owner.allies[system.owner.index])); + for (final MoveFleetsOrder incomingOrder : system.incomingOrders) { if (incomingOrder.player == localPlayer) { this.maxGarrisonAtTurnEnd[system.index] += incomingOrder.quantity; this.systemCanOwn[system.index] = true; - if (incomingOrder.target.owner == localPlayer || incomingOrder.target.garrison == 0) { + if ((incomingOrder.target.owner == localPlayer || incomingOrder.target.garrison == 0) + && !this.systemBombable[incomingOrder.source.index]) { this.minGarrisonAtTurnEnd[system.index] += incomingOrder.quantity; this.systemWillOwn[system.index] = true; }