Verbunden wird nur beim Start ueber die Lobby, bricht die Verbindung ab alle 10 s neu (nicht nach Ablehnung oder Konto-Problem). release.ps1 legt jetzt Gitea-Releases mit bso-release.json an. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
113 lines
4.9 KiB
C#
113 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using BSO.Net;
|
|
|
|
namespace BSO
|
|
{
|
|
/// <summary>
|
|
/// Anzeige oben links: eigene Position (LocalPlayer) und Online-Status mit allen Mitspielern (Multiplayer).
|
|
/// F9 blendet ein/aus, F10 schreibt alle Entities in eine Datei.
|
|
///
|
|
/// Update rechnet (wenn die Engine-Uhr weiterlaeuft), Draw gibt den fertigen Text bei jedem Durchlauf aus - die
|
|
/// Engine zeigt Vision::Message-Text nur fuer einen Durchlauf, sonst flackert die Anzeige.
|
|
/// </summary>
|
|
public static class PositionHud
|
|
{
|
|
const int X = 10, Y = 10, Line = 18;
|
|
|
|
static bool visible = true, rateLogged;
|
|
static int frame;
|
|
static string status = "";
|
|
static byte[][] lines = Array.Empty<byte[]>();
|
|
|
|
static readonly Stopwatch rateClock = Stopwatch.StartNew();
|
|
static int draws;
|
|
|
|
public static void Update()
|
|
{
|
|
frame++;
|
|
if (Input.Pressed(Input.F9)) visible = !visible;
|
|
if (!LocalPlayer.InScene) { lines = Array.Empty<byte[]>(); return; } // Menue / Laden
|
|
if (Input.Pressed(Input.F10))
|
|
{
|
|
Entities.Dump(LocalPlayer.Camera);
|
|
status = "Entities gespeichert: BSO\\entities.txt";
|
|
}
|
|
|
|
// Text nur alle paar Durchlaeufe neu bauen - Draw gibt ihn dazwischen unveraendert aus
|
|
if (frame % 5 != 0 && lines.Length > 0) return;
|
|
PlayerState me = LocalPlayer.State;
|
|
var text = new List<string>
|
|
{
|
|
$"BSO {Bootstrap.ModVersion} [F9] Anzeige [F10] Entities [F11] Vollbild/Fenster",
|
|
me.Mode switch
|
|
{
|
|
PlayerMode.InBus => $"Du: im Bus {LocalPlayer.Bus.Pos} {LocalPlayer.Speed * 0.036f:0} km/h",
|
|
PlayerMode.OnFoot => $"Du: zu Fuss {LocalPlayer.Character.Pos}" + (LocalPlayer.Bus.Valid ? $" Bus {Meters(LocalPlayer.Bus.Pos - LocalPlayer.Character.Pos)} entfernt" : ""),
|
|
_ => "Du: -"
|
|
},
|
|
"",
|
|
};
|
|
AddOnline(text, me);
|
|
if (status.Length > 0) text.Add(status);
|
|
lines = text.ConvertAll(Vision.ToAscii).ToArray();
|
|
}
|
|
|
|
static void AddOnline(List<string> text, PlayerState me)
|
|
{
|
|
switch (Multiplayer.Status)
|
|
{
|
|
case Multiplayer.NetStatus.Offline when Multiplayer.AccountProblem != null:
|
|
text.Add(Multiplayer.AccountProblem);
|
|
return;
|
|
case Multiplayer.NetStatus.Offline when !Config.Current.AutoConnect:
|
|
text.Add("Allein unterwegs - zusammen spielen: im Launcher unter Freunde & Lobby");
|
|
return;
|
|
case Multiplayer.NetStatus.Offline:
|
|
text.Add($"Offline - verbinde gleich neu mit {Multiplayer.ServerDisplay} als {Multiplayer.PlayerName}");
|
|
if (Multiplayer.LastError.Length > 0) text.Add(" " + Multiplayer.LastError);
|
|
return;
|
|
case Multiplayer.NetStatus.Connecting:
|
|
text.Add($"Verbinde mit {Multiplayer.ServerDisplay} ...");
|
|
return;
|
|
}
|
|
if (!Multiplayer.Welcomed)
|
|
{
|
|
text.Add($"Verbinde mit {Multiplayer.ServerDisplay} ... warte auf Server");
|
|
return;
|
|
}
|
|
|
|
string ping = Multiplayer.PingMs >= 0 ? $"{Multiplayer.PingMs} ms" : "...";
|
|
text.Add($"Online: \"{Multiplayer.ServerName}\" ({ping}) - {Multiplayer.Players.Count + 1} Spieler");
|
|
foreach (Multiplayer.Remote p in Multiplayer.Players.Values.OrderBy(p => p.HasState ? p.State.DistanceTo(me) : float.MaxValue))
|
|
{
|
|
if (!p.HasState || p.State.Mode == PlayerMode.Menu) { text.Add($" {p.Name,-16} im Menue"); continue; }
|
|
string mode = p.State.Mode == PlayerMode.InBus ? "Bus " : "zu Fuss ";
|
|
string dist = me.Mode == PlayerMode.Menu ? "" : $"{p.State.DistanceTo(me) / 100,6:0} m";
|
|
text.Add($" {p.Name,-16} {mode} {dist} {p.State.Speed * 0.036f,3:0} km/h");
|
|
}
|
|
}
|
|
|
|
static string Meters(Vec3 d) => $"{d.Length / 100:0} m";
|
|
|
|
public static void Draw()
|
|
{
|
|
CountDraws();
|
|
if (!visible) return;
|
|
byte[][] current = lines;
|
|
for (int i = 0; i < current.Length; i++) Vision.Print(X, Y + i * Line, current[i]);
|
|
}
|
|
|
|
static void CountDraws()
|
|
{
|
|
draws++;
|
|
if (rateLogged || rateClock.ElapsedMilliseconds < 5000) return;
|
|
if (!LocalPlayer.InScene) { draws = 0; rateClock.Restart(); return; } // erst im Spiel messen
|
|
rateLogged = true;
|
|
Bootstrap.Log($"Anzeige: {draws / 5} Durchlaeufe pro Sekunde");
|
|
}
|
|
}
|
|
}
|