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; float shieldRegen = 10f; // * 100 ticks per second = 5s fully recharge public float Shield => shieldCurrent; public float ShieldMax => shieldMax; public string ShieldPct => $"{((shieldCurrent / shieldMax) * 100f):0}"; float ShieldRegen => boostActive.Count switch { 0 => (shieldMax / 5f) * Time.fixedDeltaTime, _ => 0f, }; // Boost List<(Output output, double expiresAt)> boostActive = new(); static double boostFullChargeSeconds = 10f; static double boostDurationSeconds = 2f; double boostMax = 2f * boostDurationSeconds; double boostAvailable = 0f; // in seconds public string BoostAvailable => $"{boostAvailable / 2f:0.0}"; // public string BoostAvailable => $"{((boostAvailable / boostMax) * 100f):0}"; 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(); boostAvailable = 0f; shieldMax = initialShieldMax ; shieldCurrent = initialShieldMax; } public void Deploy(Output output) { if (boostAvailable < boostDurationSeconds * (boostActive.Count + 1)) return; boostActive.Add((output, Time.timeAsDouble + boostDurationSeconds)); } public void Tick() { // 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(boostAvailable + delta, boostMax); boostAvailable = Math.Max(0f, next); shieldMax = initialShieldMax + boostActive.Count(b => b.output == Output.Shield) * 1000f; shieldCurrent = Math.Min(shieldCurrent + ShieldRegen, shieldMax); } // returns whether shield depleted public bool ShieldReduce(float amt) { shieldCurrent = shieldCurrent - amt; return shieldCurrent < 0f; } }