001package com.fs.starfarer.api.impl.combat; 002 003import java.util.List; 004 005import org.lwjgl.util.vector.Vector2f; 006 007import com.fs.starfarer.api.combat.BeamAPI; 008import com.fs.starfarer.api.combat.BeamEffectPlugin; 009import com.fs.starfarer.api.combat.CombatEngineAPI; 010import com.fs.starfarer.api.combat.CombatEntityAPI; 011import com.fs.starfarer.api.combat.DamageAPI; 012import com.fs.starfarer.api.combat.ShipAPI; 013import com.fs.starfarer.api.combat.WeaponAPI; 014import com.fs.starfarer.api.combat.listeners.AdvanceableListener; 015import com.fs.starfarer.api.util.TimeoutTracker; 016 017public class GravitonBeamEffect implements BeamEffectPlugin { 018 019 public static float EFFECT_DUR = 1f; 020 021 public static float DAMAGE_PERCENT_ONE = 5f; 022 public static float DAMAGE_PERCENT_TWO = 8f; 023 public static float DAMAGE_PERCENT_THREE = 10f; 024 025 protected boolean wasZero = true; 026 027 028 public void advance(float amount, CombatEngineAPI engine, BeamAPI beam) { 029 CombatEntityAPI target = beam.getDamageTarget(); 030 if (target instanceof ShipAPI && beam.getBrightness() >= 1f && beam.getWeapon() != null) { 031 float dur = beam.getDamage().getDpsDuration(); 032 // needed because when the ship is in fast-time, dpsDuration will not be reset every frame as it should be 033 if (!wasZero) dur = 0; 034 wasZero = beam.getDamage().getDpsDuration() <= 0; 035 036 // beam tick, apply damage modifier effect if needed 037 if (dur > 0) { 038 boolean hitShield = target.getShield() != null && target.getShield().isWithinArc(beam.getTo()); 039 if (hitShield) { 040 ShipAPI ship = (ShipAPI) target; 041 if (!ship.hasListenerOfClass(GravitonBeamDamageTakenMod.class)) { 042 ship.addListener(new GravitonBeamDamageTakenMod(ship)); 043 } 044 List<GravitonBeamDamageTakenMod> listeners = ship.getListeners(GravitonBeamDamageTakenMod.class); 045 if (listeners.isEmpty()) return; // ??? 046 047 GravitonBeamDamageTakenMod listener = listeners.get(0); 048 listener.notifyHit(beam.getWeapon()); 049 } 050 } 051 } 052 } 053 054 055 public static String DAMAGE_MOD_ID = "gravitonbeam_dam_mod"; 056 057 public static class GravitonBeamDamageTakenMod implements AdvanceableListener { 058 //implements DamageTakenModifier, AdvanceableListener { 059 protected ShipAPI ship; 060 protected TimeoutTracker<WeaponAPI> recentHits = new TimeoutTracker<WeaponAPI>(); 061 public GravitonBeamDamageTakenMod(ShipAPI ship) { 062 this.ship = ship; 063 //ship.addListener(new GravitonBeamDamageTakenModRemover(ship)); 064 } 065 066 public void notifyHit(WeaponAPI w) { 067 recentHits.add(w, EFFECT_DUR, EFFECT_DUR); 068 069 } 070 071 public void advance(float amount) { 072 recentHits.advance(amount); 073 074 int beams = recentHits.getItems().size(); 075 076 float bonus = 0; 077 if (beams == 1) { 078 bonus = DAMAGE_PERCENT_ONE; 079 } else if (beams == 2) { 080 bonus = DAMAGE_PERCENT_TWO; 081 } else if (beams >= 3) { 082 bonus = DAMAGE_PERCENT_THREE; 083 } 084 085 if (bonus > 0) { 086 ship.getMutableStats().getShieldDamageTakenMult().modifyMult(DAMAGE_MOD_ID, 1f + bonus * 0.01f); 087 } else { 088 ship.removeListener(this); 089 ship.getMutableStats().getShieldDamageTakenMult().unmodify(DAMAGE_MOD_ID); 090 } 091 } 092 093 public String modifyDamageTaken(Object param, 094 CombatEntityAPI target, DamageAPI damage, 095 Vector2f point, boolean shieldHit) { 096 return null; 097 } 098 099 } 100 101}