001package com.fs.starfarer.api.impl.campaign.abilities;
002
003import java.awt.Color;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.campaign.BattleAPI;
009import com.fs.starfarer.api.campaign.CampaignFleetAPI;
010import com.fs.starfarer.api.fleet.FleetMemberViewAPI;
011import com.fs.starfarer.api.impl.campaign.ids.Stats;
012import com.fs.starfarer.api.ui.LabelAPI;
013import com.fs.starfarer.api.ui.TooltipMakerAPI;
014import com.fs.starfarer.api.util.Misc;
015
016public class SustainedBurnAbility extends BaseToggleAbility {
017
018        public static String SB_NO_STOP = "$sb_active";
019        public static String SB_NO_SLOW = "$sb_no_slow";
020        //public static float SENSOR_RANGE_MULT = 0.75f;
021        public static float DETECTABILITY_PERCENT = 100f;
022        //public static float MAX_BURN_MOD = 10f;
023        public static float MAX_BURN_PERCENT = 100f;
024        public static float ACCELERATION_MULT = 0.2f;
025        
026//      public String getSpriteName() {
027//              return Global.getSettings().getSpriteName("abilities", Abilities.SUSTAINED_BURN);
028//      }
029        
030        
031        @Override
032        protected String getActivationText() {
033                return super.getActivationText();
034                //return "Engaging sustained burn";
035        }
036
037
038        @Override
039        protected void activateImpl() {
040                CampaignFleetAPI fleet = getFleet();
041                if (fleet == null) return;
042                
043                if (!fleet.getMemoryWithoutUpdate().is(SB_NO_STOP, true)) {
044                        fleet.setVelocity(0, 0);
045                }
046        }
047
048        @Override
049        protected void applyEffect(float amount, float level) {
050                CampaignFleetAPI fleet = getFleet();
051                if (fleet == null) return;
052                
053                //System.out.println("Level: " + level);
054                //level = 0.01f;
055                
056                if (level > 0 && !fleet.isAIMode() && fleet.getCargo().getFuel() <= 0 && 
057                                fleet.getContainingLocation() != null && fleet.getContainingLocation().isHyperspace()) {
058                        deactivate();
059                        return;
060                }
061                
062                fleet.getMemoryWithoutUpdate().set(SB_NO_STOP, true, 0.3f);
063                
064                if (level > 0 && level < 1 && amount > 0 && !fleet.getMemoryWithoutUpdate().is(SB_NO_SLOW, true)) {
065                        float activateSeconds = getActivationDays() * Global.getSector().getClock().getSecondsPerDay();
066                        float speed = fleet.getVelocity().length();
067                        float acc = Math.max(speed, 200f)/activateSeconds + fleet.getAcceleration();
068                        float ds = acc * amount;
069                        if (ds > speed) ds = speed;
070                        Vector2f dv = Misc.getUnitVectorAtDegreeAngle(Misc.getAngleInDegrees(fleet.getVelocity()));
071                        dv.scale(ds);
072                        fleet.setVelocity(fleet.getVelocity().x - dv.x, fleet.getVelocity().y - dv.y);
073                        return;
074                }
075                
076                //fleet.getStats().getSensorRangeMod().modifyMult(getModId(), 1f + (SENSOR_RANGE_MULT - 1f) * level, "Sustained burn");
077                fleet.getStats().getDetectedRangeMod().modifyPercent(getModId(), DETECTABILITY_PERCENT * level, "Sustained burn");
078                
079                //int burnModifier = (int)(MAX_BURN_MOD * level) - (int)(INITIAL_BURN_PENALTY * (1f - level));
080                //int burnModifier = (int)(MAX_BURN_MOD * level);
081                int burnModifier = 0;
082                float burnMult = 1f;
083                
084                float b = fleet.getStats().getDynamic().getValue(Stats.SUSTAINED_BURN_BONUS, 0f);
085                //burnModifier = (int)((MAX_BURN_MOD + b) * level);
086                burnModifier = (int)((b) * level);
087                
088//              if (level > 0.5f) {
089//                      burnModifier = (int)(MAX_BURN_MOD * (level - 0.5f) / 0.5f);
090//              } else {
091//                      //burnModifier = -1 * (int)(INITIAL_BURN_PENALTY * (1f - level / 0.5f));
092//                      burnMult = 1f + ((INITIAL_BURN_PENALTY - 1f) * (1f - level / 0.5f));
093//              }
094                fleet.getStats().getFleetwideMaxBurnMod().modifyFlat(getModId(), burnModifier, "Sustained burn");
095                fleet.getStats().getFleetwideMaxBurnMod().modifyMult(getModId(), burnMult, "Sustained burn");
096                fleet.getStats().getFleetwideMaxBurnMod().modifyPercent(getModId(), MAX_BURN_PERCENT, "Sustained burn");
097                
098                
099                float accImpact = 0f;
100                float burn = Misc.getBurnLevelForSpeed(fleet.getVelocity().length());
101                if (burn > 1) {
102                        float dir = Misc.getDesiredMoveDir(fleet);
103//                      if (fleet.isPlayerFleet()) {
104//                              System.out.println("DIR: " + dir);
105//                      }
106                        float velDir = Misc.getAngleInDegrees(fleet.getVelocity());
107                        float diff = Misc.getAngleDiff(dir, velDir);
108                        //float pad = 90f;
109                        float pad = 120f;
110                        diff -= pad;
111                        if (diff < 0) diff = 0;
112                        accImpact = 1f - 0.5f * Math.min(1f, (diff / (180f - pad)));
113                }
114                
115//              if (fleet.isPlayerFleet()) {
116//                      System.out.println("Acc mult: " + (1f - (1f - ACCELERATION_MULT) * accImpact));
117//              }
118                fleet.getStats().getAccelerationMult().modifyMult(getModId(), 1f - (1f - ACCELERATION_MULT) * accImpact);
119                //fleet.getStats().getAccelerationMult().modifyMult(getModId(), 1f + (ACCELERATION_MULT - 1f) * level);
120                
121                for (FleetMemberViewAPI view : fleet.getViews()) {
122                        //view.getContrailColor().shift(getModId(), new Color(50,50,50,155), 1f, 1f, .5f);
123                        view.getContrailColor().shift(getModId(), view.getEngineColor().getBase(), 1f, 1f, 0.5f * level);
124                        view.getEngineGlowSizeMult().shift(getModId(), 1.5f, 1f, 1f, 1f * level);
125                        view.getEngineHeightMult().shift(getModId(), 3f, 1f, 1f, 1f * level);
126                        view.getEngineWidthMult().shift(getModId(), 2f, 1f, 1f, 1f * level);
127                }
128                
129
130                if (level <= 0) {
131                        cleanupImpl();
132                }
133        }
134        
135        @Override
136        protected void deactivateImpl() {
137                //cleanupImpl();
138        }
139        
140        @Override
141        protected void cleanupImpl() {
142                CampaignFleetAPI fleet = getFleet();
143                if (fleet == null) return;
144                
145                //fleet.getStats().getSensorRangeMod().unmodify(getModId());
146                fleet.getStats().getDetectedRangeMod().unmodify(getModId());
147                fleet.getStats().getFleetwideMaxBurnMod().unmodify(getModId());
148                fleet.getStats().getAccelerationMult().unmodify(getModId());
149        }
150        
151        @Override
152        public boolean showProgressIndicator() {
153                return super.showProgressIndicator();
154                //return false;
155        }
156        
157        @Override
158        public boolean showActiveIndicator() {
159                //super.showActiveIndicator()
160                return isActive();
161        }
162
163        @Override
164        public void createTooltip(TooltipMakerAPI tooltip, boolean expanded) {
165                Color gray = Misc.getGrayColor();
166                Color highlight = Misc.getHighlightColor();
167                
168                String status = " (off)";
169                if (turnedOn) {
170                        status = " (on)";
171                }
172                
173                if (!Global.CODEX_TOOLTIP_MODE) {
174                        LabelAPI title = tooltip.addTitle("Sustained Burn" + status);
175                        title.highlightLast(status);
176                        title.setHighlightColor(gray);
177                } else {
178                        tooltip.addSpacer(-10f);
179                }
180
181                float pad = 10f;
182                
183                
184                tooltip.addPara("Switch the drives of all ships in the fleet to a mode suited for long-distance travel. " +
185                                "The fleet has to stop briefly to make the switch-over. ", pad);
186                
187//              public static final float SENSOR_RANGE_MULT = 0.75f;
188//              public static final float DETECTABILITY_PERCENT = 50f;
189//              public static final float MAX_BURN_MOD = 10f;
190//              private static final float ACCELERATION_MULT = 0.25f;
191                tooltip.addPara("Increases the maximum burn level by %s, at the expense of lower acceleration, " +
192                                "especially in the direction of the fleet's movement. " +
193                                "Also increases the range at which the fleet can be detected by %s.", pad,
194                                highlight,
195                                //"" + (int) MAX_BURN_MOD,
196                                "" + (int) Math.round(MAX_BURN_PERCENT) + "%",
197                                "" + (int)(DETECTABILITY_PERCENT) + "%"
198                );
199                
200                tooltip.addPara("The burn level increase does not apply to flat burn bonuses, " +
201                                                "such as those from Nav Buoys or tugs.", pad);
202                
203                if (!Global.CODEX_TOOLTIP_MODE) {
204                        CampaignFleetAPI fleet = getFleet();
205                        if (fleet != null) {
206                                if (!fleet.isAIMode() && fleet.getCargo().getFuel() <= 0 && 
207                                                fleet.getContainingLocation() != null && fleet.getContainingLocation().isHyperspace()) {
208                                        tooltip.addPara("Out of fuel.", Misc.getNegativeHighlightColor(), pad);
209                                }
210                        }
211                }
212                
213//              tooltip.addPara("Increases the maximum burn level by %s, Acceleration is greatly reduced, and " +
214//                              "higher drive emissions interfere with sensors, decreasing their range by %s. " +
215//                              "The fleet is also %s easier to detect.", pad,
216//                              highlight,
217//                              "" + (int) MAX_BURN_MOD,
218//                              "" + (int)((1f - SENSOR_RANGE_MULT) * 100f) + "%",
219//                              "" + (int)(DETECTABILITY_PERCENT) + "%"
220//              );
221                //tooltip.addPara("Disables the transponder when activated.", pad);
222                addIncompatibleToTooltip(tooltip, expanded);
223        }
224        
225        public boolean isUsable() {
226                if (!super.isUsable()) return false;
227                if (getFleet() == null) return false;
228                
229                CampaignFleetAPI fleet = getFleet();
230                if (!fleet.isAIMode() && fleet.getCargo().getFuel() <= 0 && 
231                                fleet.getContainingLocation() != null && fleet.getContainingLocation().isHyperspace()) {
232                        return false;
233                }
234                
235                return true;
236        }
237
238        public boolean hasTooltip() {
239                return true;
240        }
241        
242        
243        @Override
244        public void fleetLeftBattle(BattleAPI battle, boolean engagedInHostilities) {
245//              if (battle.isPlayerInvolved() && engagedInHostilities) {
246//                      deactivate();
247//              }
248        }
249
250
251        @Override
252        public void fleetJoinedBattle(BattleAPI battle) {
253                if (!battle.isPlayerInvolved()) {
254                        deactivate();
255                }
256        }
257
258}
259
260
261
262
263