Alte Transporter neuladen.
Es ist schwierig, nach Aenderungen an /std/transport die
erbenden Transporter zu aktualisieren. Daher prueft der
traveld einmal am Tag die ihm bekannten Transporter.
Ist deren Programm aelter als das von /std/transport,
wird versucht, ihn neu zu laden.
Hierbei wird bei Spielern im Transporter natuerlich
gewartet und bei sonstigem Krempel bis zu 3 Stunden.
Geclonte Transporter werden nicht neugeladen. Es kann
allerdings sein, dass VC-Transporter Probleme machen.
Generell waere es vorstellbar, dass einzelne Transporter
nicht kompatibel zu diesem Verfahren sind.
Change-Id: Ia16eb923e0281216d6d249a1caef06627ab845e1
diff --git a/p/daemon/traveld.c b/p/daemon/traveld.c
index fd9f843..aff17c8 100644
--- a/p/daemon/traveld.c
+++ b/p/daemon/traveld.c
@@ -70,6 +70,9 @@
#define MEMORY "/secure/memory"
+// Propertyname zum Speichern der Reloadversuchszaehler
+#define RELOAD_TRIES "p_lib_reload_try_counter"
+
// Key: string Schiff.
// Value0: string* Haefen, die von <Schiff> angefahren werden.
mapping transporters = ([]);
@@ -103,12 +106,72 @@
if (MEMORY->Save("transporters",transporters) != 1)
raise_error("Could not save memory to /secure/memory.");
}
- set_next_reset(10800);
+ set_next_reset(86400);
+}
+
+protected void reload_transporters(object *ships)
+{
+ if (!sizeof(ships))
+ return;
+ else if (sizeof(ships) > 1)
+ call_out(#'reload_transporters, 45, ships[1..]);
+
+ object s = ships[0];
+ if (s)
+ {
+ object *inv = all_inventory(s);
+ if (sizeof(inv))
+ {
+ // Wenn Spieler drin sind, muss auf jeden Fall gewartet werden.
+ // Bei sonstigem Krempel nur dann, wenn wir das noch nicht oft genug
+ // erfolglos versucht haben.
+ // Bemerkung: eigentlich muesste man hier pruefen, was davon per
+ // AddItem() erzeugt wurde. Das ist mir gerade aber zu aufwendig.
+ if (sizeof(filter(inv, #'query_once_interactive))
+ || s->QueryProp(RELOAD_TRIES) < 3)
+ {
+ s->SetProp(RELOAD_TRIES, s->QueryProp(RELOAD_TRIES) + 1);
+ // naechsten reset vorziehen
+ set_next_reset(10800);
+ return;
+ }
+ // ansonsten ist uns das Inventar jetzt egal und bald Schrott...
+ }
+ string sname = object_name(s);
+ s->remove(1);
+ load_object(sname);
+ // Und hoffentlich starten Transporter selber. Wenn nicht, muss hier evtl.
+ // noch nen Continue hin.
+ }
}
public void reset()
{
+ set_next_reset(86400);
+ // Zeit des Programms vom Standardtransporter herausfinden. Wenn der nicht
+ // geladen ist, muss nix gemacht werden.
+ object std_transport = find_object("/std/transport");
+ if (!std_transport)
+ return;
+ int std_time = program_time(std_transport);
+ // ueber alle Transporter laufen. Wenn der Transport aelter ist als
+ // /std/transport, wird er neu gelauden.
+ // Das kann Nebenwirkungen haben. Aber in diesem Fall sollte man besser
+ // den Transporter so bauen, dass es OK ist.
+ // Aber speziell bei VC-Transportern ist fraglich, wie gut das
+ // funktioniert...
+ // Und es funktioniert nur fuer Blueprints.
+ object *old_ships = map(transporters, function object (string sname)
+ {
+ object ship = find_object(sname);
+ if (ship && !clonep(ship) && program_time(ship) < std_time)
+ return ship;
+ return 0;
+ } );
+ old_ships -= ({0});
+ if (sizeof(old_ships))
+ reload_transporters(old_ships);
}
varargs int remove(int s)