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