initial commit
This commit is contained in:
commit
d701598350
67 changed files with 9351 additions and 0 deletions
48
Outnumbered/Domain/SurvivalEconomy.cs
Normal file
48
Outnumbered/Domain/SurvivalEconomy.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using Outnumbered.Config;
|
||||
|
||||
namespace Outnumbered.Domain;
|
||||
|
||||
// Pure survival run-economy + escalation curves. The wave state machine + run banking stay engine-side; this owns the
|
||||
// numbers they read.
|
||||
public static class SurvivalEconomy
|
||||
{
|
||||
// Bots ALIVE at once this wave (simultaneous pressure), ramping from AliveBase to AliveCap.
|
||||
public static int AliveForWave(int wave, SurvivalConfig c) =>
|
||||
Math.Clamp(c.AliveBase + c.AlivePerWave * (wave - 1), 1, c.AliveCap);
|
||||
|
||||
// Total kills to clear a wave.
|
||||
public static int WaveBudget(int wave, int aliveHumans, SurvivalConfig c) =>
|
||||
Math.Max(1, c.BudgetBase + c.BudgetPerWave * (wave - 1) + c.BudgetPerPlayer * aliveHumans);
|
||||
|
||||
// Monotonic escalate-only handicap floor in t-space; -1 = no floor (idle / between runs).
|
||||
public static double HandicapFloor(int wave, SurvivalConfig c) =>
|
||||
// wave>=1 and Max(1,MaxNerfWave)>=1 => quotient>=0, so the lower clamp can never bind; Min(1,x) == Clamp(x,0,1) here.
|
||||
wave <= 0 ? -1.0 : Math.Min(1.0, wave / (double)Math.Max(1, c.MaxNerfWave));
|
||||
|
||||
// Per-wave XP multiplier: ramps exponentially from x1 (wave 1) to xWinMult (the final wave). WinMult is the single
|
||||
// knob (the FINAL-wave / "win" multiplier). Back-loaded by design so early waves pay ~nothing and the last few pay big.
|
||||
// waveMult(w) = WinMult ^ ((w-1)/(WaveCount-1))
|
||||
public static double WaveMult(int wave, SurvivalConfig c) =>
|
||||
Math.Pow(c.WinMult, (wave - 1) / (double)Math.Max(1, c.WaveCount - 1));
|
||||
|
||||
// XP granted at the END of ONE cleared wave: raw wave XP (HP-damage + HS/crit, already xp_mult-card-scaled when banked)
|
||||
// x prestige x the wave multiplier. NO per-run cap, NO XpBoost stat, NO handicap mult here — depth is the gate (you must
|
||||
// survive + contribute to reach the big back-wave multipliers), and the handicap mult stays excluded so run XP can't
|
||||
// re-couple to gameable K/D. 0 for a non-positive wave.
|
||||
public static long WaveXpLump(double rawWaveXp, int wave, int prestige, SurvivalConfig c, ProgressionConfig p)
|
||||
{
|
||||
if (rawWaveXp <= 0) return 0;
|
||||
double lump = rawWaveXp * ProgressionModel.PrestigeXpMultiplier(prestige, p) * WaveMult(wave, c);
|
||||
return (long)Math.Floor(lump);
|
||||
}
|
||||
|
||||
// Raw combat XP banked into the CURRENT wave's accumulator, scaled by the xp_mult card (so it compounds with the
|
||||
// per-wave prestige x waveMult chain applied at grant time).
|
||||
public static double AccrueWaveXp(double amount, double xpMultCardPct) =>
|
||||
amount * (1.0 + xpMultCardPct / 100.0);
|
||||
|
||||
// Team-card squad multiplier (compounding): global_deal increases, global_take decreases.
|
||||
public static double TeamMult(int level, double perPickPct, bool increase) =>
|
||||
increase ? Math.Pow(1.0 + perPickPct / 100.0, level)
|
||||
: Math.Pow(Math.Max(0.0, 1.0 - perPickPct / 100.0), level);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue