blob: 65332ce2d5237bbdd81339dbc85322bc70c13786 [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";
24
25#include <thing/properties.h>
26#include <config.h>
27#include <properties.h>
28#include <rooms.h>
29#include <language.h>
30#include <wizlevels.h>
31#include <moving.h>
32#include <defines.h>
33#include <doorroom.h>
34#include <functionlist.h>
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +010035#include <hook.h>
MG Mud User88f12472016-06-24 23:31:02 +020036
37void reset()
38{
39 items::reset();
Zesstra44030452018-11-12 22:34:02 +010040 vitems::reset();
MG Mud User88f12472016-06-24 23:31:02 +020041 exits::reset();
42 doors::reset();
43}
44
45static int
46_query_noget()
47{
48 return 1;
49}
50
MG Mud User88f12472016-06-24 23:31:02 +020051void maybe_replace_program()
52{
53 string *list, first;
54 object first_ob;
55
MG Mud User88f12472016-06-24 23:31:02 +020056 if (object_name(this_object())=="/std/room" ||
57 !(first_ob=find_object(first=(list=inherit_list(this_object()))[1])) ||
58 (sizeof(list)!=1+sizeof(inherit_list(first_ob))) ||
59 (1!=sizeof(list=functionlist(this_object(),
60 RETURN_FUNCTION_NAME|NAME_INHERITED))) ||
61 list[0]!="create")
62 return;
MG Mud User88f12472016-06-24 23:31:02 +020063 replace_program(first);
64}
65
66protected void create()
67{
68 maybe_replace_program();
69 /* Set effective userid to userid */
70 /* so that we may clone other things */
71 seteuid(getuid(this_object()));
72 properties::create();
73 restrictions::create();
74 commands::create();
75 light::create();
76 description::create();
77 exits::create();
78 items::create();
79 doors::create();
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +010080 offerHook(H_HOOK_INIT, 1);
MG Mud User88f12472016-06-24 23:31:02 +020081
82 SetProp(P_NAME,0);
83 SetProp(P_NAME_ADJ,({}));
84 Set(P_SHORT,0);
85 Set(P_LONG,0);
86 Set(P_TRANSPARENT,0);
87 Set(P_ADJECTIVES,({}));
88 Set(P_IDS,({}));
89 Set(P_WEIGHT,PROTECTED,F_MODE);
90 Set(P_TOTAL_WEIGHT,PROTECTED,F_MODE);
91 Set(" clean counter ",2);
92}
93
94protected void create_super() {
95 set_next_reset(-1);
96}
97
98private int
99check_clean_count()
100{
101 int cc;
102
103 cc=Query(" clean counter ");
104 if (--cc<=0)
105 return 1;
106 Set(" clean counter ",cc);
107 return 0;
108}
109
110int
111clean_up(int arg)
112{
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
Zesstra8a4fe3b2018-02-12 21:20:24 +0100122 // if there are any items we have produced ourselfes check them
123 mixed itema = QueryProp(P_ITEMS);
124 if(pointerp(itema))
MG Mud User88f12472016-06-24 23:31:02 +0200125 {
126 mixed names;
127 int i;
128 i = sizeof(names = all_inventory(this_object()));
129 while(i--)
130 {
131 if (query_once_interactive(names[i]))
132 {
Zesstrae12be202018-02-12 21:10:38 +0100133 Set(" clean counter ",2);
134 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200135 }
136 if(objectp(names[i])) names[i] = explode(object_name(names[i]),"#")[0];
137 }
138
139 for(i = sizeof(itema)-1; i >= 0; i--)
140 {
141 // Semantik:
142 // 1. Wenn RITEM_OBJECT ein array ist, kann evtl ge'clean'ed werden.
143 // 2. Wenn es ein REFRESH_NONE Item ist und es entweder nicht mehr
144 // existiert oder nicht in diesem Raum ist, kein clean_up (es wuerde
145 // beim neuladen des Raumes ja wieder erzeugt;
146 // falls es aber hier ist, wird es mitvernichtet, dann ists ok)
147 // 3. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
148 // hier ist, KEIN clean_up.
149 if (!pointerp(itema[i][RITEM_OBJECT])
Zesstrae12be202018-02-12 21:10:38 +0100150 && ((itema[i][RITEM_REFRESH] == REFRESH_NONE
151 && (!itema[i][RITEM_OBJECT]
152 || environment(itema[i][RITEM_OBJECT])!=this_object()))
153 || (itema[i][RITEM_REFRESH] == REFRESH_DESTRUCT
154 && itema[i][RITEM_OBJECT]
155 && environment(itema[i][RITEM_OBJECT]) != this_object())))
156 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200157 names -= (pointerp(itema[i][RITEM_FILE]) ?
Zesstrae12be202018-02-12 21:10:38 +0100158 itema[i][RITEM_FILE] : ({ itema[i][RITEM_FILE] }));
MG Mud User88f12472016-06-24 23:31:02 +0200159 }
160 // if there are objects left in the room do not clean up but try again later
161 if(sizeof(names) && !check_clean_count()) return 1;
162 }
163 else
164 // is there any object lying around?
165 if(first_inventory(this_object()) && !check_clean_count()) return 2;
166
167 // do clean_up
168 //log_file("clean_up_log",sprintf(
Zesstrae12be202018-02-12 21:10:38 +0100169 // "%s:%s: %O\n",ctime(time())[11..18],__HOST_NAME__,this_object()));
170
MG Mud User88f12472016-06-24 23:31:02 +0200171 remove();
172 // wenn der Raum sich im remove() nicht zerstoert, hat er dafuer vermutlich
173 // nen Grund. Evtl. klappts ja naechstes Mal.
174
175 return(1);
176}
177
178/* Instead of printing the exits with the long description, we implement */
179/* the command "exits" to show them. */
180int
181show_exits() {
182 mixed ex;
183 if( this_player()->CannotSee() ) return 1;
184 if ((ex=QueryProp(P_HIDE_EXITS)) && intp(ex)) return 1;
185 if (ex = GetExits(this_player())) write(ex);
186 return 1;
187}
188
189int
190toggle_exits(string str)
191{
192 int ex;
193
194 /* Nur das aktuelle Environment des Spielers ist zustaendig fuer die
195 Auflistung der Ausgaenge. Anderenfalls wird das Kommando von Raeumen
196 im Raum (z.B. Transportern) abgefangen und es werden dessen Ausgaenge
197 aufgelistet.
198 Sprich: keine Auflistung von Aussen. */
199 if (environment(this_player()) != this_object()) return 0;
200 if (!str) return show_exits();
201 if (str!="auto") return 0;
202 ex = this_player()->QueryProp(P_SHOW_EXITS);
203 this_player()->SetProp(P_SHOW_EXITS, !ex);
204 if (ex) write("Ausgaenge werden nicht mehr automatisch angezeigt.\n");
205 else write("Ausgaenge werden automatisch angezeigt.\n");
206 return 1;
207}
208
Zesstra5b71ebb2018-03-07 20:50:35 +0100209public varargs void init(object origin)
MG Mud User88f12472016-06-24 23:31:02 +0200210{
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +0100211 if (HookFlow(H_HOOK_INIT, 0)[H_RETCODE] == H_CANCELLED)
212 return;
MG Mud User88f12472016-06-24 23:31:02 +0200213 Set(" clean counter ",2);
Zesstra5b71ebb2018-03-07 20:50:35 +0100214 exits::init(origin);
215 commands::init(origin);
216 description::init(origin);
217 doors::init(origin);
MG Mud User88f12472016-06-24 23:31:02 +0200218
219 add_action("toggle_exits", "exits");
220 add_action("toggle_exits", "ausgang");
221 add_action("toggle_exits", "ausgaenge");
222 add_action("toggle_exits", "aus");
223}
224
225int _query_para(){
226 int re;
227 if(re=Query(P_PARA))return re;
228 if(sizeof(regexp(({object_name(this_object())}),".*\\^0$")))
229 return -1;
230 return to_int(
231 regreplace(object_name(this_object()),".*\\^\([1-9][0-9]*\)$","\\1",1));
232}
233
234//dies ist ein Raum, war gewuenscht von mehreren Leuten.
235status IsRoom() {return(1);}