blob: e7c80a3eda4c35545a71e0d5e0aa97b53e6e3792 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// room.c -- room base object
4//
5// $Id: room.c 9475 2016-02-19 21:16:17Z Zesstra $
6#pragma strong_types
7#pragma save_types
8#pragma range_check
9#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +020010
11inherit "/std/thing/properties";
12inherit "/std/thing/language";
13inherit "/std/hook_provider";
14inherit "/std/room/light";
15inherit "/std/container/inventory";
16inherit "/std/room/moving";
17inherit "/std/room/restrictions";
18inherit "/std/room/description";
19inherit "/std/room/exits";
20inherit "/std/room/commands";
21inherit "/std/room/items";
Zesstra44030452018-11-12 22:34:02 +010022inherit "/std/container/vitems";
MG Mud User88f12472016-06-24 23:31:02 +020023inherit "/std/room/doors";
Bugfixb1d9b4d2021-09-14 20:07:04 +020024inherit "/std/room/comm";
MG Mud User88f12472016-06-24 23:31:02 +020025
26#include <thing/properties.h>
27#include <config.h>
28#include <properties.h>
29#include <rooms.h>
30#include <language.h>
31#include <wizlevels.h>
32#include <moving.h>
33#include <defines.h>
34#include <doorroom.h>
35#include <functionlist.h>
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +010036#include <hook.h>
MG Mud User88f12472016-06-24 23:31:02 +020037
38void reset()
39{
40 items::reset();
Zesstra44030452018-11-12 22:34:02 +010041 vitems::reset();
MG Mud User88f12472016-06-24 23:31:02 +020042 exits::reset();
43 doors::reset();
44}
45
46static int
47_query_noget()
48{
49 return 1;
50}
51
MG Mud User88f12472016-06-24 23:31:02 +020052void maybe_replace_program()
53{
54 string *list, first;
55 object first_ob;
56
MG Mud User88f12472016-06-24 23:31:02 +020057 if (object_name(this_object())=="/std/room" ||
58 !(first_ob=find_object(first=(list=inherit_list(this_object()))[1])) ||
59 (sizeof(list)!=1+sizeof(inherit_list(first_ob))) ||
60 (1!=sizeof(list=functionlist(this_object(),
61 RETURN_FUNCTION_NAME|NAME_INHERITED))) ||
62 list[0]!="create")
63 return;
MG Mud User88f12472016-06-24 23:31:02 +020064 replace_program(first);
65}
66
67protected void create()
68{
69 maybe_replace_program();
70 /* Set effective userid to userid */
71 /* so that we may clone other things */
72 seteuid(getuid(this_object()));
73 properties::create();
74 restrictions::create();
75 commands::create();
76 light::create();
77 description::create();
78 exits::create();
79 items::create();
80 doors::create();
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +010081 offerHook(H_HOOK_INIT, 1);
MG Mud User88f12472016-06-24 23:31:02 +020082
83 SetProp(P_NAME,0);
84 SetProp(P_NAME_ADJ,({}));
85 Set(P_SHORT,0);
86 Set(P_LONG,0);
87 Set(P_TRANSPARENT,0);
88 Set(P_ADJECTIVES,({}));
89 Set(P_IDS,({}));
90 Set(P_WEIGHT,PROTECTED,F_MODE);
91 Set(P_TOTAL_WEIGHT,PROTECTED,F_MODE);
92 Set(" clean counter ",2);
93}
94
95protected void create_super() {
96 set_next_reset(-1);
97}
98
99private int
100check_clean_count()
101{
102 int cc;
103
104 cc=Query(" clean counter ");
105 if (--cc<=0)
106 return 1;
107 Set(" clean counter ",cc);
108 return 0;
109}
110
Bugfix017fabf2024-04-06 23:13:06 +0200111public int clean_up(int arg)
MG Mud User88f12472016-06-24 23:31:02 +0200112{
Zesstra8a4fe3b2018-02-12 21:20:24 +0100113 // Never try again when P_NEVER_CLEAN is set.
114 if (Query(P_NEVER_CLEAN)) return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200115
Zesstra8a4fe3b2018-02-12 21:20:24 +0100116 // do not cleanup, if this room is used as blueprint for clones or inherited
117 // (arg>1) or if there are valid hook consumers waiting for something to
118 // happen here. This is temporary and could change, so return 1;
119 if (arg>1 || HHasConsumers())
120 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200121
Bugfix017fabf2024-04-06 23:13:06 +0200122 // Pruefen ob Spieler (auch netztote) anwesend sind.
123 // Es fuehrt leider kein Weg dran vorbei einmal über das inventar und einmal
124 // ueber P_ITEMS zu iterieren.
125 object* inv = all_inventory();
126 foreach(object ob : inv)
MG Mud User88f12472016-06-24 23:31:02 +0200127 {
Bugfix017fabf2024-04-06 23:13:06 +0200128 if(query_once_interactive(ob))
MG Mud User88f12472016-06-24 23:31:02 +0200129 {
Bugfix017fabf2024-04-06 23:13:06 +0200130 Set(" clean counter ",2);
131 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200132 }
MG Mud User88f12472016-06-24 23:31:02 +0200133 }
Bugfix017fabf2024-04-06 23:13:06 +0200134
135 // Auf Objekte aus P_ITEMS pruefen
136 foreach(<object|<string|string*>|int|mapping>* item : QueryProp(P_ITEMS))
137 {
138 // Semantik:
139 // 1. Wenn RITEM_OBJECT ein REFRESH_NONE Item ist und es entweder nicht mehr
140 // existiert oder nicht in diesem Raum ist, kein clean_up (es wuerde
141 // beim neuladen des Raumes ja wieder erzeugt;
142 // falls es aber hier ist, wird es mitvernichtet, dann ists ok)
143 // 2. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
144 // hier ist, KEIN clean_up.
145 // Hier heisst fuer beide Faelle direkt in diesem Raum, befindet es sich in
146 // einem Container koennte es beim Zerstoeren woanders hin bewegt werden und
147 // damit nach dem neuladen doppelt existieren.
148 if( (item[RITEM_REFRESH] == REFRESH_NONE &&
149 (!item[RITEM_OBJECT] ||
Zesstra6a83eb32025-07-02 21:38:00 +0200150 environment(item[RITEM_OBJECT]) != ME)) ||
Bugfix017fabf2024-04-06 23:13:06 +0200151 (item[RITEM_REFRESH] == REFRESH_DESTRUCT &&
152 item[RITEM_OBJECT] &&
Zesstra6a83eb32025-07-02 21:38:00 +0200153 environment(item[RITEM_OBJECT]) != ME))
Bugfix017fabf2024-04-06 23:13:06 +0200154 {
155 return 1;
156 }
157 inv -= ({item[RITEM_OBJECT]});
158 }
159 // if there are objects left in the room do not clean up but try again later
160 if(sizeof(inv) && !check_clean_count())
161 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200162
163 // do clean_up
164 //log_file("clean_up_log",sprintf(
Zesstrae12be202018-02-12 21:10:38 +0100165 // "%s:%s: %O\n",ctime(time())[11..18],__HOST_NAME__,this_object()));
166
MG Mud User88f12472016-06-24 23:31:02 +0200167 remove();
168 // wenn der Raum sich im remove() nicht zerstoert, hat er dafuer vermutlich
169 // nen Grund. Evtl. klappts ja naechstes Mal.
170
171 return(1);
172}
173
174/* Instead of printing the exits with the long description, we implement */
175/* the command "exits" to show them. */
176int
177show_exits() {
178 mixed ex;
179 if( this_player()->CannotSee() ) return 1;
180 if ((ex=QueryProp(P_HIDE_EXITS)) && intp(ex)) return 1;
181 if (ex = GetExits(this_player())) write(ex);
182 return 1;
183}
184
185int
186toggle_exits(string str)
187{
188 int ex;
189
190 /* Nur das aktuelle Environment des Spielers ist zustaendig fuer die
191 Auflistung der Ausgaenge. Anderenfalls wird das Kommando von Raeumen
192 im Raum (z.B. Transportern) abgefangen und es werden dessen Ausgaenge
193 aufgelistet.
194 Sprich: keine Auflistung von Aussen. */
195 if (environment(this_player()) != this_object()) return 0;
196 if (!str) return show_exits();
197 if (str!="auto") return 0;
198 ex = this_player()->QueryProp(P_SHOW_EXITS);
199 this_player()->SetProp(P_SHOW_EXITS, !ex);
200 if (ex) write("Ausgaenge werden nicht mehr automatisch angezeigt.\n");
201 else write("Ausgaenge werden automatisch angezeigt.\n");
202 return 1;
203}
204
Zesstra5b71ebb2018-03-07 20:50:35 +0100205public varargs void init(object origin)
MG Mud User88f12472016-06-24 23:31:02 +0200206{
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +0100207 if (HookFlow(H_HOOK_INIT, 0)[H_RETCODE] == H_CANCELLED)
208 return;
MG Mud User88f12472016-06-24 23:31:02 +0200209 Set(" clean counter ",2);
Zesstra5b71ebb2018-03-07 20:50:35 +0100210 exits::init(origin);
211 commands::init(origin);
212 description::init(origin);
213 doors::init(origin);
MG Mud User88f12472016-06-24 23:31:02 +0200214
215 add_action("toggle_exits", "exits");
216 add_action("toggle_exits", "ausgang");
217 add_action("toggle_exits", "ausgaenge");
218 add_action("toggle_exits", "aus");
219}
220
221int _query_para(){
222 int re;
223 if(re=Query(P_PARA))return re;
224 if(sizeof(regexp(({object_name(this_object())}),".*\\^0$")))
225 return -1;
226 return to_int(
227 regreplace(object_name(this_object()),".*\\^\([1-9][0-9]*\)$","\\1",1));
228}
229
230//dies ist ein Raum, war gewuenscht von mehreren Leuten.
231status IsRoom() {return(1);}