blob: bf2ca56a6e7c071608d6d7e91e1df6f4ba85ca1b [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001/*
2 * queue.c -- Eine Schlange, an der man anstehen kann
3 *
4 * (c) 1994 Wargon@MorgenGrauen
5 *
6 */
7
8#include <properties.h>
9#include <defines.h>
10#include <wizlevels.h>
11#include <moving.h>
12#include "queue.h"
13
14#define TP this_player()
15
16inherit "std/thing/moving";
17inherit "std/room";
18
19static mapping peopleInQueue;
20static object lastMoved;
21
22/* Spielerkommendos */
23static int anstellen(string str);
24static int draengeln(string str);
25
26/* Spieler in Schlange einfuegen/aus Schlange entfernen */
27static void enqueue(object ob);
28private void leaveQueue(object ob, int silent);
29
30private object *queuedPeople();
31private int queueScan();
32private object adjust(int thresh);
33
34/* werden bei "schlafe ein" bzw. "ende" aufgerufen */
35void BecomesNetDead(object player);
36void PlayerQuit(object player);
37
38create()
39{
40 if (IS_BLUE(this_object())) return;
41
42 ::create();
43
44 SetProp( P_INDOORS, 1 );
45 SetProp( P_LIGHT, 1 );
46 SetProp( P_GENDER, FEMALE );
47
48 SetProp( P_SHORT, "Eine Schlange" );
49 SetProp( P_LONG, "Du siehst eine Schlange.\n" );
50 SetProp( P_INT_SHORT, "In der Schlange" );
51 SetProp( P_INT_LONG, "Du stehst in einer Schlange.\n" );
52 SetProp( P_NAME, "Schlange" );
53 SetProp( P_TRANSPARENT, 0 );
54
55// Netztote werden beim disconnecten eh aus der Schlange entfernt.
56// Hiermit wird die Ausgabe des Hinweises unterdrueckt.
57 SetProp( P_NETDEAD_INFO, 1 );
58
59 AddId( ({ "queue", "schlange" }) );
60
61 peopleInQueue = ([ ]);
62 lastMoved = 0;
63
64// Defaults setzen
65 SetProp( Q_CYCLE_TIME, 15 );
66 SetProp( Q_DEST, "/gilden/abenteurer" );
67 SetProp( Q_LENGTH, 3 );
68 SetProp( Q_SUSPEND, 0 );
69 SetProp( Q_MSGS, ({ "@@wer@@ ist an der Reihe!", "Du bist jetzt an der Reihe!",
70 "Der Naechste ist an der Reihe, und die anderen ruecken auf.",
71 "Die Schlange rueckt weiter. Sogleich stellt sich jemand neu an." }) );
72
73 AddSpecialExit( "raustreten", "raustreten" );
74
75 AddCmd( ({ "anstellen", "stell", "stelle" }), "anstellen" );
76 AddCmd( ({ "draengeln", "draengle", "draengel", "vordraengeln" }), "draengeln" );
77}
78
79int clean_up(int i) { return 0; }
80
81int
82remove()
83{
84 string *wer;
85 mixed raus;
86 int i;
87
88 while( remove_call_out( "rotate" ) != -1 );
89 while( remove_call_out( "funny" ) != -1 );
90
91 if (clonep(this_object())) {
92 if (!(raus = environment()))
93 raus = "/gilden/abenteurer";
94
95 if (i = sizeof(wer = m_indices(peopleInQueue))) {
96 tell_room(this_object(), "Die Schlange loest sich auf.\n" );
97
98 while ((--i)>0)
99 if (peopleInQueue[wer[i],1])
100 peopleInQueue[wer[i],1]->move(raus, M_GO | M_SILENT | M_NO_SHOW);
101 }
102 }
103 return ::remove();
104}
105
106string
107_query_long()
108{
109 string ret, add;
110 mixed *people, ob;
111 closure n;
112
113 people = filter(all_inventory(this_object()), #'interactive/*'*/);
114
115 ret = Query(P_LONG);
116 add = "In der Schlange stehen " + QueryProp(Q_LENGTH) + " Leute.";
117 if (sizeof(people)) {
118 n = lambda( ({ 'ob }), ({#'call_other, 'ob, "Name", WER}) );
119 people = map(people, n);
120 add += " Unter anderem steh";
121 if (sizeof(people) == 1)
122 add += ( "t dort " + people[0] + "." );
123 else {
124 add += ( "en dort " + implode(people[0..<2], ", ") +
125 " und " + people[<1] + "." );
126 }
127 }
128 return ret + break_string(add, 76);
129}
130
131string
132_query_int_long()
133{
134 string ret, add;
135 int act, cur;
136
137 ret = Query(P_INT_LONG);
138 add = "";
139 act = peopleInQueue[getuid(TP), 0];
140 cur = QueryProp(Q_LENGTH);
141
142 if (act == 0)
143 add += ( "Du bist als naechster an der Reihe. Hinter Dir"
144 +" stehen noch " + (cur - 1) +" Leute an." );
145 else {
146 if (act == 1)
147 add += "Es ist noch jemand vor Dir dran.";
148 else
149 add += ( "Es sind noch " + act + " Leute vor Dir dran." );
150
151 if ((cur = cur - act -1) > 0) {
152 if (cur == 1)
153 add += " Es steht noch jemand hinter Dir.";
154 else
155 add += ( " Hinter Dir stehen noch " + cur +" Leute an." );
156 }
157 }
158 return ret + break_string(add, 76);
159}
160
161int _query_qLength()
162{
163 return Query(Q_LENGTH) + sizeof(filter(all_inventory(this_object()), #'interactive/*'*/));
164}
165
166static int
167anstellen(string str)
168{
169 object tp;
170 string *part;
171
172 if (query_verb() != "anstellen") {
173 notify_fail( "stelle was?\n" );
174 if (!str || str == "")
175 return 0;
176
177 part = old_explode(str, " ");
178 if (part[0] != "an" && part[<1] != "an") {
179 notify_fail( "Syntax: stelle an <schlange> an\n" );
180 return 0;
181 }
182 if (!id(implode(part[1..<2], " ")))
183 return 0;
184 }
185 enqueue(TP);
186 return 1;
187}
188
189static int
190raustreten()
191{
192 if (environment(this_object())) {
193 leaveQueue(TP, 0);
194 return 1;
195 }
196 return 0;
197}
198
199static int
200draengeln(string str)
201{
202 int prob;
203 string *people;
204
205 if (environment(TP) != this_object())
206 return 0;
207
208 prob = random(11);
209
210 if (10 == prob) {
211 say( TP->Name(WER) + " will sich vordraengeln. Zur Strafe wird "
212 +TP->QueryPronoun(WER) +" von der auf-\n"
213 +"gebrachten Menge aus der Schlange hinausgeworfen. Du grinst Dir eins.\n" );
214 write( "Du draengelst Dich vor, wirst aber von der aufgebrachten "
215 +"Menge aus der\nSchlange herausgedraengt.\n" );
216 leaveQueue(TP, 0);
217 }
218 else if (prob < 8) {
219 say( TP->Name(WER) + " will sich vordraengeln.\n" );
220 write( "Du willst Dich vordraengeln.\n" );
221 tell_room(this_object(), sprintf("Es kommen Rufe auf: %s\n",
222 ({ "He! Was soll denn das? Unerhoert!",
223 "Also wirklich! Unverschaemtheit sowas!",
224 "...soll'n das? Mistbacke!",
225 "Jau, soweit kommts noch! Ich glaub' es geht los!",
226 "Wieder mal typisch "+TP->QueryProp(P_RACESTRING)[WER]+"!",
227 "Wenn sich das jeder erlauben wuerde...",
228 "Ne, ne, das geht aber nicht! Mal langsam, "+
229 (TP->QueryProp(P_GENDER)==MALE ? "Buerschchen":"Frollein")+"!",
230 "POLIZEI! HILFAEEEH!!! Also die Jugend von heute..." })[prob] ));
231 say( capitalize(TP->QueryPronoun())+" ueberlegt es sich anders.\n" );
232 write( "Du ueberlegst es Dir anders.\n" );
233 }
234 else {
235 say( TP->Name(WER) + " draengelt sich vor.\n" );
236 write( "Du draengelst Dich vor.\n" );
237 prob = peopleInQueue[getuid(TP)];
238 m_delete(peopleInQueue, getuid(TP));
239 for(people = m_indices(peopleInQueue); sizeof(people); people = people[1..] ) {
240 if(peopleInQueue[people[0],0] < prob)
241 peopleInQueue[people[0],0]++;
242 }
243 peopleInQueue += ([ getuid(TP) : 0; TP ]);
244 }
245 return 1;
246}
247
248static void
249enqueue(object ob)
250{
251 int i;
252
253 if (environment(ob) == this_object()) {
254 say(ob->Name(WER) + " stellt sich wieder hinten an.\n", ob );
255 tell_object(ob, "Du stellst Dich wieder hinten an.\n" );
256
257 i = peopleInQueue[getuid(ob),0];
258 m_delete(peopleInQueue, getuid(ob));
259 adjust(i);
260 peopleInQueue += ([ getuid(ob) : QueryProp(Q_LENGTH)-1; ob ]);
261 }
262 else {
263 peopleInQueue += ([ getuid(ob) : QueryProp(Q_LENGTH); ob ]);
264 ob->move(this_object(), M_NOCHECK, 0, "stellt sich an "+name(WEM)+" an",
265 "stellt sich hinten an");
266 }
267 if (find_call_out("rotate") == -1)
268 call_out("rotate", QueryProp(Q_CYCLE_TIME));
269}
270
271private void
272leaveQueue(object ob, int silent)
273{
274 int i;
275
276 if (silent)
277 ob->move(environment(this_object()), M_NOCHECK | M_SILENT);
278 else
279 ob->move(environment(this_object()), M_NOCHECK, 0, "verlaesst die Schlange",
280 "verlaesst "+name(WEN)+" und steht jetzt neben Dir" );
281
282 i = peopleInQueue[getuid(ob), 0];
283
284 m_delete(peopleInQueue, getuid(ob));
285
286 if (sizeof(peopleInQueue))
287 adjust(i);
288 else {
289 while(remove_call_out("rotate") != -1);
290 while(remove_call_out("funny") != -1);
291 }
292}
293
294private int
295queueScan()
296{
297 string *peop;
298 object act;
299 int i, a;
300
301 peop = m_indices(peopleInQueue);
302
303 for (i=sizeof(peop)-1; i>=0; i--) {
304 if (!objectp(act = peopleInQueue[peop[i],1]) ||
305 (environment(act) != this_object())) {
306 a = peopleInQueue[peop[i], 0];
307 m_delete(peopleInQueue, peop[i]);
308 adjust(a);
309 }
310 }
311
312 return sizeof(peopleInQueue);
313}
314
315private object
316adjust(int thresh)
317{
318 string *peop;
319 object ret;
320 int cnt, i;
321
322 ret = 0;
323 peop = m_indices(peopleInQueue);
324
325 for (i=sizeof(peop)-1; i>=0; i--) {
326 cnt = peopleInQueue[peop[i],0];
327 if (cnt > thresh)
328 cnt--;
329 if (cnt < 0)
330 ret = peopleInQueue[peop[i],1];
331 peopleInQueue[peop[i],0] = cnt;
332 }
333 return ret;
334}
335
336rotate()
337{
338 object ich;
339 string oth, *msgs;
340 int rotating, inDest;
341
342 rotating = 1;
343
344 if (QueryProp(Q_SUSPEND)) {
345 if (lastMoved) {
346 rotating = 0;
347 inDest = (object_name(environment(lastMoved)) == QueryProp(Q_DEST));
348 if (!interactive(lastMoved) || !inDest )
349 rotating = 1;
350 if (interactive(lastMoved) && inDest && environment() && query_idle(lastMoved) > 180) {
351 tell_object(lastMoved, "Du wirst rausgeworfen.\n");
352 lastMoved->move(environment(), M_GO, 0, "idlet herein");
353 rotating = 1;
354 }
355 }
356 }
357 if (rotating) {
358 queueScan();
359 msgs = QueryProp(Q_MSGS);
360 if (ich = adjust(-1)) {
361 oth = implode(explode(msgs[QMSG_OTHER], "@@wer@@"), ich->name(WER) );
362 oth = implode(explode(oth, "@@wessen@@"), ich->name(WESSEN) );
363 oth = implode(explode(oth, "@@wem@@"), ich->name(WEM) );
364 oth = implode(explode(oth, "@@wen@@"), ich->name(WEN) );
365 tell_room(this_object(), capitalize(break_string(oth, 78)), ({ ich }) );
366 tell_object(ich, break_string(msgs[QMSG_ME], 78) );
367 tell_room(environment(), break_string(msgs[QMSG_OUTSIDE], 78) );
368 ich->move(QueryProp(Q_DEST), M_GO);
369 lastMoved = ich;
370 m_delete(peopleInQueue, getuid(ich));
371 if (!sizeof(peopleInQueue))
372 return;
373 }
374 else
375 tell_room(this_object(), break_string(msgs[QMSG_DEFAULT], 78) );
376 }
377
378 if (random(100) < 20)
379 call_out("funny", random(QueryProp(Q_CYCLE_TIME)) );
380
381 call_out("rotate", QueryProp(Q_CYCLE_TIME));
382}
383
384funny()
385{
386 string m;
387
388 switch(random(7)) {
389 case 0:
390 m= "Jemand vor Dir laesst tierisch einen fahren. Seltsamerweise wirft man\n"
391 +"aber Dir missbilligende Blicke zu.\n";
392 break;
393 case 1:
394 m= "Von hinten draengelt wer! Wuetend drehst Du Dich um, schaust hoch, schaust\n"
395 +"hoeher, schaust noch hoeher... und schon ist Deine Wut verflogen!\n";
396 break;
397 case 2:
398 m= "Vor Langeweile popelt jemand vor Dir in der Nase. Das quietschende Ge-\n"
399 +"raeusch laesst Dir das Blut in den Adern gefrieren.\n";
400 break;
401 case 3:
402 m= "Ein fliegender Haendler landet neben der Schlange und bietet Kurzwaren\n"
403 +"feil. Da aber niemand etwas kaufen will, hebt er kurz darauf wieder ab\n"
404 +"und fliegt zu einer anderen Schlange, um dort sein Glueck zu versuchen.\n";
405 break;
406 case 4:
407 m= "Vom hinteren Ende der Schlange sickert das Geruecht durch, dass der\n"
408 +"Schalter heute geschlossen ist. Du hoffst instaendig, dass dies nicht\n"
409 +"wahr ist.\n";
410 break;
411 case 5:
412 m= "Fasziniert beobachtest Du, wie eine Spinne zwischen Deinem Vordermann und\n"
413 +"der Wand ein kunstvolles Netz spinnt.\n";
414 break;
415 case 6:
416 m= "Boah, iss dat langweilich...\n";
417 break;
418 }
419 tell_room(this_object(), m);
420}
421
422void
423BecomesNetDead(object player)
424{
425 if(present(player,this_object()))leaveQueue(player, 0);
426}
427
428void
429PlayerQuit(object player)
430{
431 if(present(player,this_player()))leaveQueue(player, 1);
432}
433