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