Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Improved By Originem, Original By Nicke535, handles the trails for various projectiles in the mod
- package data.scripts.plugins;
- import com.fs.starfarer.api.Global;
- import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
- import com.fs.starfarer.api.combat.CombatEngineAPI;
- import com.fs.starfarer.api.combat.DamagingProjectileAPI;
- import com.fs.starfarer.api.graphics.SpriteAPI;
- import com.fs.starfarer.api.input.InputEventAPI;
- import com.fs.starfarer.api.loading.ProjectileSpawnType;
- import com.fs.starfarer.api.util.IntervalUtil;
- import org.lazywizard.lazylib.MathUtils;
- import org.lazywizard.lazylib.VectorUtils;
- import org.lwjgl.util.vector.Vector2f;
- import java.awt.*;
- import java.util.*;
- import java.util.List;
- import java.util.Map.Entry;
- import static org.lwjgl.opengl.GL11.*;
- public class trails_OptimizedProjectileTrailHandlerPlugin extends BaseEveryFrameCombatPlugin {
- /**
- * To specify trail's features.
- */
- private static class TrailData {
- /**
- * sprites must be under TSW_fx
- */
- String spriteID = "trail_fuzzy";
- float durationIn = 0f;
- float durationMain = 0f;
- float durationOut = 0f;
- float startSize = 10f;
- float endSize = 10f;
- Color startColor = Color.white;
- Color endColor = Color.white;
- float opacity = 1f;
- int blendSrc = GL_SRC_ALPHA;
- int blendDest = GL_ONE;
- float loopLength = -1f;
- float scrollSpeed = 0f;
- float spawnOffset = 0f;
- /**
- * NEW: compensates for lateral movement of a projectile. Should generally be 0f in most cases, due to some oddities
- * in behaviour with direction-changing scripts, but can be helpful for aligning certain projectiles
- */
- float lateralCompensationMult = 1f;
- /**
- * NEW: whether a shot's trail loses opacity as the projectile fades out. Should generally be true, but may need to
- * be set to false on some scripted weapons. Has no real effect on flak rounds or missiles, and should thus be set
- * false for those
- */
- boolean fadeOutFadeTrail = true;
- /**
- * NEW: whether a shot should have its direction adjusted to face the same way as its velocity vector, thus
- * helping with trail alignment for projectiles without using lateral compensation. DOES NOT WORK FOR
- * PROJECTILES SPAWNED WITH BALLISTIC_AS_BEAM AS SPAWNTYPE, and should not be used on missiles
- */
- boolean projectileAngleAdjustment = false;
- TrailData() {
- }
- /**
- * Save the data to the TRAIL_DATAS in this plugin.
- *
- * @param projectileID projectile's ID
- */
- private void save(String projectileID) {
- TRAIL_DATAS.put(projectileID, this);
- }
- }
- //Auto-generate data by maps above,based on TRAIL_SPRITES
- private static final Map<String, TrailData> TRAIL_DATAS = new HashMap<>();
- static {
- TrailData data;
- data = new TrailData();
- data.spriteID = "trail_fuzzy";
- data.durationIn = 0f;
- data.durationMain = 0f;
- data.durationOut = 0.3f;
- data.startSize = 10f;
- data.endSize = 5f;
- data.startColor = new Color(255, 160, 30);
- data.endColor = new Color(204, 185, 155);
- data.opacity = 0.8f;
- data.blendSrc = GL_SRC_ALPHA;
- data.blendDest = GL_ONE;
- data.loopLength = 300f;
- data.scrollSpeed = 500f;
- data.spawnOffset = 0f;
- data.lateralCompensationMult = 1f;
- data.fadeOutFadeTrail = true;
- data.projectileAngleAdjustment = false;
- data.save("hellbore_shot");
- data = new TrailData();
- data.spriteID = "trail_zappy";
- data.durationIn = 0f;
- data.durationMain = 0f;
- data.durationOut = 0.8f;
- data.startSize = 7f;
- data.endSize = 3f;
- data.startColor = new Color(120, 120, 255);
- data.endColor = new Color(100, 100, 25);
- data.opacity = 0.8f;
- data.blendSrc = GL_SRC_ALPHA;
- data.blendDest = GL_ONE;
- data.loopLength = -1f;
- data.scrollSpeed = 0f;
- data.spawnOffset = 30f;
- data.lateralCompensationMult = 1f;
- data.fadeOutFadeTrail = true;
- data.projectileAngleAdjustment = false;
- data.save("gauss_shot");
- data = new TrailData();
- data.spriteID = "trail_zappy";
- data.durationIn = 0f;
- data.durationMain = 0f;
- data.durationOut = 0.4f;
- data.startSize = 12f;
- data.endSize = 5f;
- data.startColor = new Color(150, 100, 255);
- data.endColor = new Color(150, 100, 255);
- data.opacity = 0.6f;
- data.blendSrc = GL_SRC_ALPHA;
- data.blendDest = GL_ONE;
- data.loopLength = -1f;
- data.scrollSpeed = 0f;
- data.spawnOffset = 2f;
- data.lateralCompensationMult = 1f;
- data.fadeOutFadeTrail = true;
- data.projectileAngleAdjustment = false;
- data.save("amblaster_shot");
- data = new TrailData();
- data.spriteID = "trail_fuzzy";
- data.durationIn = 0f;
- data.durationMain = 0.1f;
- data.durationOut = 0.5f;
- data.startSize = 7f;
- data.endSize = 1f;
- data.startColor = new Color(255, 255, 215);
- data.endColor = new Color(255, 255, 245);
- data.opacity = 0.5f;
- data.blendSrc = GL_SRC_ALPHA;
- data.blendDest = GL_ONE_MINUS_SRC_ALPHA;
- data.loopLength = -1f;
- data.scrollSpeed = 0f;
- data.spawnOffset = 20f;
- data.lateralCompensationMult = 1f;
- data.fadeOutFadeTrail = true;
- data.projectileAngleAdjustment = false;
- data.save("hveldriver_shot");
- data = new TrailData();
- data.spriteID = "trail_zappy";
- data.durationIn = 0.05f;
- data.durationMain = 0.05f;
- data.durationOut = 0.2f;
- data.startSize = 8f;
- data.endSize = 25f;
- data.startColor = new Color(255, 170, 60);
- data.endColor = new Color(60, 30, 20);
- data.opacity = 0.4f;
- data.blendSrc = GL_SRC_ALPHA;
- data.blendDest = GL_ONE;
- data.loopLength = 400f;
- data.scrollSpeed = 1000f;
- data.spawnOffset = 30f;
- data.lateralCompensationMult = 1f;
- data.fadeOutFadeTrail = true;
- data.projectileAngleAdjustment = false;
- data.save("heavymauler_shot");
- data = new TrailData();
- data.spriteID = "trail_zappy";
- data.durationIn = 0f;
- data.durationMain = 0f;
- data.durationOut = 0.2f;
- data.startSize = 16f;
- data.endSize = 8f;
- data.startColor = new Color(95, 75, 255);
- data.endColor = new Color(125, 95, 255);
- data.opacity = 0.6f;
- data.blendSrc = GL_SRC_ALPHA;
- data.blendDest = GL_ONE;
- data.loopLength = 200f;
- data.scrollSpeed = 1000f;
- data.spawnOffset = 0f;
- data.lateralCompensationMult = 1f;
- data.fadeOutFadeTrail = true;
- data.projectileAngleAdjustment = false;
- data.save("mjolnir_shot");
- }
- // Map to record trail ids
- private Map<DamagingProjectileAPI, TrailIDC> projectileTrailIDCs = new WeakHashMap<>();
- // Timer to clean projectiles
- private IntervalUtil trailDataCleanerTimer = new IntervalUtil(3f, 3f);
- @Override
- public void init(CombatEngineAPI engine) {
- //Reinitialize the lists
- projectileTrailIDCs.clear();
- }
- @Override
- public void advance(float amount, List<InputEventAPI> events) {
- if (Global.getCombatEngine() == null || Global.getCombatEngine().isPaused()) {
- return;
- }
- CombatEngineAPI engine = Global.getCombatEngine();
- //clean the projectile references per 3 seconds
- trailDataCleanerTimer.advance(amount);
- if (trailDataCleanerTimer.intervalElapsed()) {
- Iterator<Entry<DamagingProjectileAPI, TrailIDC>> iterator = projectileTrailIDCs.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<DamagingProjectileAPI, TrailIDC> entry = iterator.next();
- DamagingProjectileAPI projectile = entry.getKey();
- if (projectile == null || !engine.isEntityInPlay(projectile)) iterator.remove();
- }
- }
- //Runs once on each projectile that matches one of the IDs specified in our maps
- for (DamagingProjectileAPI proj : engine.getProjectiles()) {
- //Ignore already-collided projectiles, and projectiles that don't match our IDs
- if (proj.getProjectileSpecId() == null || proj.didDamage()) {
- continue;
- }
- if (!TRAIL_DATAS.keySet().contains(proj.getProjectileSpecId())) {
- continue;
- }
- //-------------------------------------------For visual effects---------------------------------------------
- String specID = proj.getProjectileSpecId();
- TrailData trailData = TRAIL_DATAS.get(specID);
- SpriteAPI spriteToUse = Global.getSettings().getSprite("trails_fx", trailData.spriteID);
- Vector2f projVel = new Vector2f(proj.getVelocity());
- //If we use angle adjustment, do that here
- if (trailData.projectileAngleAdjustment && projVel.length() > 0.1f && !proj.getSpawnType().equals(ProjectileSpawnType.BALLISTIC_AS_BEAM)) {
- proj.setFacing(VectorUtils.getAngle(new Vector2f(0f, 0f), projVel));
- }
- //Fix for some first-frame error shenanigans
- if (projVel.length() < 0.1f && proj.getSource() != null) {
- projVel = new Vector2f(proj.getSource().getVelocity());
- }
- //Gets a custom "offset" position, so we can slightly alter the spawn location to account for "natural fade-in", and add that to our spawn position
- Vector2f offsetPoint = new Vector2f((float) Math.cos(Math.toRadians(proj.getFacing())) * trailData.spawnOffset, (float) Math.sin(Math.toRadians(proj.getFacing())) * trailData.spawnOffset);
- Vector2f spawnPosition = new Vector2f(offsetPoint.x + proj.getLocation().x, offsetPoint.y + proj.getLocation().y);
- //Sideway offset velocity, for projectiles that use it
- Vector2f projBodyVel = VectorUtils.rotate(projVel, -proj.getFacing());
- Vector2f projLateralBodyVel = new Vector2f(0f, projBodyVel.getY());
- Vector2f sidewayVel = (Vector2f) VectorUtils.rotate(projLateralBodyVel, proj.getFacing()).scale(trailData.lateralCompensationMult);
- //Opacity adjustment for fade-out, if the projectile uses it
- float opacityMult = 1f;
- if (trailData.fadeOutFadeTrail && proj.isFading()) {
- opacityMult = proj.getDamageAmount() / proj.getBaseDamageAmount();
- }
- TrailIDC trailIDC = projectileTrailIDCs.get(proj);
- if (specID.contains("gauss_shot")) {
- if (trailIDC == null) {
- trailIDC = new TrailIDC(true, true, false);
- projectileTrailIDCs.put(proj, trailIDC);
- }
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.mainId, spriteToUse, spawnPosition, 0f, MathUtils.getRandomNumberInRange(0f, 105f), proj.getFacing() - 180f,
- 0f, MathUtils.getRandomNumberInRange(-330f, 330f), trailData.startSize, trailData.endSize, trailData.startColor, new Color(180, 190, 255),
- 0.4f * opacityMult, trailData.durationIn, 0.2f, trailData.durationOut + 0.2f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, trailData.scrollSpeed, sidewayVel, null);
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.dualCoreId, spriteToUse, spawnPosition, 0f, MathUtils.getRandomNumberInRange(0f, 105f), proj.getFacing() - 180f,
- 0f, MathUtils.getRandomNumberInRange(-330f, 330f), trailData.startSize, trailData.endSize, trailData.startColor, new Color(180, 190, 255),
- 0.4f * opacityMult, trailData.durationIn, 0.2f, trailData.durationOut + 0.2f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, trailData.scrollSpeed, sidewayVel, null);
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.equityId, Global.getSettings().getSprite("trails_fx", "trail_smooth"), spawnPosition, 0f, 0f, proj.getFacing() - 180f,
- 0f, 0f, 60f, 30f, trailData.startColor, trailData.startColor,
- 0.5f * opacityMult, 0f, 0.05f, 0.15f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, 0f, sidewayVel, null);
- } else {
- if (trailIDC == null) {
- trailIDC = new TrailIDC();
- projectileTrailIDCs.put(proj, trailIDC);
- }
- //Then, actually spawn a trail
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.mainId, spriteToUse, spawnPosition, 0f, 0f, proj.getFacing() - 180f,
- 0f, 0f, trailData.startSize, trailData.endSize, trailData.startColor, trailData.endColor,
- trailData.opacity * opacityMult, trailData.durationIn, trailData.durationMain, trailData.durationOut, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, trailData.scrollSpeed, sidewayVel, null);
- //adding secondary trail for hellbore
- if (specID.contains("hellbore_shot")) {
- //If we haven't already started a second trail for this projectile, set the extra id for it
- if (!trailIDC.isInit) {
- trailIDC.setExtraIDs(true, false, false);
- }
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.dualCoreId, Global.getSettings().getSprite("trails_fx", "trail_contrail"), spawnPosition, 0f, 0f, proj.getFacing() - 180f,
- 0f, 0f, 25f, 35f, new Color(100, 90, 80), new Color(100, 90, 80),
- 0.4f * opacityMult, trailData.durationIn, 0f, 0.8f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, 800f, sidewayVel, null);
- }
- if (specID.contains("mjolnir_shot")) {
- if (!trailIDC.isInit) {
- trailIDC.setExtraIDs(true, false, false);
- }
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.dualCoreId, spriteToUse, spawnPosition, 0f, 0f, proj.getFacing() - 180f,
- 0f, 0f, 5f, 5f, new Color(200, 200, 200), new Color(200, 200, 200),
- 0.3f * opacityMult, trailData.durationIn, trailData.durationMain, 0.3f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, trailData.scrollSpeed, sidewayVel, null);
- }
- if (specID.contains("amblaster_shot")) {
- if (!trailIDC.isInit) {
- trailIDC.setExtraIDs(true, true, false);
- }
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.dualCoreId, spriteToUse, spawnPosition, MathUtils.getRandomNumberInRange(0f, 200f), MathUtils.getRandomNumberInRange(0f, 500f), proj.getFacing() - 180f,
- MathUtils.getRandomNumberInRange(-200f, 200f), MathUtils.getRandomNumberInRange(-500f, 500f), trailData.startSize, trailData.endSize, trailData.startColor, trailData.endColor,
- trailData.opacity * opacityMult, trailData.durationIn, trailData.durationMain, 0.2f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, trailData.scrollSpeed, sidewayVel, null);
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.equityId, spriteToUse, spawnPosition, MathUtils.getRandomNumberInRange(0f, 200f), MathUtils.getRandomNumberInRange(0f, 500f), proj.getFacing() - 180f,
- MathUtils.getRandomNumberInRange(-200f, 200f), MathUtils.getRandomNumberInRange(-500f, 500f), trailData.startSize, trailData.endSize, trailData.startColor, trailData.endColor,
- trailData.opacity * opacityMult, trailData.durationIn, trailData.durationMain, 0.2f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, trailData.scrollSpeed, sidewayVel, null);
- }
- if (specID.contains("heavymauler_shot")) {
- //If we haven't already started a second trail for this projectile, set the extra id for it
- if (!trailIDC.isInit) {
- trailIDC.setExtraIDs(true, false, false);
- }
- MagicTrailPlugin.AddTrailMemberAdvanced(proj, trailIDC.dualCoreId, Global.getSettings().getSprite("trails_fx", "trail_smooth"), spawnPosition, 0f, 0f, proj.getFacing() - 180f,
- 0f, 0f, 60f, 60f, new Color(255, 140, 60), new Color(255, 140, 60),
- 0.3f * opacityMult, 0f, 0f, 0.15f, trailData.blendSrc,
- trailData.blendDest, trailData.loopLength, 0f, sidewayVel, null);
- }
- }
- }
- }
- //A class which deal with the MagicTrailIDs
- private class TrailIDC {
- //A map for known projectiles and their IDs: should be cleared in init
- float mainId;
- //Used when doing dual-core sprites
- float dualCoreId;
- //Used for the Equity
- float equityId;
- //Used for glow gauss
- float glowId;
- boolean isInit = false;
- public TrailIDC(boolean initDualCore, boolean initEquityId, boolean initGlowId) {
- this.mainId = MagicTrailPlugin.getUniqueID();
- setExtraIDs(initDualCore, initEquityId, initGlowId);
- }
- public TrailIDC() {
- this.mainId = MagicTrailPlugin.getUniqueID();
- }
- public void setExtraIDs(boolean initDualCore, boolean initEquityId, boolean initGlowId) {
- if (initDualCore) dualCoreId = MagicTrailPlugin.getUniqueID();
- if (initEquityId) equityId = MagicTrailPlugin.getUniqueID();
- if (initGlowId) glowId = MagicTrailPlugin.getUniqueID();
- this.isInit = true;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement