001package com.fs.starfarer.api.impl.combat.dweller; 002 003import org.lwjgl.util.vector.Vector2f; 004 005import com.fs.starfarer.api.Global; 006import com.fs.starfarer.api.combat.MutableShipStatsAPI; 007import com.fs.starfarer.api.combat.ShipAPI; 008import com.fs.starfarer.api.combat.ShipCommand; 009import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags; 010import com.fs.starfarer.api.impl.combat.BaseShipSystemScript; 011import com.fs.starfarer.api.impl.combat.threat.RoilingSwarmEffect.SwarmMember; 012import com.fs.starfarer.api.util.Misc; 013 014public class ConvulsiveLungeSystemScript extends BaseShipSystemScript { 015 016 public static float PULL_DIST = 1000f; 017 public static float PARTICLE_WINDUP_ACCEL = 1500f; 018 public static float SPRING_CONSTANT = 4f; 019 public static float FRICTION = 1000f; 020 021 public static float MAW_WINDUP_MULT = 3f; 022 023 protected Vector2f dest; 024 protected boolean fadedFlash = false; 025 026 protected void init(ShipAPI ship) { 027 } 028 029 030// public static boolean isMaw(ShipAPI ship) { 031// boolean isMaw = ship != null && ship.isCapital(); 032// return isMaw; 033// } 034 035 @Override 036 public void apply(MutableShipStatsAPI stats, String id, State state, float effectLevel) { 037 ShipAPI ship = null; 038 if (stats.getEntity() instanceof ShipAPI) { 039 ship = (ShipAPI) stats.getEntity(); 040 } else { 041 return; 042 } 043 044 DwellerShroud shroud = DwellerShroud.getShroudFor(ship); 045 if (state == State.IN) { 046 boolean destWasNull = dest == null; 047 if (dest == null) { 048 dest = new Vector2f(ship.getMouseTarget()); 049 if (ship.getShipAI() != null && ship.getAIFlags().hasFlag(AIFlags.SYSTEM_TARGET_COORDS)){ 050 dest = (Vector2f) ship.getAIFlags().getCustom(AIFlags.SYSTEM_TARGET_COORDS); 051 } 052 } 053 if (dest == null) { 054 dest = Misc.getUnitVectorAtDegreeAngle(ship.getFacing() + 180f); 055 dest.scale(PULL_DIST); 056 Vector2f.add(dest, ship.getLocation(), dest); 057 } 058 059// float dist = Misc.getDistance(ship.getLocation(), dest); 060// if (dist < PULL_DIST) { 061 if (destWasNull) { 062 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(Misc.getAngleInDegrees(ship.getLocation(), dest)); 063 dest = dir; 064 dest.scale(PULL_DIST); 065 Vector2f.add(dest, ship.getLocation(), dest); 066 } 067 } 068 069 if (dest != null) { 070 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(Misc.getAngleInDegrees(ship.getLocation(), dest)); 071 float amount = Global.getCombatEngine().getElapsedInLastFrame(); 072 073 if (state == State.IN) { 074 boolean isMaw = DwellerCombatStrategyAI.isMaw(ship); 075 float accel = PARTICLE_WINDUP_ACCEL * amount * effectLevel; 076 if (isMaw) { 077 accel *= MAW_WINDUP_MULT; 078 } 079 if (shroud != null) { 080 boolean affect = true; 081 for (SwarmMember p : shroud.getMembers()) { 082 if (affect) { 083 p.vel.x += dir.x * accel; 084 p.vel.y += dir.y * accel; 085 } 086 affect = !affect; 087 } 088 //shroud.getParams().baseMembersToMaintain = 150; 089 } 090 } 091 092 if (state == State.ACTIVE) { 093 if (!fadedFlash) { 094 //shroud.getParams().baseMembersToMaintain = 100; 095 if (shroud != null) { 096 for (SwarmMember p : shroud.getMembers()) { 097 if (p.flash != null) { 098 p.flash.fadeOut(); 099 } 100 } 101 } 102 fadedFlash = true; 103 } 104 105 Vector2f loc = ship.getLocation(); 106 float dist = Misc.getDistance(loc, dest); 107 108 //Vector2f perp = new Vector2f(-dir.y, dir.x); 109 110 float friction = FRICTION; 111 float k = SPRING_CONSTANT; 112 float freeLength = 0f; 113 float stretch = dist - freeLength; 114 115 float forceMag = k * Math.abs(stretch); 116 117 float forceMagReduction = Math.min(Math.abs(forceMag), friction); 118 forceMag -= forceMagReduction; 119 friction -= forceMagReduction; 120 121 Vector2f force = new Vector2f(dir); 122 force.scale(forceMag * Math.signum(stretch)); 123 124 Vector2f acc = new Vector2f(force); 125 acc.scale(amount); 126 Vector2f.add(ship.getVelocity(), acc, ship.getVelocity()); 127 } 128 129 } 130 131 if (state == State.OUT) { 132 dest = null; 133 fadedFlash = false; 134 } else if (state == State.ACTIVE) { 135 } 136 137 if (effectLevel > 0.85f && state != State.OUT) { 138 if (ship.getShield() != null) { 139 if (ship.getShield().isOn()) { 140 ship.getShield().toggleOff(); 141 } 142 ship.blockCommandForOneFrame(ShipCommand.TOGGLE_SHIELD_OR_PHASE_CLOAK); 143 } 144 } 145 146 147 if (effectLevel > 0f) { 148 //if (state == State.OUT) { 149 ship.blockCommandForOneFrame(ShipCommand.ACCELERATE); 150 ship.blockCommandForOneFrame(ShipCommand.ACCELERATE_BACKWARDS); 151 ship.giveCommand(ShipCommand.DECELERATE, null, 0); 152 } 153 154 //stats.getMaxSpeed().modifyFlat(id, SPEED_BONUS * effectLevel); 155 156 157 //ship.getAIFlags().setFlag(AIFlags.DO_NOT_BACK_OFF, 1f); 158 //ship.getAIFlags().setFlag(AIFlags.DO_NOT_VENT, 1f); 159 //ship.getAIFlags().setFlag(AIFlags.IGNORES_ORDERS, 1f); 160 } 161 162 163 public StatusData getStatusData(int index, State state, float effectLevel) { 164 return null; 165 } 166 167} 168 169 170 171 172 173 174 175