ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.350
Committed: Sun May 8 12:40:41 2011 UTC (13 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.349: +5 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.199 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.116 *
4 root 1.343 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.314 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992 Frank Tore Johansen
7 pippijn 1.116 *
8 root 1.291 * Deliantra is free software: you can redistribute it and/or modify it under
9     * the terms of the Affero GNU General Public License as published by the
10     * Free Software Foundation, either version 3 of the License, or (at your
11     * option) any later version.
12 pippijn 1.116 *
13 root 1.163 * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17 pippijn 1.116 *
18 root 1.291 * You should have received a copy of the Affero GNU General Public License
19     * and the GNU General Public License along with this program. If not, see
20     * <http://www.gnu.org/licenses/>.
21 root 1.157 *
22 root 1.199 * The authors can be reached via e-mail to <support@deliantra.net>
23 pippijn 1.116 */
24 elmex 1.1
25     #include <global.h>
26 root 1.28 #include <stdio.h>
27     #include <sys/types.h>
28     #include <sys/uio.h>
29 elmex 1.1 #include <object.h>
30 root 1.146 #include <sproto.h>
31 root 1.28
32 root 1.68 #include <bitset>
33    
34 root 1.202 UUID UUID::cur;
35 root 1.204 static uint64_t seq_next_save;
36     static const uint64 UUID_GAP = 1<<19;
37 root 1.272 uint32_t mapspace::smellcount = 10000;
38 elmex 1.1
39 root 1.108 objectvec objects;
40     activevec actives;
41 elmex 1.1
42 root 1.324 freelist_item *object::freelist;
43     uint32_t object::object_count;
44     uint32_t object::free_count;
45     uint32_t object::create_count;
46     uint32_t object::destroy_count;
47    
48 root 1.294 //+GPL
49    
50 root 1.203 short freearr_x[SIZEOFFREE] = {
51     0,
52     0, 1, 1, 1, 0, -1, -1, -1,
53     0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1,
54     0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1
55 root 1.24 };
56 root 1.203 short freearr_y[SIZEOFFREE] = {
57     0,
58     -1, -1, 0, 1, 1, 1, 0, -1,
59     -2, -2, -2, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2,
60     -3, -3, -3, -3, -2, -1, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3
61 root 1.24 };
62     int freedir[SIZEOFFREE] = {
63 root 1.203 0,
64     1, 2, 3, 4, 5, 6, 7, 8,
65     1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8,
66     1, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8
67 root 1.24 };
68 elmex 1.1
69 root 1.295 static int maxfree[SIZEOFFREE] = {
70     0,
71     9, 10, 13, 14, 17, 18, 21, 22,
72     25, 26, 27, 30, 31, 32, 33, 36, 37, 39, 39, 42, 43, 44, 45, 48,
73     49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49
74     };
75    
76 root 1.338 const char *wall_suffix[16] = {
77     "0",
78     "1_3",
79     "1_4",
80     "2_1_2",
81     "1_2",
82     "2_2_4",
83     "2_2_1",
84     "3_1",
85     "1_1",
86     "2_2_3",
87     "2_2_2",
88     "3_3",
89     "2_1_1",
90     "3_4",
91     "3_2",
92     "4"
93     };
94    
95 root 1.39 static void
96 root 1.203 write_uuid (uval64 skip, bool sync)
97 root 1.39 {
98 root 1.203 CALL_BEGIN (2);
99     CALL_ARG_SV (newSVval64 (skip));
100     CALL_ARG_SV (boolSV (sync));
101     CALL_CALL ("cf::write_uuid", G_DISCARD);
102     CALL_END;
103 root 1.39 }
104    
105     static void
106 root 1.307 read_uuid ()
107 root 1.39 {
108     char filename[MAX_BUF];
109    
110     sprintf (filename, "%s/uuid", settings.localdir);
111    
112 root 1.204 seq_next_save = 0;
113    
114 root 1.39 FILE *fp;
115    
116     if (!(fp = fopen (filename, "r")))
117     {
118     if (errno == ENOENT)
119     {
120     LOG (llevInfo, "RESET uid to 1\n");
121 root 1.202 UUID::cur.seq = 0;
122 root 1.204 write_uuid (UUID_GAP, true);
123 root 1.39 return;
124     }
125    
126     LOG (llevError, "FATAL: cannot open %s for reading!\n", filename);
127     _exit (1);
128     }
129    
130 root 1.300 char buf [UUID::MAX_LEN];
131 root 1.203 buf[0] = 0;
132     fgets (buf, sizeof (buf), fp);
133    
134     if (!UUID::cur.parse (buf))
135 root 1.39 {
136 root 1.203 LOG (llevError, "FATAL: error reading uid from %s (%s)!\n", filename, buf);
137 root 1.39 _exit (1);
138     }
139    
140 root 1.203 LOG (llevDebug, "read UUID: %s\n", UUID::cur.c_str ());
141    
142 root 1.204 write_uuid (UUID_GAP, true);
143 root 1.39 fclose (fp);
144     }
145    
146     UUID
147 root 1.202 UUID::gen ()
148 root 1.39 {
149     UUID uid;
150    
151 root 1.202 uid.seq = ++cur.seq;
152 root 1.39
153 root 1.204 if (expect_false (cur.seq >= seq_next_save))
154     {
155     seq_next_save = UUID::cur.seq + (UUID_GAP >> 1);
156     write_uuid (UUID_GAP, false);
157     }
158    
159 root 1.39
160     return uid;
161     }
162    
163     void
164 root 1.202 UUID::init ()
165 root 1.39 {
166     read_uuid ();
167     }
168    
169 root 1.300 bool
170     UUID::parse (const char *s)
171     {
172     if (*s++ != '<' || *s++ != '1' || *s++ != '.')
173     return false;
174    
175     seq = 0;
176    
177     while (*s != '>')
178     {
179     if (*s < '0')
180     return false;
181    
182     // this gives nice branchless code with gcc
183     assert ('0' < 'a' && '0' == 48 && 'a' == 97);
184     int digit = (*s + (*s & 0x40 ? 9 : 0)) & 15;
185    
186     seq = (seq << 4) | digit;
187    
188     ++s;
189     }
190    
191     return true;
192     }
193    
194     char *
195     UUID::append (char *buf) const
196     {
197     *buf++ = '<';
198     *buf++ = '1';
199     *buf++ = '.';
200    
201     uint64_t seq = this->seq;
202     const int bits = 64;
203     char nz = 0;
204     static const char tohex [] = "0123456789abcdef";
205    
206     // assert (len >= 3 + bits / 4 + 1 + 1);
207     for (int i = bits / 4; --i; )
208     {
209     uint8_t digit = seq >> (bits - 4);
210    
211     *buf = tohex [digit];
212     nz |= digit;
213     buf += nz ? 1 : 0;
214     seq <<= 4;
215     }
216    
217     // last digit is special - always emit
218     uint8_t digit = seq >> (bits - 4);
219     *buf++ = tohex [digit];
220    
221     *buf++ = '>';
222    
223     return buf;
224     }
225    
226     char *
227     UUID::c_str () const
228     {
229     static char buf [MAX_LEN];
230     *append (buf) = 0;
231     return buf;
232     }
233    
234 elmex 1.1 /* Returns TRUE if every key_values in wants has a partner with the same value in has. */
235 root 1.205 static bool
236 root 1.24 compare_ob_value_lists_one (const object *wants, const object *has)
237     {
238 root 1.344 /* n-squared behaviour (see kv.get), but I'm hoping both
239 root 1.24 * objects with lists are rare, and lists stay short. If not, use a
240     * different structure or at least keep the lists sorted...
241     */
242    
243     /* For each field in wants, */
244 root 1.344 for (key_value *kv = wants->kv.first; kv; kv = kv->next)
245     if (has->kv.get (kv->key) != kv->value)
246 root 1.228 return false;
247 root 1.24
248     /* If we get here, every field in wants has a matching field in has. */
249 root 1.228 return true;
250 elmex 1.1 }
251    
252     /* Returns TRUE if ob1 has the same key_values as ob2. */
253 root 1.205 static bool
254 root 1.24 compare_ob_value_lists (const object *ob1, const object *ob2)
255     {
256     /* However, there may be fields in has which aren't partnered in wants,
257     * so we need to run the comparison *twice*. :(
258     */
259 root 1.228 return compare_ob_value_lists_one (ob1, ob2)
260     && compare_ob_value_lists_one (ob2, ob1);
261 elmex 1.1 }
262    
263     /* Function examines the 2 objects given to it, and returns true if
264     * they can be merged together.
265     *
266     * Note that this function appears a lot longer than the macro it
267     * replaces - this is mostly for clarity - a decent compiler should hopefully
268     * reduce this to the same efficiency.
269     *
270 root 1.66 * Check nrof variable *before* calling can_merge()
271 elmex 1.1 *
272     * Improvements made with merge: Better checking on potion, and also
273     * check weight
274     */
275 root 1.66 bool object::can_merge_slow (object *ob1, object *ob2)
276 root 1.16 {
277 root 1.310 /* A couple quick sanity checks */
278 root 1.66 if (ob1 == ob2
279 sf-kernelpanic 1.342 || ob1->type != ob2->type
280     || ob1->value != ob2->value
281     || ob1->name != ob2->name
282     || ob1->custom_name != ob2->custom_name
283 root 1.310 || fabs (ob1->speed - ob2->speed) >= MIN_ACTIVE_SPEED)
284 root 1.16 return 0;
285    
286 root 1.254 /* Do not merge objects if nrof would overflow, assume nrof
287     * is always 0 .. 2**31-1 */
288     if (ob1->nrof > 0x7fffffff - ob2->nrof)
289 root 1.16 return 0;
290    
291     /* If the objects have been identified, set the BEEN_APPLIED flag.
292 root 1.205 * This is to the comparison of the flags below will be OK. We
293 root 1.16 * just can't ignore the been applied or identified flags, as they
294     * are not equal - just if it has been identified, the been_applied
295     * flags lose any meaning.
296     */
297 root 1.322 if (ob1->flag [FLAG_IDENTIFIED])
298     ob1->set_flag (FLAG_BEEN_APPLIED);
299 root 1.16
300 root 1.322 if (ob2->flag [FLAG_IDENTIFIED])
301     ob2->set_flag (FLAG_BEEN_APPLIED);
302 elmex 1.1
303 root 1.243 if (ob1->arch->archname != ob2->arch->archname
304 root 1.68 || ob1->name != ob2->name
305     || ob1->title != ob2->title
306     || ob1->msg != ob2->msg
307     || ob1->weight != ob2->weight
308     || ob1->attacktype != ob2->attacktype
309     || ob1->magic != ob2->magic
310     || ob1->slaying != ob2->slaying
311     || ob1->skill != ob2->skill
312     || ob1->value != ob2->value
313     || ob1->animation_id != ob2->animation_id
314 root 1.310 || (ob1->face != ob2->face && !ob1->animation_id) // face and animation are dependend on each other
315 root 1.68 || ob1->client_type != ob2->client_type
316 root 1.303 || ob1->material != ob2->material
317 root 1.68 || ob1->lore != ob2->lore
318     || ob1->subtype != ob2->subtype
319     || ob1->move_type != ob2->move_type
320     || ob1->move_block != ob2->move_block
321     || ob1->move_allow != ob2->move_allow
322     || ob1->move_on != ob2->move_on
323     || ob1->move_off != ob2->move_off
324     || ob1->move_slow != ob2->move_slow
325 root 1.298 || fabs (ob1->move_slow_penalty - ob2->move_slow_penalty) >= (1.f / 1024.f)
326 root 1.208 || memcmp (&ob1->resist, &ob2->resist, sizeof (ob1->resist))
327     || memcmp (&ob1->stats , &ob2->stats , sizeof (ob1->stats)))
328     return 0;
329    
330     if ((ob1->flag ^ ob2->flag)
331     .reset (FLAG_INV_LOCKED)
332     .reset (FLAG_REMOVED)
333     .any ())
334 root 1.16 return 0;
335    
336 root 1.205 /* This is really a spellbook check - we should in general
337     * not merge objects with real inventories, as splitting them
338     * is hard.
339 root 1.16 */
340     if (ob1->inv || ob2->inv)
341     {
342 root 1.193 if (!(ob1->inv && ob2->inv))
343     return 0; /* inventories differ in length */
344    
345     if (ob1->inv->below || ob2->inv->below)
346     return 0; /* more than one object in inv */
347 root 1.16
348 root 1.66 if (!object::can_merge (ob1->inv, ob2->inv))
349 root 1.205 return 0; /* inventory objects differ */
350 root 1.16
351     /* inventory ok - still need to check rest of this object to see
352     * if it is valid.
353     */
354     }
355 elmex 1.1
356 root 1.16 /* Don't merge objects that are applied. With the new 'body' code,
357     * it is possible for most any character to have more than one of
358     * some items equipped, and we don't want those to merge.
359     */
360 root 1.322 if (ob1->flag [FLAG_APPLIED] || ob2->flag [FLAG_APPLIED])
361 root 1.16 return 0;
362 elmex 1.1
363 root 1.16 /* Note sure why the following is the case - either the object has to
364     * be animated or have a very low speed. Is this an attempted monster
365     * check?
366     */
367 root 1.322 if (!ob1->flag [FLAG_ANIMATE] && ob1->has_active_speed ())
368 root 1.16 return 0;
369 elmex 1.1
370 root 1.16 switch (ob1->type)
371     {
372 root 1.29 case SCROLL:
373     if (ob1->level != ob2->level)
374     return 0;
375     break;
376 root 1.16 }
377 elmex 1.1
378 root 1.344 if (!ob1->kv.empty () || !ob2->kv.empty ())
379 root 1.16 {
380     /* At least one of these has key_values. */
381 root 1.344 if (ob1->kv.empty () != ob2->kv.empty ())
382 root 1.208 return 0; /* One has fields, but the other one doesn't. */
383    
384     if (!compare_ob_value_lists (ob1, ob2))
385 root 1.24 return 0;
386 elmex 1.1 }
387 root 1.16
388     if (ob1->self || ob2->self)
389     {
390     ob1->optimise ();
391     ob2->optimise ();
392    
393     if (ob1->self || ob2->self)
394 root 1.192 {
395 root 1.195 int k1 = ob1->self ? HvTOTALKEYS (ob1->self) : 0;
396     int k2 = ob2->self ? HvTOTALKEYS (ob2->self) : 0;
397 root 1.192
398     if (k1 != k2)
399     return 0;
400 root 1.208
401     if (k1 == 0)
402 root 1.192 return 1;
403 root 1.208
404     if (!cfperl_can_merge (ob1, ob2))
405 root 1.192 return 0;
406     }
407 elmex 1.1 }
408    
409 root 1.16 /* Everything passes, must be OK. */
410     return 1;
411 elmex 1.1 }
412 root 1.24
413 root 1.214 // find player who can see this object
414     object *
415     object::visible_to () const
416     {
417 root 1.220 if (client_visible () && !flag [FLAG_REMOVED])
418 root 1.214 {
419     // see if we are in a container of sorts
420     if (env)
421     {
422     // the player inventory itself is always visible
423 root 1.270 if (env->is_player ())
424 root 1.214 return env;
425    
426     // else a player could have our env open
427 root 1.285 object *envest = env->outer_env_or_self ();
428 root 1.214
429     // the player itself is always on a map, so we will find him here
430     // even if our inv is in a player.
431     if (envest->is_on_map ())
432     if (object *pl = envest->ms ().player ())
433 root 1.292 if (pl->container_ () == env)
434 root 1.214 return pl;
435     }
436     else
437     {
438     // maybe there is a player standing on the same mapspace
439     // this will catch the case where "this" is a player
440     if (object *pl = ms ().player ())
441 root 1.292 if ((pl->contr->ns && !pl->container_ () && !pl->contr->ns->update_look)
442     || pl->container_ () == this)
443 root 1.220 return pl;
444 root 1.214 }
445     }
446    
447     return 0;
448     }
449    
450 root 1.208 // adjust weight per container type ("of holding")
451 root 1.337 static uint32
452     weight_adjust_for (object *op, uint32 weight)
453 root 1.207 {
454     return op->type == CONTAINER
455 root 1.337 ? weight - weight * op->stats.Str / 100
456 root 1.207 : weight;
457     }
458    
459 elmex 1.1 /*
460 root 1.337 * subtracts, then adds, the specified weight to an object,
461 root 1.207 * and also updates how much the environment(s) is/are carrying.
462 elmex 1.1 */
463 root 1.207 static void
464 root 1.337 adjust_weight (object *op, sint32 sub, sint32 add)
465 root 1.24 {
466 root 1.207 while (op)
467 root 1.24 {
468 root 1.337 sint32 ocarrying = op->carrying;
469 root 1.142
470 root 1.337 op->carrying -= weight_adjust_for (op, sub);
471     op->carrying += weight_adjust_for (op, add);
472 root 1.212
473     if (object *pl = op->visible_to ())
474 root 1.215 if (pl != op) // player is handled lazily
475     esrv_update_item (UPD_WEIGHT, pl, op);
476 root 1.212
477 root 1.337 sub = ocarrying;
478     add = op->carrying;
479    
480 root 1.207 op = op->env;
481 root 1.24 }
482 root 1.207 }
483 root 1.37
484 root 1.207 /*
485     * this is a recursive function which calculates the weight
486     * an object is carrying. It goes through op and figures out how much
487     * containers are carrying, and sums it up.
488     */
489     void
490     object::update_weight ()
491     {
492     sint32 sum = 0;
493 root 1.37
494 root 1.207 for (object *op = inv; op; op = op->below)
495     {
496 root 1.337 op->update_weight ();
497 elmex 1.1
498 root 1.337 sum += weight_adjust_for (this, op->total_weight ());
499 root 1.207 }
500 elmex 1.1
501 root 1.212 if (sum != carrying)
502     {
503 root 1.337 if (carrying != sum && carrying)//D
504 root 1.333 LOG (llevDebug, "updating carrying got %ld, expected %ld (%s)\n",
505 root 1.326 (long long)sum, (long long)carrying, debug_desc ());
506    
507 root 1.212 carrying = sum;
508    
509     if (object *pl = visible_to ())
510 root 1.215 if (pl != this) // player is handled lazily
511     esrv_update_item (UPD_WEIGHT, pl, this);
512 root 1.212 }
513 elmex 1.1 }
514    
515     /*
516 root 1.208 * Used by: Server DM commands: dumpbelow, dump. Some error messages.
517 elmex 1.1 */
518 root 1.53 char *
519 root 1.24 dump_object (object *op)
520     {
521 root 1.53 if (!op)
522     return strdup ("[NULLOBJ]");
523 elmex 1.1
524 root 1.53 object_freezer freezer;
525 root 1.133 op->write (freezer);
526 root 1.53 return freezer.as_string ();
527 elmex 1.1 }
528    
529 root 1.289 char *
530     object::as_string ()
531     {
532     return dump_object (this);
533     }
534    
535 elmex 1.1 /*
536     * Returns the object which has the count-variable equal to the argument.
537 root 1.208 * VERRRY slow.
538 elmex 1.1 */
539 root 1.24 object *
540     find_object (tag_t i)
541     {
542 root 1.112 for_all_objects (op)
543     if (op->count == i)
544     return op;
545    
546     return 0;
547 elmex 1.1 }
548    
549     /*
550 elmex 1.312 * Returns the object which has the uuid equal to the argument.
551     * MOAR VERRRY slow.
552     */
553    
554     object *
555     find_object_uuid (UUID i)
556     {
557     for_all_objects (op)
558     if (op->uuid == i)
559     return op;
560    
561     return 0;
562     }
563    
564     /*
565 elmex 1.1 * Returns the first object which has a name equal to the argument.
566     * Used only by the patch command, but not all that useful.
567     * Enables features like "patch <name-of-other-player> food 999"
568     */
569 root 1.24 object *
570     find_object_name (const char *str)
571     {
572 root 1.35 shstr_cmp str_ (str);
573 root 1.24
574 root 1.243 if (str_)
575     for_all_objects (op)
576     if (op->name == str_)
577     return op;
578 root 1.11
579 root 1.243 return 0;
580 elmex 1.1 }
581    
582     /*
583     * Sets the owner and sets the skill and exp pointers to owner's current
584     * skill and experience objects.
585 root 1.183 * ACTUALLY NO! investigate! TODO
586 elmex 1.1 */
587 root 1.24 void
588 root 1.30 object::set_owner (object *owner)
589 elmex 1.1 {
590 root 1.183 // allow objects which own objects
591     if (owner)
592     while (owner->owner)
593     owner = owner->owner;
594 elmex 1.1
595 root 1.198 if (flag [FLAG_FREED])
596     {
597     LOG (llevError | logBacktrace, "tried to set owner of %s to %s\n", debug_desc (), owner->debug_desc ());
598     return;
599     }
600    
601 root 1.30 this->owner = owner;
602 elmex 1.1 }
603    
604 root 1.227 /*
605     * copy_to first frees everything allocated by the dst object,
606     * and then copies the contents of itself into the second
607     * object, allocating what needs to be allocated. Basically, any
608     * data that is malloc'd needs to be re-malloc/copied. Otherwise,
609     * if the first object is freed, the pointers in the new object
610     * will point at garbage.
611     */
612     void
613     object::copy_to (object *dst)
614 root 1.11 {
615 root 1.227 dst->remove ();
616     *(object_copy *)dst = *this;
617 elmex 1.1
618 root 1.344 // maybe move to object_copy?
619     dst->kv = kv;
620 root 1.137
621 root 1.344 dst->flag [FLAG_REMOVED] = true;
622 root 1.256 dst->activate ();
623 elmex 1.1 }
624    
625 root 1.133 void
626     object::instantiate ()
627     {
628     if (!uuid.seq) // HACK
629 root 1.202 uuid = UUID::gen ();
630 root 1.133
631 root 1.341 // TODO: unclean state changes, should not be done in copy_to AND instantiate
632 root 1.306 if (flag [FLAG_RANDOM_SPEED] && speed)
633 root 1.308 speed_left = - speed - rndm (); // TODO animation
634 root 1.306 else
635 root 1.308 speed_left = -1.;
636 root 1.306
637 root 1.133 /* copy the body_info to the body_used - this is only really
638     * need for monsters, but doesn't hurt to do it for everything.
639     * by doing so, when a monster is created, it has good starting
640     * values for the body_used info, so when items are created
641     * for it, they can be properly equipped.
642     */
643 root 1.145 for (int i = NUM_BODY_LOCATIONS; i--; )
644     slot[i].used = slot[i].info;
645 root 1.133
646     attachable::instantiate ();
647     }
648    
649 root 1.65 object *
650     object::clone ()
651     {
652     object *neu = create ();
653     copy_to (neu);
654 root 1.306
655     // TODO: unclean state changes, should not be done in clone AND instantiate
656     if (neu->flag [FLAG_RANDOM_SPEED] && neu->speed)
657 root 1.308 neu->speed_left = - neu->speed - rndm (); // TODO animation
658 root 1.306
659 root 1.225 neu->map = map; // not copied by copy_to
660 root 1.65 return neu;
661     }
662    
663 elmex 1.1 /*
664     * If an object with the IS_TURNABLE() flag needs to be turned due
665     * to the closest player being on the other side, this function can
666     * be called to update the face variable, _and_ how it looks on the map.
667     */
668 root 1.24 void
669     update_turn_face (object *op)
670     {
671 root 1.322 if (!op->flag [FLAG_IS_TURNABLE] || !op->arch)
672 root 1.24 return;
673 root 1.96
674 root 1.24 SET_ANIMATION (op, op->direction);
675     update_object (op, UP_OBJ_FACE);
676 elmex 1.1 }
677    
678     /*
679     * Updates the speed of an object. If the speed changes from 0 to another
680     * value, or vice versa, then add/remove the object from the active list.
681     * This function needs to be called whenever the speed of an object changes.
682     */
683 root 1.24 void
684 root 1.87 object::set_speed (float speed)
685 root 1.24 {
686 root 1.87 this->speed = speed;
687    
688 elmex 1.97 if (has_active_speed ())
689 root 1.98 activate ();
690 root 1.24 else
691 root 1.98 deactivate ();
692 elmex 1.1 }
693    
694     /*
695 root 1.75 * update_object() updates the the map.
696 elmex 1.1 * It takes into account invisible objects (and represent squares covered
697     * by invisible objects by whatever is below them (unless it's another
698     * invisible object, etc...)
699     * If the object being updated is beneath a player, the look-window
700     * of that player is updated (this might be a suboptimal way of
701     * updating that window, though, since update_object() is called _often_)
702     *
703     * action is a hint of what the caller believes need to be done.
704     * current action are:
705     * UP_OBJ_INSERT: op was inserted
706     * UP_OBJ_REMOVE: op was removed
707     * UP_OBJ_CHANGE: object has somehow changed. In this case, we always update
708     * as that is easier than trying to look at what may have changed.
709     * UP_OBJ_FACE: only the objects face has changed.
710     */
711 root 1.24 void
712     update_object (object *op, int action)
713     {
714 root 1.222 if (!op)
715 root 1.24 {
716     /* this should never happen */
717 root 1.222 LOG (llevError | logBacktrace, "update_object() called for NULL object.\n");
718 root 1.24 return;
719 elmex 1.1 }
720 root 1.24
721 root 1.222 if (!op->is_on_map ())
722 root 1.24 {
723     /* Animation is currently handled by client, so nothing
724     * to do in this case.
725     */
726     return;
727 elmex 1.1 }
728    
729 root 1.24 /* make sure the object is within map boundaries */
730 root 1.83 if (op->x < 0 || op->x >= op->map->width || op->y < 0 || op->y >= op->map->height)
731 root 1.24 {
732     LOG (llevError, "update_object() called for object out of map!\n");
733 elmex 1.1 #ifdef MANY_CORES
734 root 1.24 abort ();
735 elmex 1.1 #endif
736 root 1.24 return;
737 elmex 1.1 }
738    
739 root 1.76 mapspace &m = op->ms ();
740 elmex 1.1
741 root 1.99 if (!(m.flags_ & P_UPTODATE))
742 root 1.348 m.update_up (); // nothing to do except copy up
743 root 1.75 else if (action == UP_OBJ_INSERT)
744     {
745 root 1.297 #if 0
746 root 1.75 // this is likely overkill, TODO: revisit (schmorp)
747 root 1.322 if ((op->flag [FLAG_BLOCKSVIEW] && !(m.flags_ & P_BLOCKSVIEW))
748     || (op->flag [FLAG_NO_MAGIC] && !(m.flags_ & P_NO_MAGIC))
749 root 1.270 || (op->is_player () && !(m.flags_ & P_PLAYER))
750 root 1.75 || (op->type == SAFE_GROUND && !(m.flags_ & P_SAFE))
751 root 1.322 || (op->flag [FLAG_ALIVE] && !(m.flags_ & P_IS_ALIVE))
752     || (op->flag [FLAG_DAMNED] && !(m.flags_ & P_NO_CLERIC))
753 root 1.75 || (m.move_on | op->move_on ) != m.move_on
754     || (m.move_off | op->move_off ) != m.move_off
755     || (m.move_slow | op->move_slow) != m.move_slow
756     /* This isn't perfect, but I don't expect a lot of objects to
757 root 1.252 * have move_allow right now.
758 root 1.75 */
759     || ((m.move_block | op->move_block) & ~op->move_allow) != m.move_block
760 root 1.265 m.invalidate ();
761 root 1.297 #else
762     // the above is not strong enough a test to skip updating. los maybe? TODO (schmorp)
763     m.invalidate ();
764     #endif
765 root 1.75 }
766     /* if the object is being removed, we can't make intelligent
767     * decisions, because remove_ob can't really pass the object
768     * that is being removed.
769     */
770 root 1.24 else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE)
771 root 1.265 m.invalidate ();
772 root 1.24 else if (action == UP_OBJ_FACE)
773 root 1.348 m.update_up (); // nothing to do for that case, except copy up
774 root 1.24 else
775 root 1.27 LOG (llevError, "update_object called with invalid action: %d\n", action);
776 elmex 1.1
777 root 1.75 if (op->more)
778 root 1.24 update_object (op->more, action);
779 elmex 1.1 }
780    
781 root 1.21 object::object ()
782     {
783 root 1.322 this->set_flag (FLAG_REMOVED);
784 root 1.22
785 root 1.284 //expmul = 1.0; declared const for the time being
786 root 1.303 face = blank_face;
787 root 1.304 material = MATERIAL_NULL;
788 root 1.22 }
789    
790     object::~object ()
791     {
792 root 1.121 unlink ();
793 root 1.119
794 root 1.344 kv.clear ();
795 root 1.22 }
796    
797 root 1.24 void object::link ()
798 root 1.22 {
799 root 1.112 assert (!index);//D
800 root 1.202 uuid = UUID::gen ();
801 root 1.21
802 root 1.109 refcnt_inc ();
803 root 1.108 objects.insert (this);
804 root 1.324
805     ++create_count;
806    
807 root 1.21 }
808    
809 root 1.24 void object::unlink ()
810 root 1.21 {
811 root 1.121 if (!index)
812     return;
813    
814 root 1.324 ++destroy_count;
815    
816 root 1.108 objects.erase (this);
817 root 1.109 refcnt_dec ();
818 root 1.98 }
819    
820 root 1.96 void
821 root 1.98 object::activate ()
822 root 1.96 {
823 root 1.98 /* If already on active list, don't do anything */
824 root 1.108 if (active)
825 root 1.98 return;
826    
827 root 1.286 if (has_active_speed ())
828     {
829     if (flag [FLAG_FREED])
830     LOG (llevError | logBacktrace, "BUG: tried to activate freed object %s\n", debug_desc ());//D
831 root 1.256
832 root 1.286 actives.insert (this);
833     }
834 root 1.98 }
835 root 1.96
836 root 1.98 void
837     object::activate_recursive ()
838     {
839     activate ();
840    
841 root 1.104 for (object *op = inv; op; op = op->below)
842 root 1.98 op->activate_recursive ();
843 root 1.96 }
844    
845     /* This function removes object 'op' from the list of active
846     * objects.
847     * This should only be used for style maps or other such
848     * reference maps where you don't want an object that isn't
849     * in play chewing up cpu time getting processed.
850     * The reverse of this is to call update_ob_speed, which
851     * will do the right thing based on the speed of the object.
852     */
853     void
854 root 1.98 object::deactivate ()
855 root 1.96 {
856     /* If not on the active list, nothing needs to be done */
857 root 1.108 if (!active)
858 root 1.96 return;
859    
860 root 1.108 actives.erase (this);
861 root 1.98 }
862 root 1.96
863 root 1.98 void
864     object::deactivate_recursive ()
865     {
866 root 1.104 for (object *op = inv; op; op = op->below)
867 root 1.98 op->deactivate_recursive ();
868    
869     deactivate ();
870 root 1.96 }
871    
872 root 1.106 void
873     object::set_flag_inv (int flag, int value)
874     {
875     for (object *op = inv; op; op = op->below)
876     {
877     op->flag [flag] = value;
878     op->set_flag_inv (flag, value);
879     }
880     }
881    
882 root 1.89 /*
883     * Remove and free all objects in the inventory of the given object.
884     * object.c ?
885     */
886     void
887     object::destroy_inv (bool drop_to_ground)
888     {
889 root 1.94 // need to check first, because the checks below might segfault
890     // as we might be on an invalid mapspace and crossfire code
891     // is too buggy to ensure that the inventory is empty.
892 root 1.217 // corollary: if you create arrows etc. with stuff in its inventory,
893 root 1.94 // cf will crash below with off-map x and y
894     if (!inv)
895     return;
896    
897 root 1.89 /* Only if the space blocks everything do we not process -
898     * if some form of movement is allowed, let objects
899     * drop on that space.
900     */
901 root 1.92 if (!drop_to_ground
902     || !map
903 root 1.346 || !map->linkable ()
904 root 1.238 || map->no_drop
905 root 1.95 || ms ().move_block == MOVE_ALL)
906 root 1.89 {
907     while (inv)
908 root 1.259 inv->destroy ();
909 root 1.89 }
910     else
911     { /* Put objects in inventory onto this space */
912     while (inv)
913     {
914     object *op = inv;
915    
916     if (op->flag [FLAG_STARTEQUIP]
917     || op->flag [FLAG_NO_DROP]
918     || op->type == RUNE
919     || op->type == TRAP
920 root 1.110 || op->flag [FLAG_IS_A_TEMPLATE]
921     || op->flag [FLAG_DESTROY_ON_DEATH])
922 root 1.259 op->destroy ();
923 root 1.89 else
924 root 1.93 map->insert (op, x, y);
925 root 1.89 }
926     }
927     }
928    
929 root 1.320 /*
930     * Remove and free all objects in the inventory of the given object.
931     * Unlike destroy_inv, this assumes the *this is destroyed as well
932     * well, so we can (and have to!) take shortcuts.
933     */
934     void
935     object::destroy_inv_fast ()
936     {
937     while (object *op = inv)
938     {
939     // remove from object the fast way
940     op->flag [FLAG_REMOVED] = true;
941     op->env = 0;
942     if ((inv = inv->below))
943     inv->above = 0;
944    
945     // then destroy
946     op->destroy ();
947     }
948     }
949    
950 root 1.324 void
951     object::freelist_free (int count)
952 root 1.21 {
953 root 1.324 while (count-- && freelist)
954     {
955     freelist_item *next = freelist->next;
956     // count is being "destroyed"
957    
958     sfree ((char *)freelist, sizeof (object));
959    
960     freelist = next;
961     --free_count;
962     }
963     }
964    
965     object *
966     object::create ()
967     {
968     object *op;
969    
970     if (freelist)
971     {
972     freelist_item li = *freelist;
973     memset (freelist, 0, sizeof (object));
974    
975     op = new (freelist) object;
976     op->count = li.count;
977    
978     freelist = li.next;
979     --free_count;
980     }
981     else
982     {
983     void *ni = salloc0<char> (sizeof (object));
984    
985     op = new(ni) object;
986    
987     op->count = ++object_count;
988     }
989    
990 root 1.22 op->link ();
991 root 1.324
992 root 1.22 return op;
993 root 1.21 }
994 elmex 1.1
995 root 1.324 void
996     object::do_delete ()
997     {
998     uint32_t count = this->count;
999    
1000     this->~object ();
1001    
1002     freelist_item *li = (freelist_item *)this;
1003     li->next = freelist;
1004     li->count = count;
1005    
1006     freelist = li;
1007     ++free_count;
1008     }
1009    
1010 root 1.350 // special "grave" map used to store all removed objects
1011     // till they can be destroyed - saves a lot of checks in the rest
1012     // of the code
1013     static struct freed_map
1014     : maptile
1015 root 1.223 {
1016     freed_map ()
1017 root 1.327 : maptile (3, 3)
1018 root 1.223 {
1019 root 1.238 path = "<freed objects map>";
1020     name = "/internal/freed_objects_map";
1021     no_drop = 1;
1022     no_reset = 1;
1023 root 1.223
1024 root 1.347 state = MAP_ACTIVE;
1025 root 1.223 }
1026 root 1.229
1027     ~freed_map ()
1028     {
1029     destroy ();
1030     }
1031 root 1.223 } freed_map; // freed objects are moved here to avoid crashes
1032    
1033 root 1.82 void
1034     object::do_destroy ()
1035 root 1.14 {
1036 root 1.82 if (flag [FLAG_IS_LINKED])
1037 root 1.279 remove_link ();
1038 root 1.29
1039 root 1.82 if (flag [FLAG_FRIENDLY])
1040 root 1.140 remove_friendly_object (this);
1041 root 1.32
1042 root 1.213 remove ();
1043    
1044     attachable::do_destroy ();
1045 root 1.14
1046 root 1.112 deactivate ();
1047     unlink ();
1048 root 1.92
1049 root 1.82 flag [FLAG_FREED] = 1;
1050 root 1.14
1051 root 1.57 // hack to ensure that freed objects still have a valid map
1052 root 1.223 map = &freed_map;
1053     x = 1;
1054     y = 1;
1055 root 1.57
1056 root 1.88 if (more)
1057     {
1058 root 1.259 more->destroy ();
1059 root 1.88 more = 0;
1060     }
1061 root 1.82
1062 root 1.162 head = 0;
1063    
1064     // clear those pointers that likely might cause circular references
1065     owner = 0;
1066     enemy = 0;
1067     attacked_by = 0;
1068     current_weapon = 0;
1069 root 1.82 }
1070    
1071     void
1072 root 1.260 object::destroy ()
1073 root 1.82 {
1074     if (destroyed ())
1075     return;
1076    
1077 root 1.219 if (!is_head () && !head->destroyed ())
1078     {
1079     LOG (llevError | logBacktrace, "tried to destroy the tail of an object");
1080 root 1.260 head->destroy ();
1081 root 1.223 return;
1082 root 1.219 }
1083    
1084 root 1.320 destroy_inv_fast ();
1085 root 1.22
1086 root 1.173 if (is_head ())
1087     if (sound_destroy)
1088     play_sound (sound_destroy);
1089     else if (flag [FLAG_MONSTER])
1090     play_sound (sound_find ("monster_destroy")); // quick hack, too lazy to create a generic mechanism
1091 root 1.169
1092 root 1.82 attachable::destroy ();
1093 elmex 1.1 }
1094    
1095 root 1.63 /* op->remove ():
1096 elmex 1.1 * This function removes the object op from the linked list of objects
1097     * which it is currently tied to. When this function is done, the
1098     * object will have no environment. If the object previously had an
1099     * environment, the x and y coordinates will be updated to
1100     * the previous environment.
1101     */
1102 root 1.24 void
1103 root 1.128 object::do_remove ()
1104 root 1.24 {
1105 root 1.213 if (flag [FLAG_REMOVED])
1106 root 1.29 return;
1107 root 1.24
1108 root 1.82 INVOKE_OBJECT (REMOVE, this);
1109 root 1.26
1110 root 1.213 flag [FLAG_REMOVED] = true;
1111    
1112 root 1.59 if (more)
1113     more->remove ();
1114 root 1.24
1115     /*
1116     * In this case, the object to be removed is in someones
1117     * inventory.
1118     */
1119 root 1.59 if (env)
1120 root 1.24 {
1121 root 1.221 flag [FLAG_REMOVED] = false; // hack around the issue of visible_to checking flag_removed
1122 root 1.220 if (object *pl = visible_to ())
1123     esrv_del_item (pl->contr, count);
1124 root 1.221 flag [FLAG_REMOVED] = true; // hack around the issue of visible_to checking flag_removed
1125 root 1.220
1126 root 1.337 adjust_weight (env, total_weight (), 0);
1127 root 1.24
1128 root 1.265 object *pl = in_player ();
1129    
1130 root 1.237 /* we set up values so that it could be inserted into
1131     * the map, but we don't actually do that - it is up
1132     * to the caller to decide what we want to do.
1133     */
1134     map = env->map;
1135     x = env->x;
1136     y = env->y;
1137    
1138 root 1.236 // make sure cmov optimisation is applicable
1139 root 1.208 *(above ? &above->below : &env->inv) = below;
1140 root 1.236 *(below ? &below->above : &above ) = above; // &above is just a dummy
1141 root 1.24
1142 root 1.236 above = 0;
1143     below = 0;
1144     env = 0;
1145 root 1.24
1146 root 1.305 if (pl && pl->is_player ())
1147     {
1148 root 1.317 if (expect_false (pl->contr->combat_ob == this))
1149     {
1150 root 1.339 pl->apply (pl->contr->combat_ob, AP_UNAPPLY | AP_IGNORE_CURSE);
1151 root 1.317 pl->contr->combat_ob = 0;
1152     if (pl->contr->ranged_ob) pl->apply (pl->contr->ranged_ob);
1153     }
1154    
1155     if (expect_false (pl->contr->ranged_ob == this))
1156     {
1157 root 1.339 pl->apply (pl->contr->ranged_ob, AP_UNAPPLY | AP_IGNORE_CURSE);
1158 root 1.317 pl->contr->ranged_ob = 0;
1159     if (pl->contr->combat_ob) pl->apply (pl->contr->combat_ob);
1160     }
1161    
1162 root 1.305 pl->contr->queue_stats_update ();
1163 root 1.265
1164 root 1.317 if (expect_false (glow_radius) && pl->is_on_map ())
1165 root 1.305 update_all_los (pl->map, pl->x, pl->y);
1166     }
1167 root 1.59 }
1168     else if (map)
1169     {
1170 root 1.220 map->dirty = true;
1171     mapspace &ms = this->ms ();
1172    
1173     if (object *pl = ms.player ())
1174 root 1.96 {
1175 root 1.270 if (is_player ())
1176 root 1.220 {
1177 root 1.273 if (!flag [FLAG_WIZPASS])
1178     ms.smell = ++mapspace::smellcount; // remember the smell of the player
1179 root 1.270
1180 root 1.220 // leaving a spot always closes any open container on the ground
1181     if (container && !container->env)
1182     // this causes spurious floorbox updates, but it ensures
1183     // that the CLOSE event is being sent.
1184     close_container ();
1185    
1186     --map->players;
1187     map->touch ();
1188     }
1189 root 1.292 else if (pl->container_ () == this)
1190 root 1.220 {
1191     // removing a container should close it
1192     close_container ();
1193     }
1194 root 1.323 else
1195     esrv_del_item (pl->contr, count);
1196 root 1.96 }
1197    
1198 root 1.29 /* link the object above us */
1199 root 1.236 // re-link, make sure compiler can easily use cmove
1200     *(above ? &above->below : &ms.top) = below;
1201     *(below ? &below->above : &ms.bot) = above;
1202 root 1.26
1203 root 1.59 above = 0;
1204     below = 0;
1205 root 1.26
1206 root 1.265 ms.invalidate ();
1207 root 1.253
1208 root 1.82 int check_walk_off = !flag [FLAG_NO_APPLY];
1209 elmex 1.1
1210 root 1.175 if (object *pl = ms.player ())
1211     {
1212 root 1.292 if (pl->container_ () == this)
1213 root 1.175 /* If a container that the player is currently using somehow gets
1214     * removed (most likely destroyed), update the player view
1215     * appropriately.
1216     */
1217     pl->close_container ();
1218    
1219 root 1.218 //TODO: the floorbox prev/next might need updating
1220 root 1.226 //esrv_del_item (pl->contr, count);
1221     //TODO: update floorbox to preserve ordering
1222     if (pl->contr->ns)
1223     pl->contr->ns->floorbox_update ();
1224 root 1.175 }
1225    
1226 root 1.293 if (check_walk_off)
1227     for (object *above, *tmp = ms.bot; tmp; tmp = above)
1228     {
1229     above = tmp->above;
1230    
1231     /* No point updating the players look faces if he is the object
1232     * being removed.
1233     */
1234 root 1.29
1235 root 1.293 /* See if object moving off should effect something */
1236     if ((move_type & tmp->move_off)
1237     && (move_type & ~tmp->move_off & ~tmp->move_block) == 0)
1238 elmex 1.72 move_apply (tmp, this, 0);
1239 root 1.293 }
1240 root 1.26
1241 root 1.270 if (affects_los ())
1242 root 1.59 update_all_los (map, x, y);
1243 elmex 1.1 }
1244     }
1245    
1246     /*
1247     * merge_ob(op,top):
1248     *
1249     * This function goes through all objects below and including top, and
1250     * merges op to the first matching object.
1251     * If top is NULL, it is calculated.
1252     * Returns pointer to object if it succeded in the merge, otherwise NULL
1253     */
1254 root 1.24 object *
1255     merge_ob (object *op, object *top)
1256     {
1257     if (!op->nrof)
1258 elmex 1.1 return 0;
1259 root 1.29
1260 root 1.194 if (!top)
1261 root 1.82 for (top = op; top && top->above; top = top->above)
1262     ;
1263 root 1.29
1264 root 1.82 for (; top; top = top->below)
1265 root 1.214 if (object::can_merge (op, top))
1266     {
1267     top->nrof += op->nrof;
1268    
1269     if (object *pl = top->visible_to ())
1270     esrv_update_item (UPD_NROF, pl, top);
1271    
1272     op->weight = 0; // cancel the addition above
1273     op->carrying = 0; // must be 0 already
1274 root 1.66
1275 root 1.259 op->destroy ();
1276 root 1.24
1277 root 1.214 return top;
1278     }
1279 root 1.29
1280 root 1.45 return 0;
1281 elmex 1.1 }
1282    
1283 root 1.138 void
1284     object::expand_tail ()
1285     {
1286     if (more)
1287     return;
1288    
1289     object *prev = this;
1290    
1291 root 1.160 for (archetype *at = (archetype *)arch->more; at; at = (archetype *)at->more)
1292 root 1.138 {
1293 root 1.309 object *op = at->instance ();
1294 root 1.138
1295     op->name = name;
1296     op->name_pl = name_pl;
1297     op->title = title;
1298    
1299     op->head = this;
1300     prev->more = op;
1301    
1302     prev = op;
1303     }
1304     }
1305    
1306 elmex 1.1 /*
1307 root 1.117 * same as insert_ob_in_map except it handles separate coordinates and does a clean
1308     * job preparing multi-part monsters.
1309 elmex 1.1 */
1310 root 1.24 object *
1311 root 1.49 insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y)
1312 root 1.24 {
1313 root 1.244 op->remove ();
1314    
1315 root 1.93 for (object *tmp = op->head_ (); tmp; tmp = tmp->more)
1316 root 1.24 {
1317 root 1.159 tmp->x = x + tmp->arch->x;
1318     tmp->y = y + tmp->arch->y;
1319 elmex 1.1 }
1320 root 1.29
1321 root 1.24 return insert_ob_in_map (op, m, originator, flag);
1322 elmex 1.1 }
1323    
1324     /*
1325     * insert_ob_in_map (op, map, originator, flag):
1326     * This function inserts the object in the two-way linked list
1327     * which represents what is on a map.
1328     * The second argument specifies the map, and the x and y variables
1329     * in the object about to be inserted specifies the position.
1330     *
1331     * originator: Player, monster or other object that caused 'op' to be inserted
1332     * into 'map'. May be NULL.
1333     *
1334     * flag is a bitmask about special things to do (or not do) when this
1335     * function is called. see the object.h file for the INS_ values.
1336     * Passing 0 for flag gives proper default values, so flag really only needs
1337     * to be set if special handling is needed.
1338     *
1339     * Return value:
1340     * new object if 'op' was merged with other object
1341 root 1.313 * NULL if there was an error (destroyed, blocked etc.)
1342 elmex 1.1 * just 'op' otherwise
1343     */
1344 root 1.24 object *
1345 root 1.49 insert_ob_in_map (object *op, maptile *m, object *originator, int flag)
1346 elmex 1.1 {
1347 root 1.261 op->remove ();
1348 root 1.117
1349 root 1.258 if (m == &freed_map)//D TODO: remove soon
1350 root 1.245 {//D
1351 root 1.345 LOG (llevError | logBacktrace, "tries to insert object on freed objects map: %s", op->debug_desc ());//D
1352 root 1.245 }//D
1353    
1354 root 1.187 /* Ideally, the caller figures this out. However, it complicates a lot
1355     * of areas of callers (eg, anything that uses find_free_spot would now
1356     * need extra work
1357     */
1358 root 1.274 maptile *newmap = m;
1359     if (!xy_normalise (newmap, op->x, op->y))
1360 root 1.24 {
1361 root 1.259 op->head_ ()->destroy ();// remove head_ once all tail object destroyers found
1362 root 1.187 return 0;
1363 elmex 1.1 }
1364 root 1.25
1365 root 1.117 if (object *more = op->more)
1366 root 1.155 if (!insert_ob_in_map (more, m, originator, flag))
1367     return 0;
1368 root 1.25
1369 root 1.283 op->flag [FLAG_REMOVED] = false;
1370     op->env = 0;
1371     op->map = newmap;
1372 root 1.8
1373 root 1.117 mapspace &ms = op->ms ();
1374 root 1.24
1375     /* this has to be done after we translate the coordinates.
1376     */
1377     if (op->nrof && !(flag & INS_NO_MERGE))
1378 root 1.155 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1379 root 1.66 if (object::can_merge (op, tmp))
1380 root 1.25 {
1381 root 1.237 // TODO: we actually want to update tmp, not op,
1382 root 1.218 // but some caller surely breaks when we return tmp
1383     // from here :/
1384 root 1.25 op->nrof += tmp->nrof;
1385 root 1.259 tmp->destroy ();
1386 root 1.25 }
1387 root 1.24
1388 root 1.322 op->clr_flag (FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */
1389     op->clr_flag (FLAG_INV_LOCKED);
1390 root 1.25
1391 root 1.322 if (!op->flag [FLAG_ALIVE])
1392     op->clr_flag (FLAG_NO_STEAL);
1393 root 1.24
1394     if (flag & INS_BELOW_ORIGINATOR)
1395     {
1396 root 1.241 if (originator->map != op->map || originator->x != op->x || originator->y != op->y)
1397 root 1.24 {
1398     LOG (llevError, "insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
1399     abort ();
1400     }
1401 root 1.25
1402 root 1.241 if (!originator->is_on_map ())
1403 root 1.282 {
1404     LOG (llevError, "insert_ob_in_map(%s) called with INS_BELOW_ORIGINATOR when originator '%s' not on map",
1405     op->debug_desc (), originator->debug_desc ());
1406     abort ();
1407     }
1408 root 1.241
1409 root 1.24 op->above = originator;
1410     op->below = originator->below;
1411 root 1.237 originator->below = op;
1412 root 1.25
1413 root 1.237 *(op->below ? &op->below->above : &ms.bot) = op;
1414 elmex 1.1 }
1415 root 1.24 else
1416     {
1417 root 1.237 object *floor = 0;
1418     object *top = ms.top;
1419 root 1.117
1420 root 1.24 /* If there are other objects, then */
1421 root 1.191 if (top)
1422 root 1.24 {
1423     /*
1424     * If there are multiple objects on this space, we do some trickier handling.
1425     * We've already dealt with merging if appropriate.
1426     * Generally, we want to put the new object on top. But if
1427     * flag contains INS_ABOVE_FLOOR_ONLY, once we find the last
1428     * floor, we want to insert above that and no further.
1429     * Also, if there are spell objects on this space, we stop processing
1430     * once we get to them. This reduces the need to traverse over all of
1431     * them when adding another one - this saves quite a bit of cpu time
1432     * when lots of spells are cast in one area. Currently, it is presumed
1433     * that flying non pickable objects are spell objects.
1434     */
1435 root 1.237 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1436 root 1.24 {
1437 root 1.322 if (tmp->flag [FLAG_IS_FLOOR] || tmp->flag [FLAG_OVERLAY_FLOOR])
1438 root 1.237 floor = tmp;
1439 root 1.26
1440 root 1.322 if (tmp->flag [FLAG_NO_PICK] && (tmp->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) && !tmp->flag [FLAG_IS_FLOOR])
1441 root 1.24 {
1442     /* We insert above top, so we want this object below this */
1443 root 1.237 top = tmp->below;
1444 root 1.24 break;
1445     }
1446 root 1.26
1447 root 1.237 top = tmp;
1448 root 1.24 }
1449 root 1.26
1450 root 1.24 /* We let update_position deal with figuring out what the space
1451     * looks like instead of lots of conditions here.
1452     * makes things faster, and effectively the same result.
1453     */
1454    
1455     /* Have object 'fall below' other objects that block view.
1456 root 1.135 * Unless those objects are exits.
1457 root 1.24 * If INS_ON_TOP is used, don't do this processing
1458     * Need to find the object that in fact blocks view, otherwise
1459     * stacking is a bit odd.
1460     */
1461 root 1.117 if (!(flag & INS_ON_TOP)
1462     && ms.flags () & P_BLOCKSVIEW
1463 root 1.135 && (op->face && !faces [op->face].visibility))
1464 root 1.24 {
1465 root 1.237 object *last;
1466    
1467 root 1.24 for (last = top; last != floor; last = last->below)
1468 root 1.322 if (last->flag [FLAG_BLOCKSVIEW] && (last->type != EXIT))
1469 root 1.24 break;
1470 root 1.117
1471 root 1.24 /* Check to see if we found the object that blocks view,
1472     * and make sure we have a below pointer for it so that
1473     * we can get inserted below this one, which requires we
1474     * set top to the object below us.
1475     */
1476     if (last && last->below && last != floor)
1477     top = last->below;
1478 root 1.8 }
1479 root 1.24 } /* If objects on this space */
1480 root 1.25
1481 root 1.24 if (flag & INS_ABOVE_FLOOR_ONLY)
1482     top = floor;
1483    
1484 root 1.240 // insert object above top, or bottom-most if top = 0
1485 root 1.24 if (!top)
1486     {
1487 root 1.239 op->below = 0;
1488     op->above = ms.bot;
1489     ms.bot = op;
1490 root 1.25
1491 root 1.239 *(op->above ? &op->above->below : &ms.top) = op;
1492 root 1.24 }
1493     else
1494 root 1.240 {
1495 root 1.24 op->above = top->above;
1496 root 1.237 top->above = op;
1497 root 1.25
1498 root 1.24 op->below = top;
1499 root 1.237 *(op->above ? &op->above->below : &ms.top) = op;
1500 root 1.24 }
1501 root 1.240 }
1502 root 1.8
1503 root 1.270 if (op->is_player ())
1504 root 1.96 {
1505     op->contr->do_los = 1;
1506     ++op->map->players;
1507 root 1.100 op->map->touch ();
1508 root 1.96 }
1509 root 1.24
1510 root 1.98 op->map->dirty = true;
1511    
1512 root 1.191 if (object *pl = ms.player ())
1513 root 1.218 //TODO: the floorbox prev/next might need updating
1514 root 1.226 //esrv_send_item (pl, op);
1515     //TODO: update floorbox to preserve ordering
1516     if (pl->contr->ns)
1517     pl->contr->ns->floorbox_update ();
1518 root 1.24
1519     /* If this object glows, it may affect lighting conditions that are
1520     * visible to others on this map. But update_all_los is really
1521     * an inefficient way to do this, as it means los for all players
1522     * on the map will get recalculated. The players could very well
1523     * be far away from this change and not affected in any way -
1524     * this should get redone to only look for players within range,
1525 root 1.99 * or just updating the P_UPTODATE for spaces within this area
1526 root 1.24 * of effect may be sufficient.
1527     */
1528 root 1.270 if (op->affects_los ())
1529 root 1.265 {
1530     op->ms ().invalidate ();
1531     update_all_los (op->map, op->x, op->y);
1532     }
1533 root 1.24
1534     /* updates flags (blocked, alive, no magic, etc) for this map space */
1535     update_object (op, UP_OBJ_INSERT);
1536    
1537 root 1.82 INVOKE_OBJECT (INSERT, op);
1538    
1539 root 1.24 /* Don't know if moving this to the end will break anything. However,
1540 root 1.70 * we want to have floorbox_update called before calling this.
1541 root 1.24 *
1542     * check_move_on() must be after this because code called from
1543     * check_move_on() depends on correct map flags (so functions like
1544     * blocked() and wall() work properly), and these flags are updated by
1545     * update_object().
1546     */
1547    
1548     /* if this is not the head or flag has been passed, don't check walk on status */
1549 root 1.287 if (!(flag & INS_NO_WALK_ON) && op->is_head ())
1550 root 1.24 {
1551 root 1.336 if (check_move_on (op, originator, flag))
1552 root 1.82 return 0;
1553 elmex 1.1
1554 root 1.334 /* If we are a multi part object, let's work our way through the check
1555 root 1.24 * walk on's.
1556     */
1557 root 1.155 for (object *tmp = op->more; tmp; tmp = tmp->more)
1558 root 1.336 if (check_move_on (tmp, originator, flag))
1559 root 1.82 return 0;
1560 elmex 1.1 }
1561 root 1.25
1562 root 1.24 return op;
1563 elmex 1.1 }
1564    
1565     /* this function inserts an object in the map, but if it
1566 root 1.75 * finds an object of its own type, it'll remove that one first.
1567     * op is the object to insert it under: supplies x and the map.
1568 elmex 1.1 */
1569 root 1.24 void
1570 root 1.277 replace_insert_ob_in_map (shstr_tmp archname, object *op)
1571 root 1.24 {
1572     /* first search for itself and remove any old instances */
1573 elmex 1.1
1574 root 1.208 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
1575 root 1.277 if (tmp->arch->archname == archname) /* same archetype */
1576 root 1.259 tmp->destroy ();
1577 root 1.208
1578 root 1.308 object *tmp = archetype::find (archname)->instance ();
1579 elmex 1.1
1580 root 1.208 tmp->x = op->x;
1581     tmp->y = op->y;
1582 elmex 1.1
1583 root 1.208 insert_ob_in_map (tmp, op->map, op, 0);
1584 root 1.24 }
1585 elmex 1.1
1586 root 1.93 object *
1587     object::insert_at (object *where, object *originator, int flags)
1588     {
1589 root 1.205 if (where->env)
1590     return where->env->insert (this);
1591     else
1592     return where->map->insert (this, where->x, where->y, originator, flags);
1593 root 1.93 }
1594    
1595 root 1.301 // check whether we can put this into the map, respect max_volume, max_items
1596 root 1.299 bool
1597     object::can_drop_at (maptile *m, int x, int y, object *originator)
1598     {
1599     mapspace &ms = m->at (x, y);
1600    
1601     int items = ms.items ();
1602    
1603     if (!items // testing !items ensures we can drop at least one item
1604     || (items < m->max_items
1605 root 1.301 && ms.volume () < m->max_volume))
1606 root 1.299 return true;
1607    
1608     if (originator && originator->is_player ())
1609 root 1.321 originator->contr->failmsgf (
1610 root 1.299 "No matter how hard you try, you just cannot put the %s here H<Try to remove some items from the floor first.>",
1611     query_name ()
1612 root 1.321 );
1613 root 1.299
1614     return false;
1615     }
1616    
1617 elmex 1.1 /*
1618 root 1.209 * decrease(object, number) decreases a specified number from
1619 root 1.208 * the amount of an object. If the amount reaches 0, the object
1620 elmex 1.1 * is subsequently removed and freed.
1621     *
1622     * Return value: 'op' if something is left, NULL if the amount reached 0
1623     */
1624 root 1.208 bool
1625 root 1.209 object::decrease (sint32 nr)
1626 elmex 1.1 {
1627 root 1.212 if (!nr)
1628     return true;
1629    
1630 root 1.208 nr = min (nr, nrof);
1631 elmex 1.1
1632 root 1.251 if (nrof > nr)
1633 elmex 1.1 {
1634 root 1.337 sint64 oweight = total_weight ();
1635    
1636 root 1.251 nrof -= nr;
1637 elmex 1.1
1638 root 1.212 if (object *pl = visible_to ())
1639     esrv_update_item (UPD_NROF, pl, this);
1640 root 1.29
1641 root 1.337 adjust_weight (env, oweight, total_weight ());
1642    
1643 root 1.212 return true;
1644 elmex 1.1 }
1645 root 1.24 else
1646     {
1647 root 1.249 destroy ();
1648 root 1.212 return false;
1649 elmex 1.1 }
1650     }
1651    
1652 root 1.209 /*
1653 root 1.210 * split(ob,nr) splits up ob into two parts. The part which
1654 root 1.209 * is returned contains nr objects, and the remaining parts contains
1655 root 1.210 * the rest (or is removed and returned if that number is 0).
1656     * On failure, NULL is returned.
1657 root 1.209 */
1658 root 1.208 object *
1659 root 1.209 object::split (sint32 nr)
1660 root 1.208 {
1661 root 1.212 int have = number_of ();
1662    
1663     if (have < nr)
1664 root 1.209 return 0;
1665 root 1.212 else if (have == nr)
1666 root 1.209 {
1667     remove ();
1668     return this;
1669     }
1670     else
1671     {
1672     decrease (nr);
1673    
1674 root 1.230 object *op = deep_clone ();
1675 root 1.209 op->nrof = nr;
1676     return op;
1677     }
1678     }
1679    
1680 root 1.24 object *
1681     insert_ob_in_ob (object *op, object *where)
1682     {
1683 root 1.59 if (!where)
1684 root 1.24 {
1685 root 1.53 char *dump = dump_object (op);
1686     LOG (llevError, "Trying to put object in NULL.\n%s\n", dump);
1687     free (dump);
1688 root 1.24 return op;
1689     }
1690 root 1.29
1691 root 1.154 if (where->head_ () != where)
1692 root 1.24 {
1693 root 1.153 LOG (llevError | logBacktrace, "Warning: Tried to insert object into wrong part of multipart object.\n");
1694 root 1.24 where = where->head;
1695     }
1696 root 1.29
1697 root 1.59 return where->insert (op);
1698     }
1699    
1700     /*
1701     * env->insert (op)
1702     * This function inserts the object op in the linked list
1703     * inside the object environment.
1704     *
1705     * The function returns now pointer to inserted item, and return value can
1706     * be != op, if items are merged. -Tero
1707     */
1708     object *
1709     object::insert (object *op)
1710     {
1711 root 1.24 if (op->more)
1712     {
1713     LOG (llevError, "Tried to insert multipart object %s (%d)\n", &op->name, op->count);
1714     return op;
1715     }
1716 root 1.29
1717 root 1.208 op->remove ();
1718    
1719     op->flag [FLAG_OBJ_ORIGINAL] = 0;
1720 root 1.182
1721 root 1.24 if (op->nrof)
1722 root 1.208 for (object *tmp = inv; tmp; tmp = tmp->below)
1723     if (object::can_merge (tmp, op))
1724     {
1725     /* return the original object and remove inserted object
1726 root 1.337 (client prefers the original object) */
1727    
1728     // carring must be 0 for mergable objects
1729     sint64 oweight = tmp->weight * tmp->nrof;
1730    
1731 root 1.208 tmp->nrof += op->nrof;
1732 root 1.214
1733     if (object *pl = tmp->visible_to ())
1734     esrv_update_item (UPD_NROF, pl, tmp);
1735    
1736 root 1.337 adjust_weight (this, oweight, tmp->weight * tmp->nrof);
1737 root 1.210
1738 root 1.259 op->destroy ();
1739 root 1.208 op = tmp;
1740     goto inserted;
1741     }
1742    
1743     op->owner = 0; // it's his/hers now. period.
1744     op->map = 0;
1745     op->x = 0;
1746     op->y = 0;
1747    
1748     op->above = 0;
1749     op->below = inv;
1750     op->env = this;
1751    
1752     if (inv)
1753     inv->above = op;
1754 root 1.24
1755 root 1.208 inv = op;
1756 elmex 1.1
1757 root 1.208 op->flag [FLAG_REMOVED] = 0;
1758 elmex 1.1
1759 root 1.214 if (object *pl = op->visible_to ())
1760     esrv_send_item (pl, op);
1761    
1762 root 1.337 adjust_weight (this, 0, op->total_weight ());
1763 elmex 1.1
1764 root 1.208 inserted:
1765 elmex 1.1 /* reset the light list and los of the players on the map */
1766 root 1.270 if (op->glow_radius && is_on_map ())
1767 root 1.265 {
1768     update_stats ();
1769     update_all_los (map, x, y);
1770     }
1771 root 1.305 else if (is_player ())
1772 root 1.265 // if this is a player's inventory, update stats
1773 root 1.305 contr->queue_stats_update ();
1774 root 1.59
1775 root 1.82 INVOKE_OBJECT (INSERT, this);
1776    
1777 elmex 1.1 return op;
1778     }
1779    
1780     /*
1781     * Checks if any objects has a move_type that matches objects
1782     * that effect this object on this space. Call apply() to process
1783     * these events.
1784     *
1785     * Any speed-modification due to SLOW_MOVE() of other present objects
1786     * will affect the speed_left of the object.
1787     *
1788     * originator: Player, monster or other object that caused 'op' to be inserted
1789     * into 'map'. May be NULL.
1790     *
1791     * Return value: 1 if 'op' was destroyed, 0 otherwise.
1792     *
1793     * 4-21-95 added code to check if appropriate skill was readied - this will
1794     * permit faster movement by the player through this terrain. -b.t.
1795     *
1796     * MSW 2001-07-08: Check all objects on space, not just those below
1797     * object being inserted. insert_ob_in_map may not put new objects
1798     * on top.
1799     */
1800 root 1.24 int
1801 root 1.336 check_move_on (object *op, object *originator, int flags)
1802 elmex 1.1 {
1803 root 1.322 if (op->flag [FLAG_NO_APPLY])
1804 root 1.287 return 0;
1805    
1806 root 1.48 object *tmp;
1807 root 1.49 maptile *m = op->map;
1808 root 1.48 int x = op->x, y = op->y;
1809 root 1.26
1810 root 1.287 mapspace &ms = m->at (x, y);
1811 root 1.24
1812 root 1.287 ms.update ();
1813 root 1.24
1814 root 1.287 MoveType move_on = ms.move_on;
1815     MoveType move_slow = ms.move_slow;
1816     MoveType move_block = ms.move_block;
1817 root 1.24
1818     /* if nothing on this space will slow op down or be applied,
1819     * no need to do checking below. have to make sure move_type
1820     * is set, as lots of objects don't have it set - we treat that
1821     * as walking.
1822     */
1823     if (op->move_type && !(op->move_type & move_on) && !(op->move_type & move_slow))
1824     return 0;
1825 elmex 1.1
1826 root 1.24 /* This is basically inverse logic of that below - basically,
1827     * if the object can avoid the move on or slow move, they do so,
1828     * but can't do it if the alternate movement they are using is
1829     * blocked. Logic on this seems confusing, but does seem correct.
1830     */
1831     if ((op->move_type & ~move_on & ~move_block) != 0 && (op->move_type & ~move_slow & ~move_block) != 0)
1832     return 0;
1833    
1834     /* The objects have to be checked from top to bottom.
1835     * Hence, we first go to the top:
1836     */
1837 root 1.287 for (object *next, *tmp = ms.top; tmp; tmp = next)
1838 root 1.24 {
1839 root 1.287 next = tmp->below;
1840 root 1.26
1841 root 1.24 if (tmp == op)
1842     continue; /* Can't apply yourself */
1843 elmex 1.1
1844 root 1.24 /* Check to see if one of the movement types should be slowed down.
1845     * Second check makes sure that the movement types not being slowed
1846     * (~slow_move) is not blocked on this space - just because the
1847     * space doesn't slow down swimming (for example), if you can't actually
1848     * swim on that space, can't use it to avoid the penalty.
1849     */
1850 root 1.322 if (!op->flag [FLAG_WIZPASS])
1851 root 1.24 {
1852     if ((!op->move_type && tmp->move_slow & MOVE_WALK) ||
1853     ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0))
1854     {
1855 root 1.287 float diff = tmp->move_slow_penalty * fabs (op->speed);
1856 elmex 1.1
1857 root 1.270 if (op->is_player ())
1858 root 1.287 if ((tmp->flag [FLAG_IS_HILLY ] && find_skill_by_number (op, SK_CLIMBING)) ||
1859     (tmp->flag [FLAG_IS_WOODED] && find_skill_by_number (op, SK_WOODSMAN)))
1860 root 1.26 diff /= 4.0;
1861    
1862 root 1.24 op->speed_left -= diff;
1863 root 1.8 }
1864     }
1865 elmex 1.1
1866 root 1.24 /* Basically same logic as above, except now for actual apply. */
1867     if ((!op->move_type && tmp->move_on & MOVE_WALK) ||
1868     ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0))
1869     {
1870 root 1.336 if ((flags & INS_NO_AUTO_EXIT)
1871     && (tmp->type == EXIT || tmp->type == TELEPORTER
1872     || tmp->type == HOLE || tmp->type == TRAPDOOR)) //TODO: temporary, fix exits instead
1873     continue;
1874    
1875 elmex 1.72 move_apply (tmp, op, originator);
1876 root 1.24
1877 root 1.48 if (op->destroyed ())
1878 root 1.24 return 1;
1879    
1880     /* what the person/creature stepped onto has moved the object
1881     * someplace new. Don't process any further - if we did,
1882     * have a feeling strange problems would result.
1883     */
1884     if (op->map != m || op->x != x || op->y != y)
1885     return 0;
1886 root 1.8 }
1887 elmex 1.1 }
1888 root 1.26
1889 root 1.24 return 0;
1890 elmex 1.1 }
1891    
1892     /*
1893     * present_arch(arch, map, x, y) searches for any objects with
1894     * a matching archetype at the given map and coordinates.
1895     * The first matching object is returned, or NULL if none.
1896     */
1897 root 1.24 object *
1898 root 1.49 present_arch (const archetype *at, maptile *m, int x, int y)
1899 root 1.24 {
1900 root 1.104 if (!m || out_of_map (m, x, y))
1901 root 1.24 {
1902     LOG (llevError, "Present_arch called outside map.\n");
1903     return NULL;
1904     }
1905 root 1.84
1906 root 1.104 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1907 root 1.231 if (tmp->arch->archname == at->archname)
1908 elmex 1.1 return tmp;
1909 root 1.84
1910 elmex 1.1 return NULL;
1911     }
1912    
1913     /*
1914     * present(type, map, x, y) searches for any objects with
1915     * a matching type variable at the given map and coordinates.
1916     * The first matching object is returned, or NULL if none.
1917     */
1918 root 1.24 object *
1919 root 1.49 present (unsigned char type, maptile *m, int x, int y)
1920 root 1.24 {
1921     if (out_of_map (m, x, y))
1922     {
1923     LOG (llevError, "Present called outside map.\n");
1924     return NULL;
1925     }
1926 root 1.84
1927 root 1.104 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1928 root 1.24 if (tmp->type == type)
1929 elmex 1.1 return tmp;
1930 root 1.84
1931 elmex 1.1 return NULL;
1932     }
1933    
1934     /*
1935     * present_in_ob(type, object) searches for any objects with
1936     * a matching type variable in the inventory of the given object.
1937     * The first matching object is returned, or NULL if none.
1938     */
1939 root 1.24 object *
1940     present_in_ob (unsigned char type, const object *op)
1941     {
1942 root 1.84 for (object *tmp = op->inv; tmp != NULL; tmp = tmp->below)
1943 root 1.24 if (tmp->type == type)
1944 elmex 1.1 return tmp;
1945 root 1.84
1946 elmex 1.1 return NULL;
1947     }
1948    
1949     /*
1950     * present_in_ob (type, str, object) searches for any objects with
1951     * a matching type & name variable in the inventory of the given object.
1952     * The first matching object is returned, or NULL if none.
1953     * This is mostly used by spell effect code, so that we only
1954     * have one spell effect at a time.
1955     * type can be used to narrow the search - if type is set,
1956     * the type must also match. -1 can be passed for the type,
1957     * in which case the type does not need to pass.
1958     * str is the string to match against. Note that we match against
1959     * the object name, not the archetype name. this is so that the
1960     * spell code can use one object type (force), but change it's name
1961     * to be unique.
1962     */
1963 root 1.24 object *
1964     present_in_ob_by_name (int type, const char *str, const object *op)
1965     {
1966 root 1.84 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1967 root 1.82 if ((type == -1 || tmp->type == type) && (!strcmp (str, tmp->name)))
1968     return tmp;
1969 elmex 1.1
1970 root 1.82 return 0;
1971 elmex 1.1 }
1972    
1973     /*
1974     * present_arch_in_ob(archetype, object) searches for any objects with
1975     * a matching archetype in the inventory of the given object.
1976     * The first matching object is returned, or NULL if none.
1977     */
1978 root 1.24 object *
1979     present_arch_in_ob (const archetype *at, const object *op)
1980     {
1981 root 1.231 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1982     if (tmp->arch->archname == at->archname)
1983 elmex 1.1 return tmp;
1984 root 1.82
1985 elmex 1.1 return NULL;
1986     }
1987    
1988     /*
1989     * activate recursively a flag on an object inventory
1990     */
1991 root 1.24 void
1992     flag_inv (object *op, int flag)
1993     {
1994 root 1.197 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1995     {
1996 root 1.322 tmp->set_flag (flag);
1997 root 1.197 flag_inv (tmp, flag);
1998     }
1999 root 1.82 }
2000    
2001     /*
2002     * deactivate recursively a flag on an object inventory
2003     */
2004 root 1.24 void
2005     unflag_inv (object *op, int flag)
2006     {
2007 root 1.197 for (object *tmp = op->inv; tmp; tmp = tmp->below)
2008     {
2009 root 1.322 tmp->clr_flag (flag);
2010 root 1.197 unflag_inv (tmp, flag);
2011     }
2012 elmex 1.1 }
2013    
2014     /*
2015     * find_free_spot(object, map, x, y, start, stop) will search for
2016     * a spot at the given map and coordinates which will be able to contain
2017     * the given object. start and stop specifies how many squares
2018     * to search (see the freearr_x/y[] definition).
2019     * It returns a random choice among the alternatives found.
2020     * start and stop are where to start relative to the free_arr array (1,9
2021     * does all 4 immediate directions). This returns the index into the
2022     * array of the free spot, -1 if no spot available (dir 0 = x,y)
2023 root 1.196 * Note: This function does correctly handle tiled maps, but does not
2024 elmex 1.1 * inform the caller. However, insert_ob_in_map will update as
2025     * necessary, so the caller shouldn't need to do any special work.
2026     * Note - updated to take an object instead of archetype - this is necessary
2027     * because arch_blocked (now ob_blocked) needs to know the movement type
2028     * to know if the space in question will block the object. We can't use
2029     * the archetype because that isn't correct if the monster has been
2030     * customized, changed states, etc.
2031     */
2032 root 1.24 int
2033 root 1.49 find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
2034 root 1.24 {
2035 root 1.190 int altern[SIZEOFFREE];
2036 root 1.82 int index = 0, flag;
2037 root 1.24
2038 root 1.82 for (int i = start; i < stop; i++)
2039 root 1.24 {
2040 root 1.188 mapxy pos (m, x, y); pos.move (i);
2041    
2042     if (!pos.normalise ())
2043     continue;
2044    
2045     mapspace &ms = *pos;
2046 root 1.189
2047     if (ms.flags () & P_IS_ALIVE)
2048     continue;
2049 root 1.188
2050     /* However, often
2051     * ob doesn't have any move type (when used to place exits)
2052     * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work.
2053     */
2054 root 1.200 if (ob && ob->move_type == 0 && ms.move_block != MOVE_ALL)
2055 root 1.190 {
2056     altern [index++] = i;
2057     continue;
2058     }
2059 root 1.24
2060     /* Basically, if we find a wall on a space, we cut down the search size.
2061     * In this way, we won't return spaces that are on another side of a wall.
2062     * This mostly work, but it cuts down the search size in all directions -
2063     * if the space being examined only has a wall to the north and empty
2064     * spaces in all the other directions, this will reduce the search space
2065     * to only the spaces immediately surrounding the target area, and
2066     * won't look 2 spaces south of the target space.
2067     */
2068 root 1.188 if (ms.move_block == MOVE_ALL && maxfree[i] < stop)
2069     {
2070     stop = maxfree[i];
2071     continue;
2072     }
2073    
2074     /* Note it is intentional that we check ob - the movement type of the
2075     * head of the object should correspond for the entire object.
2076     */
2077     if (OB_TYPE_MOVE_BLOCK (ob, ms.move_block))
2078     continue;
2079    
2080 elmex 1.262 if (ob->blocked (pos.m, pos.x, pos.y))
2081 root 1.196 continue;
2082    
2083 root 1.188 altern [index++] = i;
2084 elmex 1.1 }
2085 root 1.74
2086 root 1.24 if (!index)
2087     return -1;
2088 root 1.74
2089 root 1.124 return altern [rndm (index)];
2090 elmex 1.1 }
2091    
2092     /*
2093 root 1.49 * find_first_free_spot(archetype, maptile, x, y) works like
2094 elmex 1.1 * find_free_spot(), but it will search max number of squares.
2095     * But it will return the first available spot, not a random choice.
2096     * Changed 0.93.2: Have it return -1 if there is no free spot available.
2097     */
2098 root 1.24 int
2099 root 1.49 find_first_free_spot (const object *ob, maptile *m, int x, int y)
2100 root 1.24 {
2101 root 1.82 for (int i = 0; i < SIZEOFFREE; i++)
2102 root 1.188 if (!ob->blocked (m, x + freearr_x[i], y + freearr_y[i]))
2103 root 1.82 return i;
2104 root 1.24
2105     return -1;
2106 elmex 1.1 }
2107    
2108     /*
2109     * The function permute(arr, begin, end) randomly reorders the array
2110     * arr[begin..end-1].
2111 root 1.82 * now uses a fisher-yates shuffle, old permute was broken
2112 elmex 1.1 */
2113 root 1.24 static void
2114     permute (int *arr, int begin, int end)
2115 elmex 1.1 {
2116 root 1.82 arr += begin;
2117     end -= begin;
2118    
2119     while (--end)
2120 root 1.124 swap (arr [end], arr [rndm (end + 1)]);
2121 elmex 1.1 }
2122    
2123     /* new function to make monster searching more efficient, and effective!
2124     * This basically returns a randomized array (in the passed pointer) of
2125     * the spaces to find monsters. In this way, it won't always look for
2126     * monsters to the north first. However, the size of the array passed
2127     * covers all the spaces, so within that size, all the spaces within
2128     * the 3x3 area will be searched, just not in a predictable order.
2129     */
2130 root 1.24 void
2131     get_search_arr (int *search_arr)
2132 elmex 1.1 {
2133 root 1.82 int i;
2134 elmex 1.1
2135 root 1.24 for (i = 0; i < SIZEOFFREE; i++)
2136 root 1.82 search_arr[i] = i;
2137 elmex 1.1
2138 root 1.24 permute (search_arr, 1, SIZEOFFREE1 + 1);
2139     permute (search_arr, SIZEOFFREE1 + 1, SIZEOFFREE2 + 1);
2140     permute (search_arr, SIZEOFFREE2 + 1, SIZEOFFREE);
2141 elmex 1.1 }
2142    
2143     /*
2144     * find_dir(map, x, y, exclude) will search some close squares in the
2145     * given map at the given coordinates for live objects.
2146     * It will not considered the object given as exclude among possible
2147     * live objects.
2148     * It returns the direction toward the first/closest live object if finds
2149     * any, otherwise 0.
2150     * Perhaps incorrectly, but I'm making the assumption that exclude
2151     * is actually want is going to try and move there. We need this info
2152     * because we have to know what movement the thing looking to move
2153     * there is capable of.
2154     */
2155 root 1.24 int
2156 root 1.49 find_dir (maptile *m, int x, int y, object *exclude)
2157 root 1.24 {
2158 root 1.275 int max = SIZEOFFREE, mflags;
2159     MoveType move_type;
2160 root 1.24
2161 root 1.155 if (exclude && exclude->head_ () != exclude)
2162 root 1.24 {
2163     exclude = exclude->head;
2164     move_type = exclude->move_type;
2165     }
2166     else
2167     {
2168     /* If we don't have anything, presume it can use all movement types. */
2169     move_type = MOVE_ALL;
2170     }
2171    
2172 root 1.275 for (int i = 1; i < max; i++)
2173 root 1.24 {
2174 root 1.275 mapxy pos (m, x, y);
2175     pos.move (i);
2176 root 1.75
2177 root 1.275 if (!pos.normalise ())
2178 root 1.75 max = maxfree[i];
2179 root 1.24 else
2180     {
2181 root 1.275 mapspace &ms = *pos;
2182 root 1.82
2183 root 1.275 if ((move_type & ms.move_block) == move_type)
2184     max = maxfree [i];
2185     else if (ms.flags () & P_IS_ALIVE)
2186 root 1.24 {
2187 root 1.275 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
2188 root 1.270 if ((tmp->flag [FLAG_MONSTER] || tmp->is_player ())
2189 root 1.155 && (tmp != exclude || (tmp->head_ () != tmp && tmp->head_ () != exclude)))
2190 root 1.275 return freedir [i];
2191 root 1.8 }
2192     }
2193 elmex 1.1 }
2194 root 1.75
2195 root 1.24 return 0;
2196 elmex 1.1 }
2197    
2198     /*
2199     * distance(object 1, object 2) will return the square of the
2200     * distance between the two given objects.
2201     */
2202 root 1.24 int
2203     distance (const object *ob1, const object *ob2)
2204     {
2205 root 1.82 return (ob1->x - ob2->x) * (ob1->x - ob2->x) + (ob1->y - ob2->y) * (ob1->y - ob2->y);
2206 elmex 1.1 }
2207    
2208     /*
2209 root 1.329 * find_dir_2(delta-x,delta-y) will return a direction value
2210     * for running into direct [dx, dy].
2211     * (the opposite of crossfire's find_dir_2!)
2212 elmex 1.1 */
2213 root 1.24 int
2214     find_dir_2 (int x, int y)
2215     {
2216 root 1.330 #if 1 // new algorithm
2217     // this works by putting x, y into 16 sectors, which
2218     // are not equal sized, but are a better approximation
2219     // then the old algorithm, and then using a mapping
2220     // table to map it into a direction value.
2221 root 1.331 // basically, it maps these comparisons to each bit
2222     // bit #3: x < 0
2223     // bit #2: y < 0
2224     // bit #1: x > y
2225     // bit #0: x > 2y
2226 root 1.330
2227     static const uint8 dir[16] = {
2228     4, 5, 4, 3,
2229     2, 1, 2, 3,
2230     6, 5, 6, 7,
2231     8, 1, 8, 7,
2232     };
2233     int sector = 0;
2234    
2235     // this is a bit ugly, but more likely to result in branchless code
2236     sector |= x < 0 ? 8 : 0;
2237     x = x < 0 ? -x : x; // abs
2238    
2239     sector |= y < 0 ? 4 : 0;
2240     y = y < 0 ? -y : y; // abs
2241    
2242     if (x > y)
2243     {
2244     sector |= 2;
2245    
2246     if (x > y * 2)
2247     sector |= 1;
2248     }
2249     else
2250     {
2251     if (y > x * 2)
2252     sector |= 1;
2253     else if (!y)
2254     return 0; // x == 0 here
2255     }
2256    
2257     return dir [sector];
2258     #else // old algorithm
2259 root 1.75 int q;
2260 elmex 1.1
2261 root 1.24 if (y)
2262 root 1.328 q = 128 * x / y;
2263 elmex 1.1 else if (x)
2264 root 1.329 q = -512 * x; // to make it > 309
2265 elmex 1.1 else
2266     return 0;
2267    
2268 root 1.24 if (y > 0)
2269     {
2270 root 1.329 if (q < -309) return 7;
2271     if (q < -52) return 6;
2272     if (q < 52) return 5;
2273     if (q < 309) return 4;
2274    
2275     return 3;
2276     }
2277     else
2278     {
2279 root 1.328 if (q < -309) return 3;
2280     if (q < -52) return 2;
2281     if (q < 52) return 1;
2282     if (q < 309) return 8;
2283    
2284 root 1.24 return 7;
2285     }
2286 root 1.330 #endif
2287 elmex 1.1 }
2288    
2289     /*
2290     * dirdiff(dir1, dir2) returns how many 45-degrees differences there is
2291     * between two directions (which are expected to be absolute (see absdir())
2292     */
2293 root 1.24 int
2294     dirdiff (int dir1, int dir2)
2295     {
2296 root 1.328 int d = abs (dir1 - dir2);
2297 root 1.82
2298 root 1.328 return d > 4 ? 8 - d : d;
2299 elmex 1.1 }
2300    
2301     /* peterm:
2302     * do LOS stuff for ball lightning. Go after the closest VISIBLE monster.
2303     * Basically, this is a table of directions, and what directions
2304     * one could go to go back to us. Eg, entry 15 below is 4, 14, 16.
2305     * This basically means that if direction is 15, then it could either go
2306     * direction 4, 14, or 16 to get back to where we are.
2307     * Moved from spell_util.c to object.c with the other related direction
2308     * functions.
2309     */
2310 root 1.295 static const int reduction_dir[SIZEOFFREE][3] = {
2311 root 1.24 {0, 0, 0}, /* 0 */
2312     {0, 0, 0}, /* 1 */
2313     {0, 0, 0}, /* 2 */
2314     {0, 0, 0}, /* 3 */
2315     {0, 0, 0}, /* 4 */
2316     {0, 0, 0}, /* 5 */
2317     {0, 0, 0}, /* 6 */
2318     {0, 0, 0}, /* 7 */
2319     {0, 0, 0}, /* 8 */
2320     {8, 1, 2}, /* 9 */
2321     {1, 2, -1}, /* 10 */
2322     {2, 10, 12}, /* 11 */
2323     {2, 3, -1}, /* 12 */
2324     {2, 3, 4}, /* 13 */
2325     {3, 4, -1}, /* 14 */
2326     {4, 14, 16}, /* 15 */
2327     {5, 4, -1}, /* 16 */
2328     {4, 5, 6}, /* 17 */
2329     {6, 5, -1}, /* 18 */
2330     {6, 20, 18}, /* 19 */
2331     {7, 6, -1}, /* 20 */
2332     {6, 7, 8}, /* 21 */
2333     {7, 8, -1}, /* 22 */
2334     {8, 22, 24}, /* 23 */
2335     {8, 1, -1}, /* 24 */
2336     {24, 9, 10}, /* 25 */
2337     {9, 10, -1}, /* 26 */
2338     {10, 11, -1}, /* 27 */
2339     {27, 11, 29}, /* 28 */
2340     {11, 12, -1}, /* 29 */
2341     {12, 13, -1}, /* 30 */
2342     {12, 13, 14}, /* 31 */
2343     {13, 14, -1}, /* 32 */
2344     {14, 15, -1}, /* 33 */
2345     {33, 15, 35}, /* 34 */
2346     {16, 15, -1}, /* 35 */
2347     {17, 16, -1}, /* 36 */
2348     {18, 17, 16}, /* 37 */
2349     {18, 17, -1}, /* 38 */
2350     {18, 19, -1}, /* 39 */
2351     {41, 19, 39}, /* 40 */
2352     {19, 20, -1}, /* 41 */
2353     {20, 21, -1}, /* 42 */
2354     {20, 21, 22}, /* 43 */
2355     {21, 22, -1}, /* 44 */
2356     {23, 22, -1}, /* 45 */
2357     {45, 47, 23}, /* 46 */
2358     {23, 24, -1}, /* 47 */
2359     {24, 9, -1}
2360     }; /* 48 */
2361 elmex 1.1
2362     /* Recursive routine to step back and see if we can
2363     * find a path to that monster that we found. If not,
2364     * we don't bother going toward it. Returns 1 if we
2365     * can see a direct way to get it
2366     * Modified to be map tile aware -.MSW
2367     */
2368 root 1.24 int
2369 root 1.49 can_see_monsterP (maptile *m, int x, int y, int dir)
2370 root 1.24 {
2371 root 1.29 sint16 dx, dy;
2372 root 1.75 int mflags;
2373 root 1.24
2374     if (dir < 0)
2375     return 0; /* exit condition: invalid direction */
2376    
2377     dx = x + freearr_x[dir];
2378     dy = y + freearr_y[dir];
2379    
2380     mflags = get_map_flags (m, &m, dx, dy, &dx, &dy);
2381    
2382     /* This functional arguably was incorrect before - it was
2383     * checking for P_WALL - that was basically seeing if
2384     * we could move to the monster - this is being more
2385     * literal on if we can see it. To know if we can actually
2386     * move to the monster, we'd need the monster passed in or
2387     * at least its move type.
2388     */
2389     if (mflags & (P_OUT_OF_MAP | P_BLOCKSVIEW))
2390     return 0;
2391    
2392     /* yes, can see. */
2393     if (dir < 9)
2394     return 1;
2395 root 1.75
2396     return can_see_monsterP (m, x, y, reduction_dir[dir][0])
2397     | can_see_monsterP (m, x, y, reduction_dir[dir][1])
2398     | can_see_monsterP (m, x, y, reduction_dir[dir][2]);
2399 root 1.24 }
2400    
2401 elmex 1.1 /*
2402     * can_pick(picker, item): finds out if an object is possible to be
2403     * picked up by the picker. Returnes 1 if it can be
2404     * picked up, otherwise 0.
2405     *
2406     * Cf 0.91.3 - don't let WIZ's pick up anything - will likely cause
2407     * core dumps if they do.
2408     *
2409     * Add a check so we can't pick up invisible objects (0.93.8)
2410     */
2411 root 1.24 int
2412     can_pick (const object *who, const object *item)
2413     {
2414 root 1.322 return /*who->flag [FLAG_WIZ]|| */
2415     (item->weight > 0 && !item->flag [FLAG_NO_PICK] &&
2416     !item->flag [FLAG_ALIVE] && !item->invisible && (who->is_player () || item->weight < who->weight / 3));
2417 elmex 1.1 }
2418    
2419 root 1.349 //-GPL
2420    
2421 elmex 1.1 /*
2422     * create clone from object to another
2423     */
2424 root 1.24 object *
2425 root 1.230 object::deep_clone ()
2426 root 1.24 {
2427 root 1.230 assert (("deep_clone called on non-head object", is_head ()));
2428 elmex 1.1
2429 root 1.230 object *dst = clone ();
2430 root 1.24
2431 root 1.230 object *prev = dst;
2432     for (object *part = this->more; part; part = part->more)
2433 root 1.24 {
2434 root 1.224 object *tmp = part->clone ();
2435 root 1.230 tmp->head = dst;
2436     prev->more = tmp;
2437 root 1.24 prev = tmp;
2438 elmex 1.1 }
2439 root 1.24
2440 root 1.230 for (object *item = inv; item; item = item->below)
2441     insert_ob_in_ob (item->deep_clone (), dst);
2442 elmex 1.1
2443 root 1.24 return dst;
2444 elmex 1.1 }
2445    
2446     /* This returns the first object in who's inventory that
2447     * has the same type and subtype match.
2448     * returns NULL if no match.
2449     */
2450 root 1.24 object *
2451     find_obj_by_type_subtype (const object *who, int type, int subtype)
2452 elmex 1.1 {
2453 root 1.82 for (object *tmp = who->inv; tmp; tmp = tmp->below)
2454 root 1.24 if (tmp->type == type && tmp->subtype == subtype)
2455     return tmp;
2456 elmex 1.1
2457 root 1.82 return 0;
2458 elmex 1.1 }
2459    
2460 root 1.344 /* Zero the key_values on op, decrementing the shared-string
2461     * refcounts and freeing the links.
2462     */
2463     void
2464     key_values::clear ()
2465     {
2466     for (key_value *kvp = first; kvp; )
2467     {
2468     key_value *next = kvp->next;
2469     delete kvp;
2470     kvp = next;
2471     }
2472    
2473     first = 0;
2474     }
2475    
2476 root 1.276 shstr_tmp
2477 root 1.344 key_values::get (shstr_tmp key) const
2478 root 1.24 {
2479 root 1.344 for (key_value *kv = first; kv; kv = kv->next)
2480 root 1.228 if (kv->key == key)
2481     return kv->value;
2482 root 1.24
2483 root 1.276 return shstr ();
2484 root 1.24 }
2485 elmex 1.1
2486 root 1.228 void
2487 root 1.344 key_values::add (shstr_tmp key, shstr_tmp value)
2488     {
2489     key_value *kv = new key_value;
2490    
2491     kv->next = first;
2492     kv->key = key;
2493     kv->value = value;
2494    
2495     first = kv;
2496     }
2497    
2498     void
2499     key_values::set (shstr_tmp key, shstr_tmp value)
2500 root 1.24 {
2501 root 1.344 for (key_value *kv = first; kv; kv = kv->next)
2502 root 1.228 if (kv->key == key)
2503     {
2504     kv->value = value;
2505     return;
2506     }
2507 root 1.24
2508 root 1.344 add (key, value);
2509 elmex 1.1 }
2510    
2511 root 1.228 void
2512 root 1.344 key_values::del (shstr_tmp key)
2513 root 1.24 {
2514 root 1.344 for (key_value **kvp = &first; *kvp; kvp = &(*kvp)->next)
2515 root 1.228 if ((*kvp)->key == key)
2516     {
2517     key_value *kv = *kvp;
2518     *kvp = (*kvp)->next;
2519     delete kv;
2520     return;
2521     }
2522 elmex 1.1 }
2523 root 1.31
2524 root 1.344 void
2525     key_values::reverse ()
2526     {
2527     key_value *prev = 0;
2528     key_value *head = first;
2529    
2530     while (head)
2531     {
2532     key_value *node = head;
2533     head = head->next;
2534     node->next = prev;
2535     prev = node;
2536     }
2537    
2538     first = prev;
2539     }
2540    
2541     key_values &
2542     key_values::operator =(const key_values &kv)
2543     {
2544     clear ();
2545    
2546     for (key_value *kvp = kv.first; kvp; kvp = kvp->next)
2547     add (kvp->key, kvp->value);
2548    
2549     reverse ();
2550     }
2551    
2552 root 1.34 object::depth_iterator::depth_iterator (object *container)
2553     : iterator_base (container)
2554     {
2555     while (item->inv)
2556     item = item->inv;
2557     }
2558    
2559 root 1.31 void
2560 root 1.34 object::depth_iterator::next ()
2561 root 1.31 {
2562 root 1.34 if (item->below)
2563     {
2564     item = item->below;
2565    
2566     while (item->inv)
2567     item = item->inv;
2568     }
2569 root 1.31 else
2570 root 1.34 item = item->env;
2571 root 1.31 }
2572 root 1.34
2573 elmex 1.97 const char *
2574     object::flag_desc (char *desc, int len) const
2575     {
2576     char *p = desc;
2577     bool first = true;
2578    
2579 root 1.101 *p = 0;
2580    
2581 elmex 1.97 for (int i = 0; i < NUM_FLAGS; i++)
2582     {
2583     if (len <= 10) // magic constant!
2584     {
2585     snprintf (p, len, ",...");
2586     break;
2587     }
2588    
2589 root 1.101 if (flag [i])
2590 elmex 1.97 {
2591     int cnt = snprintf (p, len, "%s%d", first ? "" : ",", i);
2592     len -= cnt;
2593     p += cnt;
2594     first = false;
2595     }
2596     }
2597    
2598     return desc;
2599     }
2600    
2601 root 1.101 // return a suitable string describing an object in enough detail to find it
2602 root 1.36 const char *
2603     object::debug_desc (char *info) const
2604     {
2605 elmex 1.97 char flagdesc[512];
2606     char info2[256 * 4];
2607 root 1.36 char *p = info;
2608    
2609 elmex 1.242 p += snprintf (p, 512, "{cnt:%d,uuid:%s,name:\"%s\"%s%s%s,flags:[%s],type:%d}",
2610 root 1.203 count,
2611     uuid.c_str (),
2612 root 1.36 &name,
2613 elmex 1.242 title ? ",title:\"" : "",
2614 elmex 1.97 title ? (const char *)title : "",
2615 elmex 1.242 title ? "\"" : "",
2616 elmex 1.97 flag_desc (flagdesc, 512), type);
2617 root 1.36
2618 root 1.217 if (!flag[FLAG_REMOVED] && env)
2619 root 1.36 p += snprintf (p, 256, "(in %s)", env->debug_desc (info2));
2620    
2621     if (map)
2622 root 1.96 p += snprintf (p, 256, "(on %s@%d+%d)", &map->path, x, y);
2623 root 1.36
2624     return info;
2625     }
2626    
2627     const char *
2628     object::debug_desc () const
2629     {
2630 root 1.143 static char info[3][256 * 4];
2631     static int info_idx;
2632 root 1.36
2633 root 1.143 return debug_desc (info [++info_idx % 3]);
2634 root 1.114 }
2635    
2636 root 1.125 struct region *
2637     object::region () const
2638     {
2639     return map ? map->region (x, y)
2640     : region::default_region ();
2641     }
2642    
2643 root 1.349 //+GPL
2644    
2645 root 1.130 void
2646     object::open_container (object *new_container)
2647     {
2648     if (container == new_container)
2649     return;
2650    
2651 root 1.220 object *old_container = container;
2652    
2653     if (old_container)
2654 root 1.130 {
2655     if (INVOKE_OBJECT (CLOSE, old_container, ARG_OBJECT (this)))
2656     return;
2657    
2658     #if 0
2659     // remove the "Close old_container" object.
2660     if (object *closer = old_container->inv)
2661     if (closer->type == CLOSE_CON)
2662 root 1.259 closer->destroy ();
2663 root 1.130 #endif
2664    
2665 root 1.220 // make sure the container is available
2666     esrv_send_item (this, old_container);
2667    
2668 root 1.216 old_container->flag [FLAG_APPLIED] = false;
2669 root 1.130 container = 0;
2670    
2671 root 1.220 // client needs item update to make it work, client bug requires this to be separate
2672 root 1.130 esrv_update_item (UPD_FLAGS, this, old_container);
2673 root 1.220
2674 root 1.281 new_draw_info_format (NDI_UNIQUE, 0, this, "You close %s.", old_container->query_name ());
2675 root 1.177 play_sound (sound_find ("chest_close"));
2676 root 1.130 }
2677    
2678     if (new_container)
2679     {
2680     if (INVOKE_OBJECT (OPEN, new_container, ARG_OBJECT (this)))
2681     return;
2682    
2683     // TODO: this does not seem to serve any purpose anymore?
2684     #if 0
2685     // insert the "Close Container" object.
2686     if (archetype *closer = new_container->other_arch)
2687     {
2688 root 1.309 object *closer = new_container->other_arch->instance ();
2689 root 1.130 closer->flag [FLAG_NO_MAP_SAVE] = 1;
2690     new_container->insert (closer);
2691     }
2692     #endif
2693    
2694 root 1.281 new_draw_info_format (NDI_UNIQUE, 0, this, "You open %s.", new_container->query_name ());
2695 root 1.132
2696 root 1.220 // make sure the container is available, client bug requires this to be separate
2697     esrv_send_item (this, new_container);
2698    
2699 root 1.216 new_container->flag [FLAG_APPLIED] = true;
2700 root 1.130 container = new_container;
2701    
2702 root 1.220 // client needs flag change
2703 root 1.130 esrv_update_item (UPD_FLAGS, this, new_container);
2704 root 1.131 esrv_send_inventory (this, new_container);
2705 root 1.177 play_sound (sound_find ("chest_open"));
2706 root 1.130 }
2707 root 1.220 // else if (!old_container->env && contr && contr->ns)
2708     // contr->ns->floorbox_reset ();
2709 root 1.130 }
2710    
2711 root 1.349 //-GPL
2712    
2713     // prefetch some flat area around the player
2714     static void
2715     prefetch_surrounding_area (object *op, maptile *map, int range)
2716     {
2717     for (maprect *rect = map->split_to_tiles (mapwalk_buf,
2718     op->x - range , op->y - range ,
2719     op->x + range + 1, op->y + range + 1);
2720     rect->m;
2721     ++rect)
2722     {
2723     rect->m->touch ();
2724     rect->m->activate ();
2725     }
2726     }
2727    
2728     // prefetch a generous area around the player, also up and down
2729     void
2730     object::prefetch_surrounding_maps ()
2731     {
2732     prefetch_surrounding_area (this, map, 40);
2733    
2734     if (maptile *m = map->tile_available (TILE_DOWN))
2735     prefetch_surrounding_area (this, m, 20);
2736    
2737     if (maptile *m = map->tile_available (TILE_UP))
2738     prefetch_surrounding_area (this, m, 20);
2739     }
2740    
2741     //+GPL
2742    
2743 root 1.164 object *
2744 root 1.276 object::force_find (shstr_tmp name)
2745 root 1.164 {
2746     /* cycle through his inventory to look for the MARK we want to
2747     * place
2748     */
2749     for (object *tmp = inv; tmp; tmp = tmp->below)
2750     if (tmp->type == FORCE && tmp->slaying == name)
2751     return splay (tmp);
2752    
2753     return 0;
2754     }
2755    
2756 sf-marcmagus 1.290 void
2757     object::force_set_timer (int duration)
2758     {
2759     this->duration = 1;
2760     this->speed_left = -1.f;
2761    
2762     this->set_speed (duration ? 1.f / duration : 0.f);
2763     }
2764    
2765 root 1.265 object *
2766 root 1.276 object::force_add (shstr_tmp name, int duration)
2767 root 1.164 {
2768     if (object *force = force_find (name))
2769 root 1.259 force->destroy ();
2770 root 1.164
2771 root 1.345 object *force = archetype::get (FORCE_NAME);
2772 root 1.164
2773 sf-marcmagus 1.290 force->slaying = name;
2774     force->force_set_timer (duration);
2775 root 1.294 force->flag [FLAG_APPLIED] = true;
2776 root 1.164
2777 root 1.265 return insert (force);
2778 root 1.164 }
2779    
2780 root 1.178 void
2781 root 1.280 object::play_sound (faceidx sound) const
2782 root 1.178 {
2783     if (!sound)
2784     return;
2785    
2786 root 1.280 if (is_on_map ())
2787     map->play_sound (sound, x, y);
2788     else if (object *pl = in_player ())
2789     pl->contr->play_sound (sound);
2790     }
2791 root 1.178
2792 root 1.280 void
2793     object::say_msg (const char *msg) const
2794     {
2795     if (is_on_map ())
2796     map->say_msg (msg, x, y);
2797     else if (object *pl = in_player ())
2798     pl->contr->play_sound (sound);
2799 root 1.178 }
2800    
2801 root 1.265 void
2802     object::make_noise ()
2803     {
2804     // we do not model noise in the map, so instead put
2805     // a temporary light into the noise source
2806     // could use the map instead, but that's less reliable for our
2807     // goal, which is to make invisibility a bit harder to exploit
2808    
2809 root 1.266 // currently only works sensibly for players
2810     if (!is_player ())
2811     return;
2812    
2813 root 1.265 // find old force, or create new one
2814     object *force = force_find (shstr_noise_force);
2815    
2816     if (force)
2817 root 1.269 force->speed_left = -1.f; // patch old speed up
2818 root 1.265 else
2819 root 1.269 {
2820     force = archetype::get (shstr_noise_force);
2821    
2822     force->slaying = shstr_noise_force;
2823     force->stats.food = 1;
2824     force->speed_left = -1.f;
2825    
2826     force->set_speed (1.f / 4.f);
2827     force->flag [FLAG_IS_USED_UP] = true;
2828     force->flag [FLAG_APPLIED] = true;
2829    
2830     insert (force);
2831     }
2832 root 1.265 }
2833    
2834 root 1.313 void object::change_move_type (MoveType mt)
2835     {
2836     if (move_type == mt)
2837     return;
2838    
2839     if (is_on_map ())
2840     {
2841     // we are on the map, so handle move_on/off effects
2842     remove ();
2843     move_type = mt;
2844     map->insert (this, x, y, this);
2845     }
2846     else
2847     move_type = mt;
2848     }
2849    
2850 root 1.325 /* object should be a player.
2851     * we return the object the player has marked with the 'mark' command
2852     * below. If no match is found (or object has changed), we return
2853     * NULL. We leave it up to the calling function to print messages if
2854     * nothing is found.
2855     */
2856     object *
2857     object::mark () const
2858     {
2859     if (contr && contr->mark && contr->mark->env == this)
2860     return contr->mark;
2861     else
2862     return 0;
2863     }
2864    
2865 root 1.340 // put marked object first in the inventory
2866     // this is used by identify-like spells so players can influence
2867     // the order a bit.
2868     void
2869     object::splay_marked ()
2870     {
2871     if (object *marked = mark ())
2872     splay (marked);
2873     }
2874