Admin: install parts, set time and weather; join without prompt

- VEHICLE: INSTALL for parts that are not installed - runs the game's own
  assembly (trigger "Assembly" like on load), so the part sits exactly on its
  pivot; synced to other players via FsmSync (MSCO_INSTALL)
- WORLD: time buttons (2-hour steps via the sun FSM's load path) and
  CLEAR / RAIN / THUNDERSTORM (weather front moved above the admin);
  sent to everyone as mod message "msco.world" (no server update needed)
- JOIN from the server browser/website connects right away in the main menu;
  server mods still ask before downloading

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 13:04:27 +02:00
co-authored by Claude Opus 5.5
parent 06df8fecc5
commit 4be6b68f25
7 changed files with 384 additions and 4 deletions
+39 -2
View File
@@ -578,9 +578,22 @@ namespace MSCO
float right = row.xMax;
if (RightButton(ref right, row, 66, "BREAK", danger)) { VehicleAdmin.Break(p); mp.VehicleCheat("broke " + p.Name + " (testing)"); }
if (RightButton(ref right, row, 70, "REPAIR", secondary)) { VehicleAdmin.Repair(p); mp.VehicleCheat("repaired " + p.Name); }
if (!installed)
{
// nicht eingebaut: statt der Schrauben-Knöpfe INSTALL (setzt das Teil auf seinen Halter)
if (RightButton(ref right, row, 154, "INSTALL", primary, p.CanInstall))
{
string error = VehicleAdmin.Install(p);
if (error == null) mp.VehicleCheat("installed " + p.Name);
else Log(p.Name + ": " + error);
}
}
bool bolts = p.HasBolts && installed;
if (RightButton(ref right, row, 72, "LOOSEN", secondary, bolts)) { VehicleAdmin.SetBolts(p, false); mp.VehicleCheat("loosened " + p.Name); }
if (RightButton(ref right, row, 76, "TIGHTEN", secondary, bolts)) { VehicleAdmin.SetBolts(p, true); mp.VehicleCheat("tightened " + p.Name); }
if (installed)
{
if (RightButton(ref right, row, 72, "LOOSEN", secondary, bolts)) { VehicleAdmin.SetBolts(p, false); mp.VehicleCheat("loosened " + p.Name); }
if (RightButton(ref right, row, 76, "TIGHTEN", secondary, bolts)) { VehicleAdmin.SetBolts(p, true); mp.VehicleCheat("tightened " + p.Name); }
}
// Verschleiß
float wearX = row.x + 410;
@@ -632,6 +645,30 @@ namespace MSCO
/// <summary>Welt zurücksetzen, Backups anlegen und wiederherstellen (dedizierter Server).</summary>
void DrawAdminWorld(MultiplayerManager mp)
{
// Uhrzeit: je 2 Stunden ein Knopf (so schaltet das Spiel die Tageszeit)
int hour = WorldAdmin.CurrentHour;
GUILayout.Label("TIME" + (hour >= 0 ? " (now " + hour.ToString("00") + ":00 - " + ((hour + 2) % 24).ToString("00") + ":00)" : ""), caption);
Rect hours = GUILayoutUtility.GetRect(10, 30, GUILayout.ExpandWidth(true));
float hw = (hours.width - AdminGap * 11) / 12f;
for (int i = 0; i < 12; i++)
{
int h = i * 2;
if (GUI.Button(new Rect(hours.x + i * (hw + AdminGap), hours.y, hw, 28), h.ToString("00") + ":00", hour == h ? chipOn : chipOff))
mp.WorldCheat(WorldAdmin.KindHour, h);
}
GUILayout.Space(8);
int weatherNow = WorldAdmin.CurrentWeather;
GUILayout.Label("WEATHER" + (weatherNow >= 0 ? " (now " + WorldAdmin.WeatherNames[weatherNow] + ")" : ""), caption);
Rect wr = GUILayoutUtility.GetRect(10, 34, GUILayout.ExpandWidth(true));
float ww = (wr.width - AdminGap * 2) / 3f;
string[] labels = { "CLEAR", "RAIN", "THUNDERSTORM" };
for (int i = 0; i < 3; i++)
if (GUI.Button(new Rect(wr.x + i * (ww + AdminGap), wr.y, ww, 32), labels[i], weatherNow == i ? primary : secondary))
mp.WorldCheat(WorldAdmin.KindWeather, i);
GUILayout.Label("Rain and thunder start right above you. Everyone gets the same time and weather.", small);
GUILayout.Space(14);
if (!mp.IsDedicated)
{
GUILayout.Label("World reset and save backups are only available on a dedicated server.", small);