Hinter MatchOptions.Extended (Standard im Spiel, Schalter im Startbildschirm): Söldner-Einkommen (Angriffschampion +Preis/12 Einkommen dauerhaft), Kasernen (gefallener innerer Turm: Gegnerwellen +25 % und ein Monster mehr), Erschöpfung und Rückkauf (60 % Leben, Rückkauf 60 + 20 x Stufe), Mondsegen (Grottensieg +4 % je Stapel, Mondseele bei 4). Bots wählen mit erweiterten Regeln auch Sylvara und kaufen Helden zurück. Netz überträgt Regeln und neue Zustände. HUD: Einkommen, Kasernen-Symbol, Rückkauf, Segen im Teamkopf. Kern 531/531 (s1 31), EditMode 31/31, PlayMode 16/16, Verify 718/0, Selbsttest 30/30, Golden 0 Abweichungen, Fingerabdruck unverändert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
4.4 KiB
C#
124 lines
4.4 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace Luneraria.Core
|
|
{
|
|
/// <summary>Roles of a session (lune_session.gd Role).</summary>
|
|
public enum LuneRole { Offline, Host, Client }
|
|
|
|
/// <summary>One lobby row: peer 0 is a bot, peer 1 the host.</summary>
|
|
public sealed class LobbyEntry
|
|
{
|
|
public int Peer;
|
|
public int Slot;
|
|
public string Name = "";
|
|
public bool Ready;
|
|
public bool Bot;
|
|
|
|
public LobbyEntry Clone() { return (LobbyEntry)MemberwiseClone(); }
|
|
}
|
|
|
|
/// <summary>Result of a session intent (Godot returns a Dictionary with ok, message, pending).</summary>
|
|
public struct SessionResult
|
|
{
|
|
public bool Ok;
|
|
public string Message;
|
|
public bool Pending;
|
|
|
|
public SessionResult(bool ok, string message, bool pending = false)
|
|
{
|
|
Ok = ok;
|
|
Message = message;
|
|
Pending = pending;
|
|
}
|
|
}
|
|
|
|
/// <summary>One player row of the public state; Draft is set only for the receiving seat.</summary>
|
|
public sealed class NetPlayerRow
|
|
{
|
|
public int Slot;
|
|
public string Name = "";
|
|
public bool IsHuman;
|
|
public int Gold;
|
|
public bool Ready;
|
|
public int Earned;
|
|
public int Spent;
|
|
public int NextSeq;
|
|
public List<RosterEntry> Roster = new List<RosterEntry>();
|
|
public HeroState Hero;
|
|
public List<Booking> Bookings = new List<Booking>();
|
|
/// <summary>Private draft of the receiving seat only; null for every other seat.</summary>
|
|
public Draft Draft;
|
|
/// <summary>Undo stack size of the receiving seat (0 for others).</summary>
|
|
public int Undo;
|
|
/// <summary>S1: permanent champion income (public, like the champion bookings).</summary>
|
|
public int IncomeBonus;
|
|
}
|
|
|
|
/// <summary>Public state of the match for one seat (rpc_state).</summary>
|
|
public sealed class NetState
|
|
{
|
|
public Phase Phase;
|
|
public int Round;
|
|
public int Winner;
|
|
public string EndNote = "";
|
|
public Dictionary<string, double> BuildingHp = new Dictionary<string, double>();
|
|
public BossState Boss = new BossState();
|
|
public Settlement LastSettlement;
|
|
public List<int> DestroyedCores = new List<int>();
|
|
public List<NetPlayerRow> Players = new List<NetPlayerRow>();
|
|
}
|
|
|
|
/// <summary>A mobile unit as it crosses the wire (rpc_combat_begin / rpc_units_spawned).</summary>
|
|
public sealed class NetUnitRecord
|
|
{
|
|
public int Id;
|
|
public string Kind = "";
|
|
public int Team;
|
|
public int TeamIndex;
|
|
public int OwnerSlot = -1;
|
|
public string Uid = "";
|
|
public string Lane = "";
|
|
public string Zone = "";
|
|
public UnitDef Def = new UnitDef();
|
|
public double X;
|
|
public double Y;
|
|
public double Facing;
|
|
public double Hp;
|
|
public double MaxHp;
|
|
public bool Alive;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Outbound session messages (the Godot RPCs). A transport or a test recorder implements this;
|
|
/// without a link the session still runs offline and for in-process host tests.
|
|
/// </summary>
|
|
public interface ILuneNetLink
|
|
{
|
|
/// <summary>Reliable message to one peer (1 = host).</summary>
|
|
void Send(int peer, string kind, object payload);
|
|
/// <summary>Unreliable ordered combat frame to one peer.</summary>
|
|
void SendFrame(int peer, int serial, double elapsed, float[] units, float[] buildingHp);
|
|
}
|
|
|
|
/// <summary>Frames carry 13 floats per mobile unit (lune_session.gd FRAME_STRIDE).</summary>
|
|
public static class LuneNet
|
|
{
|
|
public const int DefaultPort = 24571;
|
|
public const int MaxClients = 5;
|
|
public const int Protocol = 4;
|
|
/// <summary>Seconds between combat snapshots the host sends.</summary>
|
|
public const double FrameInterval = 0.05;
|
|
public const int FrameStride = 13;
|
|
|
|
public const string KHello = "hello";
|
|
public const string KSubmit = "submit";
|
|
public const string KReady = "ready";
|
|
public const string KRefused = "refused";
|
|
public const string KFeedback = "feedback";
|
|
public const string KSetup = "setup";
|
|
public const string KState = "state";
|
|
public const string KLobby = "lobby";
|
|
public const string KCombatBegin = "combat_begin";
|
|
public const string KUnitsSpawned = "units_spawned";
|
|
}
|
|
}
|