Erweiterte Regeln: in jeder dritten Runde ein neutraler Wächter in jeder Lanemitte; wer beim Fall mehr Einheiten (dann mehr Leben) in 8 m hat, nimmt das Lager: Glutsegen (+10 % Schaden), Mondschild (Schild 10 %), Beute (50 Gold je Spieler). Fog of War (LuneFog, nur Darstellung): Gegner sichtbar in 9 m um eigene Einheiten, 10 m um Gebäude, 12 m um Späher; Späher (40 Gold, 3 Runden, Teamwirkung) zeigen in der Planung die gegnerische Armee ihrer Lane. HUD: Teampanel SPÄHER und LAGER, Lager-Sechseck, Nebel in Feld, Minimap, Namensschildern und Lane-Zählung. Kern 597/597 (s3 31), EditMode 33/33, PlayMode 18/18, Verify 718/0, Selbsttest 30/30, Golden 0, Fingerabdruck unverändert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
5.8 KiB
C#
121 lines
5.8 KiB
C#
namespace Luneraria.Core
|
|
{
|
|
/// <summary>
|
|
/// Every tunable number of Champions of Luneraria (reference: lune_balance.gd with
|
|
/// data/luneraria/balance_default.tres). Tests may use variants; bots never get extras.
|
|
/// </summary>
|
|
public sealed class LuneBalance
|
|
{
|
|
// Simulation
|
|
/// <summary>Fixed combat step in seconds (20 steps per second of combat time).</summary>
|
|
public double SimStep = 0.05;
|
|
/// <summary>Ends only the current combat phase, never the match.</summary>
|
|
public double CombatTimeLimit = 180.0;
|
|
public double MarchSpeedFactor = 1.6;
|
|
public double AggroRadius = 7.0;
|
|
/// <summary>Targets further away than this are dropped and re-acquired.</summary>
|
|
public double LeashRadius = 10.0;
|
|
public double LaneHalfWidth = 2.6;
|
|
|
|
// Economy
|
|
public int StartGold = 220;
|
|
public int BaseIncome = 70;
|
|
public int IncomePerRound = 4;
|
|
public int IncomeGrowthCap = 80;
|
|
public int SupplyCap = 12;
|
|
public double SellRefund = 0.75;
|
|
/// <summary>Share of lane kill gold for the lane player; the rest splits evenly in the team.</summary>
|
|
public double LaneShare = 0.5;
|
|
|
|
// Waves
|
|
public int WaveBaseCount = 3;
|
|
/// <summary>One more monster per lane every N rounds, up to WaveMaxCount.</summary>
|
|
public int WaveCountEvery = 3;
|
|
public int WaveMaxCount = 7;
|
|
public double WaveHpGrowth = 0.11;
|
|
public double WaveDamageGrowth = 0.07;
|
|
public double WaveGrowthQuadratic = 0.0015;
|
|
public double MonsterBountyScale = 2.0;
|
|
public double BountyGrowth = 0.04;
|
|
/// <summary>Monster types in rotation order; later indices unlock later.</summary>
|
|
public string[] MonsterPool = { "e01", "e02", "e04", "e03", "e06", "e05" };
|
|
|
|
// Buildings
|
|
public double TowerOuterHp = 6000.0;
|
|
public double TowerInnerHp = 7500.0;
|
|
public double BaseTowerHp = 9000.0;
|
|
public double CoreHp = 12000.0;
|
|
public double TowerDamage = 90.0;
|
|
public double BaseTowerDamage = 120.0;
|
|
/// <summary>Must exceed the longest unit reach (6.5 m + building radius).</summary>
|
|
public double TowerRange = 8.6;
|
|
public double TowerAttackInterval = 1.0;
|
|
public double BuildingRadius = 1.3;
|
|
public int BountyOuterTower = 150;
|
|
public int BountyInnerTower = 210;
|
|
public int BountyBaseTower = 270;
|
|
|
|
// Map
|
|
public double InnerTowerFraction = 0.17;
|
|
public double OuterTowerFraction = 0.35;
|
|
public double TowerSideOffset = 3.4;
|
|
|
|
// S1: extended rules (MatchOptions.Extended; the reference rules ignore all of these).
|
|
/// <summary>Legion TD 2: a booked attack champion raises the booker's income by cost / this, for good.</summary>
|
|
public int ChampionIncomeDivisor = 12;
|
|
/// <summary>S3: share of a champion's bounty the defenders get under the extended rules (Legion TD 2: less than the send costs).</summary>
|
|
public double ChampionBountyShare = 0.5;
|
|
/// <summary>Dota 2 barracks: waves of a team on a lane whose enemy inner tower fell get stronger.</summary>
|
|
public double BarracksBoost = 0.25;
|
|
public int BarracksExtraMonsters = 1;
|
|
/// <summary>Dota 2 buyback, adapted: a fallen hero starts the next combat exhausted, unless bought back.</summary>
|
|
public double ExhaustedHp = 0.6;
|
|
public int BuybackBase = 60;
|
|
public int BuybackPerLevel = 20;
|
|
/// <summary>League of Legends dragon souls: each grotto victory blesses the team, up to the soul.</summary>
|
|
public double BlessingStep = 0.04;
|
|
public int BlessingMax = 4;
|
|
/// <summary>Moon soul (all stacks): heroes regenerate this share of their health per second.</summary>
|
|
public double SoulRegen = 0.01;
|
|
|
|
// S2: extended rules.
|
|
/// <summary>Dota 2 glyph: a planned lane's towers turn invulnerable for this long once one falls below half health.</summary>
|
|
public double GlyphSeconds = 5.0;
|
|
public double GlyphThreshold = 0.5;
|
|
public int GlyphCooldown = 4;
|
|
/// <summary>Legion TD 2 king: Ancient levels bought by the team's players; price per level, attack and repair per level.</summary>
|
|
public int CoreLevelMax = 3;
|
|
public int CoreLevelPrice = 150;
|
|
public double[] CoreDamage = { 0.0, 45.0, 75.0, 110.0 };
|
|
public double CoreRange = 7.5;
|
|
public double CoreRepair = 1000.0;
|
|
|
|
// S3: neutral camps (League of Legends buff camps) under the extended rules.
|
|
/// <summary>A guardian stands at the middle of every lane in rounds divisible by this.</summary>
|
|
public int CampEvery = 3;
|
|
public double CampHp = 1500.0;
|
|
public double CampDamage = 30.0;
|
|
public double CampRange = 2.5;
|
|
/// <summary>Units within this distance decide which team takes a fallen guardian.</summary>
|
|
public double CampClaimRadius = 8.0;
|
|
/// <summary>Combats a lane buff lasts; Glutsegen damage, Mondschild shield share, Beute gold per player.</summary>
|
|
public int CampBuffRounds = 2;
|
|
public double CampDamageBuff = 0.10;
|
|
public double CampShieldBuff = 0.10;
|
|
public int CampLootGold = 50;
|
|
/// <summary>S3 wards (Dota 2): price and rounds a ward watches its lane.</summary>
|
|
public int WardCost = 40;
|
|
public int WardRounds = 3;
|
|
|
|
public static LuneBalance Default() { return new LuneBalance(); }
|
|
|
|
public int CoreUpgradeCost(int level) { return CoreLevelPrice * (level + 1); }
|
|
|
|
public int BuybackCost(int level) { return BuybackBase + BuybackPerLevel * level; }
|
|
|
|
public int RoundIncome(int roundNumber)
|
|
{
|
|
return BaseIncome + GdMath.Min(IncomeGrowthCap, IncomePerRound * GdMath.Max(0, roundNumber - 1));
|
|
}
|
|
}
|
|
}
|