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