MSCO 2.9.1: fixes without MSCLoader, admin teleport, MSCO branding
- Own JSON reader (MiniJson) instead of Newtonsoft.Json - the server browser failed with "Could not load System.Runtime.Serialization" once MSCLoader was gone - Mouse cursor visible in admin menu/chat/console (PlayerInMenu) - Intro "Press any key" screen replaced by an MSCO loading screen; hook PlayMakerFSM.Awake too - Join links while the game runs: picked up from MSCO\join.txt (written by the launcher) - Admin menu: TELEPORT tab (home, shop, repair shop, inspection, villages, events, Satsuma) - Window title/icon "MSCO - My Summer Car Online", MSCO logo in the main menu - In-game UI restyled like the keymaster website (rounded cards, pills, glow, slim scrollbars) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,74 @@ namespace MSCO
|
||||
return done > 0 ? "Hunger, thirst, stress, fatigue, bladder and dirt reset" : "Player needs not found (only works in the game)";
|
||||
}
|
||||
|
||||
/// <summary>Teleport-Ziele im Admin-Menü: Anzeigename und Objekt im Spiel.</summary>
|
||||
public static readonly string[][] Places =
|
||||
{
|
||||
new[] { "Home", "YARD" }, new[] { "Shop (Teimo)", "STORE" }, new[] { "Repair shop", "REPAIRSHOP" },
|
||||
new[] { "Inspection", "INSPECTION" }, new[] { "Peräjärvi", "PERAJARVI" }, new[] { "Landfill", "LANDFILL" },
|
||||
new[] { "Dance hall", "DANCEHALL" }, new[] { "Cottage", "COTTAGE" }, new[] { "Cabin", "CABIN" },
|
||||
new[] { "Rally", "RALLY" }, new[] { "Drag race", "DRAGRACE" }, new[] { "Soccer field", "SOCCER" },
|
||||
new[] { "Kilju buyer", "KILJUGUY" }, new[] { "Theatre", "THEATRE" }, new[] { "Satsuma", "SATSUMA" },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Wohin bei einem Teleport-Ziel? Neben das Objekt (Mitte seiner sichtbaren Teile, ein Stück außerhalb, damit man
|
||||
/// nicht im Dach oder in einer Wand landet) und dort auf den Boden.
|
||||
/// </summary>
|
||||
public static bool FindPlace(string objectName, out Vector3 position)
|
||||
{
|
||||
position = Vector3.zero;
|
||||
GameObject root = FindRoot(objectName);
|
||||
if (root == null) return false;
|
||||
|
||||
Bounds bounds = new Bounds(root.transform.position, Vector3.zero);
|
||||
bool any = false;
|
||||
foreach (Renderer r in root.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
if (r == null || r.bounds.size == Vector3.zero) continue;
|
||||
if (!any) { bounds = r.bounds; any = true; }
|
||||
else bounds.Encapsulate(r.bounds);
|
||||
}
|
||||
|
||||
Vector3 center = bounds.center;
|
||||
float ox = Mathf.Min(bounds.extents.x, 25f) + 3f, oz = Mathf.Min(bounds.extents.z, 25f) + 3f;
|
||||
Vector3[] candidates =
|
||||
{
|
||||
center + new Vector3(ox, 0f, 0f), center + new Vector3(-ox, 0f, 0f),
|
||||
center + new Vector3(0f, 0f, oz), center + new Vector3(0f, 0f, -oz), center,
|
||||
};
|
||||
foreach (Vector3 c in candidates)
|
||||
{
|
||||
Vector3 ground;
|
||||
if (Ground(c, bounds.max.y + 30f, out ground)) { position = ground; return true; }
|
||||
}
|
||||
position = center;
|
||||
return true;
|
||||
}
|
||||
|
||||
static GameObject FindRoot(string name)
|
||||
{
|
||||
GameObject go = GameObject.Find(name);
|
||||
if (go != null) return go;
|
||||
// auch ausgeblendete Objekte (das Spiel schaltet entfernte Orte ab)
|
||||
foreach (GameObject candidate in Resources.FindObjectsOfTypeAll<GameObject>())
|
||||
if (candidate.name == name && candidate.transform.parent == null && candidate.hideFlags == HideFlags.None) return candidate;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Höchster fester Boden unter einem Punkt (ohne Trigger).</summary>
|
||||
static bool Ground(Vector3 at, float top, out Vector3 ground)
|
||||
{
|
||||
ground = at;
|
||||
bool found = false;
|
||||
foreach (RaycastHit hit in Physics.RaycastAll(new Vector3(at.x, top, at.z), Vector3.down, 1000f))
|
||||
{
|
||||
if (hit.collider == null || hit.collider.isTrigger || hit.normal.y < 0.6f) continue;
|
||||
if (!found || hit.point.y > ground.y) { ground = hit.point; found = true; }
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>Eigenen Spieler an eine Position setzen (etwas darüber, damit er nicht im Boden steckt).</summary>
|
||||
public static bool Teleport(Transform player, Vector3 position)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user