001package com.fs.starfarer.api.impl.combat; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin; 007import com.fs.starfarer.api.combat.CombatEngineAPI; 008import com.fs.starfarer.api.combat.ShipAPI; 009import com.fs.starfarer.api.combat.WeaponAPI; 010import com.fs.starfarer.api.combat.ShipEngineControllerAPI.ShipEngineAPI; 011import com.fs.starfarer.api.input.InputEventAPI; 012import com.fs.starfarer.api.util.IntervalUtil; 013import com.fs.starfarer.api.util.WeightedRandomPicker; 014 015public class LowCRShipDamageSequence extends BaseEveryFrameCombatPlugin { 016 private ShipAPI ship; 017 private CombatEngineAPI engine; 018 019 private float severity; 020 private float elapsed = 0f; 021 private float beforeDamage; 022 private IntervalUtil tracker = new IntervalUtil(0.25f, 1f); 023 024 private WeightedRandomPicker<Object> disableTargets = new WeightedRandomPicker<Object>(true); 025 private float disableAttempts = 0; 026 027 public LowCRShipDamageSequence(ShipAPI ship, float severity) { 028 this.ship = ship; 029 this.severity = severity; 030 031 beforeDamage = 1f + 2f * (float) Math.random(); 032 033 List<WeaponAPI> weapons = ship.getUsableWeapons(); 034 for (WeaponAPI weapon : weapons) { 035 disableTargets.add(weapon); 036 } 037 List<ShipEngineAPI> engines = ship.getEngineController().getShipEngines(); 038 for (ShipEngineAPI engine : engines) { 039 if (!engine.isSystemActivated()) { 040 disableTargets.add(engine); 041 } 042 } 043 044 disableAttempts = Math.max(1, Math.round((0.25f + 0.75f * severity) * (float) disableTargets.getItems().size() * 0.25f)); 045 046 if (severity >= 1) { 047 disableAttempts *= 2f; 048 } 049 } 050 051 public void disableNext() { 052 if (disableAttempts <= 0) return; 053 disableAttempts--; 054 List<Object> remove = new ArrayList<Object>(); 055// List<Object> usableWeapons = new ArrayList<Object>(); 056 for (Object target : disableTargets.getItems()) { 057// if (target instanceof ShipEngineAPI) { 058// float fractionIfDisabled = ((ShipEngineAPI) target).getContribution() + ship.getEngineFractionPermanentlyDisabled(); 059// if (fractionIfDisabled > 0.5f) { 060// remove.add(target); 061// } 062// } else if (target instanceof WeaponAPI) { 063// WeaponAPI weapon = (WeaponAPI) target; 064// if (weapon.getAmmo() > 0) { 065// usableWeapons.add(target); 066// } 067// } 068 if (!CRPluginImpl.isOkToPermanentlyDisableStatic(ship, target)) { 069 remove.add(target); 070 } 071 } 072// if (usableWeapons.size() <= 1) remove.addAll(usableWeapons); 073 for (Object target : remove) { 074 disableTargets.remove(target); 075 } 076 077 Object module = disableTargets.pick(); 078 if (module != null) { 079 disableTargets.remove(module); 080 ship.applyCriticalMalfunction(module); 081 } 082 } 083 084 085 086 public void init(CombatEngineAPI engine) { 087 this.engine = engine; 088 } 089 090 public void advance(float amount, List<InputEventAPI> events) { 091 if (engine.isPaused()) return; 092 093 if (!engine.isEntityInPlay(ship)) return; // ship is in refit screen 094 095// System.out.println("Advance: " + amount); 096 elapsed += amount; 097 098 if (elapsed > beforeDamage) { 099 tracker.advance(amount); 100 if (tracker.intervalElapsed()) { 101 disableNext(); 102 103 } 104 if (ship.isHulk() || disableAttempts <= 0) { 105 engine.removePlugin(this); 106 } 107 } 108 } 109 110 111 112 113 114 115} 116 117 118 119 120 121