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