+106
@@ -0,0 +1,106 @@
|
||||
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} [F8] Online [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:
|
||||
text.Add($"Offline - [F8] verbinden mit {Multiplayer.ServerAddress}");
|
||||
if (Multiplayer.LastError.Length > 0) text.Add(" " + Multiplayer.LastError);
|
||||
return;
|
||||
case Multiplayer.NetStatus.Connecting:
|
||||
text.Add($"Verbinde mit {Multiplayer.ServerAddress} ...");
|
||||
return;
|
||||
}
|
||||
if (!Multiplayer.Welcomed)
|
||||
{
|
||||
text.Add($"Verbinde mit {Multiplayer.ServerAddress} ... warte auf Server");
|
||||
return;
|
||||
}
|
||||
|
||||
string ping = Multiplayer.PingMs >= 0 ? $"{Multiplayer.PingMs} ms" : "...";
|
||||
text.Add($"Online: \"{Multiplayer.ServerName}\" ({ping}) - {Multiplayer.Players.Count + 1} Spieler [F8] trennen");
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user