Files
2023-10-02 19:18:36 +11:00

127 lines
4.1 KiB
C#

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 float ShieldMax => shieldMax;
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;
}
}