blob: b293382c2e7289507cf453e077513980d2ff2f4a [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001#pragma strong_types,save_types
2#pragma no_clone,no_shadow
3
4#include <wizlevels.h>
5
6#define DB_NAME "/p/daemon/save/routingd"
7#define MAX_LEN 50
8#define TP this_player()
9
10mapping domains;
11mapping exits;
12mapping targets;
13static mapping directions;
14static mapping reverse_directions;
15
16void create() {
17 seteuid(getuid());
18 if (!restore_object(DB_NAME)) {
19 domains=(["/d/":1]);
20 exits=([]);
21 targets=([]);
22 }
23
24 // Umsetzung zur Speicherersparnis:
25 directions=(["norden":1,
26 "nordosten":2,
27 "osten":3,
28 "suedosten":4,
29 "oben":5,
30 "sueden":-1,
31 "suedwesten":-2,
32 "westen":-3,
33 "nordwesten":-4,
34 "unten":-5
35 ]);
36 reverse_directions=([1:"norden",
37 2:"nordosten",
38 3:"osten",
39 4:"suedosten",
40 5:"oben",
41 -1:"sueden",
42 -2:"suedwesten",
43 -3:"westen",
44 -4:"nordwesten",
45 -5:"unten"
46 ]);
47}
48
49// Fuer Debug-Zecke:
50mixed query_exits(string room) {return exits[room];}
51mixed query_targets(string typ) {return targets[typ];}
52
53int AddDomain(string dom, int val) {
54 // Fuegt neue Domain hinzu, in der Routing moeglich sein soll.
55 // +1: Einschliessen
56 // -1: Ausschliessen
57 if (!IS_ARCH(TP)
58 || val<-1
59 || val>1)
60 return 0;
61 if (!val)
62 domains=m_copy_delete(domains,dom);
63 else
64 domains[dom]=val;
65 save_object(DB_NAME);
66 return 1;
67}
68
69int RegisterTarget(string type, string fname) {
70 // Registriert Raum als zu einer Gruppe von Zielen zugehoerig
71 // (z.B. RegisterTarget("pub","/d/ebene/room/PortVain/pub2"))
72 mapping map_ldfied;
73
74 if (!type || !fname)
75 return 0;
76 type=lower_case(type);
77 if (type[0..1]!="##")
78 type="##"+type;
79 if (!mappingp(map_ldfied=targets[type]))
80 map_ldfied=([]);
81 map_ldfied[fname]=1;
82 targets[type]=map_ldfied;
83 return 1;
84}
85
86int RegisterExit(string start, mixed richtungen, string ziel) {
87 // Registriert Ausgang in der angegebenen Richtung von Start nach Ziel,
88 // wenn Routing dort moeglich sein soll.
89 string *dirs;
90 int i,sz,ok,pos;
91 mixed ex,x,richtung;
92
93 if (stringp(richtungen))
94 richtungen=({richtungen});
95 if (!start || !pointerp(richtungen) || !ziel)
96 return 0;
97 dirs=old_explode(start,"/");sz=sizeof(dirs)-1;x="/";ok=0;
98 for (i=0;i<sz;i++) {
99 x=x+dirs[i]+"/";
100 if (domains[x]==-1) // Subdomain ausgeschlossen?
101 return 0;
102 if (domains[x]==1) // Domain erlaubt?
103 ok=1;
104 }
105 if (!ok)
106 return 0;
107
108 if (!pointerp(ex=exits[start])) {
109 if (file_size(start+".c")<=0) // Beim ersten Ausgang auf VC testen
110 return 0; // Keine Virtual Compiler Raeume routen
111 ex=({});
112 }
113 for (i=sizeof(richtungen)-1;i>=0;i--) {
114 richtung=richtungen[i];
115 if (!(x=directions[richtung]))
116 x=richtung;
117
118 pos=member(ex,x);
119 if (pos>=0 && pos+1<sizeof(ex)) // Richtung schon eingetragen?
120 ex[pos+1]=ziel; // Wurde umdefiniert
121 else
122 ex+=({x,ziel}); // ({ richtung, ziel })
123 }
124 exits[start]=ex;
125 return 1;
126}
127
128// Low-Level FindRoute :-)
129mapping do_find_route(string start, mapping is_target) {
130 mapping erreicht;
131 int i,j,k;
132 mixed *newx, *actx, ex;
133 string room, dir, x;
134
135 erreicht=([start:"##START"]);
136 newx=({start});
137 for (k=MAX_LEN;k>=0;k--) {
138 actx=newx; // In diesem Schritt die neu erreichten Raeume pruefen
139 newx=({}); // Noch keine Raeume neu erreicht
140 for (i=sizeof(actx)-1;i>=0;i--) {
141 room=actx[i];
142 // printf("%O\n",room);
143 if (!pointerp(ex=exits[room]))
144 continue;
145 // printf("-> %O\n",ex);
146 for (j=sizeof(ex)-1;j>=1;j-=2) {
147 x=ex[j]; // Zielraum
148 // printf("-> %O\n",x);
149 if (!erreicht[x]) { // Wurde bisher noch nicht erreicht
150 erreicht[x]=({room,ex[j-1]});
151 if (is_target[x]) { // Ein Ziel wurde erreicht
152 erreicht["##ZIEL"]=erreicht[x]; // Kann ja auch Gruppe sein
153 return erreicht;
154 }
155 newx+=({x});
156 }
157 }
158 }
159 }
160 return 0;
161}
162
163varargs mixed FindRoute(string start, string ziel, int etyp) {
164 mapping res,ziele;
165 string x;
166 mixed ex,r,result;
167 int k;
168
169 if (!start || !ziel)
170 return 0;
171 if (!mappingp(ziele=targets[ziel]))
172 ziele=([ziel:1]);
173 if (!mappingp(res=do_find_route(start, ziele)))
174 return 0; // nicht gefunden
175 if (etyp)
176 result=({});
177 else
178 result=([]);
179 x="##ZIEL";
180 for (k=MAX_LEN+2;k>=0;k--) {
181 ex=res[x];
182 if (ex=="##START") // Fertig.
183 return result;
184 if (!(r=reverse_directions[ex[1]])) // richtige Richtungen eintragen.
185 r=ex[1];
186 x=ex[0];
187 if (etyp)
188 result=({r})+result;
189 else
190 result[x]=r;
191 }
192 return 0;
193}
194
195void save() {
196 save_object(DB_NAME);
197}
198
199void reset() {
200 set_next_reset(43200); // Alle 12 Stunden speichern reicht
201 save();
202}