using System; using System.Collections.Generic; using System.Linq; using UnityEngine; public enum Output { Acceleration, Deceleration, Strafing, Shield, } public class PowerUnit { static float stablisation = 75f; public float Stabilisation => stablisation; // Outputs static float baseOutput = 25.0f; static float initialAcceleration = 2f * baseOutput; static float initialDeceleration = 4f * baseOutput; static float initialStrafing = 1f * baseOutput; float acceleration = initialAcceleration; float deceleration = initialDeceleration; float strafing = initialStrafing; // public float Acceleration => acceleration; // public float Deceleration => deceleration; // public float Strafing => strafing; // Shields static float initialShieldMax = 5000f; float shieldCurrent = initialShieldMax; float shieldMax = initialShieldMax; static float shieldBoostIncrease = 1000f; static float shieldBoostAmount = 1000f; public float Shield => shieldCurrent; public string ShieldPct => $"{((shieldCurrent / shieldMax) * 100f):0}"; bool UsingMovementBoost => BoostActive.Any(b => b.output != Output.Shield); float ShieldRegen => UsingMovementBoost switch { false => (shieldMax / 5f) * Time.fixedDeltaTime, true => 0f, }; // Boost static double boostFullChargeSeconds = 10f; public static double boostDurationSeconds = 2f; double boostMax = 2f * boostDurationSeconds; double boostProgress = 0f; double boostAvailable = 0f; public List<(Output output, double expiresAt)> BoostActive = new(); public double BoostProgress => boostProgress / boostMax; public int BoostCharges => (int)(boostMax / boostDurationSeconds); public int BoostChargesAvailable => (int)(boostAvailable / boostDurationSeconds); public float Acceleration => acceleration + BoostActive.Count(b => b.output == Output.Acceleration) * baseOutput; public float Deceleration => deceleration + BoostActive.Count(b => b.output == Output.Deceleration) * baseOutput; public float Strafing => strafing + BoostActive.Count(b => b.output == Output.Strafing) * baseOutput; double BoostRegen => (boostMax / boostFullChargeSeconds) * Time.fixedDeltaTime; public void Reset() { acceleration = initialAcceleration; deceleration = initialDeceleration; strafing = initialStrafing; BoostActive = new(); boostProgress = 0f; shieldMax = initialShieldMax; shieldCurrent = initialShieldMax; } public bool Deploy(Output output) { if (boostAvailable < boostDurationSeconds) return false; BoostActive.Add((output, Time.timeAsDouble + boostDurationSeconds)); boostAvailable -= boostDurationSeconds; if (output == Output.Shield) ShieldsBoost(); return true; } public void Tick() { if (boostProgress <= 0f) BoostActive.Clear(); // remove expired boosts BoostActive = BoostActive.Where(b => b.expiresAt > Time.timeAsDouble).ToList(); double delta = BoostActive.Count switch { // if there are no boosts active we can increase the store 0 => BoostRegen, // if there are active boosts we deplete it int count => count * Time.fixedDeltaTime * -1f, }; double next = Math.Min(boostProgress + delta, boostMax); boostProgress = Math.Max(0f, next); if (delta > 0f) boostAvailable = boostProgress; ShieldsSetMax(); shieldCurrent = Math.Min(shieldCurrent + ShieldRegen, shieldMax); } // returns whether shield depleted public bool ShieldReduce(float amt) { shieldCurrent = shieldCurrent - amt; return shieldCurrent < 0f; } void ShieldsBoost() { ShieldsSetMax(); shieldCurrent = Math.Min(shieldCurrent + shieldBoostIncrease, shieldMax); } void ShieldsSetMax() { shieldMax = initialShieldMax + BoostActive.Count(b => b.output == Output.Shield) * shieldBoostAmount; } }