001package com.fs.starfarer.api.impl.hullmods;
002
003import java.awt.Color;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.combat.BaseHullMod;
008import com.fs.starfarer.api.combat.BeamAPI;
009import com.fs.starfarer.api.combat.CombatEntityAPI;
010import com.fs.starfarer.api.combat.DamageAPI;
011import com.fs.starfarer.api.combat.DamagingProjectileAPI;
012import com.fs.starfarer.api.combat.MutableShipStatsAPI;
013import com.fs.starfarer.api.combat.ShipAPI;
014import com.fs.starfarer.api.combat.ShipAPI.HullSize;
015import com.fs.starfarer.api.combat.WeaponAPI;
016import com.fs.starfarer.api.combat.listeners.DamageDealtModifier;
017import com.fs.starfarer.api.combat.listeners.WeaponBaseRangeModifier;
018import com.fs.starfarer.api.impl.campaign.ids.HullMods;
019import com.fs.starfarer.api.ui.Alignment;
020import com.fs.starfarer.api.ui.TooltipMakerAPI;
021import com.fs.starfarer.api.util.Misc;
022
023public class HighScatterAmp extends BaseHullMod {
024
025        public static float RANGE_THRESHOLD = 200f;
026        public static float RANGE_MULT = 0.5f;
027        
028//      public static float RANGE_FRIGATE = 500;
029//      public static float RANGE_DESTROYER = 600;
030//      public static float RANGE_LARGE = 700;
031        
032        public static float DAMAGE_BONUS_PERCENT = 10f;
033        public static float SMOD_MODIFIER = 5f;
034        
035        
036        @Override
037        public boolean isApplicableToShip(ShipAPI ship) {
038                return !ship.getVariant().getHullMods().contains(HullMods.ADVANCEDOPTICS);
039        }
040        
041        public String getUnapplicableReason(ShipAPI ship) {
042                if (ship.getVariant().getHullMods().contains(HullMods.ADVANCEDOPTICS)) {
043                        return "Incompatible with Advanced Optics";
044                }
045                return null;
046        }
047        
048        
049        public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
050                boolean sMod = isSMod(stats);
051                
052                //stats.getBeamWeaponRangeBonus().modifyMult(id, 1f - RANGE_PENALTY_PERCENT * 0.01f);
053                stats.getBeamWeaponDamageMult().modifyPercent(id, DAMAGE_BONUS_PERCENT + (sMod ? SMOD_MODIFIER : 0));
054                
055                // test code for WeaponOPCostModifier, FighterOPCostModifier
056//              stats.addListener(new WeaponOPCostModifier() {
057//                      public int getWeaponOPCost(MutableShipStatsAPI stats, WeaponSpecAPI weapon, int currCost) {
058//                              if (weapon.getWeaponId().equals("amblaster")) {
059//                                      return 1;
060//                              }
061//                              return currCost;
062//                      }
063//              });
064//              stats.addListener(new FighterOPCostModifier() {
065//                      public int getFighterOPCost(MutableShipStatsAPI stats, FighterWingSpecAPI fighter, int currCost) {
066//                              if (fighter.getId().equals("talon_wing")) {
067//                                      return 20;
068//                              }
069//                              return currCost;
070//                      }
071//              });
072        }
073        
074//      @Override
075//      public boolean affectsOPCosts() {
076//              return true;
077//      }
078
079        public String getSModDescriptionParam(int index, HullSize hullSize, ShipAPI ship) {
080                if (index == 0) return "" + (int) Math.round(SMOD_MODIFIER) + "%";
081                return null;
082        }
083
084
085        @Override
086        public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
087                ship.addListener(new HighScatterAmpDamageDealtMod(ship));
088                ship.addListener(new HighScatterAmpRangeMod());
089                
090                /* test code for WeaponRangeModifier
091                ship.addListener(new WeaponRangeModifier() {
092                        public float getWeaponRangePercentMod(ShipAPI ship, WeaponAPI weapon) {
093                                return 0;
094                        }
095                        public float getWeaponRangeMultMod(ShipAPI ship, WeaponAPI weapon) {
096                                return 1f;
097                        }
098                        public float getWeaponRangeFlatMod(ShipAPI ship, WeaponAPI weapon) {
099                                if (weapon.getId().equals("amblaster")) {
100                                        return 500;
101                                }
102                                return 0f;
103                        }
104                });
105                */
106        }
107        
108        public static class HighScatterAmpDamageDealtMod implements DamageDealtModifier {
109                protected ShipAPI ship;
110                public HighScatterAmpDamageDealtMod(ShipAPI ship) {
111                        this.ship = ship;
112                }
113                
114                public String modifyDamageDealt(Object param,
115                                                                                CombatEntityAPI target, DamageAPI damage,
116                                                                                Vector2f point, boolean shieldHit) {
117                        
118                        if (!(param instanceof DamagingProjectileAPI) && param instanceof BeamAPI) {
119                                damage.setForceHardFlux(true);
120                        }
121                        return null;
122                }
123        }
124        
125        public static class HighScatterAmpRangeMod implements WeaponBaseRangeModifier {
126                public HighScatterAmpRangeMod() {
127                }
128                public float getWeaponBaseRangePercentMod(ShipAPI ship, WeaponAPI weapon) {
129                        return 0;
130                }
131                public float getWeaponBaseRangeMultMod(ShipAPI ship, WeaponAPI weapon) {
132                        return 1f;
133                }
134                public float getWeaponBaseRangeFlatMod(ShipAPI ship, WeaponAPI weapon) {
135                        if (weapon.isBeam()) {
136                                float range = weapon.getSpec().getMaxRange();
137                                if (range < RANGE_THRESHOLD) return 0;
138                                
139                                float past = range - RANGE_THRESHOLD;
140                                float penalty = past * (1f - RANGE_MULT);
141                                return -penalty;
142                        }
143                        return 0f;
144                }
145        }
146//      public static class HighScatterAmpRangeMod implements WeaponBaseRangeModifier {
147//              public HighScatterAmpRangeMod() {
148//              }
149//              public float getWeaponBaseRangePercentMod(ShipAPI ship, WeaponAPI weapon) {
150//                      return 0;
151//              }
152//              public float getWeaponBaseRangeMultMod(ShipAPI ship, WeaponAPI weapon) {
153//                      return 1f;
154//              }
155//              public float getWeaponBaseRangeFlatMod(ShipAPI ship, WeaponAPI weapon) {
156//                      if (weapon.isBeam()) {
157//                              float range = weapon.getSpec().getMaxRange();
158//                              float max = range;
159//                              if (ship.isFighter() || ship.isFrigate()) {
160//                                      max = RANGE_FRIGATE;
161//                              } else if (ship.isDestroyer()) {
162//                                      max = RANGE_DESTROYER;
163//                              } else if (ship.isCruiser() || ship.isCapital()) {
164//                                      max = RANGE_LARGE;
165//                              }
166//                              return Math.min(0f, max - range);
167//                      }
168//                      return 0f;
169//              }
170//      }
171
172        public String getDescriptionParam(int index, HullSize hullSize) {
173                //if (index == 0) return "" + (int)RANGE_PENALTY_PERCENT + "%";
174                return null;
175        }
176        
177        @Override
178        public boolean shouldAddDescriptionToTooltip(HullSize hullSize, ShipAPI ship, boolean isForModSpec) {
179                return false;
180        }
181
182        @Override
183        public void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) {
184                float pad = 3f;
185                float opad = 10f;
186                Color h = Misc.getHighlightColor();
187                Color bad = Misc.getNegativeHighlightColor();
188                
189                tooltip.addPara("Beam weapons deal %s more damage and deal hard flux damage to shields.", opad, h,
190                                "" + (int)DAMAGE_BONUS_PERCENT + "%"
191                                );
192                
193                tooltip.addPara("Reduces the portion of the range of beam weapons that is above %s units by %s. The base range is affected.", opad, h,
194                                "" + (int)RANGE_THRESHOLD,
195                                "" + (int)Math.round((1f - RANGE_MULT) * 100f) + "%"
196                                );
197//              tooltip.addPara("Reduces the base range of beam weapons to %s for frigates, %s for destroyers, "
198//                              + "and %s for larger ships.", opad, h,
199//                              "" + (int)RANGE_FRIGATE,
200//                              "" + (int)RANGE_DESTROYER,
201//                              "" + (int)RANGE_LARGE
202//                              );
203                
204                tooltip.addSectionHeading("Interactions with other modifiers", Alignment.MID, opad);
205                tooltip.addPara("The base range is reduced, thus percentage and multiplicative modifiers - such as from Integrated Targeting Unit, "
206                                + "skills, or similar sources - apply to the reduced base value.", opad);
207        }
208}
209
210
211
212
213
214
215
216
217