ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.323
Committed: Sun Apr 11 23:56:09 2010 UTC (14 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.322: +2 -2 lines
Log Message:
no delitem player

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