blob: 79deec1ae0e2f36a1ff3cf899588d4408ca7a9c5 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// transport.c -- Basisklasse fuer Schiffe und aehnliche Transporter
4//
5// $Id: transport.c 9400 2015-12-11 21:56:14Z Zesstra $
Zesstra@Morgengrauen2315aa12016-10-30 22:36:26 +01006#pragma strong_types,rtt_checks
MG Mud User88f12472016-06-24 23:31:02 +02007#pragma range_check
8#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +02009
10inherit "/std/thing/moving";
11inherit "/std/room";
12
13#include <properties.h>
14#include <moving.h>
15#include <defines.h>
16#include <language.h>
17#include <transport.h>
18#include <regexp.h>
Zesstra179db0d2016-11-26 13:13:41 +010019#include <hook.h>
20
MG Mud User88f12472016-06-24 23:31:02 +020021
22/* transport.c
23 *
24 * Ueberarbeitete und
25 * erweiterte Version : Tilly@MorgenGrauen, 10.01.02
26 * Basierend auf : transport.c@SilberLand (Woody@SilberLand), 05.12.99
27 * Basierend auf : Hates und Rumatas generisches Transport Objekt
28 * MorgenGrauen 15.02.93
29 */
30
31/*
32 ********************* Variablen *********************
33 */
34
35// TODO: langfristig waer ja private schoen...
36//
37// Datenstruktur von 'route' (bei HP_ROOM)
38// 0 ({string ID, : HP_ROOM
39// 1 string room, : Dateiname Zielraum
40// 2 int stay, : Dauer Haltezeit
41// 3 int next, : Dauer naechste Fahrtzeit
42// 4 string code, : Haltestellenname fuer QueryArrived
43// 5 mixed dest, : Haltestellen-IDs fuer HasRoute (reise nach)
44// 6 mixed deststr }): unbenutzt.
45//
46// Datenstruktur von 'route' (bei HP_MSG, HP_FUN)
47// 0 ({string ID, : HP_MSG
48// 1 string message, : Meldung oder string fun : Funktionsname
49// 2 int next}) : Dauer bis zum naechsten Ereignis
50nosave mixed *route; /* Liste der Haltepunkte. */
51nosave int rpos; /* Momentane Position in obiger Liste. */
52nosave string roomCode; /* Code des aktuellen Raumes (oder 0). */
Zesstrae805e3a2018-02-12 19:48:06 +010053// Letzter Spielerkontakt. Das muss != 0 sein (sonst funktioniert der
54// Mechanismus zum Fortsetzen der Route nach einer Pause nicht ordentlich,
55// daher wird es auf 1 initialisiert.
56nosave int meet_last_player = 1;
Zesstra7842b8e2019-07-04 21:55:39 +020057// Dauer der Route
58nosave int route_time;
Zesstra179db0d2016-11-26 13:13:41 +010059
60private void unsubscribe_init();
61private int subscribe_init();
Zesstra72843372018-02-12 21:34:49 +010062void changeHp();
MG Mud User88f12472016-06-24 23:31:02 +020063
64/*
65 ********** Management der builtin-properties **********
66 */
67
68string _query_short()
69{
70 if (roomCode) return Query(P_SHORT);
71 return 0;
72}
73
74mixed _query_transparent()
75{
76 if (roomCode) return Query(P_TRANSPARENT);
77 return 0;
78}
79
Zesstra179db0d2016-11-26 13:13:41 +010080static mixed *_set_route(mixed *r) { return route = r; }
81static mixed *_query_route() { return route; }
82static int _query_mnpc_last_meet() { return meet_last_player; }
MG Mud User88f12472016-06-24 23:31:02 +020083
84/*
85 **************** Zugriffsfunktionen ***************
86 */
87
Zesstra179db0d2016-11-26 13:13:41 +010088public void Halt()
MG Mud User88f12472016-06-24 23:31:02 +020089{
Zesstra179db0d2016-11-26 13:13:41 +010090 // stop, but keep rpos counter.
MG Mud User88f12472016-06-24 23:31:02 +020091 while (remove_call_out( "changeHp" )>-1);
92 while (remove_call_out( "disconnect" )>-1);
93}
94
95// Aktualisiert/Setzt die Route im TravelD, wenn erlaubt (d.h. kein
96// P_NO_TRAVELING)
97private void ReportRoute()
98{
99 if(!QueryProp(P_NO_TRAVELING))
100 {
101 mixed tmp = filter(route, function int (mixed arr)
102 {
103 return arr[0] == HP_ROOM;
104 } );
105 string *route = map(tmp, function string (mixed arr)
106 { return arr[1]; }
107 );
108 TRAVELD->AddRoute(object_name(this_object()),route);
109 }
110}
111
Zesstra179db0d2016-11-26 13:13:41 +0100112public varargs void Start(int pos)
MG Mud User88f12472016-06-24 23:31:02 +0200113{
114 Halt();
Zesstra5d2ace02017-06-20 23:21:36 +0200115 // negative pos sind ein Fehler
116 if (pos<0)
117 raise_error(sprintf("Start(): Positionszaehler < 0: %d\n",pos));
118
119 // wenn pos zu gross fuer die Route ist, rpos auf Ende der Route setzen
120 // (i.e. sizeof(route)-1), damit bei der naechsten Bewegung am Anfang der
121 // Route begonnen wird.
122 rpos = min(pos, sizeof(route)-1);
123
MG Mud User88f12472016-06-24 23:31:02 +0200124 // Tell TRAVELD our current route
125 ReportRoute();
Zesstrac786fee2018-02-12 20:31:29 +0100126 // changeHp() inkrementiert zu Beginn rpos um 1. D.h. damit wir keinen
127 // Haltepunkt ueberspringen, muss dieses vorweg kompensiert werden. Da dies
128 // wiederum den Transporter aber ggf. buggen laesst (rpos<0), darf das
129 // changeHp() hier nicht asynchron per call_out gerufen werden.
130 --rpos;
131 changeHp();
MG Mud User88f12472016-06-24 23:31:02 +0200132}
133
Zesstra179db0d2016-11-26 13:13:41 +0100134// continues the current route at the point we stopped.
135public int Continue()
136{
137 if (find_call_out("changeHp") == -1
138 && find_call_out("disconnect") == -1)
139 {
Zesstra019987a2017-10-24 22:36:08 +0200140 // Nach einer Pause wird die Route am aktuellen Haltepunkt fortgesetzt
141 // (im Regelfall also am Ende der Route). Am Routenende wird auch
142 // geprueft, wann der letzte Spielerkontakt war. Das darf nach einem
143 // Continue() aber nicht passieren, sonst wuerde der Transporter ggf.
144 // sofort wieder anhalten.
145 meet_last_player*=-1; // neg. vorzeichen als Markierung
Zesstra179db0d2016-11-26 13:13:41 +0100146 unsubscribe_init();
147 Start(rpos);
148 return 1;
149 }
150 return 0;
151}
152
153// pauses the transporter temporarily in a way that it continues along its
154// route as soon as a living enters one of the stop points. If that is not
155// possible, we do nothing.
156public int Pause()
157{
158 // ok, stop
159 if (subscribe_init() == 1)
160 {
161 Halt();
162 return 1;
163 }
164 return 0;
165}
166
MG Mud User88f12472016-06-24 23:31:02 +0200167void SetTravelCmds()
168{
169 if (pointerp(QueryProp(P_LEAVECMDS)))
170 AddCmd(QueryProp(P_LEAVECMDS),"GoOutside");
171 if (pointerp(QueryProp(P_ENTERCMDS)))
172 AddCmd(QueryProp(P_ENTERCMDS),"GoInside");
173 if (pointerp(QueryProp(P_TRAVEL_CMDS)))
174 AddCmd(QueryProp(P_TRAVEL_CMDS),"GoInAndOutside");
175 return;
176}
177
178mixed HasRoute(mixed dest)
179{
Arathornb3051452021-05-13 21:13:03 +0200180 int i,s;
MG Mud User88f12472016-06-24 23:31:02 +0200181 object ob;
182 mixed harb;
183
184 s = sizeof(route);
185
186 for (i = rpos;i <= rpos+s-1;i++)
187 {
188 if (route[i%s][0] == HP_ROOM)
189 {
190 if (member(route[i%s][5],dest) != -1 &&
191 objectp(ob=load_object(route[i%s][1])) &&
192 pointerp(harb=ob->QueryProp(P_HARBOUR)) &&
193 sizeof(harb))
194 {
195 return ({ route[i%s][1], harb[0] });
196 }
197 }
198 }
199 return 0;
200}
201
202public varargs void AddRoute(string room, int stay, int next,
203 string harbour_desc, string|string* dest_ids, string deststr)
204{
205 // Daten aus dem Zielanleger abfragen.
206 <string|string*>* harbour = room->QueryProp(P_HARBOUR)||({});
207 string* harbour_ids = ({});
208
209 // IDs des Zielanlegers fuer Syntaxpruefung
210 if ( sizeof(harbour)==2 )
211 {
212 if ( pointerp(harbour[1]) )
213 harbour_ids = harbour[1];
214 else
215 harbour_ids = ({harbour[1]});
216 }
217
218 // <dest_ids> in ein Array umwandeln, ist dann ggf. leer
219 if ( !dest_ids )
220 {
221 dest_ids = ({});
222 }
223 if ( stringp(dest_ids) )
224 {
225 dest_ids = ({dest_ids});
226 }
227
228 // explizit angegebene IDs stehen jetzt in <dest_ids>, die IDs des
229 // Zielhafens aus P_HARBOUR werden addiert.
230 dest_ids += harbour_ids;
231
232 // Ist <dest> immer noch leer, versuchen wir, aus <harbour_desc> ein paar
233 // Stichwoerter zu erzeugen, die man als Zielangabe in der Syntax
234 // "reise nach <ziel>" verwenden kann.
235 if ( !sizeof(dest_ids) )
236 {
237 // Grossgeschriebene Begriffe in <harbour_desc> in <dest> eintragen. Dazu:
238 // 1) <code> erstmal so zerschneiden, dass alle ueblichen Satzzeichen
239 // rausfliegen (es gibt Transporter, die sowas in <harbour_desc>
240 // uebergeben).
241 dest_ids = regexplode(harbour_desc, "[(),.;:&\+_ ]",
242 RE_OMIT_DELIM|RE_GLOBAL);
243 // 2a) So filtern, dass nur grossgeschriebene Woerter uebrig bleiben,
244 // von 1) uebriggebliebene Leerstrings gleich mit wegwerfen.
245 // 2b) Ergebnis kleinschreiben, damit die Syntaxpruefung damit arbeiten
246 // kann.
247 dest_ids = map( filter(dest_ids, function int (string key) {
248 return (key!="" && key[0]>='A' && key[0]<='Z');
249 }), #'lower_case);
250 }
251 // Sollte <dest> jetzt immer noch leer sein, wurde an allen drei Stellen
252 // nichts oder nur Muell uebergeben.
253 if ( !sizeof(dest_ids) )
254 {
255 raise_error("Transporterfehlfunktion in AddRoute(): Identifikations"
256 "matrix unzureichend definiert. Transporter unbenutzbar fuer "
257 "Spieler. Bitte mindestens eine Ziel-ID via P_HARBOUR oder als "
258 "Argument to AddRoute().");
259 }
260 route += ({ ({ HP_ROOM, room, stay, next, harbour_desc, dest_ids,
261 deststr }) });
Zesstra7842b8e2019-07-04 21:55:39 +0200262 route_time += stay + next;
MG Mud User88f12472016-06-24 23:31:02 +0200263}
264
Zesstra7842b8e2019-07-04 21:55:39 +0200265varargs void AddMsg(string msg, int next)
MG Mud User88f12472016-06-24 23:31:02 +0200266{
Zesstra7842b8e2019-07-04 21:55:39 +0200267 route += ({ ({ HP_MSG, msg, next }) });
268 route_time += next;
MG Mud User88f12472016-06-24 23:31:02 +0200269}
270
Zesstra7842b8e2019-07-04 21:55:39 +0200271void AddFun(string fun, int next)
272{
273 route += ({ ({ HP_FUN, fun, next }) });
274 route_time += next;
275}
MG Mud User88f12472016-06-24 23:31:02 +0200276
277string QueryArrived() { return roomCode; }
278
279mixed* QueryPosition()
280{
281 return ({ route[rpos][1],route[(rpos+1)<sizeof(route)?(rpos+1):0][1] });
282}
283
284object* QueryPassengers()
285{
286 return filter(all_inventory(),#'query_once_interactive);
287}
288
289varargs string *QueryHarbours(int textflag)
290{
291 string *ret = ({});
292
293 foreach( mixed* entry : route )
294 {
295 if ( entry[0] == HP_ROOM )
296 {
297 if ( textflag )
298 {
299 string *hp_ids = entry[1]->QueryProp(P_HARBOUR)[1];
300 if (pointerp(hp_ids) && sizeof(hp_ids))
301 {
302 string *h = map( explode(hp_ids[0]," "), #'capitalize);
303 ret += ({ implode(h, " ") });
304 }
305 }
306 else
307 {
308 ret += ({ entry[1] });
309 }
310 }
311 }
312 return ret;
313}
314
315// beim zerstoeren sollte auch die route und der Transporter aus dem traveld
316// abgemeldet werden.
317public varargs int remove(int silent)
318{
319 TRAVELD->RemoveTransporter(this_object());
320 return ::remove(silent);
321}
322
323void RemoveRoute()
324{
325 Halt();
326 route = ({ });
327 rpos = 0;
Zesstra7842b8e2019-07-04 21:55:39 +0200328 route_time = 0;
MG Mud User88f12472016-06-24 23:31:02 +0200329 TRAVELD->RemoveTransporter(this_object());
330}
331
332varargs int Enter(object who)
333{
334 string *emsg;
335 mixed efail;
336
337 if (!objectp(who)) who = this_player();
338 if (environment(who) == this_object())
339 {
340 tell_object(who,"Da bist Du doch bereits, schon vergessen?\n");
341 return 1;
342 }
343 if (!QueryArrived()) return 0;
344 if (QueryProp(P_MAX_PASSENGERS) &&
345 (sizeof(QueryPassengers()) >= QueryProp(P_MAX_PASSENGERS)))
346 {
347 if (pointerp(efail=QueryProp(P_ENTERFAIL)))
348 {
349 if (sizeof(efail) == 2)
350 tell_room(this_object(),who->Name(WER,2)+" "+process_string(efail[1])+
351 ".\n",({who}));
352 tell_object(who,process_string(efail[0])+".\n");
353 }
354 else if (stringp(efail))
355 tell_object(who,process_string(efail)+".\n");
356 else if (closurep(efail)) funcall(efail);
357 return 1;
358 }
359
360 tell_object(who,"Du betrittst "+name(WEN,1)+".\n");
361 if (pointerp(emsg=QueryProp(P_ENTERMSG)) && sizeof(emsg) == 2)
362 return who->move(this_object(),M_GO,"",process_string(emsg[0]),
363 process_string(emsg[1]));
364 return who->move(this_object(),M_GO,
365 name(WEN,1),"betritt","kommt herein");
366}
367
368varargs int Leave(object who)
369{
370 string *lmsg;
371 mixed lfail;
372
373 if (!objectp(who)) who = this_player();
374 if (environment(who) != this_object())
375 {
376 if (QueryArrived())
377 {
378 tell_object(who,"Dafuer muesstest Du erstmal dort sein.\n");
379 return 1;
380 }
381 return 0;
382 }
383 if (!QueryArrived())
384 {
385 if (lfail=QueryProp(P_LEAVEFAIL))
386 {
387 if (pointerp(lfail) && sizeof(lfail))
388 {
389 if (sizeof(lfail) == 2)
390 tell_room(this_object(),who->Name(WER,2)+" "+process_string(
391 lfail[1])+".\n",({who}));
392 tell_object(who,process_string(lfail[0])+".\n");
393 }
394 else if (stringp(lfail))
395 tell_object(who,process_string(lfail)+".\n");
396 else if (closurep(lfail)) funcall(lfail);
397 return 1;
398 }
399 tell_object(who,"Fehler beim Verlassen des Transporters.\n"
400 "Bitte zustaendigen Magier verstaendigen.\n");
401 return 1;
402 }
403
404 if (who->QueryProp(P_TRAVEL_INFO)) who->SetProp(P_TRAVEL_INFO,0);
405 tell_object(who,"Du verlaesst "+name(WEN,1)+".\n");
406 if (pointerp(lmsg=QueryProp(P_LEAVEMSG)) && sizeof(lmsg) == 2)
407 return who->move(environment(),M_GO,"",process_string(lmsg[0]),
408 process_string(lmsg[1]));
409 return who->move(environment(),M_GO,
410 name(WEN,1),"verlaesst","kommt herein");
411}
412
Bugfix42754ad2022-05-06 10:57:59 +0200413// Details nur, wenn der Transporter angelegt hat bzw. fuer Livings an Bord.
414// Hintergrund: Transporter sind durch P_SHORT 0 zwar unsichtbar, es kann
415// aber mit ihnen interaggiert werden, dadurch koennen Spieler, die im Hafen
416// einen angelegten Transporter betrachten und ihn dadurch als Referenzobjekt
417// haben Details an ihm betrachten.
418public varargs string GetDetail(string key, string race, int sense)
419{
420 if(!roomCode && environment(PL) != ME) return 0;
421 return ::GetDetail(key, race, sense);
422}
423
MG Mud User88f12472016-06-24 23:31:02 +0200424/*
425 ****************** Internal Functions ******************
426 */
427
428static int GoInside(string str)
429{
430 _notify_fail("Was moechtest Du denn genau?\n");
431 if (stringp(str) && id(str)) {
432 Enter();
433 return 1;
434 }
435 return 0;
436}
437
438static int GoOutside(string str)
439{
440 _notify_fail("Was moechtest Du denn genau?\n");
441 if (stringp(str) && id(str)) {
442 Leave();
443 return 1;
444 }
445 return 0;
446}
447
448static int GoInAndOutside(string str)
449{
450 string to;
451
452 _notify_fail("Was moechtest Du denn genau?\n");
453 if (!sizeof(str)) return 0;
454 if ((sscanf(str,"auf %s",to) == 1 || sscanf(str,"in %s",to) == 1) && id(to))
455 return Enter(),1;
456 if ((sscanf(str,"von %s",to) == 1 || sscanf(str,"aus %s",to) == 1) && id(to))
457 return Leave(),1;
458 return 0;
459}
460
461protected void create()
462{
463 ::create();
464
465 route = ({});
466
467 SetProp(P_LEAVEFAIL,"Das ist momentan viel zu gefaehrlich");
468 SetProp(P_ENTERFAIL,"Dort ist kein Platz mehr fuer Dich");
469 SetProp(P_TRANSPARENT,1);
470
471 AddId("Transporter");
Zesstra179db0d2016-11-26 13:13:41 +0100472
MG Mud User88f12472016-06-24 23:31:02 +0200473 call_out("SetTravelCmds",1);
474}
475
476static varargs void disconnect(int change, int change_time)
477{
478 object room;
479 mixed *departmsg;
480
481 departmsg = QueryProp(P_DEPARTMSG);
482
483 if ((room = environment()) && pointerp(departmsg))
484 {
485 tell_room(this_object(),process_string(departmsg[0]));
486 tell_room(room,process_string(departmsg[1]));
487 }
488
489 roomCode = 0;
490
491 if (change) call_out("changeHp",change_time);
492}
493
494static varargs void connect(string room, string code)
495{
496 mixed *arrivemsg, *t;
Arathornb3051452021-05-13 21:13:03 +0200497 object *trav;
MG Mud User88f12472016-06-24 23:31:02 +0200498 int i;
499
500 if (roomCode) disconnect();
501
502 roomCode = code?code:"";
503
504 if (catch(move(room,M_SILENT|M_NOCHECK);publish))
505 {
506 roomCode = 0;
507 return;
508 }
509
510 arrivemsg = QueryProp(P_ARRIVEMSG);
511
512 if (pointerp(arrivemsg))
513 {
514 tell_room(this_object(),process_string(arrivemsg[0]));
515 tell_room(room,process_string(arrivemsg[1]));
516 }
517
518 trav = filter(all_inventory(this_object()),#'living);
519
520 i = sizeof(trav);
521 while(i--)
522 {
523 if (pointerp(t = trav[i]->QueryProp(P_TRAVEL_INFO))&&
524 t[0]==this_object()&&t[2]==room)
525 {
526 if (trav[i]->InFight())
527 tell_object(trav[i],break_string("Du solltest Deinen Kampf "
528 "schnell beenden,denn eigentlich wolltest Du hier "
529 "aussteigen.",78));
530 else
531 Leave(trav[i]);
532 if (environment(trav[i])!=this_object())
533 trav[i]->SetProp(P_TRAVEL_INFO,0);
534 }
535 }
536 trav = filter(all_inventory(find_object(room))-trav,#'living);
537 i=sizeof(trav);
538 while(i--)
539 {
540 if (objectp(trav[i]) && pointerp(t = trav[i]->QueryProp(P_TRAVEL_INFO))&&
541 t[0] == environment(trav[i]) && t[1] == this_object())
542 {
543 if ( trav[i]->InFight() )
544 tell_object(trav[i],
545 break_string("Du solltest Deinen Kampf schnell beenden, denn "
546 "eigentlich wolltest Du mit "+name(WEM,1)+
547 " reisen.",78));
548 else
549 Enter(trav[i]);
550 if (environment(trav[i]) == this_object())
551 {
552 t[0] = this_object();
553 trav[i]->SetProp(P_TRAVEL_INFO,t);
554 }
555 }
556 }
557}
558
559// this object never performs any clean-up, the driver should not call it
560// again.
561int clean_up(int arg) { return 0; }
562
Zesstra5b71ebb2018-03-07 20:50:35 +0100563public varargs void init(object origin)
Zesstra179db0d2016-11-26 13:13:41 +0100564{
Zesstra5b71ebb2018-03-07 20:50:35 +0100565 "*"::init(origin);
Zesstra179db0d2016-11-26 13:13:41 +0100566 // if we have player contact (even if the player is just in the same
567 // environment), we update the time.
568 if (this_player() && query_once_interactive(this_player()))
Bugfix4df578b2019-03-13 18:36:59 +0100569 {
570 meet_last_player = time();
571 // Wenn jemand in uns ist, auch falls noetig die Route fortsetzen,
572 // denn wir haben natuerlich nicht H_HOOK_INIT in uns selbst abonniert.
573 if(environment(PL)==ME)
574 Continue();
575 }
Zesstra179db0d2016-11-26 13:13:41 +0100576}
577
578// we try to continue our route once some living triggers init.
579private mixed InitHookCallback(object source, int hookid, mixed hookdata)
580{
581 if (hookid == H_HOOK_INIT && previous_object() == source)
582 Continue();
583
584 return ({H_NO_MOD, hookdata});
585}
586
587// subscribes to H_HOOK_INIT in all rooms along the route
Zesstra658871d2019-07-04 21:34:02 +0200588// == 1 for success, < -1 if not (at least one hook failed, all registration
589// were already subscribed).
Zesstra179db0d2016-11-26 13:13:41 +0100590private int subscribe_init()
591{
592 // subscribe to the H_HOOK_INIT of all rooms in the route...
Zesstra179db0d2016-11-26 13:13:41 +0100593 foreach(mixed* arr : route)
594 {
595 if (arr[0] == HP_ROOM)
596 {
Bugfix7c642a72021-05-16 13:05:52 +0200597 int res = arr[1]->HRegisterToHook(H_HOOK_INIT, #'InitHookCallback,
598 H_HOOK_LIBPRIO(1), H_LISTENER,
599 0);
600 // 1 == Erfolg, -3 == bereits registriert
601 if(res != 1 && res != -3)
Zesstra658871d2019-07-04 21:34:02 +0200602 {
603 // von allen H_HOOK_INIT wieder abmelden...
604 unsubscribe_init();
605 return -1;
606 }
Zesstra179db0d2016-11-26 13:13:41 +0100607 }
608 }
Zesstra658871d2019-07-04 21:34:02 +0200609 return 1;
Zesstra179db0d2016-11-26 13:13:41 +0100610}
611
612// unsubscribes from all the H_HOOK_INIT.
613private void unsubscribe_init()
614{
615 foreach(mixed* arr : route)
616 {
617 if (arr[0] == HP_ROOM)
618 arr[1]->HUnregisterFromHook(H_HOOK_INIT, #'InitHookCallback);
619 }
620}
621
622private int maybe_pause()
623{
Zesstra7842b8e2019-07-04 21:55:39 +0200624 // we check for time of last player contact. If we did not meet any players
625 // for 2 round-trips, we try to pause.
626 if (meet_last_player < time() - (2*route_time) )
Zesstra179db0d2016-11-26 13:13:41 +0100627 {
Zesstra677b5722019-07-04 22:10:01 +0200628 // we don't stop if players are currently at one of our stops
629 foreach(mixed* arr : route)
630 {
631 if (arr[0] == HP_ROOM)
632 {
633 object room = find_object(arr[1]);
634 if(room &&
635 sizeof(filter(all_inventory(room), #'interactive)))
636 return 0; // no pause
637 }
638 }
639 // and we don't stop if players currently are in the transporter.
640 if (sizeof(filter(all_inventory(this_object()), #'interactive)))
641 return 0;
642 // ok, pause machen
643 return Pause();
Zesstra179db0d2016-11-26 13:13:41 +0100644 }
645 return 0;
646}
647
MG Mud User88f12472016-06-24 23:31:02 +0200648void changeHp()
649{
Zesstrafffd2a82017-10-24 22:03:27 +0200650 // Nicht am Ende der Route? Eins weiter.
651 if (rpos < sizeof(route) - 1)
652 ++rpos;
653 else
MG Mud User88f12472016-06-24 23:31:02 +0200654 {
Zesstra019987a2017-10-24 22:36:08 +0200655 // Routenende
656 // Nach einem expliziten Continue() ist meet_last_player < 0. Dann wird
657 // nicht geprueft, ob wir sofort wieder anhalten. Auch muss dann die Route
658 // nicht uebermittelt werden (hat Start() schon gemacht).
659 if (meet_last_player >= 0)
660 {
661 // TRAVELD die aktuelle Route uebermitteln
662 ReportRoute();
663 // everytime, we pass the end of our route, we check if we should
664 // pause our service.
665 if (maybe_pause())
666 return;
667 }
668 else
669 // Wieder pruefen im naechsten Durchlauf.
670 meet_last_player=abs(meet_last_player);
671
Zesstrafffd2a82017-10-24 22:03:27 +0200672 // wenn keine Pause, wieder zum Anfang der Route bewegen.
673 rpos = 0;
MG Mud User88f12472016-06-24 23:31:02 +0200674 }
Zesstrafffd2a82017-10-24 22:03:27 +0200675
MG Mud User88f12472016-06-24 23:31:02 +0200676 if (route[rpos][0] == HP_MSG)
677 {
678 call_out("changeHp",route[rpos][2]);
679 tell_room(this_object(),route[rpos][1]);
680 }
681 else if (route[rpos][0] == HP_FUN)
682 {
683 call_out("changeHp",route[rpos][2]);
684 call_other(this_object(),route[rpos][1]);
685 }
686 else
687 {
688 call_out("disconnect",route[rpos][2],1,route[rpos][3]);
689 connect(route[rpos][1],route[rpos][4]);
690 }
691}
692