- Mitspieler als Bus/Spielfigur mit Namensschild, weich bewegt (RemotePlayers, Models) - Ohne gueltiges Spiel-Ticket vom Launcher kein Multiplayer; Name kommt aus dem Konto - Protokoll 2 (Hello mit Ticket), IPv6-Adressen - Nach Szenenwechsel erst nach 3 s neu anlegen (Absturz im Test 0.3.0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
2.7 KiB
C#
70 lines
2.7 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace BSO
|
|
{
|
|
public struct EntityInfo
|
|
{
|
|
public int Slot;
|
|
public nint Ptr;
|
|
public string Class;
|
|
public Vec3 Pos;
|
|
}
|
|
|
|
/// <summary>Alle Entities der Szene (VisBaseEntity_cl) mit Klassenname und Position.</summary>
|
|
public static unsafe class Entities
|
|
{
|
|
public static List<EntityInfo> Scan()
|
|
{
|
|
var list = new List<EntityInfo>();
|
|
if (!Vision.TryGetEntities(out nint* data, out int count)) return list;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
nint e = data[i];
|
|
if (e == 0) continue;
|
|
string cls = Rtti.ClassName(e);
|
|
if (cls == null) continue; // kein gueltiges Objekt - lieber nicht anfassen
|
|
list.Add(new EntityInfo { Slot = i, Ptr = e, Class = cls, Pos = Vision.GetPosition(e) });
|
|
}
|
|
return list;
|
|
}
|
|
|
|
/// <summary>Platz einer Entity in der Tabelle, -1 = nicht (mehr) da.</summary>
|
|
public static int SlotOf(nint ptr)
|
|
{
|
|
if (ptr == 0 || !Vision.TryGetEntities(out nint* data, out int count)) return -1;
|
|
for (int i = 0; i < count; i++) if (data[i] == ptr) return i;
|
|
return -1;
|
|
}
|
|
|
|
/// <summary>Steht in Platz slot noch dasselbe Objekt? Dann lebt es noch und darf gelesen werden.</summary>
|
|
public static bool StillThere(int slot, nint ptr)
|
|
{
|
|
return Vision.TryGetEntities(out nint* data, out int count) && slot < count && data[slot] == ptr;
|
|
}
|
|
|
|
/// <summary>Diagnose (F10): alle Entities nach BSO\entities.txt, naechste zur Kamera zuerst.</summary>
|
|
public static string Dump(Vec3 camera)
|
|
{
|
|
var list = Scan();
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine($"BSO {Bootstrap.ModVersion} - {list.Count} Entities, Kamera bei {camera}");
|
|
sb.AppendLine();
|
|
sb.AppendLine("Klassen:");
|
|
foreach (var g in list.GroupBy(e => e.Class).OrderByDescending(g => g.Count()))
|
|
sb.AppendLine($" {g.Count(),5} {g.Key}");
|
|
sb.AppendLine();
|
|
sb.AppendLine("Platz Abstand Klasse Position");
|
|
foreach (var e in list.OrderBy(e => (e.Pos - camera).Length))
|
|
sb.AppendLine($"{e.Slot,5} {(e.Pos - camera).Length,8:0} {e.Class,-34} {e.Pos}");
|
|
|
|
string file = Path.Combine(Bootstrap.Folder, "entities.txt");
|
|
File.WriteAllText(file, sb.ToString());
|
|
Bootstrap.Log($"{list.Count} Entities nach {file} geschrieben");
|
|
return file;
|
|
}
|
|
}
|
|
}
|