Own MSC-style player figure instead of cloned NPCs; stop objects flung away by physics

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 23:28:43 +02:00
co-authored by Claude Opus 5.5
parent 24cd485bcc
commit e050712c0d
6 changed files with 172 additions and 496 deletions
+21
View File
@@ -63,6 +63,7 @@ namespace MSCO
const float ReleaseAfterStill = 1f;
const float SnapDistance = 10f;
const float RemoteTimeout = 3f; // Besitzer meldet sich nicht mehr (z.B. Teil wurde dort montiert)
const float RunawaySpeed = 90f; // m/s - schneller fährt in MSC nichts; darüber hat die Physik es weggeschleudert
const float HandoverCooldown = 3f; // nach Freigabe/Übergabe keine Übernahme durch Bewegung
const float MaxHoldDistance = 1.5f; // gehaltene Items sind so nah an der Kamera
const float VehicleClaimSpeed = 0.7f; // Fahrzeuge erst ab echter Bewegung übernehmen (nicht Federn)
@@ -245,6 +246,7 @@ namespace MSCO
if (!b.Rb.gameObject.activeInHierarchy) continue;
bool active = b == held || b == driven;
if (!IsRemoteOwned(b)) StopRunaway(b);
if (b.OwnerId == SyncedBody.NoOwner)
{
if (active) Claim(b, true);
@@ -461,6 +463,25 @@ namespace MSCO
}
}
/// <summary>
/// Wird ein Objekt von der Physik weggeschleudert (z.B. nach dem Setzen einer Position, die im Boden lag),
/// sofort anhalten und auf die letzte gute Position zurücksetzen - statt es quer über die Karte fliegen zu lassen.
/// </summary>
void StopRunaway(SyncedBody b)
{
Rigidbody rb = b.Rb;
if (rb.isKinematic || rb.velocity.sqrMagnitude < RunawaySpeed * RunawaySpeed) return;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
if (IsLocal(b) && b.LastSentTime > 0f && IsValidPose(b.LastSentPos, b.LastSentRot))
{
rb.transform.position = AboveGround(b.LastSentPos, rb.transform);
rb.transform.rotation = b.LastSentRot;
}
else rb.transform.position = AboveGround(rb.position, rb.transform);
ModConsole.Warning("[MSCO] Stopped " + b.RootName + " - it was flung away by the physics");
}
/// <summary>Position innerhalb der Karte, Drehung gültig (gleiche Regel wie auf dem Server).</summary>
static bool IsValidPose(Vector3 p, Quaternion q)
{