blob: b89a7dc330564f39e2caa938dac91471f867c40a [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{
112 mixed itema;
113
114 if(arg>1) return 1; // better not ;)
115
116 if (Query(" never clean ")) return 0;
117
118 // if there are any item we have produced ourselfes check them
119 if(pointerp(itema = QueryProp(P_ITEMS)))
120 {
121 mixed names;
122 int i;
123 i = sizeof(names = all_inventory(this_object()));
124 while(i--)
125 {
126 if (query_once_interactive(names[i]))
127 {
Zesstrae12be202018-02-12 21:10:38 +0100128 Set(" clean counter ",2);
129 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200130 }
131 if(objectp(names[i])) names[i] = explode(object_name(names[i]),"#")[0];
132 }
133
134 for(i = sizeof(itema)-1; i >= 0; i--)
135 {
136 // Semantik:
137 // 1. Wenn RITEM_OBJECT ein array ist, kann evtl ge'clean'ed werden.
138 // 2. Wenn es ein REFRESH_NONE Item ist und es entweder nicht mehr
139 // existiert oder nicht in diesem Raum ist, kein clean_up (es wuerde
140 // beim neuladen des Raumes ja wieder erzeugt;
141 // falls es aber hier ist, wird es mitvernichtet, dann ists ok)
142 // 3. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
143 // hier ist, KEIN clean_up.
144 if (!pointerp(itema[i][RITEM_OBJECT])
Zesstrae12be202018-02-12 21:10:38 +0100145 && ((itema[i][RITEM_REFRESH] == REFRESH_NONE
146 && (!itema[i][RITEM_OBJECT]
147 || environment(itema[i][RITEM_OBJECT])!=this_object()))
148 || (itema[i][RITEM_REFRESH] == REFRESH_DESTRUCT
149 && itema[i][RITEM_OBJECT]
150 && environment(itema[i][RITEM_OBJECT]) != this_object())))
151 return 1;
MG Mud User88f12472016-06-24 23:31:02 +0200152 names -= (pointerp(itema[i][RITEM_FILE]) ?
Zesstrae12be202018-02-12 21:10:38 +0100153 itema[i][RITEM_FILE] : ({ itema[i][RITEM_FILE] }));
MG Mud User88f12472016-06-24 23:31:02 +0200154 }
155 // if there are objects left in the room do not clean up but try again later
156 if(sizeof(names) && !check_clean_count()) return 1;
157 }
158 else
159 // is there any object lying around?
160 if(first_inventory(this_object()) && !check_clean_count()) return 2;
161
162 // do clean_up
163 //log_file("clean_up_log",sprintf(
Zesstrae12be202018-02-12 21:10:38 +0100164 // "%s:%s: %O\n",ctime(time())[11..18],__HOST_NAME__,this_object()));
165
MG Mud User88f12472016-06-24 23:31:02 +0200166 remove();
167 // wenn der Raum sich im remove() nicht zerstoert, hat er dafuer vermutlich
168 // nen Grund. Evtl. klappts ja naechstes Mal.
169
170 return(1);
171}
172
173/* Instead of printing the exits with the long description, we implement */
174/* the command "exits" to show them. */
175int
176show_exits() {
177 mixed ex;
178 if( this_player()->CannotSee() ) return 1;
179 if ((ex=QueryProp(P_HIDE_EXITS)) && intp(ex)) return 1;
180 if (ex = GetExits(this_player())) write(ex);
181 return 1;
182}
183
184int
185toggle_exits(string str)
186{
187 int ex;
188
189 /* Nur das aktuelle Environment des Spielers ist zustaendig fuer die
190 Auflistung der Ausgaenge. Anderenfalls wird das Kommando von Raeumen
191 im Raum (z.B. Transportern) abgefangen und es werden dessen Ausgaenge
192 aufgelistet.
193 Sprich: keine Auflistung von Aussen. */
194 if (environment(this_player()) != this_object()) return 0;
195 if (!str) return show_exits();
196 if (str!="auto") return 0;
197 ex = this_player()->QueryProp(P_SHOW_EXITS);
198 this_player()->SetProp(P_SHOW_EXITS, !ex);
199 if (ex) write("Ausgaenge werden nicht mehr automatisch angezeigt.\n");
200 else write("Ausgaenge werden automatisch angezeigt.\n");
201 return 1;
202}
203
204void
205init()
206{
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);
MG Mud User88f12472016-06-24 23:31:02 +0200210 exits::init();
211 commands::init();
212 description::init();
213 doors::init();
214
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);}