blob: 7047f2b6b67c97d7427acf3fedd3022b44540827 [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
10#pragma pedantic
11
12inherit "/std/thing/properties";
13inherit "/std/thing/language";
14inherit "/std/hook_provider";
15inherit "/std/room/light";
16inherit "/std/container/inventory";
17inherit "/std/room/moving";
18inherit "/std/room/restrictions";
19inherit "/std/room/description";
20inherit "/std/room/exits";
21inherit "/std/room/commands";
22inherit "/std/room/items";
23inherit "/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();
40 exits::reset();
41 doors::reset();
42}
43
44static int
45_query_noget()
46{
47 return 1;
48}
49
MG Mud User88f12472016-06-24 23:31:02 +020050void maybe_replace_program()
51{
52 string *list, first;
53 object first_ob;
54
MG Mud User88f12472016-06-24 23:31:02 +020055 if (object_name(this_object())=="/std/room" ||
56 !(first_ob=find_object(first=(list=inherit_list(this_object()))[1])) ||
57 (sizeof(list)!=1+sizeof(inherit_list(first_ob))) ||
58 (1!=sizeof(list=functionlist(this_object(),
59 RETURN_FUNCTION_NAME|NAME_INHERITED))) ||
60 list[0]!="create")
61 return;
MG Mud User88f12472016-06-24 23:31:02 +020062 replace_program(first);
63}
64
65protected void create()
66{
67 maybe_replace_program();
68 /* Set effective userid to userid */
69 /* so that we may clone other things */
70 seteuid(getuid(this_object()));
71 properties::create();
72 restrictions::create();
73 commands::create();
74 light::create();
75 description::create();
76 exits::create();
77 items::create();
78 doors::create();
Zesstra@Morgengrauen0f34a7e2016-10-30 22:33:25 +010079 offerHook(H_HOOK_INIT, 1);
MG Mud User88f12472016-06-24 23:31:02 +020080
81 SetProp(P_NAME,0);
82 SetProp(P_NAME_ADJ,({}));
83 Set(P_SHORT,0);
84 Set(P_LONG,0);
85 Set(P_TRANSPARENT,0);
86 Set(P_ADJECTIVES,({}));
87 Set(P_IDS,({}));
88 Set(P_WEIGHT,PROTECTED,F_MODE);
89 Set(P_TOTAL_WEIGHT,PROTECTED,F_MODE);
90 Set(" clean counter ",2);
91}
92
93protected void create_super() {
94 set_next_reset(-1);
95}
96
97private int
98check_clean_count()
99{
100 int cc;
101
102 cc=Query(" clean counter ");
103 if (--cc<=0)
104 return 1;
105 Set(" clean counter ",cc);
106 return 0;
107}
108
109int
110clean_up(int arg)
111{
Zesstra8a4fe3b2018-02-12 21:20:24 +0100112 // Never try again when P_NEVER_CLEAN is set.
113 if (Query(P_NEVER_CLEAN)) return 0;
MG Mud User88f12472016-06-24 23:31:02 +0200114
Zesstra8a4fe3b2018-02-12 21:20:24 +0100115 // do not cleanup, if this room is used as blueprint for clones or inherited
116 // (arg>1) or if there are valid hook consumers waiting for something to
117 // happen here. This is temporary and could change, so return 1;
118 if (arg>1 || HHasConsumers())
119 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200120
Zesstra8a4fe3b2018-02-12 21:20:24 +0100121 // if there are any items we have produced ourselfes check them
122 mixed itema = QueryProp(P_ITEMS);
123 if(pointerp(itema))
MG Mud User88f12472016-06-24 23:31:02 +0200124 {
125 mixed names;
126 int i;
127 i = sizeof(names = all_inventory(this_object()));
128 while(i--)
129 {
130 if (query_once_interactive(names[i]))
131 {
Zesstrae12be202018-02-12 21:10:38 +0100132 Set(" clean counter ",2);
133 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200134 }
135 if(objectp(names[i])) names[i] = explode(object_name(names[i]),"#")[0];
136 }
137
138 for(i = sizeof(itema)-1; i >= 0; i--)
139 {
140 // Semantik:
141 // 1. Wenn RITEM_OBJECT ein array ist, kann evtl ge'clean'ed werden.
142 // 2. Wenn es ein REFRESH_NONE Item ist und es entweder nicht mehr
143 // existiert oder nicht in diesem Raum ist, kein clean_up (es wuerde
144 // beim neuladen des Raumes ja wieder erzeugt;
145 // falls es aber hier ist, wird es mitvernichtet, dann ists ok)
146 // 3. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
147 // hier ist, KEIN clean_up.
148 if (!pointerp(itema[i][RITEM_OBJECT])
Zesstrae12be202018-02-12 21:10:38 +0100149 && ((itema[i][RITEM_REFRESH] == REFRESH_NONE
150 && (!itema[i][RITEM_OBJECT]
151 || environment(itema[i][RITEM_OBJECT])!=this_object()))
152 || (itema[i][RITEM_REFRESH] == REFRESH_DESTRUCT
153 && itema[i][RITEM_OBJECT]
154 && environment(itema[i][RITEM_OBJECT]) != this_object())))
155 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200156 names -= (pointerp(itema[i][RITEM_FILE]) ?
Zesstrae12be202018-02-12 21:10:38 +0100157 itema[i][RITEM_FILE] : ({ itema[i][RITEM_FILE] }));
MG Mud User88f12472016-06-24 23:31:02 +0200158 }
159 // if there are objects left in the room do not clean up but try again later
160 if(sizeof(names) && !check_clean_count()) return 1;
161 }
162 else
163 // is there any object lying around?
164 if(first_inventory(this_object()) && !check_clean_count()) return 2;
165
166 // do clean_up
167 //log_file("clean_up_log",sprintf(
Zesstrae12be202018-02-12 21:10:38 +0100168 // "%s:%s: %O\n",ctime(time())[11..18],__HOST_NAME__,this_object()));
169
MG Mud User88f12472016-06-24 23:31:02 +0200170 remove();
171 // wenn der Raum sich im remove() nicht zerstoert, hat er dafuer vermutlich
172 // nen Grund. Evtl. klappts ja naechstes Mal.
173
174 return(1);
175}
176
177/* Instead of printing the exits with the long description, we implement */
178/* the command "exits" to show them. */
179int
180show_exits() {
181 mixed ex;
182 if( this_player()->CannotSee() ) return 1;
183 if ((ex=QueryProp(P_HIDE_EXITS)) && intp(ex)) return 1;
184 if (ex = GetExits(this_player())) write(ex);
185 return 1;
186}
187
188int
189toggle_exits(string str)
190{
191 int ex;
192
193 /* Nur das aktuelle Environment des Spielers ist zustaendig fuer die
194 Auflistung der Ausgaenge. Anderenfalls wird das Kommando von Raeumen
195 im Raum (z.B. Transportern) abgefangen und es werden dessen Ausgaenge
196 aufgelistet.
197 Sprich: keine Auflistung von Aussen. */
198 if (environment(this_player()) != this_object()) return 0;
199 if (!str) return show_exits();
200 if (str!="auto") return 0;
201 ex = this_player()->QueryProp(P_SHOW_EXITS);
202 this_player()->SetProp(P_SHOW_EXITS, !ex);
203 if (ex) write("Ausgaenge werden nicht mehr automatisch angezeigt.\n");
204 else write("Ausgaenge werden automatisch angezeigt.\n");
205 return 1;
206}
207
208void
209init()
210{
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);
MG Mud User88f12472016-06-24 23:31:02 +0200214 exits::init();
215 commands::init();
216 description::init();
217 doors::init();
218
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);}