001package com.fs.starfarer.api.impl.combat.dweller; 002 003import java.util.List; 004 005import org.lwjgl.util.vector.Vector2f; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin; 009import com.fs.starfarer.api.combat.CombatEngineAPI; 010import com.fs.starfarer.api.combat.CombatEntityAPI; 011import com.fs.starfarer.api.combat.CombatFleetManagerAPI; 012import com.fs.starfarer.api.combat.DamagingProjectileAPI; 013import com.fs.starfarer.api.combat.EveryFrameWeaponEffectPlugin; 014import com.fs.starfarer.api.combat.OnFireEffectPlugin; 015import com.fs.starfarer.api.combat.ShipAPI; 016import com.fs.starfarer.api.combat.WeaponAPI; 017import com.fs.starfarer.api.impl.combat.threat.RoilingSwarmEffect.SwarmMember; 018import com.fs.starfarer.api.input.InputEventAPI; 019import com.fs.starfarer.api.util.Misc; 020import com.fs.starfarer.api.util.WeightedRandomPicker; 021 022public class VortexLauncherEffect implements OnFireEffectPlugin, EveryFrameWeaponEffectPlugin { 023 024 //public static String VORTEX_VARIANT = "shrouded_vortex_Churning"; 025 public static String VORTEX_WING = "shrouded_vortex_wing"; 026 027 public static float LAUNCH_ARC = 60f; 028 029 public static class DisturbShroudPlugin extends BaseEveryFrameCombatPlugin { 030 float elapsed = 0f; 031 float dur; 032 Vector2f dir; 033 DwellerShroud shroud; 034 int numMembers; 035 Vector2f offset; 036 CombatEntityAPI disturber; 037 038 public DisturbShroudPlugin(float dur, Vector2f dir, CombatEntityAPI disturber, Vector2f offset, DwellerShroud shroud, int numMembers) { 039 this.dur = dur; 040 this.dir = dir; 041 this.disturber = disturber; 042 this.offset = offset; 043 this.shroud = shroud; 044 this.numMembers = numMembers; 045 } 046 047 @Override 048 public void advance(float amount, List<InputEventAPI> events) { 049 if (Global.getCombatEngine().isPaused()) return; 050 051 elapsed += amount; 052 if (elapsed > dur) { 053 CombatEngineAPI engine = Global.getCombatEngine(); 054 engine.removePlugin(this); 055 return; 056 } 057 058 Vector2f loc = Vector2f.add(shroud.getAttachedTo().getLocation(), offset, new Vector2f()); 059 060 Vector2f useDir = dir; 061 if (disturber != null) { 062 useDir = new Vector2f(disturber.getVelocity()); 063 useDir = Misc.normalise(useDir); 064 } 065 066 WeightedRandomPicker<SwarmMember> picker = shroud.getPicker(false, true, loc, 70f); 067 for (int i = 0; i < numMembers; i++) { 068 SwarmMember pick = picker.pickAndRemove(); 069 if (pick == null) break; 070 float accel = ConvulsiveLungeSystemScript.PARTICLE_WINDUP_ACCEL * amount * 3f; 071 accel *= 1f + (float) Math.random(); 072 pick.vel.x += useDir.x * accel; 073 pick.vel.y += useDir.y * accel; 074 } 075 076 } 077 } 078 079 public VortexLauncherEffect() { 080 081 } 082 083 @Override 084 public void advance(float amount, CombatEngineAPI engine, WeaponAPI weapon) { 085 ShipAPI ship = weapon.getShip(); 086 if (ship == null) return; 087 088 //weapon.setForceFireOneFrame(true); 089 } 090 091 092 093 public void onFire(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine) { 094 095 //FighterWingSpecAPI spec = Global.getSettings().getFighterWingSpec(ATTACK_SWARM_WING); 096 097 CombatFleetManagerAPI manager = engine.getFleetManager(projectile.getOwner()); 098 manager.setSuppressDeploymentMessages(true); 099 // wing has size 1, so no other members besides the "leader" 100 // point is to spawn a ship but without it showing up in the deployment dialog etc 101 ShipAPI vortex = manager.spawnShipOrWing(VORTEX_WING, 102 projectile.getLocation(), projectile.getFacing(), 0f, null); 103 manager.setSuppressDeploymentMessages(false); 104 105 Vector2f takeoffVel = Misc.getUnitVectorAtDegreeAngle( 106 projectile.getFacing() + LAUNCH_ARC/2f - (float) Math.random() * LAUNCH_ARC); 107 float velMult = 1f; 108 if (Misc.getAngleDiff(projectile.getFacing(), weapon.getShip().getFacing()) > 150f) { 109 velMult = 0.5f; 110 } 111 takeoffVel.scale(vortex.getMaxSpeed() * velMult); 112 113 Vector2f.add(vortex.getVelocity(), takeoffVel, vortex.getVelocity()); 114 115 DwellerShroud shroud = DwellerShroud.getShroudFor(vortex); 116 if (shroud != null) { 117 shroud.custom1 = weapon.getShip(); 118 } 119 120 DwellerShroud sourceShroud = DwellerShroud.getShroudFor(weapon.getShip()); 121 if (sourceShroud != null) { 122 123 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(projectile.getFacing()); 124 Vector2f offset = Vector2f.sub(projectile.getLocation(), sourceShroud.getAttachedTo().getLocation(), new Vector2f()); 125 Global.getCombatEngine().addPlugin( 126 new DisturbShroudPlugin(1f, dir, vortex, offset, sourceShroud, 127 (int) (sourceShroud.getNumMembersToMaintain() * 0.1f))); 128 //new DisturbShroudPlugin(1f, dir, offset, sourceShroud, 10)); 129 130 } 131 132 engine.removeEntity(projectile); 133 } 134 135 136 137} 138 139 140 141 142 143 144 145