CONCEPT:
uhr
BESCHREIBUNG:
Fuer die Steuerung von Tag und Nacht, sowie einigen anderen Dingen
gibt es die Muduhr. Ihr Filename ist UHR, was in uhr.h definiert
ist.
Die Uhr verwaltet im wesentlichen drei Dinge:
* die Zeitansage zu jeder vollen RL-Stunde
* Funktionen zur Pruefung, ob ein Spieler sich gerade in einem
Raum mit Tag oder mit Nacht befindet (Zeitzonenverwaltung)
* Ansage von Tag-Nachtwechsel und dabei Meldungen an
Files fuer die verschiedenen Zeitzonen (siehe auch uhr.change(WL))
weiterhin enthaelt sie noch ein paar Funktionen, die einem die
Berechnungen im Zusammenhang mit Zeiten vereinfachen sollen.
Zunaechst werden hier die aufrufbaren Funktionen vorgestellt, die
nicht alle einzeln dokumentiert wurden, danach ist der interne Ablauf
der Uhr erlaeutert.
Folgernde Funktionen liefern in irgendeiner Art zurueck, ob ein
Spieler sich in einem Raum befindet, der gerade Tag bzw Nacht hat:
varargs public string GetLighting(mixed mix)
liefert "Tag" oder "Nacht"
varargs public int IsNight(mixed mix)
liefert 1 (fuer Nacht) oder 0
varargs public int QueryState(mixed mix)
liefert den Helligkeitszustand MORN EVEN DUSK DAWN
varargs public time_t QueryDay(mixed mix)
liefert den naechsten Sonnenaufgang im time()-Format
varargs public time_t QueryNight(mixed mix)
dasselbe fuer Sonnenuntergang
varargs public time_t QueryChange(mixed mix)
liefert Auf- oder Untergang; was eher eintritt
Jeder Raum (genauer: jedes Objekt, in dem direkt ein Spieler ist),
wird bei einem Tageszeitwechsel informiert. Dazu ruft die Uhr in
diesem Objekt die entsprechende der folgenden Funktionen auf:
Morgen(), Tag(), Abend() oder Nacht(). Hier koennte man nun eine
spezielle Information an den Spieler ausgeben oder aehnliches.
Bitte beachten, dass die Funktionen nur dann aufgerufen werden, wenn
auch tatsaechlich ein Spieler im Raum anwesend ist. Der Aufruf
erfolgt nach den Zeit- und Lichtwechselansagen der Uhr.
Es ist auch moeglich, Objekte bei der Uhr zur Ansage anzumelden.
Dies kann zB erfolgen, wenn man andere Funktionsnamen verwenden
moechte (bitte moeglichst nicht tun!), oder wenn ein Objekt kein
Raum sondern ein Gegenstand ist.
Bei der Anmeldung wird die Zeitzone des anmeldenden Objektes
verwendet, auch wenn ein anderes Objekt angemeldet wird:
public int add_notify(object ob, int when, mixed fun, int flag)
Im Objekt ob wird die Funktion fun (als String angeben) aufgerufen,
oder die Closure Fun ausgefuehrt, wenn im anmeldenden Objekt
die Tageszeit 'when' erreicht. when kann MORN EVEN DUSK oder DAWN
sein (Sonnenaufgang, -Untergang, Abenddaemmerung, Morgengrauen).
Die Werte sind ebenfalls in uhr.h definiert. Dieses passiert
jedoch _nur_, wenn sich ein Spieler im selben Raum wie ob befindet.
Soll statt der Zeitzone des anmeldenden Objektes die Zone im
gerade aktuellen Raum des angemeldeten Objektes verwendet werden,
so kann in Ausnahmefaellen das flag NOTIFY_ENVTZ gesetzt werden.
Dies sollte jedoch so selten wie moeglich erfolgen.
Werden nicht nur Meldungen ausgegeben, sondern auch andere Dinge
geclont, bewegt oder aehnlich, kann man einen eventuell in
Abwesenheit eines Spielers verstrichenen Wechsel im init() pruefen.
Ist es jedoch (sollte eigentlich nie vorkommen) erforderlich,
dass das Objekt immer informiert wird, auch wenn kein Spieler da
ist, so ist das flag auf NOTIFY_ALWAYS zu setzen. Dieses Flag ist
unter Umstaenden mit NOTIFY_ENVTZ mit '|' zu verknuepfen.
Objekte koennen immer nur eine Funktion fuer jeden Wechsel anmelden;
vor einer Aenderung muss man einen alten Eintrag erst loeschen.
Wird eine Funktion fuer eine bestimmte Wechselzeit angemeldet, so
unterbleibt dann der standardmaessige Aufruf (siehe oben).
public int remove_notify(object ob)
Entfernt das Objekt ob aus der Liste der Objekte, die speziell
informiert werden wollen. Eventuell wird nun wieder der standard-
maessige Aufruf ausgefuehrt.
Funktionen zum Umgang mit Zeiten:
public int get_day_ticks(time_t ticks)
Liefert die zum Zeitpunkt 'ticks' an demselben Tag schon verstrichenen
Sekunden. Nuetzlich um danach mit den Sekundenzahlen Rechenoperationen
durchzufuehren (Notwendig, da '0 ticks' 1 Uhr bzw 2 Uhr ist...)
0.00:00 Uhr -> 0, 23.59:59 -> 86399
public time_t get_0_oclock(time_t ticks)
Liefert 0:00 Uhr des durch 'ticks' bestimmten Tages.
zB: ctime(get_0_oclock(time())) -> Heute, 0 Uhr
Alle anderen Funktionen in der Uhr sind nicht von aussen zu benutzen!
Die interne Funktion der Uhr:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Im Wunderland gibt es Tag und Nacht. Tag und Nacht kann fuer
verschiedene Gebiete verschieden definiert sein; es gibt
Zeitzonen. Ob ein Spieler eine Fackel zum Sehen braucht und so
weiter haengt also von der aktuellen Zeit und der Zeitzone ab,
in der er sich befindet. Welche Zeitzone fuer ein Objekt gilt,
wird wie folgt bestimmt: Ist das Objekt ein Raum, so ist es selbst
zustaendig. Sonst werden die umgebenden Objekte nacheinander darauf
geprueft, ob sie ein Raum sind. Ist keins der umgebenden Objekte
ein Raum, so gilt das ausserste Objekt als zustaendig. (Ein
Raum ist ein Objekt mit der Funktion int_long(), also zB ein
/std/room.c oder ein /std/transport.c.) In dem zustaendigen
Objekt muss P_TIMEZONE gesetzt sein (Default ist TZ_STANDARD).
Um die Meldungen ueber den Sonnenaufgang usw zu erzeugen, wird
fuer jede Zeitzone ein call_out gestartet. Dieser steuert die
Meldungen als auch die Funktionsaufrufe in Objekten, die mit
add_notify() (siehe oben) angemeldet wurden. Wenn ein Aufruf
buggt, wird dies in /log/UHR mitgeloggt und der Eintrag aus der
Liste entfernt. Die Aufrufe werden nach der Textmeldung vorgenommen
und eventuell auch asynchron durchgefuehrt.
Die Meldungen zur vollen Stunde haben einen eigenen call_out, da
nicht unbedingt eine der Zeitzonen mit dem Stundenrythmus ueber-
einstimmt.
Beide call_outs-Versionen 'tasten' sich jeweils an den richtigen
Augenblick heran, indem sie ersteinmal 5 Minuten zu kurz
laufen. Dann tritt die Daemmerung ein und alle 30 Sekunden wird
geprueft, ob die richtige Zeit schon erreicht wurde.
DETAILS:
Die Uhr wurde mit zusaetzlichen Typen programmiert. So ist time_t
ein Define fuer int. Es zeigt jedoch zusaetzlich an, dass der
Wert im Format von time() vorliegt. zone_t ist ein int, der eine
Zonennummer enthaelt und min_t enthaelt eine Minutenanzahl.
Werden Aenderungen an der Uhr vorgenommen, kann die neue Uhr
ohne Notifikations neu gestartet werden, da sie den MEMORY
benutzt.
Eine neue Zeitzone kann temporaer mit AddTZ() eingefuegt werden.
Eine Zeitzone hat solange keinen call_out, wie sie noch niemals
betreten wurde. Soll trotzdem schon ein call_out laufen, kann
sie mit ActivateZone() aktiviert werden. DeactivateZone()
schaltet eine Zone aus. Der aktuelle call_out laeuft noch
weiter, es werden jedoch keine Notifies mehr aufgerufen. Dies kann
in manchen Files zu Problemen fuehren.
SIEHE AUCH:
time(E), IsNight(L), P_TIMEZONE, QueryChange(L), dtime(S), ctime(E),
uhr.change(WL)
|