| /** Doku: |
| public int AddRoute(string transporter, string* l_stops) |
| Beschreibung: |
| Setzt die aktuelle Route eines Transporters. |
| Die Route hier ist allerdings nur die Liste von Haltepunkten - nicht der |
| Rest, der in den Routen in den Transporter abgelegt ist. |
| Eine neue Route ersetzt immer die bisherige Route |
| Wird von /std/transport gerufen, wenn P_NO_TRAVELING nicht gesetzt ist. |
| Rueckgabewerte: |
| - 1: Transporter und Haltepunkt Eingetragen. |
| - 0: Transporter oder Haltepunkt kein string|string*. |
| - -1: Es wurde versucht einen Transporter in /p/ oder /players/ |
| einzutragen |
| und der Eintragende ist kein EM. |
| |
| public int RemoveTransporter(string|object transporter) |
| public int RemoveStop(string|object stop) |
| Beschreibung: |
| Entfernt einen kompletten Transporter oder einen Haltepunkt aus dem |
| Daemon. |
| Rueckgabewerte: |
| - 1: Erfolg. |
| - 0: Transporter|Haltepunkt existiert nicht. |
| - -1: Keine Berechtigung. |
| |
| public varargs int|object* HasTransporter(object stop, string transporter_id) |
| Beschreibung: |
| Gibt eine Liste der Transporter aus, den den Haltepunkt anlaufen, oder |
| prueft auf einen bestimmten Transporter. |
| Rueckgabewerte: |
| - 0: Haltepunkt ist kein Objekt, dem Haltepunkt sind keine Transporter |
| zugeordnet, |
| die Transporter sind nicht geladen |
| oder, bei angabe von <transporter>: <transporter> faehrt den Hafen |
| nicht an. |
| - object*: Liste mit einem oder mehreren Transportern. |
| Bemerkung: |
| Auch bei der Angabe von <transporter_id> koennen mehrere Objekte |
| zurueckgegeben werden, es wird mittels id() gefiltert. |
| |
| public mixed RouteExists(object transporter, string dest) |
| Beschreibung: |
| Prueft auf korrekte Parameter und leitet die Anfrage an |
| /std/transport weiter. |
| Rueckgabewerte: |
| - 0: <transporter> ist kein Objekt oder <dest> ist kein String. |
| - Das Ergebnis von transporter->HasRoute(dest); |
| |
| public mapping QueryTransporters() |
| public mapping QueryAllStops() |
| public mapping QueryTransporterByStop(string stop) |
| public mapping QueryStopsByTransporter(string transporter) |
| Beschreibung: |
| Gibt das jewilige gefilterte oder ungefilterte Mapping aus. |
| Rueckgabewerte: |
| Mapping mit dem Ergebnis. |
| */ |
| |
| #pragma strong_types,save_types,rtt_checks |
| #pragma pedantic,range_check,warn_deprecated |
| #pragma warn_empty_casts,warn_missing_return,warn_function_inconsistent |
| #pragma no_clone,no_shadow |
| |
| #include <transport.h> |
| #include <wizlevels.h> |
| #include <daemon.h> |
| |
| #define TRANSPORTER 0 |
| #define STOP 1 |
| |
| #define MEMORY "/secure/memory" |
| |
| // Key: string Schiff. |
| // Value0: string* Haefen, die von <Schiff> angefahren werden. |
| mapping transporters = ([]); |
| // Key: string Hafen |
| // Value0: string* Schiffe, die <Hafen> anfahren. |
| mapping stops = ([]); |
| |
| protected void create() |
| { |
| // Vom MEMORY die Daten abholen. |
| // Wenn keine da, war vermutlich Reboot, dann muessen wir warten, bis die |
| // Transporter sich wieder melden. Aber die Mappings muessen ins Memory |
| // geschrieben werden. |
| mapping tmp = MEMORY->Load("stops"); |
| if (mappingp(tmp)) |
| { |
| stops = tmp; |
| } |
| else |
| { |
| if (MEMORY->Save("stops",stops) != 1) |
| raise_error("Could not save memory to /secure/memory."); |
| } |
| tmp = MEMORY->Load("transporters"); |
| if (mappingp(tmp)) |
| { |
| transporters = tmp; |
| } |
| else |
| { |
| if (MEMORY->Save("transporters",transporters) != 1) |
| raise_error("Could not save memory to /secure/memory."); |
| } |
| } |
| |
| varargs int remove(int s) |
| { |
| destruct(this_object()); |
| return 1; |
| } |
| |
| // Loeschfunktion |
| private int _remove_data(string|object key, int what) |
| { |
| mapping first,second; |
| // Erstmal die Arbeitsmappings befuellen. |
| if(what==TRANSPORTER) |
| { |
| first=transporters; |
| second=stops; |
| } |
| else |
| { |
| first=stops; |
| second=transporters; |
| } |
| |
| // Key auf einen String normalisieren. |
| if(objectp(key)) |
| { |
| key=object_name(key); |
| } |
| |
| if(!member(first,key)) |
| { |
| return 0; |
| } |
| |
| // Erstmal aus dem jeweils anderen Mapping austragen. |
| foreach(string s : first[key]) |
| { |
| // Nicht existent oder nicht zugeordnet -> weiter. |
| if(!member(second,s) || member(second[s],key)==-1) |
| { |
| continue; |
| } |
| second[s]-=({key}); |
| if (!sizeof(second[s])) |
| m_delete(second,s); |
| } |
| // Jetzt noch aus dem eigenen Mapping austragen. |
| m_delete(first,key); |
| return 1; |
| } |
| |
| // Ein komplettes Schiff entfernen. |
| public int RemoveTransporter(object|string transporter) |
| { |
| if (extern_call() && !IS_ARCH(getuid(previous_object()))) return -1; |
| return _remove_data(transporter,TRANSPORTER); |
| } |
| |
| // Entfernt einen kompletten Hafen aus dem Daemon |
| public int RemoveStop(object|string stop) |
| { |
| if (extern_call() && !IS_ARCH(getuid(previous_object()))) return -1; |
| return _remove_data(stop,STOP); |
| } |
| |
| // Setzt die aktuelle Route eines Transporters. |
| // Die Route hier ist allerdings nur die Liste von Haltepunkten - nicht der |
| // Rest, der in den Routen in den Transporter abgelegt ist. |
| // Wird von /std/transport gerufen, wenn P_NO_TRAVELING nicht gesetzt ist. |
| public int AddRoute(string transporter, string* l_stops) |
| { |
| if (!stringp(transporter) || !pointerp(l_stops) || !sizeof(l_stops)) |
| return 0; |
| |
| if ((transporter[0..2] == "/p/" || transporter[0..8] == "/players/") |
| && !IS_ARCH(getuid(previous_object()))) |
| { |
| return -1; |
| } |
| |
| // Damit sind alle Abfragen auf find_object(transporter|stop) ueberfluessig, |
| // im Zweifelsfall knallt es naemlich hier. ;-) |
| transporter = object_name(load_object(transporter)); |
| |
| // Wenn die route bereits existiert, austragen. Dies ist noetig, weil die |
| // Haltepunkte ja auch bereinigt werden muessen. |
| if (member(transporters, transporter)) |
| RemoveTransporter(transporter); |
| |
| // Transporter eintragen, die Route wird dabei immer ueberschrieben, wenn |
| // der Transporter schon bekannt ist. Ziel: hier ist immer die aktuell |
| // konfigurierte Route drin. |
| m_add(transporters, transporter, l_stops); |
| |
| // Nach obigen Schema, nur diesmal Haltepunkte und zugehoerige Schiffe |
| // eintragen. |
| foreach(string stop : l_stops) |
| { |
| if (!member(stops,stop)) |
| { |
| m_add(stops, stop, ({transporter})); |
| } |
| else if (member(stops[stop],transporter) == -1) |
| { |
| stops[stop] += ({ transporter }); |
| } |
| } |
| return 1; |
| |
| } |
| |
| // Abfrage ob ein Schiff einen Hafen anfaehrt. |
| public varargs int|object* HasTransporter(object stop, |
| string transporter_id) |
| { |
| if (!objectp(stop)) return 0; |
| |
| <string|object>* trans=stops[object_name(stop)]; |
| if (!pointerp(trans)) return 0; |
| |
| // Eigentlich sollten sich Transporter ordentlich abmelden... Aber zur |
| // Sicherheit die nicht gefundenen Objekte ausfiltern. |
| trans = map(trans, #'find_object) - ({0}); |
| |
| // Wenn ne bestimmte ID gesucht wird, nur diese Transporter liefern. |
| if (stringp(transporter_id)) |
| trans = filter_objects(trans, "id", transporter_id); |
| |
| return sizeof(trans) ? trans : 0; |
| } |
| |
| public mixed RouteExists(object transporter, string dest) |
| { |
| if (!objectp(transporter) || !stringp(dest)) |
| { |
| return 0; |
| } |
| return transporter->HasRoute(dest); |
| } |
| |
| public mapping QueryTransporters() |
| { |
| return deep_copy(transporters); |
| } |
| |
| public mapping QueryAllStops() |
| { |
| return deep_copy(stops); |
| } |
| |
| // Liefert alle Transporter mit ihren Haltepunkten zurueck, die diesen Halt ansteuern. |
| public mapping QueryTransportByStop(string stop) |
| { |
| mapping res=m_allocate(4); |
| foreach(string s, string* arr : transporters) |
| { |
| if(member(arr,stop)!=-1) |
| { |
| m_add(res,s,arr); |
| } |
| } |
| return res; |
| } |
| |
| // Liefert alle Haltepunkte mit ihren Transportern zurueck, die dieser |
| // transporter ansteuert. |
| public mapping QueryStopsByTransporter(string transporter) |
| { |
| mapping res=m_allocate(4); |
| foreach(string s, string* arr : stops) |
| { |
| if(member(arr,transporter)!=-1) |
| { |
| m_add(res,s,arr); |
| } |
| } |
| return res; |
| } |
| |