blob: 29ab5036414a42d3e5d94a6f6b2e63b38d8a1d6f [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>
35
36void reset()
37{
38 items::reset();
39 exits::reset();
40 doors::reset();
41}
42
43static int
44_query_noget()
45{
46 return 1;
47}
48
49//#define DB(x) if (find_player("jof")) tell_object(find_player("jof"),x); else write(x)
50//#undef DB
51//#define DB(x)
52void maybe_replace_program()
53{
54 string *list, first;
55 object first_ob;
56
57// Debugkram auskommentiert, Zesstra, 04.11.06
58// DB("MAYBE_REPLACE_PROGRAM\n");
59// DB(sprintf("FILENAME: %O\n",object_name(this_object())));
60// DB(sprintf("FIRST_OB: %O\n",inherit_list(this_object())));
61// first_ob=find_object(first=(list=inherit_list(this_object()))[1]);
62// DB(sprintf("%O ?= %O\n",sizeof(list),1+sizeof(inherit_list(first_ob))));
63// DB(sprintf("%O ?= sizeof(%O)\n",1,list=functionlist(this_object(),RETURN_FUNCTION_NAME|NAME_INHERITED)));
64 if (object_name(this_object())=="/std/room" ||
65 !(first_ob=find_object(first=(list=inherit_list(this_object()))[1])) ||
66 (sizeof(list)!=1+sizeof(inherit_list(first_ob))) ||
67 (1!=sizeof(list=functionlist(this_object(),
68 RETURN_FUNCTION_NAME|NAME_INHERITED))) ||
69 list[0]!="create")
70 return;
71// DB("REPLACING\n");
72 replace_program(first);
73}
74
75protected void create()
76{
77 maybe_replace_program();
78 /* Set effective userid to userid */
79 /* so that we may clone other things */
80 seteuid(getuid(this_object()));
81 properties::create();
82 restrictions::create();
83 commands::create();
84 light::create();
85 description::create();
86 exits::create();
87 items::create();
88 doors::create();
89
90 SetProp(P_NAME,0);
91 SetProp(P_NAME_ADJ,({}));
92 Set(P_SHORT,0);
93 Set(P_LONG,0);
94 Set(P_TRANSPARENT,0);
95 Set(P_ADJECTIVES,({}));
96 Set(P_IDS,({}));
97 Set(P_WEIGHT,PROTECTED,F_MODE);
98 Set(P_TOTAL_WEIGHT,PROTECTED,F_MODE);
99 Set(" clean counter ",2);
100}
101
102protected void create_super() {
103 set_next_reset(-1);
104}
105
106private int
107check_clean_count()
108{
109 int cc;
110
111 cc=Query(" clean counter ");
112 if (--cc<=0)
113 return 1;
114 Set(" clean counter ",cc);
115 return 0;
116}
117
118int
119clean_up(int arg)
120{
121 mixed itema;
122
123 if(arg>1) return 1; // better not ;)
124
125 if (Query(" never clean ")) return 0;
126
127 // if there are any item we have produced ourselfes check them
128 if(pointerp(itema = QueryProp(P_ITEMS)))
129 {
130 mixed names;
131 int i;
132 i = sizeof(names = all_inventory(this_object()));
133 while(i--)
134 {
135 if (query_once_interactive(names[i]))
136 {
137 Set(" clean counter ",2);
138 return 1;
139 }
140 if(objectp(names[i])) names[i] = explode(object_name(names[i]),"#")[0];
141 }
142
143 for(i = sizeof(itema)-1; i >= 0; i--)
144 {
145 // Semantik:
146 // 1. Wenn RITEM_OBJECT ein array ist, kann evtl ge'clean'ed werden.
147 // 2. Wenn es ein REFRESH_NONE Item ist und es entweder nicht mehr
148 // existiert oder nicht in diesem Raum ist, kein clean_up (es wuerde
149 // beim neuladen des Raumes ja wieder erzeugt;
150 // falls es aber hier ist, wird es mitvernichtet, dann ists ok)
151 // 3. Wenn es ein REFRESH_DESTRUCT ist und noch existiert, aber nicht
152 // hier ist, KEIN clean_up.
153 if (!pointerp(itema[i][RITEM_OBJECT])
154 && ((itema[i][RITEM_REFRESH] == REFRESH_NONE
155 && (!itema[i][RITEM_OBJECT]
156 || environment(itema[i][RITEM_OBJECT])!=this_object()))
157 || (itema[i][RITEM_REFRESH] == REFRESH_DESTRUCT
158 && itema[i][RITEM_OBJECT]
159 && environment(itema[i][RITEM_OBJECT]) != this_object())))
160 return 1;
161 names -= (pointerp(itema[i][RITEM_FILE]) ?
162 itema[i][RITEM_FILE] : ({ itema[i][RITEM_FILE] }));
163 }
164 // if there are objects left in the room do not clean up but try again later
165 if(sizeof(names) && !check_clean_count()) return 1;
166 }
167 else
168 // is there any object lying around?
169 if(first_inventory(this_object()) && !check_clean_count()) return 2;
170
171 // do clean_up
172 //log_file("clean_up_log",sprintf(
173 // "%s:%s: %O\n",ctime(time())[11..18],__HOST_NAME__,this_object()));
174
175 remove();
176 // wenn der Raum sich im remove() nicht zerstoert, hat er dafuer vermutlich
177 // nen Grund. Evtl. klappts ja naechstes Mal.
178
179 return(1);
180}
181
182/* Instead of printing the exits with the long description, we implement */
183/* the command "exits" to show them. */
184int
185show_exits() {
186 mixed ex;
187 if( this_player()->CannotSee() ) return 1;
188 if ((ex=QueryProp(P_HIDE_EXITS)) && intp(ex)) return 1;
189 if (ex = GetExits(this_player())) write(ex);
190 return 1;
191}
192
193int
194toggle_exits(string str)
195{
196 int ex;
197
198 /* Nur das aktuelle Environment des Spielers ist zustaendig fuer die
199 Auflistung der Ausgaenge. Anderenfalls wird das Kommando von Raeumen
200 im Raum (z.B. Transportern) abgefangen und es werden dessen Ausgaenge
201 aufgelistet.
202 Sprich: keine Auflistung von Aussen. */
203 if (environment(this_player()) != this_object()) return 0;
204 if (!str) return show_exits();
205 if (str!="auto") return 0;
206 ex = this_player()->QueryProp(P_SHOW_EXITS);
207 this_player()->SetProp(P_SHOW_EXITS, !ex);
208 if (ex) write("Ausgaenge werden nicht mehr automatisch angezeigt.\n");
209 else write("Ausgaenge werden automatisch angezeigt.\n");
210 return 1;
211}
212
213void
214init()
215{
216 Set(" clean counter ",2);
217
218 exits::init();
219 commands::init();
220 description::init();
221 doors::init();
222
223 add_action("toggle_exits", "exits");
224 add_action("toggle_exits", "ausgang");
225 add_action("toggle_exits", "ausgaenge");
226 add_action("toggle_exits", "aus");
227}
228
229int _query_para(){
230 int re;
231 if(re=Query(P_PARA))return re;
232 if(sizeof(regexp(({object_name(this_object())}),".*\\^0$")))
233 return -1;
234 return to_int(
235 regreplace(object_name(this_object()),".*\\^\([1-9][0-9]*\)$","\\1",1));
236}
237
238//dies ist ein Raum, war gewuenscht von mehreren Leuten.
239status IsRoom() {return(1);}