blob: 5b87bf03f1fe4f9bb5369f8bbf90ed67c7db99d2 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// container/items.c -- creating extra items in room
4//
5// $Id: items.c 8811 2014-05-09 17:30:37Z Zesstra $
6
7// extra items handling
8//
9// AddItem(string filename, int refresh)
10// Clones an item and puts it into the room. <refresh> may be
11// on of the following:
12// REFRESH_NONE: No refresh done until reboot.
13// REFRESH_DESTRUCT: Refresh on reset if item was destructed.
14// REFRESH_REMOVE: Refresh on reset if item was removed from room.
15// REFRESH_ALWAYS: Create a new clone on every reset.
16//
17// The commands are implemented as properties P_ITEMS as mapping. They are
18// stored locally (_set_xx) as mapping to speed up the routines
19// in this module.
20//
21// Format of key and data in the P_ITEMS mapping:
22//
23// ([ key1 : refresh1; obp1; arr1, ..., keyn : refreshn; obpn; arrn ])
24
25#include <sys_debug.h>
26#pragma strict_types
27#pragma save_types
28#pragma range_check
29#pragma no_clone
30#pragma pedantic
31
32#define NEED_PROTOTYPES
33#include <thing/properties.h>
34#include <rooms.h>
35#include <container.h>
36#undef NEED_PROTOTYPES
37#include <defines.h>
38#include <config.h>
39#include <properties.h>
40#include <moving.h>
41#include <daemon.h>
42
43protected void create()
44{
Bugfixacdf07a2016-10-13 20:25:25 +020045 Set(P_ITEMS,({}));
46 Set(P_ITEMS,SECURED,F_MODE_AS);
47
48 OBJECTD->QueryObject(); // querying general objects
MG Mud User88f12472016-06-24 23:31:02 +020049}
50
Bugfixacdf07a2016-10-13 20:25:25 +020051protected void create_super()
52{
MG Mud User88f12472016-06-24 23:31:02 +020053 set_next_reset(-1);
54}
55
56/* Kram zum Aufraeumen von multiplen gleichen Items im Container. */
Bugfixacdf07a2016-10-13 20:25:25 +020057private object removeable_ob(object ob)
MG Mud User88f12472016-06-24 23:31:02 +020058{
Bugfixacdf07a2016-10-13 20:25:25 +020059 if(!query_once_interactive(ob) && !living(ob))
60 {
61 return ob;
62 }
MG Mud User88f12472016-06-24 23:31:02 +020063
Bugfixacdf07a2016-10-13 20:25:25 +020064 return 0;
MG Mud User88f12472016-06-24 23:31:02 +020065}
66
67protected varargs void remove_multiple(int limit, mixed fun)
68{
Bugfixacdf07a2016-10-13 20:25:25 +020069 object *inh = all_inventory(ME)-({0});
MG Mud User88f12472016-06-24 23:31:02 +020070
Bugfixacdf07a2016-10-13 20:25:25 +020071 inh=filter(inh,#'removeable_ob);
72 foreach(mixed item : QueryProp(P_ITEMS))
73 {
74 inh-=({item[0]});
75 }
76
77 if(!stringp(fun) && !closurep(fun))
78 {
79 fun="description_id";
80 }
81 inh=unique_array(inh,fun,0);
82 foreach(mixed arr : inh)
83 {
84 if(sizeof(arr)<=limit)
MG Mud User88f12472016-06-24 23:31:02 +020085 {
Bugfixacdf07a2016-10-13 20:25:25 +020086 continue;
MG Mud User88f12472016-06-24 23:31:02 +020087 }
Bugfixacdf07a2016-10-13 20:25:25 +020088 catch(call_other(arr[limit ..], "remove"); publish);
89 }
MG Mud User88f12472016-06-24 23:31:02 +020090}
91
92
93/* Item handling */
Bugfixacdf07a2016-10-13 20:25:25 +020094public varargs object AddItem(mixed filename, int refresh, mixed props)
MG Mud User88f12472016-06-24 23:31:02 +020095{
Bugfixacdf07a2016-10-13 20:25:25 +020096 string file;
97 object ob;
98 int i;
MG Mud User88f12472016-06-24 23:31:02 +020099
Bugfixacdf07a2016-10-13 20:25:25 +0200100 if(pointerp(filename))
101 {
102 for(i=sizeof(filename);i--;)
103 {
104 filename[i] = (string)master()->_get_path( filename[i], "?" );
MG Mud User88f12472016-06-24 23:31:02 +0200105 }
Bugfixacdf07a2016-10-13 20:25:25 +0200106
107 file=filename[random(sizeof(filename))];
108 }
109 else
110 {
111 file=filename=(string)master()->_get_path(filename,"?");
112 }
113
114 if(props==1)
115 {
116 catch(ob=load_object(file); publish);
117 }
118 else
119 {
120 catch(ob=clone_object(file); publish);
121 }
122
123 if(objectp(ob))
124 {
125 ob->move(ME,M_NOCHECK|M_NO_ATTACK);
126 // mit Absicht keine Pruefung aufs Move, wenns nicht geht, solls 2s
127 // spaeter auf der Ebene buggen, weil praktisch niemand im create() das
128 // Ergebnis vom AddItem() prueft.
129 }
MG Mud User88f12472016-06-24 23:31:02 +0200130
Bugfixacdf07a2016-10-13 20:25:25 +0200131 // In P_ITEMS vermerken, es sei denn, REFRESH_NONE ist gegeben, in dem
132 // Fall ist die Speicherung voellig unnoetig.
133 // TODO: Pruefen, ob das wirklich problemlos geht. Bis dahin werden auch
134 // TODO::REFRESH_NONE-Items vermerkt. (s. clean_up() in /std/room.c)
135 //if (!(refresh&REFRESH_NONE)) {
136 SetProp(P_ITEMS,QueryProp(P_ITEMS)+
137 ({
138 ({
139 ob, // RITEM_OBJECT
140 filename, // RITEM_FILE
141 refresh // RITEM_REFRESH
142 })+
143 ((mappingp(props) || props==1) ? ({props}) : ({}))
144 }));
145 //}
MG Mud User88f12472016-06-24 23:31:02 +0200146
Bugfixacdf07a2016-10-13 20:25:25 +0200147 if(ob && mappingp(props))
148 walk_mapping(props,symbol_function("SetProp",ob));
149
150 return ob;
MG Mud User88f12472016-06-24 23:31:02 +0200151}
152
153
Bugfixacdf07a2016-10-13 20:25:25 +0200154private void ri_rem_ob(object ob)
MG Mud User88f12472016-06-24 23:31:02 +0200155{
Bugfixacdf07a2016-10-13 20:25:25 +0200156 object *inv;
157 int i;
MG Mud User88f12472016-06-24 23:31:02 +0200158
Bugfixacdf07a2016-10-13 20:25:25 +0200159 if(objectp(ob) && present(ob,ME))
160 {
161 inv=deep_inventory(ob);
162
163 for(i=sizeof(inv);i--;)
164 {
165 if(inv[i])
166 {
167 inv[i]->remove(1);
168
169 if(inv[i])
170 {
171 destruct(inv[i]);
MG Mud User88f12472016-06-24 23:31:02 +0200172 }
Bugfixacdf07a2016-10-13 20:25:25 +0200173 }
174 }
175 ob->remove(1);
176
177 if(ob)
178 {
179 destruct(ob);
180 }
181 }
182}
183
184
185private int ri_filter(mixed *ritem, mixed file)
186{
187 object ob, *inv;
188 int i;
189
190 ob=ritem[RITEM_OBJECT];
191
192 if(stringp(file) && ritem[RITEM_FILE]==file)
193 return ri_rem_ob(ob), 0;
194 else if(pointerp(ritem[RITEM_FILE]) && pointerp(file) &&
195 sizeof(file&ritem[RITEM_FILE])==sizeof(ritem[RITEM_FILE]))
196 return ri_rem_ob(ob), 0;
197
198 return 1;
199}
200
201
202public void RemoveItem(mixed filename)
203{
204 mixed *items;
205 int i;
206
207 if(!pointerp(items=QueryProp(P_ITEMS)) || !sizeof(items))
208 return;
209
210 if(pointerp(filename))
211 {
212 for(i=sizeof(filename);i--;)
213 {
214 filename[i] = (string)master()->_get_path( filename[i], "?" );
215 }
216 }
217 else
218 {
219 filename = (string)master()->_get_path( filename, "?" );
220 }
221
222 SetProp(P_ITEMS,filter(items,#'ri_filter,filename));
223}
224
225
226private mixed _do_refresh(mixed item)
227{
228 string file;
229 object ob;
230
231 if(!pointerp(item) || item[RITEM_REFRESH]==REFRESH_NONE)
232 {
233 return item;
234 }
235
236 if(pointerp(item[RITEM_FILE]))
237 {
238 file=item[RITEM_FILE][random(sizeof(item[RITEM_FILE]))];
239 }
240 else
241 {
242 file=item[RITEM_FILE];
243 }
244
245 switch(item[RITEM_REFRESH])
246 {
247 case REFRESH_MOVE_HOME:
248 if(objectp(item[RITEM_OBJECT]) &&
249 environment(item[RITEM_OBJECT])!=ME)
250 {
251 item[RITEM_OBJECT]->move(ME,M_GO|M_NO_ATTACK);
252 break;
253 }
254
MG Mud User88f12472016-06-24 23:31:02 +0200255 // fall through
256 case REFRESH_DESTRUCT:
Bugfixacdf07a2016-10-13 20:25:25 +0200257 if(objectp(item[RITEM_OBJECT]))
258 break; // else FALL THROUGH
259
MG Mud User88f12472016-06-24 23:31:02 +0200260 case REFRESH_REMOVE:
Bugfixacdf07a2016-10-13 20:25:25 +0200261 if(objectp(item[RITEM_OBJECT]) &&
262 environment(item[RITEM_OBJECT])==ME)
263 break; // else FALL THROUGH
264
MG Mud User88f12472016-06-24 23:31:02 +0200265 default:
Bugfixacdf07a2016-10-13 20:25:25 +0200266 if(sizeof(item)>RITEM_PROPS && item[RITEM_PROPS]==1)
267 {
268 ob=load_object(file);
269 }
270 else
271 {
272 ob=clone_object(file);
273 }
MG Mud User88f12472016-06-24 23:31:02 +0200274
Bugfixacdf07a2016-10-13 20:25:25 +0200275 ob->move(ME,M_NOCHECK|M_NO_ATTACK);
276 break;
277 }
278
279 if(ob)
280 {
281 item[RITEM_OBJECT]=ob;
282
283 if(sizeof(item)>RITEM_PROPS && mappingp(item[RITEM_PROPS]))
284 walk_mapping(item[RITEM_PROPS],symbol_function("SetProp",ob));
285 }
286
287 return item;
MG Mud User88f12472016-06-24 23:31:02 +0200288}
289
290
291// reset handling: check how the items should be refreshed.
292void reset()
293{
Bugfixacdf07a2016-10-13 20:25:25 +0200294 mixed *items;
MG Mud User88f12472016-06-24 23:31:02 +0200295
Bugfixacdf07a2016-10-13 20:25:25 +0200296 if(!pointerp(items=QueryProp(P_ITEMS)))
297 {
298 SetProp(P_ITEMS,({}));
299 return;
300 }
301
302 SetProp(P_ITEMS,map(items,#'_do_refresh)-({0}));
MG Mud User88f12472016-06-24 23:31:02 +0200303}
304